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 2234 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2235 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2236 // A variable of class type (or array thereof) that appears in a lastprivate 2237 // clause requires an accessible, unambiguous default constructor for the 2238 // class type, unless the list item is also specified in a firstprivate 2239 // clause. 2240 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2241 for (OMPClause *C : D->clauses()) { 2242 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2243 SmallVector<Expr *, 8> PrivateCopies; 2244 for (Expr *DE : Clause->varlists()) { 2245 if (DE->isValueDependent() || DE->isTypeDependent()) { 2246 PrivateCopies.push_back(nullptr); 2247 continue; 2248 } 2249 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2250 auto *VD = cast<VarDecl>(DRE->getDecl()); 2251 QualType Type = VD->getType().getNonReferenceType(); 2252 const DSAStackTy::DSAVarData DVar = 2253 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2254 if (DVar.CKind == OMPC_lastprivate) { 2255 // Generate helper private variable and initialize it with the 2256 // default value. The address of the original variable is replaced 2257 // by the address of the new private variable in CodeGen. This new 2258 // variable is not added to IdResolver, so the code in the OpenMP 2259 // region uses original variable for proper diagnostics. 2260 VarDecl *VDPrivate = buildVarDecl( 2261 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2262 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2263 ActOnUninitializedDecl(VDPrivate); 2264 if (VDPrivate->isInvalidDecl()) { 2265 PrivateCopies.push_back(nullptr); 2266 continue; 2267 } 2268 PrivateCopies.push_back(buildDeclRefExpr( 2269 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2270 } else { 2271 // The variable is also a firstprivate, so initialization sequence 2272 // for private copy is generated already. 2273 PrivateCopies.push_back(nullptr); 2274 } 2275 } 2276 Clause->setPrivateCopies(PrivateCopies); 2277 } 2278 } 2279 // Check allocate clauses. 2280 if (!CurContext->isDependentContext()) 2281 checkAllocateClauses(*this, DSAStack, D->clauses()); 2282 } 2283 2284 DSAStack->pop(); 2285 DiscardCleanupsInEvaluationContext(); 2286 PopExpressionEvaluationContext(); 2287 } 2288 2289 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2290 Expr *NumIterations, Sema &SemaRef, 2291 Scope *S, DSAStackTy *Stack); 2292 2293 namespace { 2294 2295 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2296 private: 2297 Sema &SemaRef; 2298 2299 public: 2300 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2301 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2302 NamedDecl *ND = Candidate.getCorrectionDecl(); 2303 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2304 return VD->hasGlobalStorage() && 2305 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2306 SemaRef.getCurScope()); 2307 } 2308 return false; 2309 } 2310 2311 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2312 return std::make_unique<VarDeclFilterCCC>(*this); 2313 } 2314 2315 }; 2316 2317 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2318 private: 2319 Sema &SemaRef; 2320 2321 public: 2322 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2323 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2324 NamedDecl *ND = Candidate.getCorrectionDecl(); 2325 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2326 isa<FunctionDecl>(ND))) { 2327 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2328 SemaRef.getCurScope()); 2329 } 2330 return false; 2331 } 2332 2333 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2334 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2335 } 2336 }; 2337 2338 } // namespace 2339 2340 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2341 CXXScopeSpec &ScopeSpec, 2342 const DeclarationNameInfo &Id, 2343 OpenMPDirectiveKind Kind) { 2344 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2345 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2346 2347 if (Lookup.isAmbiguous()) 2348 return ExprError(); 2349 2350 VarDecl *VD; 2351 if (!Lookup.isSingleResult()) { 2352 VarDeclFilterCCC CCC(*this); 2353 if (TypoCorrection Corrected = 2354 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2355 CTK_ErrorRecovery)) { 2356 diagnoseTypo(Corrected, 2357 PDiag(Lookup.empty() 2358 ? diag::err_undeclared_var_use_suggest 2359 : diag::err_omp_expected_var_arg_suggest) 2360 << Id.getName()); 2361 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2362 } else { 2363 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2364 : diag::err_omp_expected_var_arg) 2365 << Id.getName(); 2366 return ExprError(); 2367 } 2368 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2369 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2370 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2371 return ExprError(); 2372 } 2373 Lookup.suppressDiagnostics(); 2374 2375 // OpenMP [2.9.2, Syntax, C/C++] 2376 // Variables must be file-scope, namespace-scope, or static block-scope. 2377 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2378 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2379 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2380 bool IsDecl = 2381 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2382 Diag(VD->getLocation(), 2383 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2384 << VD; 2385 return ExprError(); 2386 } 2387 2388 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2389 NamedDecl *ND = CanonicalVD; 2390 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2391 // A threadprivate directive for file-scope variables must appear outside 2392 // any definition or declaration. 2393 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2394 !getCurLexicalContext()->isTranslationUnit()) { 2395 Diag(Id.getLoc(), diag::err_omp_var_scope) 2396 << getOpenMPDirectiveName(Kind) << VD; 2397 bool IsDecl = 2398 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2399 Diag(VD->getLocation(), 2400 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2401 << VD; 2402 return ExprError(); 2403 } 2404 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2405 // A threadprivate directive for static class member variables must appear 2406 // in the class definition, in the same scope in which the member 2407 // variables are declared. 2408 if (CanonicalVD->isStaticDataMember() && 2409 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2410 Diag(Id.getLoc(), diag::err_omp_var_scope) 2411 << getOpenMPDirectiveName(Kind) << VD; 2412 bool IsDecl = 2413 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2414 Diag(VD->getLocation(), 2415 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2416 << VD; 2417 return ExprError(); 2418 } 2419 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2420 // A threadprivate directive for namespace-scope variables must appear 2421 // outside any definition or declaration other than the namespace 2422 // definition itself. 2423 if (CanonicalVD->getDeclContext()->isNamespace() && 2424 (!getCurLexicalContext()->isFileContext() || 2425 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2426 Diag(Id.getLoc(), diag::err_omp_var_scope) 2427 << getOpenMPDirectiveName(Kind) << VD; 2428 bool IsDecl = 2429 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2430 Diag(VD->getLocation(), 2431 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2432 << VD; 2433 return ExprError(); 2434 } 2435 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2436 // A threadprivate directive for static block-scope variables must appear 2437 // in the scope of the variable and not in a nested scope. 2438 if (CanonicalVD->isLocalVarDecl() && CurScope && 2439 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 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 2450 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2451 // A threadprivate directive must lexically precede all references to any 2452 // of the variables in its list. 2453 if (Kind == OMPD_threadprivate && VD->isUsed() && 2454 !DSAStack->isThreadPrivate(VD)) { 2455 Diag(Id.getLoc(), diag::err_omp_var_used) 2456 << getOpenMPDirectiveName(Kind) << VD; 2457 return ExprError(); 2458 } 2459 2460 QualType ExprType = VD->getType().getNonReferenceType(); 2461 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2462 SourceLocation(), VD, 2463 /*RefersToEnclosingVariableOrCapture=*/false, 2464 Id.getLoc(), ExprType, VK_LValue); 2465 } 2466 2467 Sema::DeclGroupPtrTy 2468 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2469 ArrayRef<Expr *> VarList) { 2470 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2471 CurContext->addDecl(D); 2472 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2473 } 2474 return nullptr; 2475 } 2476 2477 namespace { 2478 class LocalVarRefChecker final 2479 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2480 Sema &SemaRef; 2481 2482 public: 2483 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2484 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2485 if (VD->hasLocalStorage()) { 2486 SemaRef.Diag(E->getBeginLoc(), 2487 diag::err_omp_local_var_in_threadprivate_init) 2488 << E->getSourceRange(); 2489 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2490 << VD << VD->getSourceRange(); 2491 return true; 2492 } 2493 } 2494 return false; 2495 } 2496 bool VisitStmt(const Stmt *S) { 2497 for (const Stmt *Child : S->children()) { 2498 if (Child && Visit(Child)) 2499 return true; 2500 } 2501 return false; 2502 } 2503 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2504 }; 2505 } // namespace 2506 2507 OMPThreadPrivateDecl * 2508 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2509 SmallVector<Expr *, 8> Vars; 2510 for (Expr *RefExpr : VarList) { 2511 auto *DE = cast<DeclRefExpr>(RefExpr); 2512 auto *VD = cast<VarDecl>(DE->getDecl()); 2513 SourceLocation ILoc = DE->getExprLoc(); 2514 2515 // Mark variable as used. 2516 VD->setReferenced(); 2517 VD->markUsed(Context); 2518 2519 QualType QType = VD->getType(); 2520 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2521 // It will be analyzed later. 2522 Vars.push_back(DE); 2523 continue; 2524 } 2525 2526 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2527 // A threadprivate variable must not have an incomplete type. 2528 if (RequireCompleteType(ILoc, VD->getType(), 2529 diag::err_omp_threadprivate_incomplete_type)) { 2530 continue; 2531 } 2532 2533 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2534 // A threadprivate variable must not have a reference type. 2535 if (VD->getType()->isReferenceType()) { 2536 Diag(ILoc, diag::err_omp_ref_type_arg) 2537 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2538 bool IsDecl = 2539 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2540 Diag(VD->getLocation(), 2541 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2542 << VD; 2543 continue; 2544 } 2545 2546 // Check if this is a TLS variable. If TLS is not being supported, produce 2547 // the corresponding diagnostic. 2548 if ((VD->getTLSKind() != VarDecl::TLS_None && 2549 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2550 getLangOpts().OpenMPUseTLS && 2551 getASTContext().getTargetInfo().isTLSSupported())) || 2552 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2553 !VD->isLocalVarDecl())) { 2554 Diag(ILoc, diag::err_omp_var_thread_local) 2555 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2556 bool IsDecl = 2557 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2558 Diag(VD->getLocation(), 2559 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2560 << VD; 2561 continue; 2562 } 2563 2564 // Check if initial value of threadprivate variable reference variable with 2565 // local storage (it is not supported by runtime). 2566 if (const Expr *Init = VD->getAnyInitializer()) { 2567 LocalVarRefChecker Checker(*this); 2568 if (Checker.Visit(Init)) 2569 continue; 2570 } 2571 2572 Vars.push_back(RefExpr); 2573 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2574 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2575 Context, SourceRange(Loc, Loc))); 2576 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2577 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2578 } 2579 OMPThreadPrivateDecl *D = nullptr; 2580 if (!Vars.empty()) { 2581 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2582 Vars); 2583 D->setAccess(AS_public); 2584 } 2585 return D; 2586 } 2587 2588 static OMPAllocateDeclAttr::AllocatorTypeTy 2589 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2590 if (!Allocator) 2591 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2592 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2593 Allocator->isInstantiationDependent() || 2594 Allocator->containsUnexpandedParameterPack()) 2595 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2596 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2597 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2598 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2599 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2600 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2601 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2602 llvm::FoldingSetNodeID AEId, DAEId; 2603 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2604 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2605 if (AEId == DAEId) { 2606 AllocatorKindRes = AllocatorKind; 2607 break; 2608 } 2609 } 2610 return AllocatorKindRes; 2611 } 2612 2613 static bool checkPreviousOMPAllocateAttribute( 2614 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2615 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2616 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2617 return false; 2618 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2619 Expr *PrevAllocator = A->getAllocator(); 2620 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2621 getAllocatorKind(S, Stack, PrevAllocator); 2622 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2623 if (AllocatorsMatch && 2624 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2625 Allocator && PrevAllocator) { 2626 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2627 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2628 llvm::FoldingSetNodeID AEId, PAEId; 2629 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2630 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2631 AllocatorsMatch = AEId == PAEId; 2632 } 2633 if (!AllocatorsMatch) { 2634 SmallString<256> AllocatorBuffer; 2635 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2636 if (Allocator) 2637 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2638 SmallString<256> PrevAllocatorBuffer; 2639 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2640 if (PrevAllocator) 2641 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2642 S.getPrintingPolicy()); 2643 2644 SourceLocation AllocatorLoc = 2645 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2646 SourceRange AllocatorRange = 2647 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2648 SourceLocation PrevAllocatorLoc = 2649 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2650 SourceRange PrevAllocatorRange = 2651 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2652 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2653 << (Allocator ? 1 : 0) << AllocatorStream.str() 2654 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2655 << AllocatorRange; 2656 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2657 << PrevAllocatorRange; 2658 return true; 2659 } 2660 return false; 2661 } 2662 2663 static void 2664 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2665 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2666 Expr *Allocator, SourceRange SR) { 2667 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2668 return; 2669 if (Allocator && 2670 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2671 Allocator->isInstantiationDependent() || 2672 Allocator->containsUnexpandedParameterPack())) 2673 return; 2674 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2675 Allocator, SR); 2676 VD->addAttr(A); 2677 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2678 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2679 } 2680 2681 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2682 SourceLocation Loc, ArrayRef<Expr *> VarList, 2683 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2684 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2685 Expr *Allocator = nullptr; 2686 if (Clauses.empty()) { 2687 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2688 // allocate directives that appear in a target region must specify an 2689 // allocator clause unless a requires directive with the dynamic_allocators 2690 // clause is present in the same compilation unit. 2691 if (LangOpts.OpenMPIsDevice && 2692 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2693 targetDiag(Loc, diag::err_expected_allocator_clause); 2694 } else { 2695 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2696 } 2697 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2698 getAllocatorKind(*this, DSAStack, Allocator); 2699 SmallVector<Expr *, 8> Vars; 2700 for (Expr *RefExpr : VarList) { 2701 auto *DE = cast<DeclRefExpr>(RefExpr); 2702 auto *VD = cast<VarDecl>(DE->getDecl()); 2703 2704 // Check if this is a TLS variable or global register. 2705 if (VD->getTLSKind() != VarDecl::TLS_None || 2706 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2707 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2708 !VD->isLocalVarDecl())) 2709 continue; 2710 2711 // If the used several times in the allocate directive, the same allocator 2712 // must be used. 2713 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2714 AllocatorKind, Allocator)) 2715 continue; 2716 2717 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2718 // If a list item has a static storage type, the allocator expression in the 2719 // allocator clause must be a constant expression that evaluates to one of 2720 // the predefined memory allocator values. 2721 if (Allocator && VD->hasGlobalStorage()) { 2722 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2723 Diag(Allocator->getExprLoc(), 2724 diag::err_omp_expected_predefined_allocator) 2725 << Allocator->getSourceRange(); 2726 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2727 VarDecl::DeclarationOnly; 2728 Diag(VD->getLocation(), 2729 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2730 << VD; 2731 continue; 2732 } 2733 } 2734 2735 Vars.push_back(RefExpr); 2736 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2737 DE->getSourceRange()); 2738 } 2739 if (Vars.empty()) 2740 return nullptr; 2741 if (!Owner) 2742 Owner = getCurLexicalContext(); 2743 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2744 D->setAccess(AS_public); 2745 Owner->addDecl(D); 2746 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2747 } 2748 2749 Sema::DeclGroupPtrTy 2750 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2751 ArrayRef<OMPClause *> ClauseList) { 2752 OMPRequiresDecl *D = nullptr; 2753 if (!CurContext->isFileContext()) { 2754 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2755 } else { 2756 D = CheckOMPRequiresDecl(Loc, ClauseList); 2757 if (D) { 2758 CurContext->addDecl(D); 2759 DSAStack->addRequiresDecl(D); 2760 } 2761 } 2762 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2763 } 2764 2765 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2766 ArrayRef<OMPClause *> ClauseList) { 2767 /// For target specific clauses, the requires directive cannot be 2768 /// specified after the handling of any of the target regions in the 2769 /// current compilation unit. 2770 ArrayRef<SourceLocation> TargetLocations = 2771 DSAStack->getEncounteredTargetLocs(); 2772 if (!TargetLocations.empty()) { 2773 for (const OMPClause *CNew : ClauseList) { 2774 // Check if any of the requires clauses affect target regions. 2775 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2776 isa<OMPUnifiedAddressClause>(CNew) || 2777 isa<OMPReverseOffloadClause>(CNew) || 2778 isa<OMPDynamicAllocatorsClause>(CNew)) { 2779 Diag(Loc, diag::err_omp_target_before_requires) 2780 << getOpenMPClauseName(CNew->getClauseKind()); 2781 for (SourceLocation TargetLoc : TargetLocations) { 2782 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2783 } 2784 } 2785 } 2786 } 2787 2788 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2789 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2790 ClauseList); 2791 return nullptr; 2792 } 2793 2794 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2795 const ValueDecl *D, 2796 const DSAStackTy::DSAVarData &DVar, 2797 bool IsLoopIterVar = false) { 2798 if (DVar.RefExpr) { 2799 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2800 << getOpenMPClauseName(DVar.CKind); 2801 return; 2802 } 2803 enum { 2804 PDSA_StaticMemberShared, 2805 PDSA_StaticLocalVarShared, 2806 PDSA_LoopIterVarPrivate, 2807 PDSA_LoopIterVarLinear, 2808 PDSA_LoopIterVarLastprivate, 2809 PDSA_ConstVarShared, 2810 PDSA_GlobalVarShared, 2811 PDSA_TaskVarFirstprivate, 2812 PDSA_LocalVarPrivate, 2813 PDSA_Implicit 2814 } Reason = PDSA_Implicit; 2815 bool ReportHint = false; 2816 auto ReportLoc = D->getLocation(); 2817 auto *VD = dyn_cast<VarDecl>(D); 2818 if (IsLoopIterVar) { 2819 if (DVar.CKind == OMPC_private) 2820 Reason = PDSA_LoopIterVarPrivate; 2821 else if (DVar.CKind == OMPC_lastprivate) 2822 Reason = PDSA_LoopIterVarLastprivate; 2823 else 2824 Reason = PDSA_LoopIterVarLinear; 2825 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2826 DVar.CKind == OMPC_firstprivate) { 2827 Reason = PDSA_TaskVarFirstprivate; 2828 ReportLoc = DVar.ImplicitDSALoc; 2829 } else if (VD && VD->isStaticLocal()) 2830 Reason = PDSA_StaticLocalVarShared; 2831 else if (VD && VD->isStaticDataMember()) 2832 Reason = PDSA_StaticMemberShared; 2833 else if (VD && VD->isFileVarDecl()) 2834 Reason = PDSA_GlobalVarShared; 2835 else if (D->getType().isConstant(SemaRef.getASTContext())) 2836 Reason = PDSA_ConstVarShared; 2837 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2838 ReportHint = true; 2839 Reason = PDSA_LocalVarPrivate; 2840 } 2841 if (Reason != PDSA_Implicit) { 2842 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2843 << Reason << ReportHint 2844 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2845 } else if (DVar.ImplicitDSALoc.isValid()) { 2846 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2847 << getOpenMPClauseName(DVar.CKind); 2848 } 2849 } 2850 2851 static OpenMPMapClauseKind 2852 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 2853 bool IsAggregateOrDeclareTarget) { 2854 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 2855 switch (M) { 2856 case OMPC_DEFAULTMAP_MODIFIER_alloc: 2857 Kind = OMPC_MAP_alloc; 2858 break; 2859 case OMPC_DEFAULTMAP_MODIFIER_to: 2860 Kind = OMPC_MAP_to; 2861 break; 2862 case OMPC_DEFAULTMAP_MODIFIER_from: 2863 Kind = OMPC_MAP_from; 2864 break; 2865 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 2866 Kind = OMPC_MAP_tofrom; 2867 break; 2868 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 2869 case OMPC_DEFAULTMAP_MODIFIER_last: 2870 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2871 case OMPC_DEFAULTMAP_MODIFIER_none: 2872 case OMPC_DEFAULTMAP_MODIFIER_default: 2873 case OMPC_DEFAULTMAP_MODIFIER_unknown: 2874 // IsAggregateOrDeclareTarget could be true if: 2875 // 1. the implicit behavior for aggregate is tofrom 2876 // 2. it's a declare target link 2877 if (IsAggregateOrDeclareTarget) { 2878 Kind = OMPC_MAP_tofrom; 2879 break; 2880 } 2881 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2882 } 2883 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 2884 return Kind; 2885 } 2886 2887 namespace { 2888 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2889 DSAStackTy *Stack; 2890 Sema &SemaRef; 2891 bool ErrorFound = false; 2892 bool TryCaptureCXXThisMembers = false; 2893 CapturedStmt *CS = nullptr; 2894 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2895 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 2896 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2897 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2898 2899 void VisitSubCaptures(OMPExecutableDirective *S) { 2900 // Check implicitly captured variables. 2901 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2902 return; 2903 visitSubCaptures(S->getInnermostCapturedStmt()); 2904 // Try to capture inner this->member references to generate correct mappings 2905 // and diagnostics. 2906 if (TryCaptureCXXThisMembers || 2907 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2908 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2909 [](const CapturedStmt::Capture &C) { 2910 return C.capturesThis(); 2911 }))) { 2912 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2913 TryCaptureCXXThisMembers = true; 2914 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2915 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2916 } 2917 } 2918 2919 public: 2920 void VisitDeclRefExpr(DeclRefExpr *E) { 2921 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 2922 E->isValueDependent() || E->containsUnexpandedParameterPack() || 2923 E->isInstantiationDependent()) 2924 return; 2925 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2926 // Check the datasharing rules for the expressions in the clauses. 2927 if (!CS) { 2928 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2929 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2930 Visit(CED->getInit()); 2931 return; 2932 } 2933 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2934 // Do not analyze internal variables and do not enclose them into 2935 // implicit clauses. 2936 return; 2937 VD = VD->getCanonicalDecl(); 2938 // Skip internally declared variables. 2939 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2940 return; 2941 2942 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2943 // Check if the variable has explicit DSA set and stop analysis if it so. 2944 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2945 return; 2946 2947 // Skip internally declared static variables. 2948 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2949 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2950 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2951 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2952 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2953 return; 2954 2955 SourceLocation ELoc = E->getExprLoc(); 2956 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2957 // The default(none) clause requires that each variable that is referenced 2958 // in the construct, and does not have a predetermined data-sharing 2959 // attribute, must have its data-sharing attribute explicitly determined 2960 // by being listed in a data-sharing attribute clause. 2961 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2962 isImplicitOrExplicitTaskingRegion(DKind) && 2963 VarsWithInheritedDSA.count(VD) == 0) { 2964 VarsWithInheritedDSA[VD] = E; 2965 return; 2966 } 2967 2968 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 2969 // If implicit-behavior is none, each variable referenced in the 2970 // construct that does not have a predetermined data-sharing attribute 2971 // and does not appear in a to or link clause on a declare target 2972 // directive must be listed in a data-mapping attribute clause, a 2973 // data-haring attribute clause (including a data-sharing attribute 2974 // clause on a combined construct where target. is one of the 2975 // constituent constructs), or an is_device_ptr clause. 2976 OpenMPDefaultmapClauseKind ClauseKind = 2977 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 2978 if (SemaRef.getLangOpts().OpenMP >= 50) { 2979 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 2980 OMPC_DEFAULTMAP_MODIFIER_none; 2981 if (DVar.CKind == OMPC_unknown && IsModifierNone && 2982 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 2983 // Only check for data-mapping attribute and is_device_ptr here 2984 // since we have already make sure that the declaration does not 2985 // have a data-sharing attribute above 2986 if (!Stack->checkMappableExprComponentListsForDecl( 2987 VD, /*CurrentRegionOnly=*/true, 2988 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 2989 MapExprComponents, 2990 OpenMPClauseKind) { 2991 auto MI = MapExprComponents.rbegin(); 2992 auto ME = MapExprComponents.rend(); 2993 return MI != ME && MI->getAssociatedDeclaration() == VD; 2994 })) { 2995 VarsWithInheritedDSA[VD] = E; 2996 return; 2997 } 2998 } 2999 } 3000 3001 if (isOpenMPTargetExecutionDirective(DKind) && 3002 !Stack->isLoopControlVariable(VD).first) { 3003 if (!Stack->checkMappableExprComponentListsForDecl( 3004 VD, /*CurrentRegionOnly=*/true, 3005 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3006 StackComponents, 3007 OpenMPClauseKind) { 3008 // Variable is used if it has been marked as an array, array 3009 // section or the variable iself. 3010 return StackComponents.size() == 1 || 3011 std::all_of( 3012 std::next(StackComponents.rbegin()), 3013 StackComponents.rend(), 3014 [](const OMPClauseMappableExprCommon:: 3015 MappableComponent &MC) { 3016 return MC.getAssociatedDeclaration() == 3017 nullptr && 3018 (isa<OMPArraySectionExpr>( 3019 MC.getAssociatedExpression()) || 3020 isa<ArraySubscriptExpr>( 3021 MC.getAssociatedExpression())); 3022 }); 3023 })) { 3024 bool IsFirstprivate = false; 3025 // By default lambdas are captured as firstprivates. 3026 if (const auto *RD = 3027 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3028 IsFirstprivate = RD->isLambda(); 3029 IsFirstprivate = 3030 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3031 if (IsFirstprivate) { 3032 ImplicitFirstprivate.emplace_back(E); 3033 } else { 3034 OpenMPDefaultmapClauseModifier M = 3035 Stack->getDefaultmapModifier(ClauseKind); 3036 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3037 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3038 ImplicitMap[Kind].emplace_back(E); 3039 } 3040 return; 3041 } 3042 } 3043 3044 // OpenMP [2.9.3.6, Restrictions, p.2] 3045 // A list item that appears in a reduction clause of the innermost 3046 // enclosing worksharing or parallel construct may not be accessed in an 3047 // explicit task. 3048 DVar = Stack->hasInnermostDSA( 3049 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3050 [](OpenMPDirectiveKind K) { 3051 return isOpenMPParallelDirective(K) || 3052 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3053 }, 3054 /*FromParent=*/true); 3055 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3056 ErrorFound = true; 3057 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3058 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3059 return; 3060 } 3061 3062 // Define implicit data-sharing attributes for task. 3063 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3064 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3065 !Stack->isLoopControlVariable(VD).first) { 3066 ImplicitFirstprivate.push_back(E); 3067 return; 3068 } 3069 3070 // Store implicitly used globals with declare target link for parent 3071 // target. 3072 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3073 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3074 Stack->addToParentTargetRegionLinkGlobals(E); 3075 return; 3076 } 3077 } 3078 } 3079 void VisitMemberExpr(MemberExpr *E) { 3080 if (E->isTypeDependent() || E->isValueDependent() || 3081 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3082 return; 3083 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3084 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3085 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 3086 if (!FD) 3087 return; 3088 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3089 // Check if the variable has explicit DSA set and stop analysis if it 3090 // so. 3091 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3092 return; 3093 3094 if (isOpenMPTargetExecutionDirective(DKind) && 3095 !Stack->isLoopControlVariable(FD).first && 3096 !Stack->checkMappableExprComponentListsForDecl( 3097 FD, /*CurrentRegionOnly=*/true, 3098 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3099 StackComponents, 3100 OpenMPClauseKind) { 3101 return isa<CXXThisExpr>( 3102 cast<MemberExpr>( 3103 StackComponents.back().getAssociatedExpression()) 3104 ->getBase() 3105 ->IgnoreParens()); 3106 })) { 3107 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3108 // A bit-field cannot appear in a map clause. 3109 // 3110 if (FD->isBitField()) 3111 return; 3112 3113 // Check to see if the member expression is referencing a class that 3114 // has already been explicitly mapped 3115 if (Stack->isClassPreviouslyMapped(TE->getType())) 3116 return; 3117 3118 OpenMPDefaultmapClauseModifier Modifier = 3119 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3120 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3121 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3122 ImplicitMap[Kind].emplace_back(E); 3123 return; 3124 } 3125 3126 SourceLocation ELoc = E->getExprLoc(); 3127 // OpenMP [2.9.3.6, Restrictions, p.2] 3128 // A list item that appears in a reduction clause of the innermost 3129 // enclosing worksharing or parallel construct may not be accessed in 3130 // an explicit task. 3131 DVar = Stack->hasInnermostDSA( 3132 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3133 [](OpenMPDirectiveKind K) { 3134 return isOpenMPParallelDirective(K) || 3135 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3136 }, 3137 /*FromParent=*/true); 3138 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3139 ErrorFound = true; 3140 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3141 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3142 return; 3143 } 3144 3145 // Define implicit data-sharing attributes for task. 3146 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3147 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3148 !Stack->isLoopControlVariable(FD).first) { 3149 // Check if there is a captured expression for the current field in the 3150 // region. Do not mark it as firstprivate unless there is no captured 3151 // expression. 3152 // TODO: try to make it firstprivate. 3153 if (DVar.CKind != OMPC_unknown) 3154 ImplicitFirstprivate.push_back(E); 3155 } 3156 return; 3157 } 3158 if (isOpenMPTargetExecutionDirective(DKind)) { 3159 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3160 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3161 /*NoDiagnose=*/true)) 3162 return; 3163 const auto *VD = cast<ValueDecl>( 3164 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3165 if (!Stack->checkMappableExprComponentListsForDecl( 3166 VD, /*CurrentRegionOnly=*/true, 3167 [&CurComponents]( 3168 OMPClauseMappableExprCommon::MappableExprComponentListRef 3169 StackComponents, 3170 OpenMPClauseKind) { 3171 auto CCI = CurComponents.rbegin(); 3172 auto CCE = CurComponents.rend(); 3173 for (const auto &SC : llvm::reverse(StackComponents)) { 3174 // Do both expressions have the same kind? 3175 if (CCI->getAssociatedExpression()->getStmtClass() != 3176 SC.getAssociatedExpression()->getStmtClass()) 3177 if (!(isa<OMPArraySectionExpr>( 3178 SC.getAssociatedExpression()) && 3179 isa<ArraySubscriptExpr>( 3180 CCI->getAssociatedExpression()))) 3181 return false; 3182 3183 const Decl *CCD = CCI->getAssociatedDeclaration(); 3184 const Decl *SCD = SC.getAssociatedDeclaration(); 3185 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3186 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3187 if (SCD != CCD) 3188 return false; 3189 std::advance(CCI, 1); 3190 if (CCI == CCE) 3191 break; 3192 } 3193 return true; 3194 })) { 3195 Visit(E->getBase()); 3196 } 3197 } else if (!TryCaptureCXXThisMembers) { 3198 Visit(E->getBase()); 3199 } 3200 } 3201 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3202 for (OMPClause *C : S->clauses()) { 3203 // Skip analysis of arguments of implicitly defined firstprivate clause 3204 // for task|target directives. 3205 // Skip analysis of arguments of implicitly defined map clause for target 3206 // directives. 3207 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3208 C->isImplicit())) { 3209 for (Stmt *CC : C->children()) { 3210 if (CC) 3211 Visit(CC); 3212 } 3213 } 3214 } 3215 // Check implicitly captured variables. 3216 VisitSubCaptures(S); 3217 } 3218 void VisitStmt(Stmt *S) { 3219 for (Stmt *C : S->children()) { 3220 if (C) { 3221 // Check implicitly captured variables in the task-based directives to 3222 // check if they must be firstprivatized. 3223 Visit(C); 3224 } 3225 } 3226 } 3227 3228 void visitSubCaptures(CapturedStmt *S) { 3229 for (const CapturedStmt::Capture &Cap : S->captures()) { 3230 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3231 continue; 3232 VarDecl *VD = Cap.getCapturedVar(); 3233 // Do not try to map the variable if it or its sub-component was mapped 3234 // already. 3235 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3236 Stack->checkMappableExprComponentListsForDecl( 3237 VD, /*CurrentRegionOnly=*/true, 3238 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3239 OpenMPClauseKind) { return true; })) 3240 continue; 3241 DeclRefExpr *DRE = buildDeclRefExpr( 3242 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3243 Cap.getLocation(), /*RefersToCapture=*/true); 3244 Visit(DRE); 3245 } 3246 } 3247 bool isErrorFound() const { return ErrorFound; } 3248 ArrayRef<Expr *> getImplicitFirstprivate() const { 3249 return ImplicitFirstprivate; 3250 } 3251 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3252 return ImplicitMap[Kind]; 3253 } 3254 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3255 return VarsWithInheritedDSA; 3256 } 3257 3258 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3259 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3260 // Process declare target link variables for the target directives. 3261 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3262 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3263 Visit(E); 3264 } 3265 } 3266 }; 3267 } // namespace 3268 3269 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3270 switch (DKind) { 3271 case OMPD_parallel: 3272 case OMPD_parallel_for: 3273 case OMPD_parallel_for_simd: 3274 case OMPD_parallel_sections: 3275 case OMPD_parallel_master: 3276 case OMPD_teams: 3277 case OMPD_teams_distribute: 3278 case OMPD_teams_distribute_simd: { 3279 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3280 QualType KmpInt32PtrTy = 3281 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3282 Sema::CapturedParamNameType Params[] = { 3283 std::make_pair(".global_tid.", KmpInt32PtrTy), 3284 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3285 std::make_pair(StringRef(), QualType()) // __context with shared vars 3286 }; 3287 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3288 Params); 3289 break; 3290 } 3291 case OMPD_target_teams: 3292 case OMPD_target_parallel: 3293 case OMPD_target_parallel_for: 3294 case OMPD_target_parallel_for_simd: 3295 case OMPD_target_teams_distribute: 3296 case OMPD_target_teams_distribute_simd: { 3297 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3298 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3299 QualType KmpInt32PtrTy = 3300 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3301 QualType Args[] = {VoidPtrTy}; 3302 FunctionProtoType::ExtProtoInfo EPI; 3303 EPI.Variadic = true; 3304 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3305 Sema::CapturedParamNameType Params[] = { 3306 std::make_pair(".global_tid.", KmpInt32Ty), 3307 std::make_pair(".part_id.", KmpInt32PtrTy), 3308 std::make_pair(".privates.", VoidPtrTy), 3309 std::make_pair( 3310 ".copy_fn.", 3311 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3312 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3313 std::make_pair(StringRef(), QualType()) // __context with shared vars 3314 }; 3315 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3316 Params, /*OpenMPCaptureLevel=*/0); 3317 // Mark this captured region as inlined, because we don't use outlined 3318 // function directly. 3319 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3320 AlwaysInlineAttr::CreateImplicit( 3321 Context, {}, AttributeCommonInfo::AS_Keyword, 3322 AlwaysInlineAttr::Keyword_forceinline)); 3323 Sema::CapturedParamNameType ParamsTarget[] = { 3324 std::make_pair(StringRef(), QualType()) // __context with shared vars 3325 }; 3326 // Start a captured region for 'target' with no implicit parameters. 3327 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3328 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3329 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3330 std::make_pair(".global_tid.", KmpInt32PtrTy), 3331 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3332 std::make_pair(StringRef(), QualType()) // __context with shared vars 3333 }; 3334 // Start a captured region for 'teams' or 'parallel'. Both regions have 3335 // the same implicit parameters. 3336 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3337 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3338 break; 3339 } 3340 case OMPD_target: 3341 case OMPD_target_simd: { 3342 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3343 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3344 QualType KmpInt32PtrTy = 3345 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3346 QualType Args[] = {VoidPtrTy}; 3347 FunctionProtoType::ExtProtoInfo EPI; 3348 EPI.Variadic = true; 3349 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3350 Sema::CapturedParamNameType Params[] = { 3351 std::make_pair(".global_tid.", KmpInt32Ty), 3352 std::make_pair(".part_id.", KmpInt32PtrTy), 3353 std::make_pair(".privates.", VoidPtrTy), 3354 std::make_pair( 3355 ".copy_fn.", 3356 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3357 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3358 std::make_pair(StringRef(), QualType()) // __context with shared vars 3359 }; 3360 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3361 Params, /*OpenMPCaptureLevel=*/0); 3362 // Mark this captured region as inlined, because we don't use outlined 3363 // function directly. 3364 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3365 AlwaysInlineAttr::CreateImplicit( 3366 Context, {}, AttributeCommonInfo::AS_Keyword, 3367 AlwaysInlineAttr::Keyword_forceinline)); 3368 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3369 std::make_pair(StringRef(), QualType()), 3370 /*OpenMPCaptureLevel=*/1); 3371 break; 3372 } 3373 case OMPD_simd: 3374 case OMPD_for: 3375 case OMPD_for_simd: 3376 case OMPD_sections: 3377 case OMPD_section: 3378 case OMPD_single: 3379 case OMPD_master: 3380 case OMPD_critical: 3381 case OMPD_taskgroup: 3382 case OMPD_distribute: 3383 case OMPD_distribute_simd: 3384 case OMPD_ordered: 3385 case OMPD_atomic: 3386 case OMPD_target_data: { 3387 Sema::CapturedParamNameType Params[] = { 3388 std::make_pair(StringRef(), QualType()) // __context with shared vars 3389 }; 3390 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3391 Params); 3392 break; 3393 } 3394 case OMPD_task: { 3395 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3396 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3397 QualType KmpInt32PtrTy = 3398 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3399 QualType Args[] = {VoidPtrTy}; 3400 FunctionProtoType::ExtProtoInfo EPI; 3401 EPI.Variadic = true; 3402 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3403 Sema::CapturedParamNameType Params[] = { 3404 std::make_pair(".global_tid.", KmpInt32Ty), 3405 std::make_pair(".part_id.", KmpInt32PtrTy), 3406 std::make_pair(".privates.", VoidPtrTy), 3407 std::make_pair( 3408 ".copy_fn.", 3409 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3410 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3411 std::make_pair(StringRef(), QualType()) // __context with shared vars 3412 }; 3413 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3414 Params); 3415 // Mark this captured region as inlined, because we don't use outlined 3416 // function directly. 3417 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3418 AlwaysInlineAttr::CreateImplicit( 3419 Context, {}, AttributeCommonInfo::AS_Keyword, 3420 AlwaysInlineAttr::Keyword_forceinline)); 3421 break; 3422 } 3423 case OMPD_taskloop: 3424 case OMPD_taskloop_simd: 3425 case OMPD_master_taskloop: 3426 case OMPD_master_taskloop_simd: { 3427 QualType KmpInt32Ty = 3428 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3429 .withConst(); 3430 QualType KmpUInt64Ty = 3431 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3432 .withConst(); 3433 QualType KmpInt64Ty = 3434 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3435 .withConst(); 3436 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3437 QualType KmpInt32PtrTy = 3438 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3439 QualType Args[] = {VoidPtrTy}; 3440 FunctionProtoType::ExtProtoInfo EPI; 3441 EPI.Variadic = true; 3442 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3443 Sema::CapturedParamNameType Params[] = { 3444 std::make_pair(".global_tid.", KmpInt32Ty), 3445 std::make_pair(".part_id.", KmpInt32PtrTy), 3446 std::make_pair(".privates.", VoidPtrTy), 3447 std::make_pair( 3448 ".copy_fn.", 3449 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3450 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3451 std::make_pair(".lb.", KmpUInt64Ty), 3452 std::make_pair(".ub.", KmpUInt64Ty), 3453 std::make_pair(".st.", KmpInt64Ty), 3454 std::make_pair(".liter.", KmpInt32Ty), 3455 std::make_pair(".reductions.", VoidPtrTy), 3456 std::make_pair(StringRef(), QualType()) // __context with shared vars 3457 }; 3458 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3459 Params); 3460 // Mark this captured region as inlined, because we don't use outlined 3461 // function directly. 3462 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3463 AlwaysInlineAttr::CreateImplicit( 3464 Context, {}, AttributeCommonInfo::AS_Keyword, 3465 AlwaysInlineAttr::Keyword_forceinline)); 3466 break; 3467 } 3468 case OMPD_parallel_master_taskloop: 3469 case OMPD_parallel_master_taskloop_simd: { 3470 QualType KmpInt32Ty = 3471 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3472 .withConst(); 3473 QualType KmpUInt64Ty = 3474 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3475 .withConst(); 3476 QualType KmpInt64Ty = 3477 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3478 .withConst(); 3479 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3480 QualType KmpInt32PtrTy = 3481 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3482 Sema::CapturedParamNameType ParamsParallel[] = { 3483 std::make_pair(".global_tid.", KmpInt32PtrTy), 3484 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3485 std::make_pair(StringRef(), QualType()) // __context with shared vars 3486 }; 3487 // Start a captured region for 'parallel'. 3488 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3489 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3490 QualType Args[] = {VoidPtrTy}; 3491 FunctionProtoType::ExtProtoInfo EPI; 3492 EPI.Variadic = true; 3493 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3494 Sema::CapturedParamNameType Params[] = { 3495 std::make_pair(".global_tid.", KmpInt32Ty), 3496 std::make_pair(".part_id.", KmpInt32PtrTy), 3497 std::make_pair(".privates.", VoidPtrTy), 3498 std::make_pair( 3499 ".copy_fn.", 3500 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3501 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3502 std::make_pair(".lb.", KmpUInt64Ty), 3503 std::make_pair(".ub.", KmpUInt64Ty), 3504 std::make_pair(".st.", KmpInt64Ty), 3505 std::make_pair(".liter.", KmpInt32Ty), 3506 std::make_pair(".reductions.", VoidPtrTy), 3507 std::make_pair(StringRef(), QualType()) // __context with shared vars 3508 }; 3509 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3510 Params, /*OpenMPCaptureLevel=*/2); 3511 // Mark this captured region as inlined, because we don't use outlined 3512 // function directly. 3513 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3514 AlwaysInlineAttr::CreateImplicit( 3515 Context, {}, AttributeCommonInfo::AS_Keyword, 3516 AlwaysInlineAttr::Keyword_forceinline)); 3517 break; 3518 } 3519 case OMPD_distribute_parallel_for_simd: 3520 case OMPD_distribute_parallel_for: { 3521 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3522 QualType KmpInt32PtrTy = 3523 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3524 Sema::CapturedParamNameType Params[] = { 3525 std::make_pair(".global_tid.", KmpInt32PtrTy), 3526 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3527 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3528 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3529 std::make_pair(StringRef(), QualType()) // __context with shared vars 3530 }; 3531 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3532 Params); 3533 break; 3534 } 3535 case OMPD_target_teams_distribute_parallel_for: 3536 case OMPD_target_teams_distribute_parallel_for_simd: { 3537 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3538 QualType KmpInt32PtrTy = 3539 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3540 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3541 3542 QualType Args[] = {VoidPtrTy}; 3543 FunctionProtoType::ExtProtoInfo EPI; 3544 EPI.Variadic = true; 3545 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3546 Sema::CapturedParamNameType Params[] = { 3547 std::make_pair(".global_tid.", KmpInt32Ty), 3548 std::make_pair(".part_id.", KmpInt32PtrTy), 3549 std::make_pair(".privates.", VoidPtrTy), 3550 std::make_pair( 3551 ".copy_fn.", 3552 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3553 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3554 std::make_pair(StringRef(), QualType()) // __context with shared vars 3555 }; 3556 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3557 Params, /*OpenMPCaptureLevel=*/0); 3558 // Mark this captured region as inlined, because we don't use outlined 3559 // function directly. 3560 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3561 AlwaysInlineAttr::CreateImplicit( 3562 Context, {}, AttributeCommonInfo::AS_Keyword, 3563 AlwaysInlineAttr::Keyword_forceinline)); 3564 Sema::CapturedParamNameType ParamsTarget[] = { 3565 std::make_pair(StringRef(), QualType()) // __context with shared vars 3566 }; 3567 // Start a captured region for 'target' with no implicit parameters. 3568 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3569 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3570 3571 Sema::CapturedParamNameType ParamsTeams[] = { 3572 std::make_pair(".global_tid.", KmpInt32PtrTy), 3573 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3574 std::make_pair(StringRef(), QualType()) // __context with shared vars 3575 }; 3576 // Start a captured region for 'target' with no implicit parameters. 3577 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3578 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3579 3580 Sema::CapturedParamNameType ParamsParallel[] = { 3581 std::make_pair(".global_tid.", KmpInt32PtrTy), 3582 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3583 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3584 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3585 std::make_pair(StringRef(), QualType()) // __context with shared vars 3586 }; 3587 // Start a captured region for 'teams' or 'parallel'. Both regions have 3588 // the same implicit parameters. 3589 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3590 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3591 break; 3592 } 3593 3594 case OMPD_teams_distribute_parallel_for: 3595 case OMPD_teams_distribute_parallel_for_simd: { 3596 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3597 QualType KmpInt32PtrTy = 3598 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3599 3600 Sema::CapturedParamNameType ParamsTeams[] = { 3601 std::make_pair(".global_tid.", KmpInt32PtrTy), 3602 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3603 std::make_pair(StringRef(), QualType()) // __context with shared vars 3604 }; 3605 // Start a captured region for 'target' with no implicit parameters. 3606 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3607 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3608 3609 Sema::CapturedParamNameType ParamsParallel[] = { 3610 std::make_pair(".global_tid.", KmpInt32PtrTy), 3611 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3612 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3613 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3614 std::make_pair(StringRef(), QualType()) // __context with shared vars 3615 }; 3616 // Start a captured region for 'teams' or 'parallel'. Both regions have 3617 // the same implicit parameters. 3618 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3619 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3620 break; 3621 } 3622 case OMPD_target_update: 3623 case OMPD_target_enter_data: 3624 case OMPD_target_exit_data: { 3625 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3626 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3627 QualType KmpInt32PtrTy = 3628 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3629 QualType Args[] = {VoidPtrTy}; 3630 FunctionProtoType::ExtProtoInfo EPI; 3631 EPI.Variadic = true; 3632 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3633 Sema::CapturedParamNameType Params[] = { 3634 std::make_pair(".global_tid.", KmpInt32Ty), 3635 std::make_pair(".part_id.", KmpInt32PtrTy), 3636 std::make_pair(".privates.", VoidPtrTy), 3637 std::make_pair( 3638 ".copy_fn.", 3639 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3640 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3641 std::make_pair(StringRef(), QualType()) // __context with shared vars 3642 }; 3643 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3644 Params); 3645 // Mark this captured region as inlined, because we don't use outlined 3646 // function directly. 3647 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3648 AlwaysInlineAttr::CreateImplicit( 3649 Context, {}, AttributeCommonInfo::AS_Keyword, 3650 AlwaysInlineAttr::Keyword_forceinline)); 3651 break; 3652 } 3653 case OMPD_threadprivate: 3654 case OMPD_allocate: 3655 case OMPD_taskyield: 3656 case OMPD_barrier: 3657 case OMPD_taskwait: 3658 case OMPD_cancellation_point: 3659 case OMPD_cancel: 3660 case OMPD_flush: 3661 case OMPD_declare_reduction: 3662 case OMPD_declare_mapper: 3663 case OMPD_declare_simd: 3664 case OMPD_declare_target: 3665 case OMPD_end_declare_target: 3666 case OMPD_requires: 3667 case OMPD_declare_variant: 3668 llvm_unreachable("OpenMP Directive is not allowed"); 3669 case OMPD_unknown: 3670 llvm_unreachable("Unknown OpenMP directive"); 3671 } 3672 } 3673 3674 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3675 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3676 } 3677 3678 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3679 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3680 getOpenMPCaptureRegions(CaptureRegions, DKind); 3681 return CaptureRegions.size(); 3682 } 3683 3684 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3685 Expr *CaptureExpr, bool WithInit, 3686 bool AsExpression) { 3687 assert(CaptureExpr); 3688 ASTContext &C = S.getASTContext(); 3689 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3690 QualType Ty = Init->getType(); 3691 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3692 if (S.getLangOpts().CPlusPlus) { 3693 Ty = C.getLValueReferenceType(Ty); 3694 } else { 3695 Ty = C.getPointerType(Ty); 3696 ExprResult Res = 3697 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3698 if (!Res.isUsable()) 3699 return nullptr; 3700 Init = Res.get(); 3701 } 3702 WithInit = true; 3703 } 3704 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3705 CaptureExpr->getBeginLoc()); 3706 if (!WithInit) 3707 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3708 S.CurContext->addHiddenDecl(CED); 3709 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3710 return CED; 3711 } 3712 3713 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3714 bool WithInit) { 3715 OMPCapturedExprDecl *CD; 3716 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3717 CD = cast<OMPCapturedExprDecl>(VD); 3718 else 3719 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3720 /*AsExpression=*/false); 3721 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3722 CaptureExpr->getExprLoc()); 3723 } 3724 3725 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3726 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3727 if (!Ref) { 3728 OMPCapturedExprDecl *CD = buildCaptureDecl( 3729 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3730 /*WithInit=*/true, /*AsExpression=*/true); 3731 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3732 CaptureExpr->getExprLoc()); 3733 } 3734 ExprResult Res = Ref; 3735 if (!S.getLangOpts().CPlusPlus && 3736 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3737 Ref->getType()->isPointerType()) { 3738 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3739 if (!Res.isUsable()) 3740 return ExprError(); 3741 } 3742 return S.DefaultLvalueConversion(Res.get()); 3743 } 3744 3745 namespace { 3746 // OpenMP directives parsed in this section are represented as a 3747 // CapturedStatement with an associated statement. If a syntax error 3748 // is detected during the parsing of the associated statement, the 3749 // compiler must abort processing and close the CapturedStatement. 3750 // 3751 // Combined directives such as 'target parallel' have more than one 3752 // nested CapturedStatements. This RAII ensures that we unwind out 3753 // of all the nested CapturedStatements when an error is found. 3754 class CaptureRegionUnwinderRAII { 3755 private: 3756 Sema &S; 3757 bool &ErrorFound; 3758 OpenMPDirectiveKind DKind = OMPD_unknown; 3759 3760 public: 3761 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3762 OpenMPDirectiveKind DKind) 3763 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3764 ~CaptureRegionUnwinderRAII() { 3765 if (ErrorFound) { 3766 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3767 while (--ThisCaptureLevel >= 0) 3768 S.ActOnCapturedRegionError(); 3769 } 3770 } 3771 }; 3772 } // namespace 3773 3774 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3775 // Capture variables captured by reference in lambdas for target-based 3776 // directives. 3777 if (!CurContext->isDependentContext() && 3778 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3779 isOpenMPTargetDataManagementDirective( 3780 DSAStack->getCurrentDirective()))) { 3781 QualType Type = V->getType(); 3782 if (const auto *RD = Type.getCanonicalType() 3783 .getNonReferenceType() 3784 ->getAsCXXRecordDecl()) { 3785 bool SavedForceCaptureByReferenceInTargetExecutable = 3786 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3787 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3788 /*V=*/true); 3789 if (RD->isLambda()) { 3790 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3791 FieldDecl *ThisCapture; 3792 RD->getCaptureFields(Captures, ThisCapture); 3793 for (const LambdaCapture &LC : RD->captures()) { 3794 if (LC.getCaptureKind() == LCK_ByRef) { 3795 VarDecl *VD = LC.getCapturedVar(); 3796 DeclContext *VDC = VD->getDeclContext(); 3797 if (!VDC->Encloses(CurContext)) 3798 continue; 3799 MarkVariableReferenced(LC.getLocation(), VD); 3800 } else if (LC.getCaptureKind() == LCK_This) { 3801 QualType ThisTy = getCurrentThisType(); 3802 if (!ThisTy.isNull() && 3803 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3804 CheckCXXThisCapture(LC.getLocation()); 3805 } 3806 } 3807 } 3808 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3809 SavedForceCaptureByReferenceInTargetExecutable); 3810 } 3811 } 3812 } 3813 3814 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3815 ArrayRef<OMPClause *> Clauses) { 3816 bool ErrorFound = false; 3817 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3818 *this, ErrorFound, DSAStack->getCurrentDirective()); 3819 if (!S.isUsable()) { 3820 ErrorFound = true; 3821 return StmtError(); 3822 } 3823 3824 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3825 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3826 OMPOrderedClause *OC = nullptr; 3827 OMPScheduleClause *SC = nullptr; 3828 SmallVector<const OMPLinearClause *, 4> LCs; 3829 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3830 // This is required for proper codegen. 3831 for (OMPClause *Clause : Clauses) { 3832 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3833 Clause->getClauseKind() == OMPC_in_reduction) { 3834 // Capture taskgroup task_reduction descriptors inside the tasking regions 3835 // with the corresponding in_reduction items. 3836 auto *IRC = cast<OMPInReductionClause>(Clause); 3837 for (Expr *E : IRC->taskgroup_descriptors()) 3838 if (E) 3839 MarkDeclarationsReferencedInExpr(E); 3840 } 3841 if (isOpenMPPrivate(Clause->getClauseKind()) || 3842 Clause->getClauseKind() == OMPC_copyprivate || 3843 (getLangOpts().OpenMPUseTLS && 3844 getASTContext().getTargetInfo().isTLSSupported() && 3845 Clause->getClauseKind() == OMPC_copyin)) { 3846 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3847 // Mark all variables in private list clauses as used in inner region. 3848 for (Stmt *VarRef : Clause->children()) { 3849 if (auto *E = cast_or_null<Expr>(VarRef)) { 3850 MarkDeclarationsReferencedInExpr(E); 3851 } 3852 } 3853 DSAStack->setForceVarCapturing(/*V=*/false); 3854 } else if (CaptureRegions.size() > 1 || 3855 CaptureRegions.back() != OMPD_unknown) { 3856 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3857 PICs.push_back(C); 3858 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3859 if (Expr *E = C->getPostUpdateExpr()) 3860 MarkDeclarationsReferencedInExpr(E); 3861 } 3862 } 3863 if (Clause->getClauseKind() == OMPC_schedule) 3864 SC = cast<OMPScheduleClause>(Clause); 3865 else if (Clause->getClauseKind() == OMPC_ordered) 3866 OC = cast<OMPOrderedClause>(Clause); 3867 else if (Clause->getClauseKind() == OMPC_linear) 3868 LCs.push_back(cast<OMPLinearClause>(Clause)); 3869 } 3870 // OpenMP, 2.7.1 Loop Construct, Restrictions 3871 // The nonmonotonic modifier cannot be specified if an ordered clause is 3872 // specified. 3873 if (SC && 3874 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3875 SC->getSecondScheduleModifier() == 3876 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3877 OC) { 3878 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3879 ? SC->getFirstScheduleModifierLoc() 3880 : SC->getSecondScheduleModifierLoc(), 3881 diag::err_omp_schedule_nonmonotonic_ordered) 3882 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3883 ErrorFound = true; 3884 } 3885 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3886 for (const OMPLinearClause *C : LCs) { 3887 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3888 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3889 } 3890 ErrorFound = true; 3891 } 3892 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3893 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3894 OC->getNumForLoops()) { 3895 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3896 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3897 ErrorFound = true; 3898 } 3899 if (ErrorFound) { 3900 return StmtError(); 3901 } 3902 StmtResult SR = S; 3903 unsigned CompletedRegions = 0; 3904 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3905 // Mark all variables in private list clauses as used in inner region. 3906 // Required for proper codegen of combined directives. 3907 // TODO: add processing for other clauses. 3908 if (ThisCaptureRegion != OMPD_unknown) { 3909 for (const clang::OMPClauseWithPreInit *C : PICs) { 3910 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3911 // Find the particular capture region for the clause if the 3912 // directive is a combined one with multiple capture regions. 3913 // If the directive is not a combined one, the capture region 3914 // associated with the clause is OMPD_unknown and is generated 3915 // only once. 3916 if (CaptureRegion == ThisCaptureRegion || 3917 CaptureRegion == OMPD_unknown) { 3918 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3919 for (Decl *D : DS->decls()) 3920 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3921 } 3922 } 3923 } 3924 } 3925 if (++CompletedRegions == CaptureRegions.size()) 3926 DSAStack->setBodyComplete(); 3927 SR = ActOnCapturedRegionEnd(SR.get()); 3928 } 3929 return SR; 3930 } 3931 3932 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3933 OpenMPDirectiveKind CancelRegion, 3934 SourceLocation StartLoc) { 3935 // CancelRegion is only needed for cancel and cancellation_point. 3936 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3937 return false; 3938 3939 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3940 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3941 return false; 3942 3943 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3944 << getOpenMPDirectiveName(CancelRegion); 3945 return true; 3946 } 3947 3948 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3949 OpenMPDirectiveKind CurrentRegion, 3950 const DeclarationNameInfo &CurrentName, 3951 OpenMPDirectiveKind CancelRegion, 3952 SourceLocation StartLoc) { 3953 if (Stack->getCurScope()) { 3954 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3955 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3956 bool NestingProhibited = false; 3957 bool CloseNesting = true; 3958 bool OrphanSeen = false; 3959 enum { 3960 NoRecommend, 3961 ShouldBeInParallelRegion, 3962 ShouldBeInOrderedRegion, 3963 ShouldBeInTargetRegion, 3964 ShouldBeInTeamsRegion 3965 } Recommend = NoRecommend; 3966 if (isOpenMPSimdDirective(ParentRegion) && 3967 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 3968 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 3969 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 3970 // OpenMP [2.16, Nesting of Regions] 3971 // OpenMP constructs may not be nested inside a simd region. 3972 // OpenMP [2.8.1,simd Construct, Restrictions] 3973 // An ordered construct with the simd clause is the only OpenMP 3974 // construct that can appear in the simd region. 3975 // Allowing a SIMD construct nested in another SIMD construct is an 3976 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3977 // message. 3978 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 3979 // The only OpenMP constructs that can be encountered during execution of 3980 // a simd region are the atomic construct, the loop construct, the simd 3981 // construct and the ordered construct with the simd clause. 3982 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3983 ? diag::err_omp_prohibited_region_simd 3984 : diag::warn_omp_nesting_simd) 3985 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 3986 return CurrentRegion != OMPD_simd; 3987 } 3988 if (ParentRegion == OMPD_atomic) { 3989 // OpenMP [2.16, Nesting of Regions] 3990 // OpenMP constructs may not be nested inside an atomic region. 3991 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3992 return true; 3993 } 3994 if (CurrentRegion == OMPD_section) { 3995 // OpenMP [2.7.2, sections Construct, Restrictions] 3996 // Orphaned section directives are prohibited. That is, the section 3997 // directives must appear within the sections construct and must not be 3998 // encountered elsewhere in the sections region. 3999 if (ParentRegion != OMPD_sections && 4000 ParentRegion != OMPD_parallel_sections) { 4001 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4002 << (ParentRegion != OMPD_unknown) 4003 << getOpenMPDirectiveName(ParentRegion); 4004 return true; 4005 } 4006 return false; 4007 } 4008 // Allow some constructs (except teams and cancellation constructs) to be 4009 // orphaned (they could be used in functions, called from OpenMP regions 4010 // with the required preconditions). 4011 if (ParentRegion == OMPD_unknown && 4012 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4013 CurrentRegion != OMPD_cancellation_point && 4014 CurrentRegion != OMPD_cancel) 4015 return false; 4016 if (CurrentRegion == OMPD_cancellation_point || 4017 CurrentRegion == OMPD_cancel) { 4018 // OpenMP [2.16, Nesting of Regions] 4019 // A cancellation point construct for which construct-type-clause is 4020 // taskgroup must be nested inside a task construct. A cancellation 4021 // point construct for which construct-type-clause is not taskgroup must 4022 // be closely nested inside an OpenMP construct that matches the type 4023 // specified in construct-type-clause. 4024 // A cancel construct for which construct-type-clause is taskgroup must be 4025 // nested inside a task construct. A cancel construct for which 4026 // construct-type-clause is not taskgroup must be closely nested inside an 4027 // OpenMP construct that matches the type specified in 4028 // construct-type-clause. 4029 NestingProhibited = 4030 !((CancelRegion == OMPD_parallel && 4031 (ParentRegion == OMPD_parallel || 4032 ParentRegion == OMPD_target_parallel)) || 4033 (CancelRegion == OMPD_for && 4034 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4035 ParentRegion == OMPD_target_parallel_for || 4036 ParentRegion == OMPD_distribute_parallel_for || 4037 ParentRegion == OMPD_teams_distribute_parallel_for || 4038 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4039 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 4040 (CancelRegion == OMPD_sections && 4041 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4042 ParentRegion == OMPD_parallel_sections))); 4043 OrphanSeen = ParentRegion == OMPD_unknown; 4044 } else if (CurrentRegion == OMPD_master) { 4045 // OpenMP [2.16, Nesting of Regions] 4046 // A master region may not be closely nested inside a worksharing, 4047 // atomic, or explicit task region. 4048 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4049 isOpenMPTaskingDirective(ParentRegion); 4050 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4051 // OpenMP [2.16, Nesting of Regions] 4052 // A critical region may not be nested (closely or otherwise) inside a 4053 // critical region with the same name. Note that this restriction is not 4054 // sufficient to prevent deadlock. 4055 SourceLocation PreviousCriticalLoc; 4056 bool DeadLock = Stack->hasDirective( 4057 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4058 const DeclarationNameInfo &DNI, 4059 SourceLocation Loc) { 4060 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4061 PreviousCriticalLoc = Loc; 4062 return true; 4063 } 4064 return false; 4065 }, 4066 false /* skip top directive */); 4067 if (DeadLock) { 4068 SemaRef.Diag(StartLoc, 4069 diag::err_omp_prohibited_region_critical_same_name) 4070 << CurrentName.getName(); 4071 if (PreviousCriticalLoc.isValid()) 4072 SemaRef.Diag(PreviousCriticalLoc, 4073 diag::note_omp_previous_critical_region); 4074 return true; 4075 } 4076 } else if (CurrentRegion == OMPD_barrier) { 4077 // OpenMP [2.16, Nesting of Regions] 4078 // A barrier region may not be closely nested inside a worksharing, 4079 // explicit task, critical, ordered, atomic, or master region. 4080 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4081 isOpenMPTaskingDirective(ParentRegion) || 4082 ParentRegion == OMPD_master || 4083 ParentRegion == OMPD_parallel_master || 4084 ParentRegion == OMPD_critical || 4085 ParentRegion == OMPD_ordered; 4086 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4087 !isOpenMPParallelDirective(CurrentRegion) && 4088 !isOpenMPTeamsDirective(CurrentRegion)) { 4089 // OpenMP [2.16, Nesting of Regions] 4090 // A worksharing region may not be closely nested inside a worksharing, 4091 // explicit task, critical, ordered, atomic, or master region. 4092 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4093 isOpenMPTaskingDirective(ParentRegion) || 4094 ParentRegion == OMPD_master || 4095 ParentRegion == OMPD_parallel_master || 4096 ParentRegion == OMPD_critical || 4097 ParentRegion == OMPD_ordered; 4098 Recommend = ShouldBeInParallelRegion; 4099 } else if (CurrentRegion == OMPD_ordered) { 4100 // OpenMP [2.16, Nesting of Regions] 4101 // An ordered region may not be closely nested inside a critical, 4102 // atomic, or explicit task region. 4103 // An ordered region must be closely nested inside a loop region (or 4104 // parallel loop region) with an ordered clause. 4105 // OpenMP [2.8.1,simd Construct, Restrictions] 4106 // An ordered construct with the simd clause is the only OpenMP construct 4107 // that can appear in the simd region. 4108 NestingProhibited = ParentRegion == OMPD_critical || 4109 isOpenMPTaskingDirective(ParentRegion) || 4110 !(isOpenMPSimdDirective(ParentRegion) || 4111 Stack->isParentOrderedRegion()); 4112 Recommend = ShouldBeInOrderedRegion; 4113 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4114 // OpenMP [2.16, Nesting of Regions] 4115 // If specified, a teams construct must be contained within a target 4116 // construct. 4117 NestingProhibited = 4118 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4119 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4120 ParentRegion != OMPD_target); 4121 OrphanSeen = ParentRegion == OMPD_unknown; 4122 Recommend = ShouldBeInTargetRegion; 4123 } 4124 if (!NestingProhibited && 4125 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4126 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4127 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4128 // OpenMP [2.16, Nesting of Regions] 4129 // distribute, parallel, parallel sections, parallel workshare, and the 4130 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4131 // constructs that can be closely nested in the teams region. 4132 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4133 !isOpenMPDistributeDirective(CurrentRegion); 4134 Recommend = ShouldBeInParallelRegion; 4135 } 4136 if (!NestingProhibited && 4137 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4138 // OpenMP 4.5 [2.17 Nesting of Regions] 4139 // The region associated with the distribute construct must be strictly 4140 // nested inside a teams region 4141 NestingProhibited = 4142 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4143 Recommend = ShouldBeInTeamsRegion; 4144 } 4145 if (!NestingProhibited && 4146 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4147 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4148 // OpenMP 4.5 [2.17 Nesting of Regions] 4149 // If a target, target update, target data, target enter data, or 4150 // target exit data construct is encountered during execution of a 4151 // target region, the behavior is unspecified. 4152 NestingProhibited = Stack->hasDirective( 4153 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4154 SourceLocation) { 4155 if (isOpenMPTargetExecutionDirective(K)) { 4156 OffendingRegion = K; 4157 return true; 4158 } 4159 return false; 4160 }, 4161 false /* don't skip top directive */); 4162 CloseNesting = false; 4163 } 4164 if (NestingProhibited) { 4165 if (OrphanSeen) { 4166 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4167 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4168 } else { 4169 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4170 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4171 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4172 } 4173 return true; 4174 } 4175 } 4176 return false; 4177 } 4178 4179 struct Kind2Unsigned { 4180 using argument_type = OpenMPDirectiveKind; 4181 unsigned operator()(argument_type DK) { return unsigned(DK); } 4182 }; 4183 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4184 ArrayRef<OMPClause *> Clauses, 4185 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4186 bool ErrorFound = false; 4187 unsigned NamedModifiersNumber = 0; 4188 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4189 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4190 SmallVector<SourceLocation, 4> NameModifierLoc; 4191 for (const OMPClause *C : Clauses) { 4192 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4193 // At most one if clause without a directive-name-modifier can appear on 4194 // the directive. 4195 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4196 if (FoundNameModifiers[CurNM]) { 4197 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4198 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4199 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4200 ErrorFound = true; 4201 } else if (CurNM != OMPD_unknown) { 4202 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4203 ++NamedModifiersNumber; 4204 } 4205 FoundNameModifiers[CurNM] = IC; 4206 if (CurNM == OMPD_unknown) 4207 continue; 4208 // Check if the specified name modifier is allowed for the current 4209 // directive. 4210 // At most one if clause with the particular directive-name-modifier can 4211 // appear on the directive. 4212 bool MatchFound = false; 4213 for (auto NM : AllowedNameModifiers) { 4214 if (CurNM == NM) { 4215 MatchFound = true; 4216 break; 4217 } 4218 } 4219 if (!MatchFound) { 4220 S.Diag(IC->getNameModifierLoc(), 4221 diag::err_omp_wrong_if_directive_name_modifier) 4222 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4223 ErrorFound = true; 4224 } 4225 } 4226 } 4227 // If any if clause on the directive includes a directive-name-modifier then 4228 // all if clauses on the directive must include a directive-name-modifier. 4229 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4230 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4231 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4232 diag::err_omp_no_more_if_clause); 4233 } else { 4234 std::string Values; 4235 std::string Sep(", "); 4236 unsigned AllowedCnt = 0; 4237 unsigned TotalAllowedNum = 4238 AllowedNameModifiers.size() - NamedModifiersNumber; 4239 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4240 ++Cnt) { 4241 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4242 if (!FoundNameModifiers[NM]) { 4243 Values += "'"; 4244 Values += getOpenMPDirectiveName(NM); 4245 Values += "'"; 4246 if (AllowedCnt + 2 == TotalAllowedNum) 4247 Values += " or "; 4248 else if (AllowedCnt + 1 != TotalAllowedNum) 4249 Values += Sep; 4250 ++AllowedCnt; 4251 } 4252 } 4253 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4254 diag::err_omp_unnamed_if_clause) 4255 << (TotalAllowedNum > 1) << Values; 4256 } 4257 for (SourceLocation Loc : NameModifierLoc) { 4258 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4259 } 4260 ErrorFound = true; 4261 } 4262 return ErrorFound; 4263 } 4264 4265 static std::pair<ValueDecl *, bool> 4266 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4267 SourceRange &ERange, bool AllowArraySection = false) { 4268 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4269 RefExpr->containsUnexpandedParameterPack()) 4270 return std::make_pair(nullptr, true); 4271 4272 // OpenMP [3.1, C/C++] 4273 // A list item is a variable name. 4274 // OpenMP [2.9.3.3, Restrictions, p.1] 4275 // A variable that is part of another variable (as an array or 4276 // structure element) cannot appear in a private clause. 4277 RefExpr = RefExpr->IgnoreParens(); 4278 enum { 4279 NoArrayExpr = -1, 4280 ArraySubscript = 0, 4281 OMPArraySection = 1 4282 } IsArrayExpr = NoArrayExpr; 4283 if (AllowArraySection) { 4284 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4285 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4286 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4287 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4288 RefExpr = Base; 4289 IsArrayExpr = ArraySubscript; 4290 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4291 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4292 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4293 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4294 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4295 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4296 RefExpr = Base; 4297 IsArrayExpr = OMPArraySection; 4298 } 4299 } 4300 ELoc = RefExpr->getExprLoc(); 4301 ERange = RefExpr->getSourceRange(); 4302 RefExpr = RefExpr->IgnoreParenImpCasts(); 4303 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4304 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4305 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4306 (S.getCurrentThisType().isNull() || !ME || 4307 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4308 !isa<FieldDecl>(ME->getMemberDecl()))) { 4309 if (IsArrayExpr != NoArrayExpr) { 4310 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4311 << ERange; 4312 } else { 4313 S.Diag(ELoc, 4314 AllowArraySection 4315 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4316 : diag::err_omp_expected_var_name_member_expr) 4317 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4318 } 4319 return std::make_pair(nullptr, false); 4320 } 4321 return std::make_pair( 4322 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4323 } 4324 4325 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4326 ArrayRef<OMPClause *> Clauses) { 4327 assert(!S.CurContext->isDependentContext() && 4328 "Expected non-dependent context."); 4329 auto AllocateRange = 4330 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4331 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4332 DeclToCopy; 4333 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4334 return isOpenMPPrivate(C->getClauseKind()); 4335 }); 4336 for (OMPClause *Cl : PrivateRange) { 4337 MutableArrayRef<Expr *>::iterator I, It, Et; 4338 if (Cl->getClauseKind() == OMPC_private) { 4339 auto *PC = cast<OMPPrivateClause>(Cl); 4340 I = PC->private_copies().begin(); 4341 It = PC->varlist_begin(); 4342 Et = PC->varlist_end(); 4343 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4344 auto *PC = cast<OMPFirstprivateClause>(Cl); 4345 I = PC->private_copies().begin(); 4346 It = PC->varlist_begin(); 4347 Et = PC->varlist_end(); 4348 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4349 auto *PC = cast<OMPLastprivateClause>(Cl); 4350 I = PC->private_copies().begin(); 4351 It = PC->varlist_begin(); 4352 Et = PC->varlist_end(); 4353 } else if (Cl->getClauseKind() == OMPC_linear) { 4354 auto *PC = cast<OMPLinearClause>(Cl); 4355 I = PC->privates().begin(); 4356 It = PC->varlist_begin(); 4357 Et = PC->varlist_end(); 4358 } else if (Cl->getClauseKind() == OMPC_reduction) { 4359 auto *PC = cast<OMPReductionClause>(Cl); 4360 I = PC->privates().begin(); 4361 It = PC->varlist_begin(); 4362 Et = PC->varlist_end(); 4363 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4364 auto *PC = cast<OMPTaskReductionClause>(Cl); 4365 I = PC->privates().begin(); 4366 It = PC->varlist_begin(); 4367 Et = PC->varlist_end(); 4368 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4369 auto *PC = cast<OMPInReductionClause>(Cl); 4370 I = PC->privates().begin(); 4371 It = PC->varlist_begin(); 4372 Et = PC->varlist_end(); 4373 } else { 4374 llvm_unreachable("Expected private clause."); 4375 } 4376 for (Expr *E : llvm::make_range(It, Et)) { 4377 if (!*I) { 4378 ++I; 4379 continue; 4380 } 4381 SourceLocation ELoc; 4382 SourceRange ERange; 4383 Expr *SimpleRefExpr = E; 4384 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4385 /*AllowArraySection=*/true); 4386 DeclToCopy.try_emplace(Res.first, 4387 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4388 ++I; 4389 } 4390 } 4391 for (OMPClause *C : AllocateRange) { 4392 auto *AC = cast<OMPAllocateClause>(C); 4393 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4394 getAllocatorKind(S, Stack, AC->getAllocator()); 4395 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4396 // For task, taskloop or target directives, allocation requests to memory 4397 // allocators with the trait access set to thread result in unspecified 4398 // behavior. 4399 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4400 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4401 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4402 S.Diag(AC->getAllocator()->getExprLoc(), 4403 diag::warn_omp_allocate_thread_on_task_target_directive) 4404 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4405 } 4406 for (Expr *E : AC->varlists()) { 4407 SourceLocation ELoc; 4408 SourceRange ERange; 4409 Expr *SimpleRefExpr = E; 4410 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4411 ValueDecl *VD = Res.first; 4412 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4413 if (!isOpenMPPrivate(Data.CKind)) { 4414 S.Diag(E->getExprLoc(), 4415 diag::err_omp_expected_private_copy_for_allocate); 4416 continue; 4417 } 4418 VarDecl *PrivateVD = DeclToCopy[VD]; 4419 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4420 AllocatorKind, AC->getAllocator())) 4421 continue; 4422 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4423 E->getSourceRange()); 4424 } 4425 } 4426 } 4427 4428 StmtResult Sema::ActOnOpenMPExecutableDirective( 4429 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4430 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4431 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4432 StmtResult Res = StmtError(); 4433 // First check CancelRegion which is then used in checkNestingOfRegions. 4434 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4435 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4436 StartLoc)) 4437 return StmtError(); 4438 4439 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4440 VarsWithInheritedDSAType VarsWithInheritedDSA; 4441 bool ErrorFound = false; 4442 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4443 if (AStmt && !CurContext->isDependentContext()) { 4444 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4445 4446 // Check default data sharing attributes for referenced variables. 4447 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4448 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4449 Stmt *S = AStmt; 4450 while (--ThisCaptureLevel >= 0) 4451 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4452 DSAChecker.Visit(S); 4453 if (!isOpenMPTargetDataManagementDirective(Kind) && 4454 !isOpenMPTaskingDirective(Kind)) { 4455 // Visit subcaptures to generate implicit clauses for captured vars. 4456 auto *CS = cast<CapturedStmt>(AStmt); 4457 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4458 getOpenMPCaptureRegions(CaptureRegions, Kind); 4459 // Ignore outer tasking regions for target directives. 4460 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4461 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4462 DSAChecker.visitSubCaptures(CS); 4463 } 4464 if (DSAChecker.isErrorFound()) 4465 return StmtError(); 4466 // Generate list of implicitly defined firstprivate variables. 4467 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4468 4469 SmallVector<Expr *, 4> ImplicitFirstprivates( 4470 DSAChecker.getImplicitFirstprivate().begin(), 4471 DSAChecker.getImplicitFirstprivate().end()); 4472 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4473 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4474 ArrayRef<Expr *> ImplicitMap = 4475 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4476 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4477 } 4478 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4479 for (OMPClause *C : Clauses) { 4480 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4481 for (Expr *E : IRC->taskgroup_descriptors()) 4482 if (E) 4483 ImplicitFirstprivates.emplace_back(E); 4484 } 4485 } 4486 if (!ImplicitFirstprivates.empty()) { 4487 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4488 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4489 SourceLocation())) { 4490 ClausesWithImplicit.push_back(Implicit); 4491 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4492 ImplicitFirstprivates.size(); 4493 } else { 4494 ErrorFound = true; 4495 } 4496 } 4497 int ClauseKindCnt = -1; 4498 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4499 ++ClauseKindCnt; 4500 if (ImplicitMap.empty()) 4501 continue; 4502 CXXScopeSpec MapperIdScopeSpec; 4503 DeclarationNameInfo MapperId; 4504 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4505 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4506 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4507 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4508 ImplicitMap, OMPVarListLocTy())) { 4509 ClausesWithImplicit.emplace_back(Implicit); 4510 ErrorFound |= 4511 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4512 } else { 4513 ErrorFound = true; 4514 } 4515 } 4516 } 4517 4518 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4519 switch (Kind) { 4520 case OMPD_parallel: 4521 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4522 EndLoc); 4523 AllowedNameModifiers.push_back(OMPD_parallel); 4524 break; 4525 case OMPD_simd: 4526 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4527 VarsWithInheritedDSA); 4528 if (LangOpts.OpenMP >= 50) 4529 AllowedNameModifiers.push_back(OMPD_simd); 4530 break; 4531 case OMPD_for: 4532 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4533 VarsWithInheritedDSA); 4534 break; 4535 case OMPD_for_simd: 4536 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4537 EndLoc, VarsWithInheritedDSA); 4538 if (LangOpts.OpenMP >= 50) 4539 AllowedNameModifiers.push_back(OMPD_simd); 4540 break; 4541 case OMPD_sections: 4542 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4543 EndLoc); 4544 break; 4545 case OMPD_section: 4546 assert(ClausesWithImplicit.empty() && 4547 "No clauses are allowed for 'omp section' directive"); 4548 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4549 break; 4550 case OMPD_single: 4551 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4552 EndLoc); 4553 break; 4554 case OMPD_master: 4555 assert(ClausesWithImplicit.empty() && 4556 "No clauses are allowed for 'omp master' directive"); 4557 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4558 break; 4559 case OMPD_critical: 4560 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4561 StartLoc, EndLoc); 4562 break; 4563 case OMPD_parallel_for: 4564 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4565 EndLoc, VarsWithInheritedDSA); 4566 AllowedNameModifiers.push_back(OMPD_parallel); 4567 break; 4568 case OMPD_parallel_for_simd: 4569 Res = ActOnOpenMPParallelForSimdDirective( 4570 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4571 AllowedNameModifiers.push_back(OMPD_parallel); 4572 if (LangOpts.OpenMP >= 50) 4573 AllowedNameModifiers.push_back(OMPD_simd); 4574 break; 4575 case OMPD_parallel_master: 4576 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4577 StartLoc, EndLoc); 4578 AllowedNameModifiers.push_back(OMPD_parallel); 4579 break; 4580 case OMPD_parallel_sections: 4581 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4582 StartLoc, EndLoc); 4583 AllowedNameModifiers.push_back(OMPD_parallel); 4584 break; 4585 case OMPD_task: 4586 Res = 4587 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4588 AllowedNameModifiers.push_back(OMPD_task); 4589 break; 4590 case OMPD_taskyield: 4591 assert(ClausesWithImplicit.empty() && 4592 "No clauses are allowed for 'omp taskyield' directive"); 4593 assert(AStmt == nullptr && 4594 "No associated statement allowed for 'omp taskyield' directive"); 4595 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4596 break; 4597 case OMPD_barrier: 4598 assert(ClausesWithImplicit.empty() && 4599 "No clauses are allowed for 'omp barrier' directive"); 4600 assert(AStmt == nullptr && 4601 "No associated statement allowed for 'omp barrier' directive"); 4602 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4603 break; 4604 case OMPD_taskwait: 4605 assert(ClausesWithImplicit.empty() && 4606 "No clauses are allowed for 'omp taskwait' directive"); 4607 assert(AStmt == nullptr && 4608 "No associated statement allowed for 'omp taskwait' directive"); 4609 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4610 break; 4611 case OMPD_taskgroup: 4612 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4613 EndLoc); 4614 break; 4615 case OMPD_flush: 4616 assert(AStmt == nullptr && 4617 "No associated statement allowed for 'omp flush' directive"); 4618 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4619 break; 4620 case OMPD_ordered: 4621 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4622 EndLoc); 4623 break; 4624 case OMPD_atomic: 4625 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4626 EndLoc); 4627 break; 4628 case OMPD_teams: 4629 Res = 4630 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4631 break; 4632 case OMPD_target: 4633 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4634 EndLoc); 4635 AllowedNameModifiers.push_back(OMPD_target); 4636 break; 4637 case OMPD_target_parallel: 4638 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4639 StartLoc, EndLoc); 4640 AllowedNameModifiers.push_back(OMPD_target); 4641 AllowedNameModifiers.push_back(OMPD_parallel); 4642 break; 4643 case OMPD_target_parallel_for: 4644 Res = ActOnOpenMPTargetParallelForDirective( 4645 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4646 AllowedNameModifiers.push_back(OMPD_target); 4647 AllowedNameModifiers.push_back(OMPD_parallel); 4648 break; 4649 case OMPD_cancellation_point: 4650 assert(ClausesWithImplicit.empty() && 4651 "No clauses are allowed for 'omp cancellation point' directive"); 4652 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4653 "cancellation point' directive"); 4654 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4655 break; 4656 case OMPD_cancel: 4657 assert(AStmt == nullptr && 4658 "No associated statement allowed for 'omp cancel' directive"); 4659 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4660 CancelRegion); 4661 AllowedNameModifiers.push_back(OMPD_cancel); 4662 break; 4663 case OMPD_target_data: 4664 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4665 EndLoc); 4666 AllowedNameModifiers.push_back(OMPD_target_data); 4667 break; 4668 case OMPD_target_enter_data: 4669 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4670 EndLoc, AStmt); 4671 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4672 break; 4673 case OMPD_target_exit_data: 4674 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4675 EndLoc, AStmt); 4676 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4677 break; 4678 case OMPD_taskloop: 4679 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4680 EndLoc, VarsWithInheritedDSA); 4681 AllowedNameModifiers.push_back(OMPD_taskloop); 4682 break; 4683 case OMPD_taskloop_simd: 4684 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4685 EndLoc, VarsWithInheritedDSA); 4686 AllowedNameModifiers.push_back(OMPD_taskloop); 4687 if (LangOpts.OpenMP >= 50) 4688 AllowedNameModifiers.push_back(OMPD_simd); 4689 break; 4690 case OMPD_master_taskloop: 4691 Res = ActOnOpenMPMasterTaskLoopDirective( 4692 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4693 AllowedNameModifiers.push_back(OMPD_taskloop); 4694 break; 4695 case OMPD_master_taskloop_simd: 4696 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4697 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4698 AllowedNameModifiers.push_back(OMPD_taskloop); 4699 if (LangOpts.OpenMP >= 50) 4700 AllowedNameModifiers.push_back(OMPD_simd); 4701 break; 4702 case OMPD_parallel_master_taskloop: 4703 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4704 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4705 AllowedNameModifiers.push_back(OMPD_taskloop); 4706 AllowedNameModifiers.push_back(OMPD_parallel); 4707 break; 4708 case OMPD_parallel_master_taskloop_simd: 4709 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4710 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4711 AllowedNameModifiers.push_back(OMPD_taskloop); 4712 AllowedNameModifiers.push_back(OMPD_parallel); 4713 if (LangOpts.OpenMP >= 50) 4714 AllowedNameModifiers.push_back(OMPD_simd); 4715 break; 4716 case OMPD_distribute: 4717 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4718 EndLoc, VarsWithInheritedDSA); 4719 break; 4720 case OMPD_target_update: 4721 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4722 EndLoc, AStmt); 4723 AllowedNameModifiers.push_back(OMPD_target_update); 4724 break; 4725 case OMPD_distribute_parallel_for: 4726 Res = ActOnOpenMPDistributeParallelForDirective( 4727 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4728 AllowedNameModifiers.push_back(OMPD_parallel); 4729 break; 4730 case OMPD_distribute_parallel_for_simd: 4731 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4732 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4733 AllowedNameModifiers.push_back(OMPD_parallel); 4734 if (LangOpts.OpenMP >= 50) 4735 AllowedNameModifiers.push_back(OMPD_simd); 4736 break; 4737 case OMPD_distribute_simd: 4738 Res = ActOnOpenMPDistributeSimdDirective( 4739 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4740 if (LangOpts.OpenMP >= 50) 4741 AllowedNameModifiers.push_back(OMPD_simd); 4742 break; 4743 case OMPD_target_parallel_for_simd: 4744 Res = ActOnOpenMPTargetParallelForSimdDirective( 4745 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4746 AllowedNameModifiers.push_back(OMPD_target); 4747 AllowedNameModifiers.push_back(OMPD_parallel); 4748 if (LangOpts.OpenMP >= 50) 4749 AllowedNameModifiers.push_back(OMPD_simd); 4750 break; 4751 case OMPD_target_simd: 4752 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4753 EndLoc, VarsWithInheritedDSA); 4754 AllowedNameModifiers.push_back(OMPD_target); 4755 if (LangOpts.OpenMP >= 50) 4756 AllowedNameModifiers.push_back(OMPD_simd); 4757 break; 4758 case OMPD_teams_distribute: 4759 Res = ActOnOpenMPTeamsDistributeDirective( 4760 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4761 break; 4762 case OMPD_teams_distribute_simd: 4763 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4764 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4765 if (LangOpts.OpenMP >= 50) 4766 AllowedNameModifiers.push_back(OMPD_simd); 4767 break; 4768 case OMPD_teams_distribute_parallel_for_simd: 4769 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4770 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4771 AllowedNameModifiers.push_back(OMPD_parallel); 4772 if (LangOpts.OpenMP >= 50) 4773 AllowedNameModifiers.push_back(OMPD_simd); 4774 break; 4775 case OMPD_teams_distribute_parallel_for: 4776 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4777 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4778 AllowedNameModifiers.push_back(OMPD_parallel); 4779 break; 4780 case OMPD_target_teams: 4781 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4782 EndLoc); 4783 AllowedNameModifiers.push_back(OMPD_target); 4784 break; 4785 case OMPD_target_teams_distribute: 4786 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4787 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4788 AllowedNameModifiers.push_back(OMPD_target); 4789 break; 4790 case OMPD_target_teams_distribute_parallel_for: 4791 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4792 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4793 AllowedNameModifiers.push_back(OMPD_target); 4794 AllowedNameModifiers.push_back(OMPD_parallel); 4795 break; 4796 case OMPD_target_teams_distribute_parallel_for_simd: 4797 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4798 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4799 AllowedNameModifiers.push_back(OMPD_target); 4800 AllowedNameModifiers.push_back(OMPD_parallel); 4801 if (LangOpts.OpenMP >= 50) 4802 AllowedNameModifiers.push_back(OMPD_simd); 4803 break; 4804 case OMPD_target_teams_distribute_simd: 4805 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4806 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4807 AllowedNameModifiers.push_back(OMPD_target); 4808 if (LangOpts.OpenMP >= 50) 4809 AllowedNameModifiers.push_back(OMPD_simd); 4810 break; 4811 case OMPD_declare_target: 4812 case OMPD_end_declare_target: 4813 case OMPD_threadprivate: 4814 case OMPD_allocate: 4815 case OMPD_declare_reduction: 4816 case OMPD_declare_mapper: 4817 case OMPD_declare_simd: 4818 case OMPD_requires: 4819 case OMPD_declare_variant: 4820 llvm_unreachable("OpenMP Directive is not allowed"); 4821 case OMPD_unknown: 4822 llvm_unreachable("Unknown OpenMP directive"); 4823 } 4824 4825 ErrorFound = Res.isInvalid() || ErrorFound; 4826 4827 // Check variables in the clauses if default(none) was specified. 4828 if (DSAStack->getDefaultDSA() == DSA_none) { 4829 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4830 for (OMPClause *C : Clauses) { 4831 switch (C->getClauseKind()) { 4832 case OMPC_num_threads: 4833 case OMPC_dist_schedule: 4834 // Do not analyse if no parent teams directive. 4835 if (isOpenMPTeamsDirective(Kind)) 4836 break; 4837 continue; 4838 case OMPC_if: 4839 if (isOpenMPTeamsDirective(Kind) && 4840 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4841 break; 4842 if (isOpenMPParallelDirective(Kind) && 4843 isOpenMPTaskLoopDirective(Kind) && 4844 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 4845 break; 4846 continue; 4847 case OMPC_schedule: 4848 break; 4849 case OMPC_grainsize: 4850 case OMPC_num_tasks: 4851 case OMPC_final: 4852 case OMPC_priority: 4853 // Do not analyze if no parent parallel directive. 4854 if (isOpenMPParallelDirective(Kind)) 4855 break; 4856 continue; 4857 case OMPC_ordered: 4858 case OMPC_device: 4859 case OMPC_num_teams: 4860 case OMPC_thread_limit: 4861 case OMPC_hint: 4862 case OMPC_collapse: 4863 case OMPC_safelen: 4864 case OMPC_simdlen: 4865 case OMPC_default: 4866 case OMPC_proc_bind: 4867 case OMPC_private: 4868 case OMPC_firstprivate: 4869 case OMPC_lastprivate: 4870 case OMPC_shared: 4871 case OMPC_reduction: 4872 case OMPC_task_reduction: 4873 case OMPC_in_reduction: 4874 case OMPC_linear: 4875 case OMPC_aligned: 4876 case OMPC_copyin: 4877 case OMPC_copyprivate: 4878 case OMPC_nowait: 4879 case OMPC_untied: 4880 case OMPC_mergeable: 4881 case OMPC_allocate: 4882 case OMPC_read: 4883 case OMPC_write: 4884 case OMPC_update: 4885 case OMPC_capture: 4886 case OMPC_seq_cst: 4887 case OMPC_depend: 4888 case OMPC_threads: 4889 case OMPC_simd: 4890 case OMPC_map: 4891 case OMPC_nogroup: 4892 case OMPC_defaultmap: 4893 case OMPC_to: 4894 case OMPC_from: 4895 case OMPC_use_device_ptr: 4896 case OMPC_is_device_ptr: 4897 case OMPC_nontemporal: 4898 continue; 4899 case OMPC_allocator: 4900 case OMPC_flush: 4901 case OMPC_threadprivate: 4902 case OMPC_uniform: 4903 case OMPC_unknown: 4904 case OMPC_unified_address: 4905 case OMPC_unified_shared_memory: 4906 case OMPC_reverse_offload: 4907 case OMPC_dynamic_allocators: 4908 case OMPC_atomic_default_mem_order: 4909 case OMPC_device_type: 4910 case OMPC_match: 4911 llvm_unreachable("Unexpected clause"); 4912 } 4913 for (Stmt *CC : C->children()) { 4914 if (CC) 4915 DSAChecker.Visit(CC); 4916 } 4917 } 4918 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4919 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4920 } 4921 for (const auto &P : VarsWithInheritedDSA) { 4922 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4923 continue; 4924 ErrorFound = true; 4925 if (DSAStack->getDefaultDSA() == DSA_none) { 4926 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4927 << P.first << P.second->getSourceRange(); 4928 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4929 } else if (getLangOpts().OpenMP >= 50) { 4930 Diag(P.second->getExprLoc(), 4931 diag::err_omp_defaultmap_no_attr_for_variable) 4932 << P.first << P.second->getSourceRange(); 4933 Diag(DSAStack->getDefaultDSALocation(), 4934 diag::note_omp_defaultmap_attr_none); 4935 } 4936 } 4937 4938 if (!AllowedNameModifiers.empty()) 4939 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4940 ErrorFound; 4941 4942 if (ErrorFound) 4943 return StmtError(); 4944 4945 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4946 Res.getAs<OMPExecutableDirective>() 4947 ->getStructuredBlock() 4948 ->setIsOMPStructuredBlock(true); 4949 } 4950 4951 if (!CurContext->isDependentContext() && 4952 isOpenMPTargetExecutionDirective(Kind) && 4953 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4954 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4955 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4956 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4957 // Register target to DSA Stack. 4958 DSAStack->addTargetDirLocation(StartLoc); 4959 } 4960 4961 return Res; 4962 } 4963 4964 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4965 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4966 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4967 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4968 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4969 assert(Aligneds.size() == Alignments.size()); 4970 assert(Linears.size() == LinModifiers.size()); 4971 assert(Linears.size() == Steps.size()); 4972 if (!DG || DG.get().isNull()) 4973 return DeclGroupPtrTy(); 4974 4975 const int SimdId = 0; 4976 if (!DG.get().isSingleDecl()) { 4977 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4978 << SimdId; 4979 return DG; 4980 } 4981 Decl *ADecl = DG.get().getSingleDecl(); 4982 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4983 ADecl = FTD->getTemplatedDecl(); 4984 4985 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4986 if (!FD) { 4987 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4988 return DeclGroupPtrTy(); 4989 } 4990 4991 // OpenMP [2.8.2, declare simd construct, Description] 4992 // The parameter of the simdlen clause must be a constant positive integer 4993 // expression. 4994 ExprResult SL; 4995 if (Simdlen) 4996 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4997 // OpenMP [2.8.2, declare simd construct, Description] 4998 // The special this pointer can be used as if was one of the arguments to the 4999 // function in any of the linear, aligned, or uniform clauses. 5000 // The uniform clause declares one or more arguments to have an invariant 5001 // value for all concurrent invocations of the function in the execution of a 5002 // single SIMD loop. 5003 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5004 const Expr *UniformedLinearThis = nullptr; 5005 for (const Expr *E : Uniforms) { 5006 E = E->IgnoreParenImpCasts(); 5007 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5008 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5009 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5010 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5011 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5012 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5013 continue; 5014 } 5015 if (isa<CXXThisExpr>(E)) { 5016 UniformedLinearThis = E; 5017 continue; 5018 } 5019 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5020 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5021 } 5022 // OpenMP [2.8.2, declare simd construct, Description] 5023 // The aligned clause declares that the object to which each list item points 5024 // is aligned to the number of bytes expressed in the optional parameter of 5025 // the aligned clause. 5026 // The special this pointer can be used as if was one of the arguments to the 5027 // function in any of the linear, aligned, or uniform clauses. 5028 // The type of list items appearing in the aligned clause must be array, 5029 // pointer, reference to array, or reference to pointer. 5030 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5031 const Expr *AlignedThis = nullptr; 5032 for (const Expr *E : Aligneds) { 5033 E = E->IgnoreParenImpCasts(); 5034 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5035 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5036 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5037 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5038 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5039 ->getCanonicalDecl() == CanonPVD) { 5040 // OpenMP [2.8.1, simd construct, Restrictions] 5041 // A list-item cannot appear in more than one aligned clause. 5042 if (AlignedArgs.count(CanonPVD) > 0) { 5043 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5044 << 1 << getOpenMPClauseName(OMPC_aligned) 5045 << E->getSourceRange(); 5046 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5047 diag::note_omp_explicit_dsa) 5048 << getOpenMPClauseName(OMPC_aligned); 5049 continue; 5050 } 5051 AlignedArgs[CanonPVD] = E; 5052 QualType QTy = PVD->getType() 5053 .getNonReferenceType() 5054 .getUnqualifiedType() 5055 .getCanonicalType(); 5056 const Type *Ty = QTy.getTypePtrOrNull(); 5057 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5058 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5059 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5060 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5061 } 5062 continue; 5063 } 5064 } 5065 if (isa<CXXThisExpr>(E)) { 5066 if (AlignedThis) { 5067 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5068 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5069 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5070 << getOpenMPClauseName(OMPC_aligned); 5071 } 5072 AlignedThis = E; 5073 continue; 5074 } 5075 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5076 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5077 } 5078 // The optional parameter of the aligned clause, alignment, must be a constant 5079 // positive integer expression. If no optional parameter is specified, 5080 // implementation-defined default alignments for SIMD instructions on the 5081 // target platforms are assumed. 5082 SmallVector<const Expr *, 4> NewAligns; 5083 for (Expr *E : Alignments) { 5084 ExprResult Align; 5085 if (E) 5086 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5087 NewAligns.push_back(Align.get()); 5088 } 5089 // OpenMP [2.8.2, declare simd construct, Description] 5090 // The linear clause declares one or more list items to be private to a SIMD 5091 // lane and to have a linear relationship with respect to the iteration space 5092 // of a loop. 5093 // The special this pointer can be used as if was one of the arguments to the 5094 // function in any of the linear, aligned, or uniform clauses. 5095 // When a linear-step expression is specified in a linear clause it must be 5096 // either a constant integer expression or an integer-typed parameter that is 5097 // specified in a uniform clause on the directive. 5098 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5099 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5100 auto MI = LinModifiers.begin(); 5101 for (const Expr *E : Linears) { 5102 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5103 ++MI; 5104 E = E->IgnoreParenImpCasts(); 5105 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5106 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5107 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5108 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5109 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5110 ->getCanonicalDecl() == CanonPVD) { 5111 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5112 // A list-item cannot appear in more than one linear clause. 5113 if (LinearArgs.count(CanonPVD) > 0) { 5114 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5115 << getOpenMPClauseName(OMPC_linear) 5116 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5117 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5118 diag::note_omp_explicit_dsa) 5119 << getOpenMPClauseName(OMPC_linear); 5120 continue; 5121 } 5122 // Each argument can appear in at most one uniform or linear clause. 5123 if (UniformedArgs.count(CanonPVD) > 0) { 5124 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5125 << getOpenMPClauseName(OMPC_linear) 5126 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5127 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5128 diag::note_omp_explicit_dsa) 5129 << getOpenMPClauseName(OMPC_uniform); 5130 continue; 5131 } 5132 LinearArgs[CanonPVD] = E; 5133 if (E->isValueDependent() || E->isTypeDependent() || 5134 E->isInstantiationDependent() || 5135 E->containsUnexpandedParameterPack()) 5136 continue; 5137 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5138 PVD->getOriginalType()); 5139 continue; 5140 } 5141 } 5142 if (isa<CXXThisExpr>(E)) { 5143 if (UniformedLinearThis) { 5144 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5145 << getOpenMPClauseName(OMPC_linear) 5146 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5147 << E->getSourceRange(); 5148 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5149 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5150 : OMPC_linear); 5151 continue; 5152 } 5153 UniformedLinearThis = E; 5154 if (E->isValueDependent() || E->isTypeDependent() || 5155 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5156 continue; 5157 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5158 E->getType()); 5159 continue; 5160 } 5161 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5162 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5163 } 5164 Expr *Step = nullptr; 5165 Expr *NewStep = nullptr; 5166 SmallVector<Expr *, 4> NewSteps; 5167 for (Expr *E : Steps) { 5168 // Skip the same step expression, it was checked already. 5169 if (Step == E || !E) { 5170 NewSteps.push_back(E ? NewStep : nullptr); 5171 continue; 5172 } 5173 Step = E; 5174 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5175 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5176 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5177 if (UniformedArgs.count(CanonPVD) == 0) { 5178 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5179 << Step->getSourceRange(); 5180 } else if (E->isValueDependent() || E->isTypeDependent() || 5181 E->isInstantiationDependent() || 5182 E->containsUnexpandedParameterPack() || 5183 CanonPVD->getType()->hasIntegerRepresentation()) { 5184 NewSteps.push_back(Step); 5185 } else { 5186 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5187 << Step->getSourceRange(); 5188 } 5189 continue; 5190 } 5191 NewStep = Step; 5192 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5193 !Step->isInstantiationDependent() && 5194 !Step->containsUnexpandedParameterPack()) { 5195 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5196 .get(); 5197 if (NewStep) 5198 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5199 } 5200 NewSteps.push_back(NewStep); 5201 } 5202 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5203 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5204 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5205 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5206 const_cast<Expr **>(Linears.data()), Linears.size(), 5207 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5208 NewSteps.data(), NewSteps.size(), SR); 5209 ADecl->addAttr(NewAttr); 5210 return DG; 5211 } 5212 5213 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5214 QualType NewType) { 5215 assert(NewType->isFunctionProtoType() && 5216 "Expected function type with prototype."); 5217 assert(FD->getType()->isFunctionNoProtoType() && 5218 "Expected function with type with no prototype."); 5219 assert(FDWithProto->getType()->isFunctionProtoType() && 5220 "Expected function with prototype."); 5221 // Synthesize parameters with the same types. 5222 FD->setType(NewType); 5223 SmallVector<ParmVarDecl *, 16> Params; 5224 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5225 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5226 SourceLocation(), nullptr, P->getType(), 5227 /*TInfo=*/nullptr, SC_None, nullptr); 5228 Param->setScopeInfo(0, Params.size()); 5229 Param->setImplicit(); 5230 Params.push_back(Param); 5231 } 5232 5233 FD->setParams(Params); 5234 } 5235 5236 Optional<std::pair<FunctionDecl *, Expr *>> 5237 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5238 Expr *VariantRef, SourceRange SR) { 5239 if (!DG || DG.get().isNull()) 5240 return None; 5241 5242 const int VariantId = 1; 5243 // Must be applied only to single decl. 5244 if (!DG.get().isSingleDecl()) { 5245 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5246 << VariantId << SR; 5247 return None; 5248 } 5249 Decl *ADecl = DG.get().getSingleDecl(); 5250 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5251 ADecl = FTD->getTemplatedDecl(); 5252 5253 // Decl must be a function. 5254 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5255 if (!FD) { 5256 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5257 << VariantId << SR; 5258 return None; 5259 } 5260 5261 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5262 return FD->hasAttrs() && 5263 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5264 FD->hasAttr<TargetAttr>()); 5265 }; 5266 // OpenMP is not compatible with CPU-specific attributes. 5267 if (HasMultiVersionAttributes(FD)) { 5268 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5269 << SR; 5270 return None; 5271 } 5272 5273 // Allow #pragma omp declare variant only if the function is not used. 5274 if (FD->isUsed(false)) 5275 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5276 << FD->getLocation(); 5277 5278 // Check if the function was emitted already. 5279 const FunctionDecl *Definition; 5280 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5281 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5282 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5283 << FD->getLocation(); 5284 5285 // The VariantRef must point to function. 5286 if (!VariantRef) { 5287 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5288 return None; 5289 } 5290 5291 // Do not check templates, wait until instantiation. 5292 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5293 VariantRef->containsUnexpandedParameterPack() || 5294 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5295 return std::make_pair(FD, VariantRef); 5296 5297 // Convert VariantRef expression to the type of the original function to 5298 // resolve possible conflicts. 5299 ExprResult VariantRefCast; 5300 if (LangOpts.CPlusPlus) { 5301 QualType FnPtrType; 5302 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5303 if (Method && !Method->isStatic()) { 5304 const Type *ClassType = 5305 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5306 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5307 ExprResult ER; 5308 { 5309 // Build adrr_of unary op to correctly handle type checks for member 5310 // functions. 5311 Sema::TentativeAnalysisScope Trap(*this); 5312 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5313 VariantRef); 5314 } 5315 if (!ER.isUsable()) { 5316 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5317 << VariantId << VariantRef->getSourceRange(); 5318 return None; 5319 } 5320 VariantRef = ER.get(); 5321 } else { 5322 FnPtrType = Context.getPointerType(FD->getType()); 5323 } 5324 ImplicitConversionSequence ICS = 5325 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5326 /*SuppressUserConversions=*/false, 5327 /*AllowExplicit=*/false, 5328 /*InOverloadResolution=*/false, 5329 /*CStyle=*/false, 5330 /*AllowObjCWritebackConversion=*/false); 5331 if (ICS.isFailure()) { 5332 Diag(VariantRef->getExprLoc(), 5333 diag::err_omp_declare_variant_incompat_types) 5334 << VariantRef->getType() 5335 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5336 << VariantRef->getSourceRange(); 5337 return None; 5338 } 5339 VariantRefCast = PerformImplicitConversion( 5340 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5341 if (!VariantRefCast.isUsable()) 5342 return None; 5343 // Drop previously built artificial addr_of unary op for member functions. 5344 if (Method && !Method->isStatic()) { 5345 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5346 if (auto *UO = dyn_cast<UnaryOperator>( 5347 PossibleAddrOfVariantRef->IgnoreImplicit())) 5348 VariantRefCast = UO->getSubExpr(); 5349 } 5350 } else { 5351 VariantRefCast = VariantRef; 5352 } 5353 5354 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5355 if (!ER.isUsable() || 5356 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5357 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5358 << VariantId << VariantRef->getSourceRange(); 5359 return None; 5360 } 5361 5362 // The VariantRef must point to function. 5363 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5364 if (!DRE) { 5365 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5366 << VariantId << VariantRef->getSourceRange(); 5367 return None; 5368 } 5369 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5370 if (!NewFD) { 5371 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5372 << VariantId << VariantRef->getSourceRange(); 5373 return None; 5374 } 5375 5376 // Check if function types are compatible in C. 5377 if (!LangOpts.CPlusPlus) { 5378 QualType NewType = 5379 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5380 if (NewType.isNull()) { 5381 Diag(VariantRef->getExprLoc(), 5382 diag::err_omp_declare_variant_incompat_types) 5383 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5384 return None; 5385 } 5386 if (NewType->isFunctionProtoType()) { 5387 if (FD->getType()->isFunctionNoProtoType()) 5388 setPrototype(*this, FD, NewFD, NewType); 5389 else if (NewFD->getType()->isFunctionNoProtoType()) 5390 setPrototype(*this, NewFD, FD, NewType); 5391 } 5392 } 5393 5394 // Check if variant function is not marked with declare variant directive. 5395 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5396 Diag(VariantRef->getExprLoc(), 5397 diag::warn_omp_declare_variant_marked_as_declare_variant) 5398 << VariantRef->getSourceRange(); 5399 SourceRange SR = 5400 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5401 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5402 return None; 5403 } 5404 5405 enum DoesntSupport { 5406 VirtFuncs = 1, 5407 Constructors = 3, 5408 Destructors = 4, 5409 DeletedFuncs = 5, 5410 DefaultedFuncs = 6, 5411 ConstexprFuncs = 7, 5412 ConstevalFuncs = 8, 5413 }; 5414 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5415 if (CXXFD->isVirtual()) { 5416 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5417 << VirtFuncs; 5418 return None; 5419 } 5420 5421 if (isa<CXXConstructorDecl>(FD)) { 5422 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5423 << Constructors; 5424 return None; 5425 } 5426 5427 if (isa<CXXDestructorDecl>(FD)) { 5428 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5429 << Destructors; 5430 return None; 5431 } 5432 } 5433 5434 if (FD->isDeleted()) { 5435 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5436 << DeletedFuncs; 5437 return None; 5438 } 5439 5440 if (FD->isDefaulted()) { 5441 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5442 << DefaultedFuncs; 5443 return None; 5444 } 5445 5446 if (FD->isConstexpr()) { 5447 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5448 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5449 return None; 5450 } 5451 5452 // Check general compatibility. 5453 if (areMultiversionVariantFunctionsCompatible( 5454 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5455 PartialDiagnosticAt(SourceLocation(), 5456 PartialDiagnostic::NullDiagnostic()), 5457 PartialDiagnosticAt( 5458 VariantRef->getExprLoc(), 5459 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5460 PartialDiagnosticAt(VariantRef->getExprLoc(), 5461 PDiag(diag::err_omp_declare_variant_diff) 5462 << FD->getLocation()), 5463 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5464 /*CLinkageMayDiffer=*/true)) 5465 return None; 5466 return std::make_pair(FD, cast<Expr>(DRE)); 5467 } 5468 5469 void Sema::ActOnOpenMPDeclareVariantDirective( 5470 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5471 ArrayRef<OMPCtxSelectorData> Data) { 5472 if (Data.empty()) 5473 return; 5474 SmallVector<Expr *, 4> CtxScores; 5475 SmallVector<unsigned, 4> CtxSets; 5476 SmallVector<unsigned, 4> Ctxs; 5477 SmallVector<StringRef, 4> ImplVendors, DeviceKinds; 5478 bool IsError = false; 5479 for (const OMPCtxSelectorData &D : Data) { 5480 OpenMPContextSelectorSetKind CtxSet = D.CtxSet; 5481 OpenMPContextSelectorKind Ctx = D.Ctx; 5482 if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown) 5483 return; 5484 Expr *Score = nullptr; 5485 if (D.Score.isUsable()) { 5486 Score = D.Score.get(); 5487 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5488 !Score->isInstantiationDependent() && 5489 !Score->containsUnexpandedParameterPack()) { 5490 Score = 5491 PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score) 5492 .get(); 5493 if (Score) 5494 Score = VerifyIntegerConstantExpression(Score).get(); 5495 } 5496 } else { 5497 // OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors. 5498 // The kind, arch, and isa selectors are given the values 2^l, 2^(l+1) and 5499 // 2^(l+2), respectively, where l is the number of traits in the construct 5500 // set. 5501 // TODO: implement correct logic for isa and arch traits. 5502 // TODO: take the construct context set into account when it is 5503 // implemented. 5504 int L = 0; // Currently set the number of traits in construct set to 0, 5505 // since the construct trait set in not supported yet. 5506 if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind) 5507 Score = ActOnIntegerConstant(SourceLocation(), std::pow(2, L)).get(); 5508 else 5509 Score = ActOnIntegerConstant(SourceLocation(), 0).get(); 5510 } 5511 switch (Ctx) { 5512 case OMP_CTX_vendor: 5513 assert(CtxSet == OMP_CTX_SET_implementation && 5514 "Expected implementation context selector set."); 5515 ImplVendors.append(D.Names.begin(), D.Names.end()); 5516 break; 5517 case OMP_CTX_kind: 5518 assert(CtxSet == OMP_CTX_SET_device && 5519 "Expected device context selector set."); 5520 DeviceKinds.append(D.Names.begin(), D.Names.end()); 5521 break; 5522 case OMP_CTX_unknown: 5523 llvm_unreachable("Unknown context selector kind."); 5524 } 5525 IsError = IsError || !Score; 5526 CtxSets.push_back(CtxSet); 5527 Ctxs.push_back(Ctx); 5528 CtxScores.push_back(Score); 5529 } 5530 if (!IsError) { 5531 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5532 Context, VariantRef, CtxScores.begin(), CtxScores.size(), 5533 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(), 5534 ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(), 5535 DeviceKinds.size(), SR); 5536 FD->addAttr(NewAttr); 5537 } 5538 } 5539 5540 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5541 FunctionDecl *Func, 5542 bool MightBeOdrUse) { 5543 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5544 5545 if (!Func->isDependentContext() && Func->hasAttrs()) { 5546 for (OMPDeclareVariantAttr *A : 5547 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5548 // TODO: add checks for active OpenMP context where possible. 5549 Expr *VariantRef = A->getVariantFuncRef(); 5550 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5551 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5552 if (!F->isDefined() && F->isTemplateInstantiation()) 5553 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5554 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5555 } 5556 } 5557 } 5558 5559 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5560 Stmt *AStmt, 5561 SourceLocation StartLoc, 5562 SourceLocation EndLoc) { 5563 if (!AStmt) 5564 return StmtError(); 5565 5566 auto *CS = cast<CapturedStmt>(AStmt); 5567 // 1.2.2 OpenMP Language Terminology 5568 // Structured block - An executable statement with a single entry at the 5569 // top and a single exit at the bottom. 5570 // The point of exit cannot be a branch out of the structured block. 5571 // longjmp() and throw() must not violate the entry/exit criteria. 5572 CS->getCapturedDecl()->setNothrow(); 5573 5574 setFunctionHasBranchProtectedScope(); 5575 5576 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5577 DSAStack->isCancelRegion()); 5578 } 5579 5580 namespace { 5581 /// Iteration space of a single for loop. 5582 struct LoopIterationSpace final { 5583 /// True if the condition operator is the strict compare operator (<, > or 5584 /// !=). 5585 bool IsStrictCompare = false; 5586 /// Condition of the loop. 5587 Expr *PreCond = nullptr; 5588 /// This expression calculates the number of iterations in the loop. 5589 /// It is always possible to calculate it before starting the loop. 5590 Expr *NumIterations = nullptr; 5591 /// The loop counter variable. 5592 Expr *CounterVar = nullptr; 5593 /// Private loop counter variable. 5594 Expr *PrivateCounterVar = nullptr; 5595 /// This is initializer for the initial value of #CounterVar. 5596 Expr *CounterInit = nullptr; 5597 /// This is step for the #CounterVar used to generate its update: 5598 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5599 Expr *CounterStep = nullptr; 5600 /// Should step be subtracted? 5601 bool Subtract = false; 5602 /// Source range of the loop init. 5603 SourceRange InitSrcRange; 5604 /// Source range of the loop condition. 5605 SourceRange CondSrcRange; 5606 /// Source range of the loop increment. 5607 SourceRange IncSrcRange; 5608 /// Minimum value that can have the loop control variable. Used to support 5609 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5610 /// since only such variables can be used in non-loop invariant expressions. 5611 Expr *MinValue = nullptr; 5612 /// Maximum value that can have the loop control variable. Used to support 5613 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5614 /// since only such variables can be used in non-loop invariant expressions. 5615 Expr *MaxValue = nullptr; 5616 /// true, if the lower bound depends on the outer loop control var. 5617 bool IsNonRectangularLB = false; 5618 /// true, if the upper bound depends on the outer loop control var. 5619 bool IsNonRectangularUB = false; 5620 /// Index of the loop this loop depends on and forms non-rectangular loop 5621 /// nest. 5622 unsigned LoopDependentIdx = 0; 5623 /// Final condition for the non-rectangular loop nest support. It is used to 5624 /// check that the number of iterations for this particular counter must be 5625 /// finished. 5626 Expr *FinalCondition = nullptr; 5627 }; 5628 5629 /// Helper class for checking canonical form of the OpenMP loops and 5630 /// extracting iteration space of each loop in the loop nest, that will be used 5631 /// for IR generation. 5632 class OpenMPIterationSpaceChecker { 5633 /// Reference to Sema. 5634 Sema &SemaRef; 5635 /// Data-sharing stack. 5636 DSAStackTy &Stack; 5637 /// A location for diagnostics (when there is no some better location). 5638 SourceLocation DefaultLoc; 5639 /// A location for diagnostics (when increment is not compatible). 5640 SourceLocation ConditionLoc; 5641 /// A source location for referring to loop init later. 5642 SourceRange InitSrcRange; 5643 /// A source location for referring to condition later. 5644 SourceRange ConditionSrcRange; 5645 /// A source location for referring to increment later. 5646 SourceRange IncrementSrcRange; 5647 /// Loop variable. 5648 ValueDecl *LCDecl = nullptr; 5649 /// Reference to loop variable. 5650 Expr *LCRef = nullptr; 5651 /// Lower bound (initializer for the var). 5652 Expr *LB = nullptr; 5653 /// Upper bound. 5654 Expr *UB = nullptr; 5655 /// Loop step (increment). 5656 Expr *Step = nullptr; 5657 /// This flag is true when condition is one of: 5658 /// Var < UB 5659 /// Var <= UB 5660 /// UB > Var 5661 /// UB >= Var 5662 /// This will have no value when the condition is != 5663 llvm::Optional<bool> TestIsLessOp; 5664 /// This flag is true when condition is strict ( < or > ). 5665 bool TestIsStrictOp = false; 5666 /// This flag is true when step is subtracted on each iteration. 5667 bool SubtractStep = false; 5668 /// The outer loop counter this loop depends on (if any). 5669 const ValueDecl *DepDecl = nullptr; 5670 /// Contains number of loop (starts from 1) on which loop counter init 5671 /// expression of this loop depends on. 5672 Optional<unsigned> InitDependOnLC; 5673 /// Contains number of loop (starts from 1) on which loop counter condition 5674 /// expression of this loop depends on. 5675 Optional<unsigned> CondDependOnLC; 5676 /// Checks if the provide statement depends on the loop counter. 5677 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5678 /// Original condition required for checking of the exit condition for 5679 /// non-rectangular loop. 5680 Expr *Condition = nullptr; 5681 5682 public: 5683 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5684 SourceLocation DefaultLoc) 5685 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5686 ConditionLoc(DefaultLoc) {} 5687 /// Check init-expr for canonical loop form and save loop counter 5688 /// variable - #Var and its initialization value - #LB. 5689 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5690 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5691 /// for less/greater and for strict/non-strict comparison. 5692 bool checkAndSetCond(Expr *S); 5693 /// Check incr-expr for canonical loop form and return true if it 5694 /// does not conform, otherwise save loop step (#Step). 5695 bool checkAndSetInc(Expr *S); 5696 /// Return the loop counter variable. 5697 ValueDecl *getLoopDecl() const { return LCDecl; } 5698 /// Return the reference expression to loop counter variable. 5699 Expr *getLoopDeclRefExpr() const { return LCRef; } 5700 /// Source range of the loop init. 5701 SourceRange getInitSrcRange() const { return InitSrcRange; } 5702 /// Source range of the loop condition. 5703 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5704 /// Source range of the loop increment. 5705 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5706 /// True if the step should be subtracted. 5707 bool shouldSubtractStep() const { return SubtractStep; } 5708 /// True, if the compare operator is strict (<, > or !=). 5709 bool isStrictTestOp() const { return TestIsStrictOp; } 5710 /// Build the expression to calculate the number of iterations. 5711 Expr *buildNumIterations( 5712 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5713 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5714 /// Build the precondition expression for the loops. 5715 Expr * 5716 buildPreCond(Scope *S, Expr *Cond, 5717 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5718 /// Build reference expression to the counter be used for codegen. 5719 DeclRefExpr * 5720 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5721 DSAStackTy &DSA) const; 5722 /// Build reference expression to the private counter be used for 5723 /// codegen. 5724 Expr *buildPrivateCounterVar() const; 5725 /// Build initialization of the counter be used for codegen. 5726 Expr *buildCounterInit() const; 5727 /// Build step of the counter be used for codegen. 5728 Expr *buildCounterStep() const; 5729 /// Build loop data with counter value for depend clauses in ordered 5730 /// directives. 5731 Expr * 5732 buildOrderedLoopData(Scope *S, Expr *Counter, 5733 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5734 SourceLocation Loc, Expr *Inc = nullptr, 5735 OverloadedOperatorKind OOK = OO_Amp); 5736 /// Builds the minimum value for the loop counter. 5737 std::pair<Expr *, Expr *> buildMinMaxValues( 5738 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5739 /// Builds final condition for the non-rectangular loops. 5740 Expr *buildFinalCondition(Scope *S) const; 5741 /// Return true if any expression is dependent. 5742 bool dependent() const; 5743 /// Returns true if the initializer forms non-rectangular loop. 5744 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5745 /// Returns true if the condition forms non-rectangular loop. 5746 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5747 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5748 unsigned getLoopDependentIdx() const { 5749 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5750 } 5751 5752 private: 5753 /// Check the right-hand side of an assignment in the increment 5754 /// expression. 5755 bool checkAndSetIncRHS(Expr *RHS); 5756 /// Helper to set loop counter variable and its initializer. 5757 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5758 bool EmitDiags); 5759 /// Helper to set upper bound. 5760 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5761 SourceRange SR, SourceLocation SL); 5762 /// Helper to set loop increment. 5763 bool setStep(Expr *NewStep, bool Subtract); 5764 }; 5765 5766 bool OpenMPIterationSpaceChecker::dependent() const { 5767 if (!LCDecl) { 5768 assert(!LB && !UB && !Step); 5769 return false; 5770 } 5771 return LCDecl->getType()->isDependentType() || 5772 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5773 (Step && Step->isValueDependent()); 5774 } 5775 5776 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5777 Expr *NewLCRefExpr, 5778 Expr *NewLB, bool EmitDiags) { 5779 // State consistency checking to ensure correct usage. 5780 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5781 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5782 if (!NewLCDecl || !NewLB) 5783 return true; 5784 LCDecl = getCanonicalDecl(NewLCDecl); 5785 LCRef = NewLCRefExpr; 5786 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5787 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5788 if ((Ctor->isCopyOrMoveConstructor() || 5789 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5790 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5791 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5792 LB = NewLB; 5793 if (EmitDiags) 5794 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5795 return false; 5796 } 5797 5798 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5799 llvm::Optional<bool> LessOp, 5800 bool StrictOp, SourceRange SR, 5801 SourceLocation SL) { 5802 // State consistency checking to ensure correct usage. 5803 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5804 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5805 if (!NewUB) 5806 return true; 5807 UB = NewUB; 5808 if (LessOp) 5809 TestIsLessOp = LessOp; 5810 TestIsStrictOp = StrictOp; 5811 ConditionSrcRange = SR; 5812 ConditionLoc = SL; 5813 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5814 return false; 5815 } 5816 5817 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5818 // State consistency checking to ensure correct usage. 5819 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5820 if (!NewStep) 5821 return true; 5822 if (!NewStep->isValueDependent()) { 5823 // Check that the step is integer expression. 5824 SourceLocation StepLoc = NewStep->getBeginLoc(); 5825 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5826 StepLoc, getExprAsWritten(NewStep)); 5827 if (Val.isInvalid()) 5828 return true; 5829 NewStep = Val.get(); 5830 5831 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5832 // If test-expr is of form var relational-op b and relational-op is < or 5833 // <= then incr-expr must cause var to increase on each iteration of the 5834 // loop. If test-expr is of form var relational-op b and relational-op is 5835 // > or >= then incr-expr must cause var to decrease on each iteration of 5836 // the loop. 5837 // If test-expr is of form b relational-op var and relational-op is < or 5838 // <= then incr-expr must cause var to decrease on each iteration of the 5839 // loop. If test-expr is of form b relational-op var and relational-op is 5840 // > or >= then incr-expr must cause var to increase on each iteration of 5841 // the loop. 5842 llvm::APSInt Result; 5843 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5844 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5845 bool IsConstNeg = 5846 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5847 bool IsConstPos = 5848 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5849 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5850 5851 // != with increment is treated as <; != with decrement is treated as > 5852 if (!TestIsLessOp.hasValue()) 5853 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5854 if (UB && (IsConstZero || 5855 (TestIsLessOp.getValue() ? 5856 (IsConstNeg || (IsUnsigned && Subtract)) : 5857 (IsConstPos || (IsUnsigned && !Subtract))))) { 5858 SemaRef.Diag(NewStep->getExprLoc(), 5859 diag::err_omp_loop_incr_not_compatible) 5860 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5861 SemaRef.Diag(ConditionLoc, 5862 diag::note_omp_loop_cond_requres_compatible_incr) 5863 << TestIsLessOp.getValue() << ConditionSrcRange; 5864 return true; 5865 } 5866 if (TestIsLessOp.getValue() == Subtract) { 5867 NewStep = 5868 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5869 .get(); 5870 Subtract = !Subtract; 5871 } 5872 } 5873 5874 Step = NewStep; 5875 SubtractStep = Subtract; 5876 return false; 5877 } 5878 5879 namespace { 5880 /// Checker for the non-rectangular loops. Checks if the initializer or 5881 /// condition expression references loop counter variable. 5882 class LoopCounterRefChecker final 5883 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5884 Sema &SemaRef; 5885 DSAStackTy &Stack; 5886 const ValueDecl *CurLCDecl = nullptr; 5887 const ValueDecl *DepDecl = nullptr; 5888 const ValueDecl *PrevDepDecl = nullptr; 5889 bool IsInitializer = true; 5890 unsigned BaseLoopId = 0; 5891 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5892 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5893 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5894 << (IsInitializer ? 0 : 1); 5895 return false; 5896 } 5897 const auto &&Data = Stack.isLoopControlVariable(VD); 5898 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5899 // The type of the loop iterator on which we depend may not have a random 5900 // access iterator type. 5901 if (Data.first && VD->getType()->isRecordType()) { 5902 SmallString<128> Name; 5903 llvm::raw_svector_ostream OS(Name); 5904 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5905 /*Qualified=*/true); 5906 SemaRef.Diag(E->getExprLoc(), 5907 diag::err_omp_wrong_dependency_iterator_type) 5908 << OS.str(); 5909 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5910 return false; 5911 } 5912 if (Data.first && 5913 (DepDecl || (PrevDepDecl && 5914 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5915 if (!DepDecl && PrevDepDecl) 5916 DepDecl = PrevDepDecl; 5917 SmallString<128> Name; 5918 llvm::raw_svector_ostream OS(Name); 5919 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5920 /*Qualified=*/true); 5921 SemaRef.Diag(E->getExprLoc(), 5922 diag::err_omp_invariant_or_linear_dependency) 5923 << OS.str(); 5924 return false; 5925 } 5926 if (Data.first) { 5927 DepDecl = VD; 5928 BaseLoopId = Data.first; 5929 } 5930 return Data.first; 5931 } 5932 5933 public: 5934 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5935 const ValueDecl *VD = E->getDecl(); 5936 if (isa<VarDecl>(VD)) 5937 return checkDecl(E, VD); 5938 return false; 5939 } 5940 bool VisitMemberExpr(const MemberExpr *E) { 5941 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5942 const ValueDecl *VD = E->getMemberDecl(); 5943 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5944 return checkDecl(E, VD); 5945 } 5946 return false; 5947 } 5948 bool VisitStmt(const Stmt *S) { 5949 bool Res = false; 5950 for (const Stmt *Child : S->children()) 5951 Res = (Child && Visit(Child)) || Res; 5952 return Res; 5953 } 5954 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5955 const ValueDecl *CurLCDecl, bool IsInitializer, 5956 const ValueDecl *PrevDepDecl = nullptr) 5957 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5958 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5959 unsigned getBaseLoopId() const { 5960 assert(CurLCDecl && "Expected loop dependency."); 5961 return BaseLoopId; 5962 } 5963 const ValueDecl *getDepDecl() const { 5964 assert(CurLCDecl && "Expected loop dependency."); 5965 return DepDecl; 5966 } 5967 }; 5968 } // namespace 5969 5970 Optional<unsigned> 5971 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5972 bool IsInitializer) { 5973 // Check for the non-rectangular loops. 5974 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5975 DepDecl); 5976 if (LoopStmtChecker.Visit(S)) { 5977 DepDecl = LoopStmtChecker.getDepDecl(); 5978 return LoopStmtChecker.getBaseLoopId(); 5979 } 5980 return llvm::None; 5981 } 5982 5983 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5984 // Check init-expr for canonical loop form and save loop counter 5985 // variable - #Var and its initialization value - #LB. 5986 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5987 // var = lb 5988 // integer-type var = lb 5989 // random-access-iterator-type var = lb 5990 // pointer-type var = lb 5991 // 5992 if (!S) { 5993 if (EmitDiags) { 5994 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5995 } 5996 return true; 5997 } 5998 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5999 if (!ExprTemp->cleanupsHaveSideEffects()) 6000 S = ExprTemp->getSubExpr(); 6001 6002 InitSrcRange = S->getSourceRange(); 6003 if (Expr *E = dyn_cast<Expr>(S)) 6004 S = E->IgnoreParens(); 6005 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6006 if (BO->getOpcode() == BO_Assign) { 6007 Expr *LHS = BO->getLHS()->IgnoreParens(); 6008 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6009 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6010 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6011 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6012 EmitDiags); 6013 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6014 } 6015 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6016 if (ME->isArrow() && 6017 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6018 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6019 EmitDiags); 6020 } 6021 } 6022 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6023 if (DS->isSingleDecl()) { 6024 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6025 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6026 // Accept non-canonical init form here but emit ext. warning. 6027 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6028 SemaRef.Diag(S->getBeginLoc(), 6029 diag::ext_omp_loop_not_canonical_init) 6030 << S->getSourceRange(); 6031 return setLCDeclAndLB( 6032 Var, 6033 buildDeclRefExpr(SemaRef, Var, 6034 Var->getType().getNonReferenceType(), 6035 DS->getBeginLoc()), 6036 Var->getInit(), EmitDiags); 6037 } 6038 } 6039 } 6040 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6041 if (CE->getOperator() == OO_Equal) { 6042 Expr *LHS = CE->getArg(0); 6043 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6044 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6045 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6046 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6047 EmitDiags); 6048 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6049 } 6050 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6051 if (ME->isArrow() && 6052 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6053 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6054 EmitDiags); 6055 } 6056 } 6057 } 6058 6059 if (dependent() || SemaRef.CurContext->isDependentContext()) 6060 return false; 6061 if (EmitDiags) { 6062 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6063 << S->getSourceRange(); 6064 } 6065 return true; 6066 } 6067 6068 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6069 /// variable (which may be the loop variable) if possible. 6070 static const ValueDecl *getInitLCDecl(const Expr *E) { 6071 if (!E) 6072 return nullptr; 6073 E = getExprAsWritten(E); 6074 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6075 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6076 if ((Ctor->isCopyOrMoveConstructor() || 6077 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6078 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6079 E = CE->getArg(0)->IgnoreParenImpCasts(); 6080 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6081 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6082 return getCanonicalDecl(VD); 6083 } 6084 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6085 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6086 return getCanonicalDecl(ME->getMemberDecl()); 6087 return nullptr; 6088 } 6089 6090 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6091 // Check test-expr for canonical form, save upper-bound UB, flags for 6092 // less/greater and for strict/non-strict comparison. 6093 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6094 // var relational-op b 6095 // b relational-op var 6096 // 6097 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6098 if (!S) { 6099 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6100 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6101 return true; 6102 } 6103 Condition = S; 6104 S = getExprAsWritten(S); 6105 SourceLocation CondLoc = S->getBeginLoc(); 6106 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6107 if (BO->isRelationalOp()) { 6108 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6109 return setUB(BO->getRHS(), 6110 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6111 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6112 BO->getSourceRange(), BO->getOperatorLoc()); 6113 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6114 return setUB(BO->getLHS(), 6115 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6116 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6117 BO->getSourceRange(), BO->getOperatorLoc()); 6118 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6119 return setUB( 6120 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6121 /*LessOp=*/llvm::None, 6122 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6123 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6124 if (CE->getNumArgs() == 2) { 6125 auto Op = CE->getOperator(); 6126 switch (Op) { 6127 case OO_Greater: 6128 case OO_GreaterEqual: 6129 case OO_Less: 6130 case OO_LessEqual: 6131 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6132 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6133 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6134 CE->getOperatorLoc()); 6135 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6136 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6137 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6138 CE->getOperatorLoc()); 6139 break; 6140 case OO_ExclaimEqual: 6141 if (IneqCondIsCanonical) 6142 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6143 : CE->getArg(0), 6144 /*LessOp=*/llvm::None, 6145 /*StrictOp=*/true, CE->getSourceRange(), 6146 CE->getOperatorLoc()); 6147 break; 6148 default: 6149 break; 6150 } 6151 } 6152 } 6153 if (dependent() || SemaRef.CurContext->isDependentContext()) 6154 return false; 6155 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6156 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6157 return true; 6158 } 6159 6160 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6161 // RHS of canonical loop form increment can be: 6162 // var + incr 6163 // incr + var 6164 // var - incr 6165 // 6166 RHS = RHS->IgnoreParenImpCasts(); 6167 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6168 if (BO->isAdditiveOp()) { 6169 bool IsAdd = BO->getOpcode() == BO_Add; 6170 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6171 return setStep(BO->getRHS(), !IsAdd); 6172 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6173 return setStep(BO->getLHS(), /*Subtract=*/false); 6174 } 6175 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6176 bool IsAdd = CE->getOperator() == OO_Plus; 6177 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6178 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6179 return setStep(CE->getArg(1), !IsAdd); 6180 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6181 return setStep(CE->getArg(0), /*Subtract=*/false); 6182 } 6183 } 6184 if (dependent() || SemaRef.CurContext->isDependentContext()) 6185 return false; 6186 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6187 << RHS->getSourceRange() << LCDecl; 6188 return true; 6189 } 6190 6191 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6192 // Check incr-expr for canonical loop form and return true if it 6193 // does not conform. 6194 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6195 // ++var 6196 // var++ 6197 // --var 6198 // var-- 6199 // var += incr 6200 // var -= incr 6201 // var = var + incr 6202 // var = incr + var 6203 // var = var - incr 6204 // 6205 if (!S) { 6206 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6207 return true; 6208 } 6209 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6210 if (!ExprTemp->cleanupsHaveSideEffects()) 6211 S = ExprTemp->getSubExpr(); 6212 6213 IncrementSrcRange = S->getSourceRange(); 6214 S = S->IgnoreParens(); 6215 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6216 if (UO->isIncrementDecrementOp() && 6217 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6218 return setStep(SemaRef 6219 .ActOnIntegerConstant(UO->getBeginLoc(), 6220 (UO->isDecrementOp() ? -1 : 1)) 6221 .get(), 6222 /*Subtract=*/false); 6223 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6224 switch (BO->getOpcode()) { 6225 case BO_AddAssign: 6226 case BO_SubAssign: 6227 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6228 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6229 break; 6230 case BO_Assign: 6231 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6232 return checkAndSetIncRHS(BO->getRHS()); 6233 break; 6234 default: 6235 break; 6236 } 6237 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6238 switch (CE->getOperator()) { 6239 case OO_PlusPlus: 6240 case OO_MinusMinus: 6241 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6242 return setStep(SemaRef 6243 .ActOnIntegerConstant( 6244 CE->getBeginLoc(), 6245 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6246 .get(), 6247 /*Subtract=*/false); 6248 break; 6249 case OO_PlusEqual: 6250 case OO_MinusEqual: 6251 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6252 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6253 break; 6254 case OO_Equal: 6255 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6256 return checkAndSetIncRHS(CE->getArg(1)); 6257 break; 6258 default: 6259 break; 6260 } 6261 } 6262 if (dependent() || SemaRef.CurContext->isDependentContext()) 6263 return false; 6264 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6265 << S->getSourceRange() << LCDecl; 6266 return true; 6267 } 6268 6269 static ExprResult 6270 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6271 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6272 if (SemaRef.CurContext->isDependentContext()) 6273 return ExprResult(Capture); 6274 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6275 return SemaRef.PerformImplicitConversion( 6276 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6277 /*AllowExplicit=*/true); 6278 auto I = Captures.find(Capture); 6279 if (I != Captures.end()) 6280 return buildCapture(SemaRef, Capture, I->second); 6281 DeclRefExpr *Ref = nullptr; 6282 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6283 Captures[Capture] = Ref; 6284 return Res; 6285 } 6286 6287 /// Build the expression to calculate the number of iterations. 6288 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6289 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6290 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6291 ExprResult Diff; 6292 QualType VarType = LCDecl->getType().getNonReferenceType(); 6293 if (VarType->isIntegerType() || VarType->isPointerType() || 6294 SemaRef.getLangOpts().CPlusPlus) { 6295 Expr *LBVal = LB; 6296 Expr *UBVal = UB; 6297 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6298 // max(LB(MinVal), LB(MaxVal)) 6299 if (InitDependOnLC) { 6300 const LoopIterationSpace &IS = 6301 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6302 InitDependOnLC.getValueOr( 6303 CondDependOnLC.getValueOr(0))]; 6304 if (!IS.MinValue || !IS.MaxValue) 6305 return nullptr; 6306 // OuterVar = Min 6307 ExprResult MinValue = 6308 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6309 if (!MinValue.isUsable()) 6310 return nullptr; 6311 6312 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6313 IS.CounterVar, MinValue.get()); 6314 if (!LBMinVal.isUsable()) 6315 return nullptr; 6316 // OuterVar = Min, LBVal 6317 LBMinVal = 6318 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6319 if (!LBMinVal.isUsable()) 6320 return nullptr; 6321 // (OuterVar = Min, LBVal) 6322 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6323 if (!LBMinVal.isUsable()) 6324 return nullptr; 6325 6326 // OuterVar = Max 6327 ExprResult MaxValue = 6328 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6329 if (!MaxValue.isUsable()) 6330 return nullptr; 6331 6332 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6333 IS.CounterVar, MaxValue.get()); 6334 if (!LBMaxVal.isUsable()) 6335 return nullptr; 6336 // OuterVar = Max, LBVal 6337 LBMaxVal = 6338 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6339 if (!LBMaxVal.isUsable()) 6340 return nullptr; 6341 // (OuterVar = Max, LBVal) 6342 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6343 if (!LBMaxVal.isUsable()) 6344 return nullptr; 6345 6346 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6347 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6348 if (!LBMin || !LBMax) 6349 return nullptr; 6350 // LB(MinVal) < LB(MaxVal) 6351 ExprResult MinLessMaxRes = 6352 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6353 if (!MinLessMaxRes.isUsable()) 6354 return nullptr; 6355 Expr *MinLessMax = 6356 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6357 if (!MinLessMax) 6358 return nullptr; 6359 if (TestIsLessOp.getValue()) { 6360 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6361 // LB(MaxVal)) 6362 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6363 MinLessMax, LBMin, LBMax); 6364 if (!MinLB.isUsable()) 6365 return nullptr; 6366 LBVal = MinLB.get(); 6367 } else { 6368 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6369 // LB(MaxVal)) 6370 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6371 MinLessMax, LBMax, LBMin); 6372 if (!MaxLB.isUsable()) 6373 return nullptr; 6374 LBVal = MaxLB.get(); 6375 } 6376 } 6377 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6378 // min(UB(MinVal), UB(MaxVal)) 6379 if (CondDependOnLC) { 6380 const LoopIterationSpace &IS = 6381 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6382 InitDependOnLC.getValueOr( 6383 CondDependOnLC.getValueOr(0))]; 6384 if (!IS.MinValue || !IS.MaxValue) 6385 return nullptr; 6386 // OuterVar = Min 6387 ExprResult MinValue = 6388 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6389 if (!MinValue.isUsable()) 6390 return nullptr; 6391 6392 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6393 IS.CounterVar, MinValue.get()); 6394 if (!UBMinVal.isUsable()) 6395 return nullptr; 6396 // OuterVar = Min, UBVal 6397 UBMinVal = 6398 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6399 if (!UBMinVal.isUsable()) 6400 return nullptr; 6401 // (OuterVar = Min, UBVal) 6402 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6403 if (!UBMinVal.isUsable()) 6404 return nullptr; 6405 6406 // OuterVar = Max 6407 ExprResult MaxValue = 6408 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6409 if (!MaxValue.isUsable()) 6410 return nullptr; 6411 6412 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6413 IS.CounterVar, MaxValue.get()); 6414 if (!UBMaxVal.isUsable()) 6415 return nullptr; 6416 // OuterVar = Max, UBVal 6417 UBMaxVal = 6418 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6419 if (!UBMaxVal.isUsable()) 6420 return nullptr; 6421 // (OuterVar = Max, UBVal) 6422 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6423 if (!UBMaxVal.isUsable()) 6424 return nullptr; 6425 6426 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6427 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6428 if (!UBMin || !UBMax) 6429 return nullptr; 6430 // UB(MinVal) > UB(MaxVal) 6431 ExprResult MinGreaterMaxRes = 6432 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6433 if (!MinGreaterMaxRes.isUsable()) 6434 return nullptr; 6435 Expr *MinGreaterMax = 6436 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6437 if (!MinGreaterMax) 6438 return nullptr; 6439 if (TestIsLessOp.getValue()) { 6440 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6441 // UB(MaxVal)) 6442 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6443 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6444 if (!MaxUB.isUsable()) 6445 return nullptr; 6446 UBVal = MaxUB.get(); 6447 } else { 6448 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6449 // UB(MaxVal)) 6450 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6451 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6452 if (!MinUB.isUsable()) 6453 return nullptr; 6454 UBVal = MinUB.get(); 6455 } 6456 } 6457 // Upper - Lower 6458 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6459 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6460 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6461 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6462 if (!Upper || !Lower) 6463 return nullptr; 6464 6465 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6466 6467 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6468 // BuildBinOp already emitted error, this one is to point user to upper 6469 // and lower bound, and to tell what is passed to 'operator-'. 6470 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6471 << Upper->getSourceRange() << Lower->getSourceRange(); 6472 return nullptr; 6473 } 6474 } 6475 6476 if (!Diff.isUsable()) 6477 return nullptr; 6478 6479 // Upper - Lower [- 1] 6480 if (TestIsStrictOp) 6481 Diff = SemaRef.BuildBinOp( 6482 S, DefaultLoc, BO_Sub, Diff.get(), 6483 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6484 if (!Diff.isUsable()) 6485 return nullptr; 6486 6487 // Upper - Lower [- 1] + Step 6488 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6489 if (!NewStep.isUsable()) 6490 return nullptr; 6491 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6492 if (!Diff.isUsable()) 6493 return nullptr; 6494 6495 // Parentheses (for dumping/debugging purposes only). 6496 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6497 if (!Diff.isUsable()) 6498 return nullptr; 6499 6500 // (Upper - Lower [- 1] + Step) / Step 6501 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6502 if (!Diff.isUsable()) 6503 return nullptr; 6504 6505 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6506 QualType Type = Diff.get()->getType(); 6507 ASTContext &C = SemaRef.Context; 6508 bool UseVarType = VarType->hasIntegerRepresentation() && 6509 C.getTypeSize(Type) > C.getTypeSize(VarType); 6510 if (!Type->isIntegerType() || UseVarType) { 6511 unsigned NewSize = 6512 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6513 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6514 : Type->hasSignedIntegerRepresentation(); 6515 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6516 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6517 Diff = SemaRef.PerformImplicitConversion( 6518 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6519 if (!Diff.isUsable()) 6520 return nullptr; 6521 } 6522 } 6523 if (LimitedType) { 6524 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6525 if (NewSize != C.getTypeSize(Type)) { 6526 if (NewSize < C.getTypeSize(Type)) { 6527 assert(NewSize == 64 && "incorrect loop var size"); 6528 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6529 << InitSrcRange << ConditionSrcRange; 6530 } 6531 QualType NewType = C.getIntTypeForBitwidth( 6532 NewSize, Type->hasSignedIntegerRepresentation() || 6533 C.getTypeSize(Type) < NewSize); 6534 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6535 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6536 Sema::AA_Converting, true); 6537 if (!Diff.isUsable()) 6538 return nullptr; 6539 } 6540 } 6541 } 6542 6543 return Diff.get(); 6544 } 6545 6546 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6547 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6548 // Do not build for iterators, they cannot be used in non-rectangular loop 6549 // nests. 6550 if (LCDecl->getType()->isRecordType()) 6551 return std::make_pair(nullptr, nullptr); 6552 // If we subtract, the min is in the condition, otherwise the min is in the 6553 // init value. 6554 Expr *MinExpr = nullptr; 6555 Expr *MaxExpr = nullptr; 6556 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6557 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6558 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6559 : CondDependOnLC.hasValue(); 6560 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6561 : InitDependOnLC.hasValue(); 6562 Expr *Lower = 6563 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6564 Expr *Upper = 6565 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6566 if (!Upper || !Lower) 6567 return std::make_pair(nullptr, nullptr); 6568 6569 if (TestIsLessOp.getValue()) 6570 MinExpr = Lower; 6571 else 6572 MaxExpr = Upper; 6573 6574 // Build minimum/maximum value based on number of iterations. 6575 ExprResult Diff; 6576 QualType VarType = LCDecl->getType().getNonReferenceType(); 6577 6578 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6579 if (!Diff.isUsable()) 6580 return std::make_pair(nullptr, nullptr); 6581 6582 // Upper - Lower [- 1] 6583 if (TestIsStrictOp) 6584 Diff = SemaRef.BuildBinOp( 6585 S, DefaultLoc, BO_Sub, Diff.get(), 6586 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6587 if (!Diff.isUsable()) 6588 return std::make_pair(nullptr, nullptr); 6589 6590 // Upper - Lower [- 1] + Step 6591 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6592 if (!NewStep.isUsable()) 6593 return std::make_pair(nullptr, nullptr); 6594 6595 // Parentheses (for dumping/debugging purposes only). 6596 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6597 if (!Diff.isUsable()) 6598 return std::make_pair(nullptr, nullptr); 6599 6600 // (Upper - Lower [- 1]) / Step 6601 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6602 if (!Diff.isUsable()) 6603 return std::make_pair(nullptr, nullptr); 6604 6605 // ((Upper - Lower [- 1]) / Step) * Step 6606 // Parentheses (for dumping/debugging purposes only). 6607 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6608 if (!Diff.isUsable()) 6609 return std::make_pair(nullptr, nullptr); 6610 6611 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6612 if (!Diff.isUsable()) 6613 return std::make_pair(nullptr, nullptr); 6614 6615 // Convert to the original type or ptrdiff_t, if original type is pointer. 6616 if (!VarType->isAnyPointerType() && 6617 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6618 Diff = SemaRef.PerformImplicitConversion( 6619 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6620 } else if (VarType->isAnyPointerType() && 6621 !SemaRef.Context.hasSameType( 6622 Diff.get()->getType(), 6623 SemaRef.Context.getUnsignedPointerDiffType())) { 6624 Diff = SemaRef.PerformImplicitConversion( 6625 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6626 Sema::AA_Converting, /*AllowExplicit=*/true); 6627 } 6628 if (!Diff.isUsable()) 6629 return std::make_pair(nullptr, nullptr); 6630 6631 // Parentheses (for dumping/debugging purposes only). 6632 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6633 if (!Diff.isUsable()) 6634 return std::make_pair(nullptr, nullptr); 6635 6636 if (TestIsLessOp.getValue()) { 6637 // MinExpr = Lower; 6638 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6639 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6640 if (!Diff.isUsable()) 6641 return std::make_pair(nullptr, nullptr); 6642 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6643 if (!Diff.isUsable()) 6644 return std::make_pair(nullptr, nullptr); 6645 MaxExpr = Diff.get(); 6646 } else { 6647 // MaxExpr = Upper; 6648 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6649 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6650 if (!Diff.isUsable()) 6651 return std::make_pair(nullptr, nullptr); 6652 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6653 if (!Diff.isUsable()) 6654 return std::make_pair(nullptr, nullptr); 6655 MinExpr = Diff.get(); 6656 } 6657 6658 return std::make_pair(MinExpr, MaxExpr); 6659 } 6660 6661 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6662 if (InitDependOnLC || CondDependOnLC) 6663 return Condition; 6664 return nullptr; 6665 } 6666 6667 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6668 Scope *S, Expr *Cond, 6669 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6670 // Do not build a precondition when the condition/initialization is dependent 6671 // to prevent pessimistic early loop exit. 6672 // TODO: this can be improved by calculating min/max values but not sure that 6673 // it will be very effective. 6674 if (CondDependOnLC || InitDependOnLC) 6675 return SemaRef.PerformImplicitConversion( 6676 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6677 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6678 /*AllowExplicit=*/true).get(); 6679 6680 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6681 Sema::TentativeAnalysisScope Trap(SemaRef); 6682 6683 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6684 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6685 if (!NewLB.isUsable() || !NewUB.isUsable()) 6686 return nullptr; 6687 6688 ExprResult CondExpr = 6689 SemaRef.BuildBinOp(S, DefaultLoc, 6690 TestIsLessOp.getValue() ? 6691 (TestIsStrictOp ? BO_LT : BO_LE) : 6692 (TestIsStrictOp ? BO_GT : BO_GE), 6693 NewLB.get(), NewUB.get()); 6694 if (CondExpr.isUsable()) { 6695 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6696 SemaRef.Context.BoolTy)) 6697 CondExpr = SemaRef.PerformImplicitConversion( 6698 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6699 /*AllowExplicit=*/true); 6700 } 6701 6702 // Otherwise use original loop condition and evaluate it in runtime. 6703 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6704 } 6705 6706 /// Build reference expression to the counter be used for codegen. 6707 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6708 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6709 DSAStackTy &DSA) const { 6710 auto *VD = dyn_cast<VarDecl>(LCDecl); 6711 if (!VD) { 6712 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6713 DeclRefExpr *Ref = buildDeclRefExpr( 6714 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6715 const DSAStackTy::DSAVarData Data = 6716 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6717 // If the loop control decl is explicitly marked as private, do not mark it 6718 // as captured again. 6719 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6720 Captures.insert(std::make_pair(LCRef, Ref)); 6721 return Ref; 6722 } 6723 return cast<DeclRefExpr>(LCRef); 6724 } 6725 6726 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6727 if (LCDecl && !LCDecl->isInvalidDecl()) { 6728 QualType Type = LCDecl->getType().getNonReferenceType(); 6729 VarDecl *PrivateVar = buildVarDecl( 6730 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6731 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6732 isa<VarDecl>(LCDecl) 6733 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6734 : nullptr); 6735 if (PrivateVar->isInvalidDecl()) 6736 return nullptr; 6737 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6738 } 6739 return nullptr; 6740 } 6741 6742 /// Build initialization of the counter to be used for codegen. 6743 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6744 6745 /// Build step of the counter be used for codegen. 6746 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6747 6748 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6749 Scope *S, Expr *Counter, 6750 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6751 Expr *Inc, OverloadedOperatorKind OOK) { 6752 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6753 if (!Cnt) 6754 return nullptr; 6755 if (Inc) { 6756 assert((OOK == OO_Plus || OOK == OO_Minus) && 6757 "Expected only + or - operations for depend clauses."); 6758 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6759 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6760 if (!Cnt) 6761 return nullptr; 6762 } 6763 ExprResult Diff; 6764 QualType VarType = LCDecl->getType().getNonReferenceType(); 6765 if (VarType->isIntegerType() || VarType->isPointerType() || 6766 SemaRef.getLangOpts().CPlusPlus) { 6767 // Upper - Lower 6768 Expr *Upper = TestIsLessOp.getValue() 6769 ? Cnt 6770 : tryBuildCapture(SemaRef, UB, Captures).get(); 6771 Expr *Lower = TestIsLessOp.getValue() 6772 ? tryBuildCapture(SemaRef, LB, Captures).get() 6773 : Cnt; 6774 if (!Upper || !Lower) 6775 return nullptr; 6776 6777 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6778 6779 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6780 // BuildBinOp already emitted error, this one is to point user to upper 6781 // and lower bound, and to tell what is passed to 'operator-'. 6782 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6783 << Upper->getSourceRange() << Lower->getSourceRange(); 6784 return nullptr; 6785 } 6786 } 6787 6788 if (!Diff.isUsable()) 6789 return nullptr; 6790 6791 // Parentheses (for dumping/debugging purposes only). 6792 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6793 if (!Diff.isUsable()) 6794 return nullptr; 6795 6796 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6797 if (!NewStep.isUsable()) 6798 return nullptr; 6799 // (Upper - Lower) / Step 6800 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6801 if (!Diff.isUsable()) 6802 return nullptr; 6803 6804 return Diff.get(); 6805 } 6806 } // namespace 6807 6808 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6809 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6810 assert(Init && "Expected loop in canonical form."); 6811 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6812 if (AssociatedLoops > 0 && 6813 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6814 DSAStack->loopStart(); 6815 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6816 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6817 if (ValueDecl *D = ISC.getLoopDecl()) { 6818 auto *VD = dyn_cast<VarDecl>(D); 6819 DeclRefExpr *PrivateRef = nullptr; 6820 if (!VD) { 6821 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6822 VD = Private; 6823 } else { 6824 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6825 /*WithInit=*/false); 6826 VD = cast<VarDecl>(PrivateRef->getDecl()); 6827 } 6828 } 6829 DSAStack->addLoopControlVariable(D, VD); 6830 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6831 if (LD != D->getCanonicalDecl()) { 6832 DSAStack->resetPossibleLoopCounter(); 6833 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6834 MarkDeclarationsReferencedInExpr( 6835 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6836 Var->getType().getNonLValueExprType(Context), 6837 ForLoc, /*RefersToCapture=*/true)); 6838 } 6839 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6840 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6841 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6842 // associated for-loop of a simd construct with just one associated 6843 // for-loop may be listed in a linear clause with a constant-linear-step 6844 // that is the increment of the associated for-loop. The loop iteration 6845 // variable(s) in the associated for-loop(s) of a for or parallel for 6846 // construct may be listed in a private or lastprivate clause. 6847 DSAStackTy::DSAVarData DVar = 6848 DSAStack->getTopDSA(D, /*FromParent=*/false); 6849 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6850 // is declared in the loop and it is predetermined as a private. 6851 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6852 OpenMPClauseKind PredeterminedCKind = 6853 isOpenMPSimdDirective(DKind) 6854 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6855 : OMPC_private; 6856 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6857 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6858 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6859 DVar.CKind != OMPC_private))) || 6860 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6861 DKind == OMPD_master_taskloop || 6862 DKind == OMPD_parallel_master_taskloop || 6863 isOpenMPDistributeDirective(DKind)) && 6864 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6865 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6866 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6867 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6868 << getOpenMPClauseName(DVar.CKind) 6869 << getOpenMPDirectiveName(DKind) 6870 << getOpenMPClauseName(PredeterminedCKind); 6871 if (DVar.RefExpr == nullptr) 6872 DVar.CKind = PredeterminedCKind; 6873 reportOriginalDsa(*this, DSAStack, D, DVar, 6874 /*IsLoopIterVar=*/true); 6875 } else if (LoopDeclRefExpr) { 6876 // Make the loop iteration variable private (for worksharing 6877 // constructs), linear (for simd directives with the only one 6878 // associated loop) or lastprivate (for simd directives with several 6879 // collapsed or ordered loops). 6880 if (DVar.CKind == OMPC_unknown) 6881 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6882 PrivateRef); 6883 } 6884 } 6885 } 6886 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6887 } 6888 } 6889 6890 /// Called on a for stmt to check and extract its iteration space 6891 /// for further processing (such as collapsing). 6892 static bool checkOpenMPIterationSpace( 6893 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6894 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6895 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6896 Expr *OrderedLoopCountExpr, 6897 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6898 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6899 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6900 // OpenMP [2.9.1, Canonical Loop Form] 6901 // for (init-expr; test-expr; incr-expr) structured-block 6902 // for (range-decl: range-expr) structured-block 6903 auto *For = dyn_cast_or_null<ForStmt>(S); 6904 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6905 // Ranged for is supported only in OpenMP 5.0. 6906 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6907 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6908 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6909 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6910 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6911 if (TotalNestedLoopCount > 1) { 6912 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6913 SemaRef.Diag(DSA.getConstructLoc(), 6914 diag::note_omp_collapse_ordered_expr) 6915 << 2 << CollapseLoopCountExpr->getSourceRange() 6916 << OrderedLoopCountExpr->getSourceRange(); 6917 else if (CollapseLoopCountExpr) 6918 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6919 diag::note_omp_collapse_ordered_expr) 6920 << 0 << CollapseLoopCountExpr->getSourceRange(); 6921 else 6922 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6923 diag::note_omp_collapse_ordered_expr) 6924 << 1 << OrderedLoopCountExpr->getSourceRange(); 6925 } 6926 return true; 6927 } 6928 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6929 "No loop body."); 6930 6931 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6932 For ? For->getForLoc() : CXXFor->getForLoc()); 6933 6934 // Check init. 6935 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6936 if (ISC.checkAndSetInit(Init)) 6937 return true; 6938 6939 bool HasErrors = false; 6940 6941 // Check loop variable's type. 6942 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6943 // OpenMP [2.6, Canonical Loop Form] 6944 // Var is one of the following: 6945 // A variable of signed or unsigned integer type. 6946 // For C++, a variable of a random access iterator type. 6947 // For C, a variable of a pointer type. 6948 QualType VarType = LCDecl->getType().getNonReferenceType(); 6949 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6950 !VarType->isPointerType() && 6951 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6952 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6953 << SemaRef.getLangOpts().CPlusPlus; 6954 HasErrors = true; 6955 } 6956 6957 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6958 // a Construct 6959 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6960 // parallel for construct is (are) private. 6961 // The loop iteration variable in the associated for-loop of a simd 6962 // construct with just one associated for-loop is linear with a 6963 // constant-linear-step that is the increment of the associated for-loop. 6964 // Exclude loop var from the list of variables with implicitly defined data 6965 // sharing attributes. 6966 VarsWithImplicitDSA.erase(LCDecl); 6967 6968 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6969 6970 // Check test-expr. 6971 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6972 6973 // Check incr-expr. 6974 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6975 } 6976 6977 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6978 return HasErrors; 6979 6980 // Build the loop's iteration space representation. 6981 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6982 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6983 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6984 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6985 (isOpenMPWorksharingDirective(DKind) || 6986 isOpenMPTaskLoopDirective(DKind) || 6987 isOpenMPDistributeDirective(DKind)), 6988 Captures); 6989 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6990 ISC.buildCounterVar(Captures, DSA); 6991 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6992 ISC.buildPrivateCounterVar(); 6993 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6994 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6995 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6996 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6997 ISC.getConditionSrcRange(); 6998 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6999 ISC.getIncrementSrcRange(); 7000 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7001 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7002 ISC.isStrictTestOp(); 7003 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7004 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7005 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7006 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7007 ISC.buildFinalCondition(DSA.getCurScope()); 7008 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7009 ISC.doesInitDependOnLC(); 7010 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7011 ISC.doesCondDependOnLC(); 7012 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7013 ISC.getLoopDependentIdx(); 7014 7015 HasErrors |= 7016 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7017 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7018 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7019 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7020 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7021 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7022 if (!HasErrors && DSA.isOrderedRegion()) { 7023 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7024 if (CurrentNestedLoopCount < 7025 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7026 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7027 CurrentNestedLoopCount, 7028 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7029 DSA.getOrderedRegionParam().second->setLoopCounter( 7030 CurrentNestedLoopCount, 7031 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7032 } 7033 } 7034 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7035 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7036 // Erroneous case - clause has some problems. 7037 continue; 7038 } 7039 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7040 Pair.second.size() <= CurrentNestedLoopCount) { 7041 // Erroneous case - clause has some problems. 7042 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7043 continue; 7044 } 7045 Expr *CntValue; 7046 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7047 CntValue = ISC.buildOrderedLoopData( 7048 DSA.getCurScope(), 7049 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7050 Pair.first->getDependencyLoc()); 7051 else 7052 CntValue = ISC.buildOrderedLoopData( 7053 DSA.getCurScope(), 7054 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7055 Pair.first->getDependencyLoc(), 7056 Pair.second[CurrentNestedLoopCount].first, 7057 Pair.second[CurrentNestedLoopCount].second); 7058 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7059 } 7060 } 7061 7062 return HasErrors; 7063 } 7064 7065 /// Build 'VarRef = Start. 7066 static ExprResult 7067 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7068 ExprResult Start, bool IsNonRectangularLB, 7069 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7070 // Build 'VarRef = Start. 7071 ExprResult NewStart = IsNonRectangularLB 7072 ? Start.get() 7073 : tryBuildCapture(SemaRef, Start.get(), Captures); 7074 if (!NewStart.isUsable()) 7075 return ExprError(); 7076 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7077 VarRef.get()->getType())) { 7078 NewStart = SemaRef.PerformImplicitConversion( 7079 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7080 /*AllowExplicit=*/true); 7081 if (!NewStart.isUsable()) 7082 return ExprError(); 7083 } 7084 7085 ExprResult Init = 7086 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7087 return Init; 7088 } 7089 7090 /// Build 'VarRef = Start + Iter * Step'. 7091 static ExprResult buildCounterUpdate( 7092 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7093 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7094 bool IsNonRectangularLB, 7095 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7096 // Add parentheses (for debugging purposes only). 7097 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7098 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7099 !Step.isUsable()) 7100 return ExprError(); 7101 7102 ExprResult NewStep = Step; 7103 if (Captures) 7104 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7105 if (NewStep.isInvalid()) 7106 return ExprError(); 7107 ExprResult Update = 7108 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7109 if (!Update.isUsable()) 7110 return ExprError(); 7111 7112 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7113 // 'VarRef = Start (+|-) Iter * Step'. 7114 if (!Start.isUsable()) 7115 return ExprError(); 7116 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7117 if (!NewStart.isUsable()) 7118 return ExprError(); 7119 if (Captures && !IsNonRectangularLB) 7120 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7121 if (NewStart.isInvalid()) 7122 return ExprError(); 7123 7124 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7125 ExprResult SavedUpdate = Update; 7126 ExprResult UpdateVal; 7127 if (VarRef.get()->getType()->isOverloadableType() || 7128 NewStart.get()->getType()->isOverloadableType() || 7129 Update.get()->getType()->isOverloadableType()) { 7130 Sema::TentativeAnalysisScope Trap(SemaRef); 7131 7132 Update = 7133 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7134 if (Update.isUsable()) { 7135 UpdateVal = 7136 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7137 VarRef.get(), SavedUpdate.get()); 7138 if (UpdateVal.isUsable()) { 7139 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7140 UpdateVal.get()); 7141 } 7142 } 7143 } 7144 7145 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7146 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7147 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7148 NewStart.get(), SavedUpdate.get()); 7149 if (!Update.isUsable()) 7150 return ExprError(); 7151 7152 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7153 VarRef.get()->getType())) { 7154 Update = SemaRef.PerformImplicitConversion( 7155 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7156 if (!Update.isUsable()) 7157 return ExprError(); 7158 } 7159 7160 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7161 } 7162 return Update; 7163 } 7164 7165 /// Convert integer expression \a E to make it have at least \a Bits 7166 /// bits. 7167 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7168 if (E == nullptr) 7169 return ExprError(); 7170 ASTContext &C = SemaRef.Context; 7171 QualType OldType = E->getType(); 7172 unsigned HasBits = C.getTypeSize(OldType); 7173 if (HasBits >= Bits) 7174 return ExprResult(E); 7175 // OK to convert to signed, because new type has more bits than old. 7176 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7177 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7178 true); 7179 } 7180 7181 /// Check if the given expression \a E is a constant integer that fits 7182 /// into \a Bits bits. 7183 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7184 if (E == nullptr) 7185 return false; 7186 llvm::APSInt Result; 7187 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7188 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7189 return false; 7190 } 7191 7192 /// Build preinits statement for the given declarations. 7193 static Stmt *buildPreInits(ASTContext &Context, 7194 MutableArrayRef<Decl *> PreInits) { 7195 if (!PreInits.empty()) { 7196 return new (Context) DeclStmt( 7197 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7198 SourceLocation(), SourceLocation()); 7199 } 7200 return nullptr; 7201 } 7202 7203 /// Build preinits statement for the given declarations. 7204 static Stmt * 7205 buildPreInits(ASTContext &Context, 7206 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7207 if (!Captures.empty()) { 7208 SmallVector<Decl *, 16> PreInits; 7209 for (const auto &Pair : Captures) 7210 PreInits.push_back(Pair.second->getDecl()); 7211 return buildPreInits(Context, PreInits); 7212 } 7213 return nullptr; 7214 } 7215 7216 /// Build postupdate expression for the given list of postupdates expressions. 7217 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7218 Expr *PostUpdate = nullptr; 7219 if (!PostUpdates.empty()) { 7220 for (Expr *E : PostUpdates) { 7221 Expr *ConvE = S.BuildCStyleCastExpr( 7222 E->getExprLoc(), 7223 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7224 E->getExprLoc(), E) 7225 .get(); 7226 PostUpdate = PostUpdate 7227 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7228 PostUpdate, ConvE) 7229 .get() 7230 : ConvE; 7231 } 7232 } 7233 return PostUpdate; 7234 } 7235 7236 /// Called on a for stmt to check itself and nested loops (if any). 7237 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7238 /// number of collapsed loops otherwise. 7239 static unsigned 7240 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7241 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7242 DSAStackTy &DSA, 7243 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7244 OMPLoopDirective::HelperExprs &Built) { 7245 unsigned NestedLoopCount = 1; 7246 if (CollapseLoopCountExpr) { 7247 // Found 'collapse' clause - calculate collapse number. 7248 Expr::EvalResult Result; 7249 if (!CollapseLoopCountExpr->isValueDependent() && 7250 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7251 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7252 } else { 7253 Built.clear(/*Size=*/1); 7254 return 1; 7255 } 7256 } 7257 unsigned OrderedLoopCount = 1; 7258 if (OrderedLoopCountExpr) { 7259 // Found 'ordered' clause - calculate collapse number. 7260 Expr::EvalResult EVResult; 7261 if (!OrderedLoopCountExpr->isValueDependent() && 7262 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7263 SemaRef.getASTContext())) { 7264 llvm::APSInt Result = EVResult.Val.getInt(); 7265 if (Result.getLimitedValue() < NestedLoopCount) { 7266 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7267 diag::err_omp_wrong_ordered_loop_count) 7268 << OrderedLoopCountExpr->getSourceRange(); 7269 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7270 diag::note_collapse_loop_count) 7271 << CollapseLoopCountExpr->getSourceRange(); 7272 } 7273 OrderedLoopCount = Result.getLimitedValue(); 7274 } else { 7275 Built.clear(/*Size=*/1); 7276 return 1; 7277 } 7278 } 7279 // This is helper routine for loop directives (e.g., 'for', 'simd', 7280 // 'for simd', etc.). 7281 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7282 SmallVector<LoopIterationSpace, 4> IterSpaces( 7283 std::max(OrderedLoopCount, NestedLoopCount)); 7284 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7285 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7286 if (checkOpenMPIterationSpace( 7287 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7288 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7289 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7290 return 0; 7291 // Move on to the next nested for loop, or to the loop body. 7292 // OpenMP [2.8.1, simd construct, Restrictions] 7293 // All loops associated with the construct must be perfectly nested; that 7294 // is, there must be no intervening code nor any OpenMP directive between 7295 // any two loops. 7296 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7297 CurStmt = For->getBody(); 7298 } else { 7299 assert(isa<CXXForRangeStmt>(CurStmt) && 7300 "Expected canonical for or range-based for loops."); 7301 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7302 } 7303 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7304 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7305 } 7306 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7307 if (checkOpenMPIterationSpace( 7308 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7309 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7310 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7311 return 0; 7312 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7313 // Handle initialization of captured loop iterator variables. 7314 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7315 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7316 Captures[DRE] = DRE; 7317 } 7318 } 7319 // Move on to the next nested for loop, or to the loop body. 7320 // OpenMP [2.8.1, simd construct, Restrictions] 7321 // All loops associated with the construct must be perfectly nested; that 7322 // is, there must be no intervening code nor any OpenMP directive between 7323 // any two loops. 7324 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7325 CurStmt = For->getBody(); 7326 } else { 7327 assert(isa<CXXForRangeStmt>(CurStmt) && 7328 "Expected canonical for or range-based for loops."); 7329 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7330 } 7331 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7332 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7333 } 7334 7335 Built.clear(/* size */ NestedLoopCount); 7336 7337 if (SemaRef.CurContext->isDependentContext()) 7338 return NestedLoopCount; 7339 7340 // An example of what is generated for the following code: 7341 // 7342 // #pragma omp simd collapse(2) ordered(2) 7343 // for (i = 0; i < NI; ++i) 7344 // for (k = 0; k < NK; ++k) 7345 // for (j = J0; j < NJ; j+=2) { 7346 // <loop body> 7347 // } 7348 // 7349 // We generate the code below. 7350 // Note: the loop body may be outlined in CodeGen. 7351 // Note: some counters may be C++ classes, operator- is used to find number of 7352 // iterations and operator+= to calculate counter value. 7353 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7354 // or i64 is currently supported). 7355 // 7356 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7357 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7358 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7359 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7360 // // similar updates for vars in clauses (e.g. 'linear') 7361 // <loop body (using local i and j)> 7362 // } 7363 // i = NI; // assign final values of counters 7364 // j = NJ; 7365 // 7366 7367 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7368 // the iteration counts of the collapsed for loops. 7369 // Precondition tests if there is at least one iteration (all conditions are 7370 // true). 7371 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7372 Expr *N0 = IterSpaces[0].NumIterations; 7373 ExprResult LastIteration32 = 7374 widenIterationCount(/*Bits=*/32, 7375 SemaRef 7376 .PerformImplicitConversion( 7377 N0->IgnoreImpCasts(), N0->getType(), 7378 Sema::AA_Converting, /*AllowExplicit=*/true) 7379 .get(), 7380 SemaRef); 7381 ExprResult LastIteration64 = widenIterationCount( 7382 /*Bits=*/64, 7383 SemaRef 7384 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7385 Sema::AA_Converting, 7386 /*AllowExplicit=*/true) 7387 .get(), 7388 SemaRef); 7389 7390 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7391 return NestedLoopCount; 7392 7393 ASTContext &C = SemaRef.Context; 7394 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7395 7396 Scope *CurScope = DSA.getCurScope(); 7397 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7398 if (PreCond.isUsable()) { 7399 PreCond = 7400 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7401 PreCond.get(), IterSpaces[Cnt].PreCond); 7402 } 7403 Expr *N = IterSpaces[Cnt].NumIterations; 7404 SourceLocation Loc = N->getExprLoc(); 7405 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7406 if (LastIteration32.isUsable()) 7407 LastIteration32 = SemaRef.BuildBinOp( 7408 CurScope, Loc, BO_Mul, LastIteration32.get(), 7409 SemaRef 7410 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7411 Sema::AA_Converting, 7412 /*AllowExplicit=*/true) 7413 .get()); 7414 if (LastIteration64.isUsable()) 7415 LastIteration64 = SemaRef.BuildBinOp( 7416 CurScope, Loc, BO_Mul, LastIteration64.get(), 7417 SemaRef 7418 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7419 Sema::AA_Converting, 7420 /*AllowExplicit=*/true) 7421 .get()); 7422 } 7423 7424 // Choose either the 32-bit or 64-bit version. 7425 ExprResult LastIteration = LastIteration64; 7426 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7427 (LastIteration32.isUsable() && 7428 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7429 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7430 fitsInto( 7431 /*Bits=*/32, 7432 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7433 LastIteration64.get(), SemaRef)))) 7434 LastIteration = LastIteration32; 7435 QualType VType = LastIteration.get()->getType(); 7436 QualType RealVType = VType; 7437 QualType StrideVType = VType; 7438 if (isOpenMPTaskLoopDirective(DKind)) { 7439 VType = 7440 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7441 StrideVType = 7442 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7443 } 7444 7445 if (!LastIteration.isUsable()) 7446 return 0; 7447 7448 // Save the number of iterations. 7449 ExprResult NumIterations = LastIteration; 7450 { 7451 LastIteration = SemaRef.BuildBinOp( 7452 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7453 LastIteration.get(), 7454 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7455 if (!LastIteration.isUsable()) 7456 return 0; 7457 } 7458 7459 // Calculate the last iteration number beforehand instead of doing this on 7460 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7461 llvm::APSInt Result; 7462 bool IsConstant = 7463 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7464 ExprResult CalcLastIteration; 7465 if (!IsConstant) { 7466 ExprResult SaveRef = 7467 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7468 LastIteration = SaveRef; 7469 7470 // Prepare SaveRef + 1. 7471 NumIterations = SemaRef.BuildBinOp( 7472 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7473 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7474 if (!NumIterations.isUsable()) 7475 return 0; 7476 } 7477 7478 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7479 7480 // Build variables passed into runtime, necessary for worksharing directives. 7481 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7482 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7483 isOpenMPDistributeDirective(DKind)) { 7484 // Lower bound variable, initialized with zero. 7485 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7486 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7487 SemaRef.AddInitializerToDecl(LBDecl, 7488 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7489 /*DirectInit*/ false); 7490 7491 // Upper bound variable, initialized with last iteration number. 7492 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7493 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7494 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7495 /*DirectInit*/ false); 7496 7497 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7498 // This will be used to implement clause 'lastprivate'. 7499 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7500 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7501 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7502 SemaRef.AddInitializerToDecl(ILDecl, 7503 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7504 /*DirectInit*/ false); 7505 7506 // Stride variable returned by runtime (we initialize it to 1 by default). 7507 VarDecl *STDecl = 7508 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7509 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7510 SemaRef.AddInitializerToDecl(STDecl, 7511 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7512 /*DirectInit*/ false); 7513 7514 // Build expression: UB = min(UB, LastIteration) 7515 // It is necessary for CodeGen of directives with static scheduling. 7516 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7517 UB.get(), LastIteration.get()); 7518 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7519 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7520 LastIteration.get(), UB.get()); 7521 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7522 CondOp.get()); 7523 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7524 7525 // If we have a combined directive that combines 'distribute', 'for' or 7526 // 'simd' we need to be able to access the bounds of the schedule of the 7527 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7528 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7529 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7530 // Lower bound variable, initialized with zero. 7531 VarDecl *CombLBDecl = 7532 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7533 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7534 SemaRef.AddInitializerToDecl( 7535 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7536 /*DirectInit*/ false); 7537 7538 // Upper bound variable, initialized with last iteration number. 7539 VarDecl *CombUBDecl = 7540 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7541 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7542 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7543 /*DirectInit*/ false); 7544 7545 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7546 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7547 ExprResult CombCondOp = 7548 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7549 LastIteration.get(), CombUB.get()); 7550 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7551 CombCondOp.get()); 7552 CombEUB = 7553 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7554 7555 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7556 // We expect to have at least 2 more parameters than the 'parallel' 7557 // directive does - the lower and upper bounds of the previous schedule. 7558 assert(CD->getNumParams() >= 4 && 7559 "Unexpected number of parameters in loop combined directive"); 7560 7561 // Set the proper type for the bounds given what we learned from the 7562 // enclosed loops. 7563 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7564 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7565 7566 // Previous lower and upper bounds are obtained from the region 7567 // parameters. 7568 PrevLB = 7569 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7570 PrevUB = 7571 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7572 } 7573 } 7574 7575 // Build the iteration variable and its initialization before loop. 7576 ExprResult IV; 7577 ExprResult Init, CombInit; 7578 { 7579 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7580 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7581 Expr *RHS = 7582 (isOpenMPWorksharingDirective(DKind) || 7583 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7584 ? LB.get() 7585 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7586 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7587 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7588 7589 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7590 Expr *CombRHS = 7591 (isOpenMPWorksharingDirective(DKind) || 7592 isOpenMPTaskLoopDirective(DKind) || 7593 isOpenMPDistributeDirective(DKind)) 7594 ? CombLB.get() 7595 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7596 CombInit = 7597 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7598 CombInit = 7599 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7600 } 7601 } 7602 7603 bool UseStrictCompare = 7604 RealVType->hasUnsignedIntegerRepresentation() && 7605 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7606 return LIS.IsStrictCompare; 7607 }); 7608 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7609 // unsigned IV)) for worksharing loops. 7610 SourceLocation CondLoc = AStmt->getBeginLoc(); 7611 Expr *BoundUB = UB.get(); 7612 if (UseStrictCompare) { 7613 BoundUB = 7614 SemaRef 7615 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7616 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7617 .get(); 7618 BoundUB = 7619 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7620 } 7621 ExprResult Cond = 7622 (isOpenMPWorksharingDirective(DKind) || 7623 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7624 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7625 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7626 BoundUB) 7627 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7628 NumIterations.get()); 7629 ExprResult CombDistCond; 7630 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7631 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7632 NumIterations.get()); 7633 } 7634 7635 ExprResult CombCond; 7636 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7637 Expr *BoundCombUB = CombUB.get(); 7638 if (UseStrictCompare) { 7639 BoundCombUB = 7640 SemaRef 7641 .BuildBinOp( 7642 CurScope, CondLoc, BO_Add, BoundCombUB, 7643 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7644 .get(); 7645 BoundCombUB = 7646 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7647 .get(); 7648 } 7649 CombCond = 7650 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7651 IV.get(), BoundCombUB); 7652 } 7653 // Loop increment (IV = IV + 1) 7654 SourceLocation IncLoc = AStmt->getBeginLoc(); 7655 ExprResult Inc = 7656 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7657 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7658 if (!Inc.isUsable()) 7659 return 0; 7660 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7661 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7662 if (!Inc.isUsable()) 7663 return 0; 7664 7665 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7666 // Used for directives with static scheduling. 7667 // In combined construct, add combined version that use CombLB and CombUB 7668 // base variables for the update 7669 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7670 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7671 isOpenMPDistributeDirective(DKind)) { 7672 // LB + ST 7673 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7674 if (!NextLB.isUsable()) 7675 return 0; 7676 // LB = LB + ST 7677 NextLB = 7678 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7679 NextLB = 7680 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7681 if (!NextLB.isUsable()) 7682 return 0; 7683 // UB + ST 7684 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7685 if (!NextUB.isUsable()) 7686 return 0; 7687 // UB = UB + ST 7688 NextUB = 7689 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7690 NextUB = 7691 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7692 if (!NextUB.isUsable()) 7693 return 0; 7694 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7695 CombNextLB = 7696 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7697 if (!NextLB.isUsable()) 7698 return 0; 7699 // LB = LB + ST 7700 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7701 CombNextLB.get()); 7702 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7703 /*DiscardedValue*/ false); 7704 if (!CombNextLB.isUsable()) 7705 return 0; 7706 // UB + ST 7707 CombNextUB = 7708 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7709 if (!CombNextUB.isUsable()) 7710 return 0; 7711 // UB = UB + ST 7712 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7713 CombNextUB.get()); 7714 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7715 /*DiscardedValue*/ false); 7716 if (!CombNextUB.isUsable()) 7717 return 0; 7718 } 7719 } 7720 7721 // Create increment expression for distribute loop when combined in a same 7722 // directive with for as IV = IV + ST; ensure upper bound expression based 7723 // on PrevUB instead of NumIterations - used to implement 'for' when found 7724 // in combination with 'distribute', like in 'distribute parallel for' 7725 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7726 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7727 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7728 DistCond = SemaRef.BuildBinOp( 7729 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7730 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7731 7732 DistInc = 7733 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7734 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7735 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7736 DistInc.get()); 7737 DistInc = 7738 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7739 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7740 7741 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7742 // construct 7743 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7744 ExprResult IsUBGreater = 7745 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7746 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7747 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7748 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7749 CondOp.get()); 7750 PrevEUB = 7751 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7752 7753 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7754 // parallel for is in combination with a distribute directive with 7755 // schedule(static, 1) 7756 Expr *BoundPrevUB = PrevUB.get(); 7757 if (UseStrictCompare) { 7758 BoundPrevUB = 7759 SemaRef 7760 .BuildBinOp( 7761 CurScope, CondLoc, BO_Add, BoundPrevUB, 7762 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7763 .get(); 7764 BoundPrevUB = 7765 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7766 .get(); 7767 } 7768 ParForInDistCond = 7769 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7770 IV.get(), BoundPrevUB); 7771 } 7772 7773 // Build updates and final values of the loop counters. 7774 bool HasErrors = false; 7775 Built.Counters.resize(NestedLoopCount); 7776 Built.Inits.resize(NestedLoopCount); 7777 Built.Updates.resize(NestedLoopCount); 7778 Built.Finals.resize(NestedLoopCount); 7779 Built.DependentCounters.resize(NestedLoopCount); 7780 Built.DependentInits.resize(NestedLoopCount); 7781 Built.FinalsConditions.resize(NestedLoopCount); 7782 { 7783 // We implement the following algorithm for obtaining the 7784 // original loop iteration variable values based on the 7785 // value of the collapsed loop iteration variable IV. 7786 // 7787 // Let n+1 be the number of collapsed loops in the nest. 7788 // Iteration variables (I0, I1, .... In) 7789 // Iteration counts (N0, N1, ... Nn) 7790 // 7791 // Acc = IV; 7792 // 7793 // To compute Ik for loop k, 0 <= k <= n, generate: 7794 // Prod = N(k+1) * N(k+2) * ... * Nn; 7795 // Ik = Acc / Prod; 7796 // Acc -= Ik * Prod; 7797 // 7798 ExprResult Acc = IV; 7799 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7800 LoopIterationSpace &IS = IterSpaces[Cnt]; 7801 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7802 ExprResult Iter; 7803 7804 // Compute prod 7805 ExprResult Prod = 7806 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7807 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7808 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7809 IterSpaces[K].NumIterations); 7810 7811 // Iter = Acc / Prod 7812 // If there is at least one more inner loop to avoid 7813 // multiplication by 1. 7814 if (Cnt + 1 < NestedLoopCount) 7815 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7816 Acc.get(), Prod.get()); 7817 else 7818 Iter = Acc; 7819 if (!Iter.isUsable()) { 7820 HasErrors = true; 7821 break; 7822 } 7823 7824 // Update Acc: 7825 // Acc -= Iter * Prod 7826 // Check if there is at least one more inner loop to avoid 7827 // multiplication by 1. 7828 if (Cnt + 1 < NestedLoopCount) 7829 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7830 Iter.get(), Prod.get()); 7831 else 7832 Prod = Iter; 7833 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7834 Acc.get(), Prod.get()); 7835 7836 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7837 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7838 DeclRefExpr *CounterVar = buildDeclRefExpr( 7839 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7840 /*RefersToCapture=*/true); 7841 ExprResult Init = 7842 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7843 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7844 if (!Init.isUsable()) { 7845 HasErrors = true; 7846 break; 7847 } 7848 ExprResult Update = buildCounterUpdate( 7849 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7850 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7851 if (!Update.isUsable()) { 7852 HasErrors = true; 7853 break; 7854 } 7855 7856 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7857 ExprResult Final = 7858 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7859 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7860 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7861 if (!Final.isUsable()) { 7862 HasErrors = true; 7863 break; 7864 } 7865 7866 if (!Update.isUsable() || !Final.isUsable()) { 7867 HasErrors = true; 7868 break; 7869 } 7870 // Save results 7871 Built.Counters[Cnt] = IS.CounterVar; 7872 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7873 Built.Inits[Cnt] = Init.get(); 7874 Built.Updates[Cnt] = Update.get(); 7875 Built.Finals[Cnt] = Final.get(); 7876 Built.DependentCounters[Cnt] = nullptr; 7877 Built.DependentInits[Cnt] = nullptr; 7878 Built.FinalsConditions[Cnt] = nullptr; 7879 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7880 Built.DependentCounters[Cnt] = 7881 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7882 Built.DependentInits[Cnt] = 7883 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7884 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7885 } 7886 } 7887 } 7888 7889 if (HasErrors) 7890 return 0; 7891 7892 // Save results 7893 Built.IterationVarRef = IV.get(); 7894 Built.LastIteration = LastIteration.get(); 7895 Built.NumIterations = NumIterations.get(); 7896 Built.CalcLastIteration = SemaRef 7897 .ActOnFinishFullExpr(CalcLastIteration.get(), 7898 /*DiscardedValue=*/false) 7899 .get(); 7900 Built.PreCond = PreCond.get(); 7901 Built.PreInits = buildPreInits(C, Captures); 7902 Built.Cond = Cond.get(); 7903 Built.Init = Init.get(); 7904 Built.Inc = Inc.get(); 7905 Built.LB = LB.get(); 7906 Built.UB = UB.get(); 7907 Built.IL = IL.get(); 7908 Built.ST = ST.get(); 7909 Built.EUB = EUB.get(); 7910 Built.NLB = NextLB.get(); 7911 Built.NUB = NextUB.get(); 7912 Built.PrevLB = PrevLB.get(); 7913 Built.PrevUB = PrevUB.get(); 7914 Built.DistInc = DistInc.get(); 7915 Built.PrevEUB = PrevEUB.get(); 7916 Built.DistCombinedFields.LB = CombLB.get(); 7917 Built.DistCombinedFields.UB = CombUB.get(); 7918 Built.DistCombinedFields.EUB = CombEUB.get(); 7919 Built.DistCombinedFields.Init = CombInit.get(); 7920 Built.DistCombinedFields.Cond = CombCond.get(); 7921 Built.DistCombinedFields.NLB = CombNextLB.get(); 7922 Built.DistCombinedFields.NUB = CombNextUB.get(); 7923 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7924 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7925 7926 return NestedLoopCount; 7927 } 7928 7929 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7930 auto CollapseClauses = 7931 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7932 if (CollapseClauses.begin() != CollapseClauses.end()) 7933 return (*CollapseClauses.begin())->getNumForLoops(); 7934 return nullptr; 7935 } 7936 7937 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7938 auto OrderedClauses = 7939 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7940 if (OrderedClauses.begin() != OrderedClauses.end()) 7941 return (*OrderedClauses.begin())->getNumForLoops(); 7942 return nullptr; 7943 } 7944 7945 static bool checkSimdlenSafelenSpecified(Sema &S, 7946 const ArrayRef<OMPClause *> Clauses) { 7947 const OMPSafelenClause *Safelen = nullptr; 7948 const OMPSimdlenClause *Simdlen = nullptr; 7949 7950 for (const OMPClause *Clause : Clauses) { 7951 if (Clause->getClauseKind() == OMPC_safelen) 7952 Safelen = cast<OMPSafelenClause>(Clause); 7953 else if (Clause->getClauseKind() == OMPC_simdlen) 7954 Simdlen = cast<OMPSimdlenClause>(Clause); 7955 if (Safelen && Simdlen) 7956 break; 7957 } 7958 7959 if (Simdlen && Safelen) { 7960 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7961 const Expr *SafelenLength = Safelen->getSafelen(); 7962 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7963 SimdlenLength->isInstantiationDependent() || 7964 SimdlenLength->containsUnexpandedParameterPack()) 7965 return false; 7966 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7967 SafelenLength->isInstantiationDependent() || 7968 SafelenLength->containsUnexpandedParameterPack()) 7969 return false; 7970 Expr::EvalResult SimdlenResult, SafelenResult; 7971 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7972 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7973 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7974 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7975 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7976 // If both simdlen and safelen clauses are specified, the value of the 7977 // simdlen parameter must be less than or equal to the value of the safelen 7978 // parameter. 7979 if (SimdlenRes > SafelenRes) { 7980 S.Diag(SimdlenLength->getExprLoc(), 7981 diag::err_omp_wrong_simdlen_safelen_values) 7982 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7983 return true; 7984 } 7985 } 7986 return false; 7987 } 7988 7989 StmtResult 7990 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7991 SourceLocation StartLoc, SourceLocation EndLoc, 7992 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7993 if (!AStmt) 7994 return StmtError(); 7995 7996 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7997 OMPLoopDirective::HelperExprs B; 7998 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7999 // define the nested loops number. 8000 unsigned NestedLoopCount = checkOpenMPLoop( 8001 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8002 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8003 if (NestedLoopCount == 0) 8004 return StmtError(); 8005 8006 assert((CurContext->isDependentContext() || B.builtAll()) && 8007 "omp simd loop exprs were not built"); 8008 8009 if (!CurContext->isDependentContext()) { 8010 // Finalize the clauses that need pre-built expressions for CodeGen. 8011 for (OMPClause *C : Clauses) { 8012 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8013 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8014 B.NumIterations, *this, CurScope, 8015 DSAStack)) 8016 return StmtError(); 8017 } 8018 } 8019 8020 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8021 return StmtError(); 8022 8023 setFunctionHasBranchProtectedScope(); 8024 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8025 Clauses, AStmt, B); 8026 } 8027 8028 StmtResult 8029 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8030 SourceLocation StartLoc, SourceLocation EndLoc, 8031 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8032 if (!AStmt) 8033 return StmtError(); 8034 8035 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8036 OMPLoopDirective::HelperExprs B; 8037 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8038 // define the nested loops number. 8039 unsigned NestedLoopCount = checkOpenMPLoop( 8040 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8041 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8042 if (NestedLoopCount == 0) 8043 return StmtError(); 8044 8045 assert((CurContext->isDependentContext() || B.builtAll()) && 8046 "omp for loop exprs were not built"); 8047 8048 if (!CurContext->isDependentContext()) { 8049 // Finalize the clauses that need pre-built expressions for CodeGen. 8050 for (OMPClause *C : Clauses) { 8051 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8052 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8053 B.NumIterations, *this, CurScope, 8054 DSAStack)) 8055 return StmtError(); 8056 } 8057 } 8058 8059 setFunctionHasBranchProtectedScope(); 8060 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8061 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8062 } 8063 8064 StmtResult Sema::ActOnOpenMPForSimdDirective( 8065 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8066 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8067 if (!AStmt) 8068 return StmtError(); 8069 8070 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8071 OMPLoopDirective::HelperExprs B; 8072 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8073 // define the nested loops number. 8074 unsigned NestedLoopCount = 8075 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8076 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8077 VarsWithImplicitDSA, B); 8078 if (NestedLoopCount == 0) 8079 return StmtError(); 8080 8081 assert((CurContext->isDependentContext() || B.builtAll()) && 8082 "omp for simd loop exprs were not built"); 8083 8084 if (!CurContext->isDependentContext()) { 8085 // Finalize the clauses that need pre-built expressions for CodeGen. 8086 for (OMPClause *C : Clauses) { 8087 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8088 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8089 B.NumIterations, *this, CurScope, 8090 DSAStack)) 8091 return StmtError(); 8092 } 8093 } 8094 8095 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8096 return StmtError(); 8097 8098 setFunctionHasBranchProtectedScope(); 8099 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8100 Clauses, AStmt, B); 8101 } 8102 8103 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8104 Stmt *AStmt, 8105 SourceLocation StartLoc, 8106 SourceLocation EndLoc) { 8107 if (!AStmt) 8108 return StmtError(); 8109 8110 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8111 auto BaseStmt = AStmt; 8112 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8113 BaseStmt = CS->getCapturedStmt(); 8114 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8115 auto S = C->children(); 8116 if (S.begin() == S.end()) 8117 return StmtError(); 8118 // All associated statements must be '#pragma omp section' except for 8119 // the first one. 8120 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8121 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8122 if (SectionStmt) 8123 Diag(SectionStmt->getBeginLoc(), 8124 diag::err_omp_sections_substmt_not_section); 8125 return StmtError(); 8126 } 8127 cast<OMPSectionDirective>(SectionStmt) 8128 ->setHasCancel(DSAStack->isCancelRegion()); 8129 } 8130 } else { 8131 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8132 return StmtError(); 8133 } 8134 8135 setFunctionHasBranchProtectedScope(); 8136 8137 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8138 DSAStack->isCancelRegion()); 8139 } 8140 8141 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8142 SourceLocation StartLoc, 8143 SourceLocation EndLoc) { 8144 if (!AStmt) 8145 return StmtError(); 8146 8147 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8148 8149 setFunctionHasBranchProtectedScope(); 8150 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8151 8152 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8153 DSAStack->isCancelRegion()); 8154 } 8155 8156 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8157 Stmt *AStmt, 8158 SourceLocation StartLoc, 8159 SourceLocation EndLoc) { 8160 if (!AStmt) 8161 return StmtError(); 8162 8163 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8164 8165 setFunctionHasBranchProtectedScope(); 8166 8167 // OpenMP [2.7.3, single Construct, Restrictions] 8168 // The copyprivate clause must not be used with the nowait clause. 8169 const OMPClause *Nowait = nullptr; 8170 const OMPClause *Copyprivate = nullptr; 8171 for (const OMPClause *Clause : Clauses) { 8172 if (Clause->getClauseKind() == OMPC_nowait) 8173 Nowait = Clause; 8174 else if (Clause->getClauseKind() == OMPC_copyprivate) 8175 Copyprivate = Clause; 8176 if (Copyprivate && Nowait) { 8177 Diag(Copyprivate->getBeginLoc(), 8178 diag::err_omp_single_copyprivate_with_nowait); 8179 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8180 return StmtError(); 8181 } 8182 } 8183 8184 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8185 } 8186 8187 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8188 SourceLocation StartLoc, 8189 SourceLocation EndLoc) { 8190 if (!AStmt) 8191 return StmtError(); 8192 8193 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8194 8195 setFunctionHasBranchProtectedScope(); 8196 8197 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8198 } 8199 8200 StmtResult Sema::ActOnOpenMPCriticalDirective( 8201 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8202 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8203 if (!AStmt) 8204 return StmtError(); 8205 8206 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8207 8208 bool ErrorFound = false; 8209 llvm::APSInt Hint; 8210 SourceLocation HintLoc; 8211 bool DependentHint = false; 8212 for (const OMPClause *C : Clauses) { 8213 if (C->getClauseKind() == OMPC_hint) { 8214 if (!DirName.getName()) { 8215 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8216 ErrorFound = true; 8217 } 8218 Expr *E = cast<OMPHintClause>(C)->getHint(); 8219 if (E->isTypeDependent() || E->isValueDependent() || 8220 E->isInstantiationDependent()) { 8221 DependentHint = true; 8222 } else { 8223 Hint = E->EvaluateKnownConstInt(Context); 8224 HintLoc = C->getBeginLoc(); 8225 } 8226 } 8227 } 8228 if (ErrorFound) 8229 return StmtError(); 8230 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8231 if (Pair.first && DirName.getName() && !DependentHint) { 8232 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8233 Diag(StartLoc, diag::err_omp_critical_with_hint); 8234 if (HintLoc.isValid()) 8235 Diag(HintLoc, diag::note_omp_critical_hint_here) 8236 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8237 else 8238 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8239 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8240 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8241 << 1 8242 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8243 /*Radix=*/10, /*Signed=*/false); 8244 } else { 8245 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8246 } 8247 } 8248 } 8249 8250 setFunctionHasBranchProtectedScope(); 8251 8252 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8253 Clauses, AStmt); 8254 if (!Pair.first && DirName.getName() && !DependentHint) 8255 DSAStack->addCriticalWithHint(Dir, Hint); 8256 return Dir; 8257 } 8258 8259 StmtResult Sema::ActOnOpenMPParallelForDirective( 8260 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8261 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8262 if (!AStmt) 8263 return StmtError(); 8264 8265 auto *CS = cast<CapturedStmt>(AStmt); 8266 // 1.2.2 OpenMP Language Terminology 8267 // Structured block - An executable statement with a single entry at the 8268 // top and a single exit at the bottom. 8269 // The point of exit cannot be a branch out of the structured block. 8270 // longjmp() and throw() must not violate the entry/exit criteria. 8271 CS->getCapturedDecl()->setNothrow(); 8272 8273 OMPLoopDirective::HelperExprs B; 8274 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8275 // define the nested loops number. 8276 unsigned NestedLoopCount = 8277 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8278 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8279 VarsWithImplicitDSA, B); 8280 if (NestedLoopCount == 0) 8281 return StmtError(); 8282 8283 assert((CurContext->isDependentContext() || B.builtAll()) && 8284 "omp parallel for loop exprs were not built"); 8285 8286 if (!CurContext->isDependentContext()) { 8287 // Finalize the clauses that need pre-built expressions for CodeGen. 8288 for (OMPClause *C : Clauses) { 8289 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8290 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8291 B.NumIterations, *this, CurScope, 8292 DSAStack)) 8293 return StmtError(); 8294 } 8295 } 8296 8297 setFunctionHasBranchProtectedScope(); 8298 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8299 NestedLoopCount, Clauses, AStmt, B, 8300 DSAStack->isCancelRegion()); 8301 } 8302 8303 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8304 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8305 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8306 if (!AStmt) 8307 return StmtError(); 8308 8309 auto *CS = cast<CapturedStmt>(AStmt); 8310 // 1.2.2 OpenMP Language Terminology 8311 // Structured block - An executable statement with a single entry at the 8312 // top and a single exit at the bottom. 8313 // The point of exit cannot be a branch out of the structured block. 8314 // longjmp() and throw() must not violate the entry/exit criteria. 8315 CS->getCapturedDecl()->setNothrow(); 8316 8317 OMPLoopDirective::HelperExprs B; 8318 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8319 // define the nested loops number. 8320 unsigned NestedLoopCount = 8321 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8322 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8323 VarsWithImplicitDSA, B); 8324 if (NestedLoopCount == 0) 8325 return StmtError(); 8326 8327 if (!CurContext->isDependentContext()) { 8328 // Finalize the clauses that need pre-built expressions for CodeGen. 8329 for (OMPClause *C : Clauses) { 8330 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8331 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8332 B.NumIterations, *this, CurScope, 8333 DSAStack)) 8334 return StmtError(); 8335 } 8336 } 8337 8338 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8339 return StmtError(); 8340 8341 setFunctionHasBranchProtectedScope(); 8342 return OMPParallelForSimdDirective::Create( 8343 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8344 } 8345 8346 StmtResult 8347 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8348 Stmt *AStmt, SourceLocation StartLoc, 8349 SourceLocation EndLoc) { 8350 if (!AStmt) 8351 return StmtError(); 8352 8353 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8354 auto *CS = cast<CapturedStmt>(AStmt); 8355 // 1.2.2 OpenMP Language Terminology 8356 // Structured block - An executable statement with a single entry at the 8357 // top and a single exit at the bottom. 8358 // The point of exit cannot be a branch out of the structured block. 8359 // longjmp() and throw() must not violate the entry/exit criteria. 8360 CS->getCapturedDecl()->setNothrow(); 8361 8362 setFunctionHasBranchProtectedScope(); 8363 8364 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8365 AStmt); 8366 } 8367 8368 StmtResult 8369 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8370 Stmt *AStmt, SourceLocation StartLoc, 8371 SourceLocation EndLoc) { 8372 if (!AStmt) 8373 return StmtError(); 8374 8375 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8376 auto BaseStmt = AStmt; 8377 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8378 BaseStmt = CS->getCapturedStmt(); 8379 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8380 auto S = C->children(); 8381 if (S.begin() == S.end()) 8382 return StmtError(); 8383 // All associated statements must be '#pragma omp section' except for 8384 // the first one. 8385 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8386 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8387 if (SectionStmt) 8388 Diag(SectionStmt->getBeginLoc(), 8389 diag::err_omp_parallel_sections_substmt_not_section); 8390 return StmtError(); 8391 } 8392 cast<OMPSectionDirective>(SectionStmt) 8393 ->setHasCancel(DSAStack->isCancelRegion()); 8394 } 8395 } else { 8396 Diag(AStmt->getBeginLoc(), 8397 diag::err_omp_parallel_sections_not_compound_stmt); 8398 return StmtError(); 8399 } 8400 8401 setFunctionHasBranchProtectedScope(); 8402 8403 return OMPParallelSectionsDirective::Create( 8404 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8405 } 8406 8407 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8408 Stmt *AStmt, SourceLocation StartLoc, 8409 SourceLocation EndLoc) { 8410 if (!AStmt) 8411 return StmtError(); 8412 8413 auto *CS = cast<CapturedStmt>(AStmt); 8414 // 1.2.2 OpenMP Language Terminology 8415 // Structured block - An executable statement with a single entry at the 8416 // top and a single exit at the bottom. 8417 // The point of exit cannot be a branch out of the structured block. 8418 // longjmp() and throw() must not violate the entry/exit criteria. 8419 CS->getCapturedDecl()->setNothrow(); 8420 8421 setFunctionHasBranchProtectedScope(); 8422 8423 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8424 DSAStack->isCancelRegion()); 8425 } 8426 8427 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8428 SourceLocation EndLoc) { 8429 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8430 } 8431 8432 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8433 SourceLocation EndLoc) { 8434 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8435 } 8436 8437 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8438 SourceLocation EndLoc) { 8439 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8440 } 8441 8442 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8443 Stmt *AStmt, 8444 SourceLocation StartLoc, 8445 SourceLocation EndLoc) { 8446 if (!AStmt) 8447 return StmtError(); 8448 8449 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8450 8451 setFunctionHasBranchProtectedScope(); 8452 8453 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8454 AStmt, 8455 DSAStack->getTaskgroupReductionRef()); 8456 } 8457 8458 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8459 SourceLocation StartLoc, 8460 SourceLocation EndLoc) { 8461 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8462 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8463 } 8464 8465 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8466 Stmt *AStmt, 8467 SourceLocation StartLoc, 8468 SourceLocation EndLoc) { 8469 const OMPClause *DependFound = nullptr; 8470 const OMPClause *DependSourceClause = nullptr; 8471 const OMPClause *DependSinkClause = nullptr; 8472 bool ErrorFound = false; 8473 const OMPThreadsClause *TC = nullptr; 8474 const OMPSIMDClause *SC = nullptr; 8475 for (const OMPClause *C : Clauses) { 8476 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8477 DependFound = C; 8478 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8479 if (DependSourceClause) { 8480 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8481 << getOpenMPDirectiveName(OMPD_ordered) 8482 << getOpenMPClauseName(OMPC_depend) << 2; 8483 ErrorFound = true; 8484 } else { 8485 DependSourceClause = C; 8486 } 8487 if (DependSinkClause) { 8488 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8489 << 0; 8490 ErrorFound = true; 8491 } 8492 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8493 if (DependSourceClause) { 8494 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8495 << 1; 8496 ErrorFound = true; 8497 } 8498 DependSinkClause = C; 8499 } 8500 } else if (C->getClauseKind() == OMPC_threads) { 8501 TC = cast<OMPThreadsClause>(C); 8502 } else if (C->getClauseKind() == OMPC_simd) { 8503 SC = cast<OMPSIMDClause>(C); 8504 } 8505 } 8506 if (!ErrorFound && !SC && 8507 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8508 // OpenMP [2.8.1,simd Construct, Restrictions] 8509 // An ordered construct with the simd clause is the only OpenMP construct 8510 // that can appear in the simd region. 8511 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8512 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8513 ErrorFound = true; 8514 } else if (DependFound && (TC || SC)) { 8515 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8516 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8517 ErrorFound = true; 8518 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8519 Diag(DependFound->getBeginLoc(), 8520 diag::err_omp_ordered_directive_without_param); 8521 ErrorFound = true; 8522 } else if (TC || Clauses.empty()) { 8523 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8524 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8525 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8526 << (TC != nullptr); 8527 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8528 ErrorFound = true; 8529 } 8530 } 8531 if ((!AStmt && !DependFound) || ErrorFound) 8532 return StmtError(); 8533 8534 if (AStmt) { 8535 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8536 8537 setFunctionHasBranchProtectedScope(); 8538 } 8539 8540 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8541 } 8542 8543 namespace { 8544 /// Helper class for checking expression in 'omp atomic [update]' 8545 /// construct. 8546 class OpenMPAtomicUpdateChecker { 8547 /// Error results for atomic update expressions. 8548 enum ExprAnalysisErrorCode { 8549 /// A statement is not an expression statement. 8550 NotAnExpression, 8551 /// Expression is not builtin binary or unary operation. 8552 NotABinaryOrUnaryExpression, 8553 /// Unary operation is not post-/pre- increment/decrement operation. 8554 NotAnUnaryIncDecExpression, 8555 /// An expression is not of scalar type. 8556 NotAScalarType, 8557 /// A binary operation is not an assignment operation. 8558 NotAnAssignmentOp, 8559 /// RHS part of the binary operation is not a binary expression. 8560 NotABinaryExpression, 8561 /// RHS part is not additive/multiplicative/shift/biwise binary 8562 /// expression. 8563 NotABinaryOperator, 8564 /// RHS binary operation does not have reference to the updated LHS 8565 /// part. 8566 NotAnUpdateExpression, 8567 /// No errors is found. 8568 NoError 8569 }; 8570 /// Reference to Sema. 8571 Sema &SemaRef; 8572 /// A location for note diagnostics (when error is found). 8573 SourceLocation NoteLoc; 8574 /// 'x' lvalue part of the source atomic expression. 8575 Expr *X; 8576 /// 'expr' rvalue part of the source atomic expression. 8577 Expr *E; 8578 /// Helper expression of the form 8579 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8580 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8581 Expr *UpdateExpr; 8582 /// Is 'x' a LHS in a RHS part of full update expression. It is 8583 /// important for non-associative operations. 8584 bool IsXLHSInRHSPart; 8585 BinaryOperatorKind Op; 8586 SourceLocation OpLoc; 8587 /// true if the source expression is a postfix unary operation, false 8588 /// if it is a prefix unary operation. 8589 bool IsPostfixUpdate; 8590 8591 public: 8592 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8593 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8594 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8595 /// Check specified statement that it is suitable for 'atomic update' 8596 /// constructs and extract 'x', 'expr' and Operation from the original 8597 /// expression. If DiagId and NoteId == 0, then only check is performed 8598 /// without error notification. 8599 /// \param DiagId Diagnostic which should be emitted if error is found. 8600 /// \param NoteId Diagnostic note for the main error message. 8601 /// \return true if statement is not an update expression, false otherwise. 8602 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8603 /// Return the 'x' lvalue part of the source atomic expression. 8604 Expr *getX() const { return X; } 8605 /// Return the 'expr' rvalue part of the source atomic expression. 8606 Expr *getExpr() const { return E; } 8607 /// Return the update expression used in calculation of the updated 8608 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8609 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8610 Expr *getUpdateExpr() const { return UpdateExpr; } 8611 /// Return true if 'x' is LHS in RHS part of full update expression, 8612 /// false otherwise. 8613 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8614 8615 /// true if the source expression is a postfix unary operation, false 8616 /// if it is a prefix unary operation. 8617 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8618 8619 private: 8620 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8621 unsigned NoteId = 0); 8622 }; 8623 } // namespace 8624 8625 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8626 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8627 ExprAnalysisErrorCode ErrorFound = NoError; 8628 SourceLocation ErrorLoc, NoteLoc; 8629 SourceRange ErrorRange, NoteRange; 8630 // Allowed constructs are: 8631 // x = x binop expr; 8632 // x = expr binop x; 8633 if (AtomicBinOp->getOpcode() == BO_Assign) { 8634 X = AtomicBinOp->getLHS(); 8635 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8636 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8637 if (AtomicInnerBinOp->isMultiplicativeOp() || 8638 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8639 AtomicInnerBinOp->isBitwiseOp()) { 8640 Op = AtomicInnerBinOp->getOpcode(); 8641 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8642 Expr *LHS = AtomicInnerBinOp->getLHS(); 8643 Expr *RHS = AtomicInnerBinOp->getRHS(); 8644 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8645 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8646 /*Canonical=*/true); 8647 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8648 /*Canonical=*/true); 8649 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8650 /*Canonical=*/true); 8651 if (XId == LHSId) { 8652 E = RHS; 8653 IsXLHSInRHSPart = true; 8654 } else if (XId == RHSId) { 8655 E = LHS; 8656 IsXLHSInRHSPart = false; 8657 } else { 8658 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8659 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8660 NoteLoc = X->getExprLoc(); 8661 NoteRange = X->getSourceRange(); 8662 ErrorFound = NotAnUpdateExpression; 8663 } 8664 } else { 8665 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8666 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8667 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8668 NoteRange = SourceRange(NoteLoc, NoteLoc); 8669 ErrorFound = NotABinaryOperator; 8670 } 8671 } else { 8672 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8673 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8674 ErrorFound = NotABinaryExpression; 8675 } 8676 } else { 8677 ErrorLoc = AtomicBinOp->getExprLoc(); 8678 ErrorRange = AtomicBinOp->getSourceRange(); 8679 NoteLoc = AtomicBinOp->getOperatorLoc(); 8680 NoteRange = SourceRange(NoteLoc, NoteLoc); 8681 ErrorFound = NotAnAssignmentOp; 8682 } 8683 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8684 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8685 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8686 return true; 8687 } 8688 if (SemaRef.CurContext->isDependentContext()) 8689 E = X = UpdateExpr = nullptr; 8690 return ErrorFound != NoError; 8691 } 8692 8693 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8694 unsigned NoteId) { 8695 ExprAnalysisErrorCode ErrorFound = NoError; 8696 SourceLocation ErrorLoc, NoteLoc; 8697 SourceRange ErrorRange, NoteRange; 8698 // Allowed constructs are: 8699 // x++; 8700 // x--; 8701 // ++x; 8702 // --x; 8703 // x binop= expr; 8704 // x = x binop expr; 8705 // x = expr binop x; 8706 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8707 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8708 if (AtomicBody->getType()->isScalarType() || 8709 AtomicBody->isInstantiationDependent()) { 8710 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8711 AtomicBody->IgnoreParenImpCasts())) { 8712 // Check for Compound Assignment Operation 8713 Op = BinaryOperator::getOpForCompoundAssignment( 8714 AtomicCompAssignOp->getOpcode()); 8715 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8716 E = AtomicCompAssignOp->getRHS(); 8717 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8718 IsXLHSInRHSPart = true; 8719 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8720 AtomicBody->IgnoreParenImpCasts())) { 8721 // Check for Binary Operation 8722 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8723 return true; 8724 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8725 AtomicBody->IgnoreParenImpCasts())) { 8726 // Check for Unary Operation 8727 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8728 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8729 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8730 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8731 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8732 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8733 IsXLHSInRHSPart = true; 8734 } else { 8735 ErrorFound = NotAnUnaryIncDecExpression; 8736 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8737 ErrorRange = AtomicUnaryOp->getSourceRange(); 8738 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8739 NoteRange = SourceRange(NoteLoc, NoteLoc); 8740 } 8741 } else if (!AtomicBody->isInstantiationDependent()) { 8742 ErrorFound = NotABinaryOrUnaryExpression; 8743 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8744 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8745 } 8746 } else { 8747 ErrorFound = NotAScalarType; 8748 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8749 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8750 } 8751 } else { 8752 ErrorFound = NotAnExpression; 8753 NoteLoc = ErrorLoc = S->getBeginLoc(); 8754 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8755 } 8756 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8757 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8758 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8759 return true; 8760 } 8761 if (SemaRef.CurContext->isDependentContext()) 8762 E = X = UpdateExpr = nullptr; 8763 if (ErrorFound == NoError && E && X) { 8764 // Build an update expression of form 'OpaqueValueExpr(x) binop 8765 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8766 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8767 auto *OVEX = new (SemaRef.getASTContext()) 8768 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8769 auto *OVEExpr = new (SemaRef.getASTContext()) 8770 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8771 ExprResult Update = 8772 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8773 IsXLHSInRHSPart ? OVEExpr : OVEX); 8774 if (Update.isInvalid()) 8775 return true; 8776 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8777 Sema::AA_Casting); 8778 if (Update.isInvalid()) 8779 return true; 8780 UpdateExpr = Update.get(); 8781 } 8782 return ErrorFound != NoError; 8783 } 8784 8785 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8786 Stmt *AStmt, 8787 SourceLocation StartLoc, 8788 SourceLocation EndLoc) { 8789 if (!AStmt) 8790 return StmtError(); 8791 8792 auto *CS = cast<CapturedStmt>(AStmt); 8793 // 1.2.2 OpenMP Language Terminology 8794 // Structured block - An executable statement with a single entry at the 8795 // top and a single exit at the bottom. 8796 // The point of exit cannot be a branch out of the structured block. 8797 // longjmp() and throw() must not violate the entry/exit criteria. 8798 OpenMPClauseKind AtomicKind = OMPC_unknown; 8799 SourceLocation AtomicKindLoc; 8800 for (const OMPClause *C : Clauses) { 8801 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8802 C->getClauseKind() == OMPC_update || 8803 C->getClauseKind() == OMPC_capture) { 8804 if (AtomicKind != OMPC_unknown) { 8805 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8806 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8807 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8808 << getOpenMPClauseName(AtomicKind); 8809 } else { 8810 AtomicKind = C->getClauseKind(); 8811 AtomicKindLoc = C->getBeginLoc(); 8812 } 8813 } 8814 } 8815 8816 Stmt *Body = CS->getCapturedStmt(); 8817 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8818 Body = EWC->getSubExpr(); 8819 8820 Expr *X = nullptr; 8821 Expr *V = nullptr; 8822 Expr *E = nullptr; 8823 Expr *UE = nullptr; 8824 bool IsXLHSInRHSPart = false; 8825 bool IsPostfixUpdate = false; 8826 // OpenMP [2.12.6, atomic Construct] 8827 // In the next expressions: 8828 // * x and v (as applicable) are both l-value expressions with scalar type. 8829 // * During the execution of an atomic region, multiple syntactic 8830 // occurrences of x must designate the same storage location. 8831 // * Neither of v and expr (as applicable) may access the storage location 8832 // designated by x. 8833 // * Neither of x and expr (as applicable) may access the storage location 8834 // designated by v. 8835 // * expr is an expression with scalar type. 8836 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8837 // * binop, binop=, ++, and -- are not overloaded operators. 8838 // * The expression x binop expr must be numerically equivalent to x binop 8839 // (expr). This requirement is satisfied if the operators in expr have 8840 // precedence greater than binop, or by using parentheses around expr or 8841 // subexpressions of expr. 8842 // * The expression expr binop x must be numerically equivalent to (expr) 8843 // binop x. This requirement is satisfied if the operators in expr have 8844 // precedence equal to or greater than binop, or by using parentheses around 8845 // expr or subexpressions of expr. 8846 // * For forms that allow multiple occurrences of x, the number of times 8847 // that x is evaluated is unspecified. 8848 if (AtomicKind == OMPC_read) { 8849 enum { 8850 NotAnExpression, 8851 NotAnAssignmentOp, 8852 NotAScalarType, 8853 NotAnLValue, 8854 NoError 8855 } ErrorFound = NoError; 8856 SourceLocation ErrorLoc, NoteLoc; 8857 SourceRange ErrorRange, NoteRange; 8858 // If clause is read: 8859 // v = x; 8860 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8861 const auto *AtomicBinOp = 8862 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8863 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8864 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8865 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8866 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8867 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8868 if (!X->isLValue() || !V->isLValue()) { 8869 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8870 ErrorFound = NotAnLValue; 8871 ErrorLoc = AtomicBinOp->getExprLoc(); 8872 ErrorRange = AtomicBinOp->getSourceRange(); 8873 NoteLoc = NotLValueExpr->getExprLoc(); 8874 NoteRange = NotLValueExpr->getSourceRange(); 8875 } 8876 } else if (!X->isInstantiationDependent() || 8877 !V->isInstantiationDependent()) { 8878 const Expr *NotScalarExpr = 8879 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8880 ? V 8881 : X; 8882 ErrorFound = NotAScalarType; 8883 ErrorLoc = AtomicBinOp->getExprLoc(); 8884 ErrorRange = AtomicBinOp->getSourceRange(); 8885 NoteLoc = NotScalarExpr->getExprLoc(); 8886 NoteRange = NotScalarExpr->getSourceRange(); 8887 } 8888 } else if (!AtomicBody->isInstantiationDependent()) { 8889 ErrorFound = NotAnAssignmentOp; 8890 ErrorLoc = AtomicBody->getExprLoc(); 8891 ErrorRange = AtomicBody->getSourceRange(); 8892 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8893 : AtomicBody->getExprLoc(); 8894 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8895 : AtomicBody->getSourceRange(); 8896 } 8897 } else { 8898 ErrorFound = NotAnExpression; 8899 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8900 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8901 } 8902 if (ErrorFound != NoError) { 8903 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8904 << ErrorRange; 8905 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8906 << NoteRange; 8907 return StmtError(); 8908 } 8909 if (CurContext->isDependentContext()) 8910 V = X = nullptr; 8911 } else if (AtomicKind == OMPC_write) { 8912 enum { 8913 NotAnExpression, 8914 NotAnAssignmentOp, 8915 NotAScalarType, 8916 NotAnLValue, 8917 NoError 8918 } ErrorFound = NoError; 8919 SourceLocation ErrorLoc, NoteLoc; 8920 SourceRange ErrorRange, NoteRange; 8921 // If clause is write: 8922 // x = expr; 8923 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8924 const auto *AtomicBinOp = 8925 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8926 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8927 X = AtomicBinOp->getLHS(); 8928 E = AtomicBinOp->getRHS(); 8929 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8930 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8931 if (!X->isLValue()) { 8932 ErrorFound = NotAnLValue; 8933 ErrorLoc = AtomicBinOp->getExprLoc(); 8934 ErrorRange = AtomicBinOp->getSourceRange(); 8935 NoteLoc = X->getExprLoc(); 8936 NoteRange = X->getSourceRange(); 8937 } 8938 } else if (!X->isInstantiationDependent() || 8939 !E->isInstantiationDependent()) { 8940 const Expr *NotScalarExpr = 8941 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8942 ? E 8943 : X; 8944 ErrorFound = NotAScalarType; 8945 ErrorLoc = AtomicBinOp->getExprLoc(); 8946 ErrorRange = AtomicBinOp->getSourceRange(); 8947 NoteLoc = NotScalarExpr->getExprLoc(); 8948 NoteRange = NotScalarExpr->getSourceRange(); 8949 } 8950 } else if (!AtomicBody->isInstantiationDependent()) { 8951 ErrorFound = NotAnAssignmentOp; 8952 ErrorLoc = AtomicBody->getExprLoc(); 8953 ErrorRange = AtomicBody->getSourceRange(); 8954 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8955 : AtomicBody->getExprLoc(); 8956 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8957 : AtomicBody->getSourceRange(); 8958 } 8959 } else { 8960 ErrorFound = NotAnExpression; 8961 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8962 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8963 } 8964 if (ErrorFound != NoError) { 8965 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8966 << ErrorRange; 8967 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8968 << NoteRange; 8969 return StmtError(); 8970 } 8971 if (CurContext->isDependentContext()) 8972 E = X = nullptr; 8973 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8974 // If clause is update: 8975 // x++; 8976 // x--; 8977 // ++x; 8978 // --x; 8979 // x binop= expr; 8980 // x = x binop expr; 8981 // x = expr binop x; 8982 OpenMPAtomicUpdateChecker Checker(*this); 8983 if (Checker.checkStatement( 8984 Body, (AtomicKind == OMPC_update) 8985 ? diag::err_omp_atomic_update_not_expression_statement 8986 : diag::err_omp_atomic_not_expression_statement, 8987 diag::note_omp_atomic_update)) 8988 return StmtError(); 8989 if (!CurContext->isDependentContext()) { 8990 E = Checker.getExpr(); 8991 X = Checker.getX(); 8992 UE = Checker.getUpdateExpr(); 8993 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8994 } 8995 } else if (AtomicKind == OMPC_capture) { 8996 enum { 8997 NotAnAssignmentOp, 8998 NotACompoundStatement, 8999 NotTwoSubstatements, 9000 NotASpecificExpression, 9001 NoError 9002 } ErrorFound = NoError; 9003 SourceLocation ErrorLoc, NoteLoc; 9004 SourceRange ErrorRange, NoteRange; 9005 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9006 // If clause is a capture: 9007 // v = x++; 9008 // v = x--; 9009 // v = ++x; 9010 // v = --x; 9011 // v = x binop= expr; 9012 // v = x = x binop expr; 9013 // v = x = expr binop x; 9014 const auto *AtomicBinOp = 9015 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9016 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9017 V = AtomicBinOp->getLHS(); 9018 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9019 OpenMPAtomicUpdateChecker Checker(*this); 9020 if (Checker.checkStatement( 9021 Body, diag::err_omp_atomic_capture_not_expression_statement, 9022 diag::note_omp_atomic_update)) 9023 return StmtError(); 9024 E = Checker.getExpr(); 9025 X = Checker.getX(); 9026 UE = Checker.getUpdateExpr(); 9027 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9028 IsPostfixUpdate = Checker.isPostfixUpdate(); 9029 } else if (!AtomicBody->isInstantiationDependent()) { 9030 ErrorLoc = AtomicBody->getExprLoc(); 9031 ErrorRange = AtomicBody->getSourceRange(); 9032 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9033 : AtomicBody->getExprLoc(); 9034 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9035 : AtomicBody->getSourceRange(); 9036 ErrorFound = NotAnAssignmentOp; 9037 } 9038 if (ErrorFound != NoError) { 9039 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9040 << ErrorRange; 9041 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9042 return StmtError(); 9043 } 9044 if (CurContext->isDependentContext()) 9045 UE = V = E = X = nullptr; 9046 } else { 9047 // If clause is a capture: 9048 // { v = x; x = expr; } 9049 // { v = x; x++; } 9050 // { v = x; x--; } 9051 // { v = x; ++x; } 9052 // { v = x; --x; } 9053 // { v = x; x binop= expr; } 9054 // { v = x; x = x binop expr; } 9055 // { v = x; x = expr binop x; } 9056 // { x++; v = x; } 9057 // { x--; v = x; } 9058 // { ++x; v = x; } 9059 // { --x; v = x; } 9060 // { x binop= expr; v = x; } 9061 // { x = x binop expr; v = x; } 9062 // { x = expr binop x; v = x; } 9063 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9064 // Check that this is { expr1; expr2; } 9065 if (CS->size() == 2) { 9066 Stmt *First = CS->body_front(); 9067 Stmt *Second = CS->body_back(); 9068 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9069 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9070 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9071 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9072 // Need to find what subexpression is 'v' and what is 'x'. 9073 OpenMPAtomicUpdateChecker Checker(*this); 9074 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9075 BinaryOperator *BinOp = nullptr; 9076 if (IsUpdateExprFound) { 9077 BinOp = dyn_cast<BinaryOperator>(First); 9078 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9079 } 9080 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9081 // { v = x; x++; } 9082 // { v = x; x--; } 9083 // { v = x; ++x; } 9084 // { v = x; --x; } 9085 // { v = x; x binop= expr; } 9086 // { v = x; x = x binop expr; } 9087 // { v = x; x = expr binop x; } 9088 // Check that the first expression has form v = x. 9089 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9090 llvm::FoldingSetNodeID XId, PossibleXId; 9091 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9092 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9093 IsUpdateExprFound = XId == PossibleXId; 9094 if (IsUpdateExprFound) { 9095 V = BinOp->getLHS(); 9096 X = Checker.getX(); 9097 E = Checker.getExpr(); 9098 UE = Checker.getUpdateExpr(); 9099 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9100 IsPostfixUpdate = true; 9101 } 9102 } 9103 if (!IsUpdateExprFound) { 9104 IsUpdateExprFound = !Checker.checkStatement(First); 9105 BinOp = nullptr; 9106 if (IsUpdateExprFound) { 9107 BinOp = dyn_cast<BinaryOperator>(Second); 9108 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9109 } 9110 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9111 // { x++; v = x; } 9112 // { x--; v = x; } 9113 // { ++x; v = x; } 9114 // { --x; v = x; } 9115 // { x binop= expr; v = x; } 9116 // { x = x binop expr; v = x; } 9117 // { x = expr binop x; v = x; } 9118 // Check that the second expression has form v = x. 9119 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9120 llvm::FoldingSetNodeID XId, PossibleXId; 9121 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9122 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9123 IsUpdateExprFound = XId == PossibleXId; 9124 if (IsUpdateExprFound) { 9125 V = BinOp->getLHS(); 9126 X = Checker.getX(); 9127 E = Checker.getExpr(); 9128 UE = Checker.getUpdateExpr(); 9129 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9130 IsPostfixUpdate = false; 9131 } 9132 } 9133 } 9134 if (!IsUpdateExprFound) { 9135 // { v = x; x = expr; } 9136 auto *FirstExpr = dyn_cast<Expr>(First); 9137 auto *SecondExpr = dyn_cast<Expr>(Second); 9138 if (!FirstExpr || !SecondExpr || 9139 !(FirstExpr->isInstantiationDependent() || 9140 SecondExpr->isInstantiationDependent())) { 9141 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9142 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9143 ErrorFound = NotAnAssignmentOp; 9144 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9145 : First->getBeginLoc(); 9146 NoteRange = ErrorRange = FirstBinOp 9147 ? FirstBinOp->getSourceRange() 9148 : SourceRange(ErrorLoc, ErrorLoc); 9149 } else { 9150 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9151 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9152 ErrorFound = NotAnAssignmentOp; 9153 NoteLoc = ErrorLoc = SecondBinOp 9154 ? SecondBinOp->getOperatorLoc() 9155 : Second->getBeginLoc(); 9156 NoteRange = ErrorRange = 9157 SecondBinOp ? SecondBinOp->getSourceRange() 9158 : SourceRange(ErrorLoc, ErrorLoc); 9159 } else { 9160 Expr *PossibleXRHSInFirst = 9161 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9162 Expr *PossibleXLHSInSecond = 9163 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9164 llvm::FoldingSetNodeID X1Id, X2Id; 9165 PossibleXRHSInFirst->Profile(X1Id, Context, 9166 /*Canonical=*/true); 9167 PossibleXLHSInSecond->Profile(X2Id, Context, 9168 /*Canonical=*/true); 9169 IsUpdateExprFound = X1Id == X2Id; 9170 if (IsUpdateExprFound) { 9171 V = FirstBinOp->getLHS(); 9172 X = SecondBinOp->getLHS(); 9173 E = SecondBinOp->getRHS(); 9174 UE = nullptr; 9175 IsXLHSInRHSPart = false; 9176 IsPostfixUpdate = true; 9177 } else { 9178 ErrorFound = NotASpecificExpression; 9179 ErrorLoc = FirstBinOp->getExprLoc(); 9180 ErrorRange = FirstBinOp->getSourceRange(); 9181 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9182 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9183 } 9184 } 9185 } 9186 } 9187 } 9188 } else { 9189 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9190 NoteRange = ErrorRange = 9191 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9192 ErrorFound = NotTwoSubstatements; 9193 } 9194 } else { 9195 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9196 NoteRange = ErrorRange = 9197 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9198 ErrorFound = NotACompoundStatement; 9199 } 9200 if (ErrorFound != NoError) { 9201 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9202 << ErrorRange; 9203 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9204 return StmtError(); 9205 } 9206 if (CurContext->isDependentContext()) 9207 UE = V = E = X = nullptr; 9208 } 9209 } 9210 9211 setFunctionHasBranchProtectedScope(); 9212 9213 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9214 X, V, E, UE, IsXLHSInRHSPart, 9215 IsPostfixUpdate); 9216 } 9217 9218 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9219 Stmt *AStmt, 9220 SourceLocation StartLoc, 9221 SourceLocation EndLoc) { 9222 if (!AStmt) 9223 return StmtError(); 9224 9225 auto *CS = cast<CapturedStmt>(AStmt); 9226 // 1.2.2 OpenMP Language Terminology 9227 // Structured block - An executable statement with a single entry at the 9228 // top and a single exit at the bottom. 9229 // The point of exit cannot be a branch out of the structured block. 9230 // longjmp() and throw() must not violate the entry/exit criteria. 9231 CS->getCapturedDecl()->setNothrow(); 9232 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9233 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9234 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9235 // 1.2.2 OpenMP Language Terminology 9236 // Structured block - An executable statement with a single entry at the 9237 // top and a single exit at the bottom. 9238 // The point of exit cannot be a branch out of the structured block. 9239 // longjmp() and throw() must not violate the entry/exit criteria. 9240 CS->getCapturedDecl()->setNothrow(); 9241 } 9242 9243 // OpenMP [2.16, Nesting of Regions] 9244 // If specified, a teams construct must be contained within a target 9245 // construct. That target construct must contain no statements or directives 9246 // outside of the teams construct. 9247 if (DSAStack->hasInnerTeamsRegion()) { 9248 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9249 bool OMPTeamsFound = true; 9250 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9251 auto I = CS->body_begin(); 9252 while (I != CS->body_end()) { 9253 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9254 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9255 OMPTeamsFound) { 9256 9257 OMPTeamsFound = false; 9258 break; 9259 } 9260 ++I; 9261 } 9262 assert(I != CS->body_end() && "Not found statement"); 9263 S = *I; 9264 } else { 9265 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9266 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9267 } 9268 if (!OMPTeamsFound) { 9269 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9270 Diag(DSAStack->getInnerTeamsRegionLoc(), 9271 diag::note_omp_nested_teams_construct_here); 9272 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9273 << isa<OMPExecutableDirective>(S); 9274 return StmtError(); 9275 } 9276 } 9277 9278 setFunctionHasBranchProtectedScope(); 9279 9280 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9281 } 9282 9283 StmtResult 9284 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9285 Stmt *AStmt, SourceLocation StartLoc, 9286 SourceLocation EndLoc) { 9287 if (!AStmt) 9288 return StmtError(); 9289 9290 auto *CS = cast<CapturedStmt>(AStmt); 9291 // 1.2.2 OpenMP Language Terminology 9292 // Structured block - An executable statement with a single entry at the 9293 // top and a single exit at the bottom. 9294 // The point of exit cannot be a branch out of the structured block. 9295 // longjmp() and throw() must not violate the entry/exit criteria. 9296 CS->getCapturedDecl()->setNothrow(); 9297 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9298 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9299 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9300 // 1.2.2 OpenMP Language Terminology 9301 // Structured block - An executable statement with a single entry at the 9302 // top and a single exit at the bottom. 9303 // The point of exit cannot be a branch out of the structured block. 9304 // longjmp() and throw() must not violate the entry/exit criteria. 9305 CS->getCapturedDecl()->setNothrow(); 9306 } 9307 9308 setFunctionHasBranchProtectedScope(); 9309 9310 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9311 AStmt); 9312 } 9313 9314 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9315 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9316 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9317 if (!AStmt) 9318 return StmtError(); 9319 9320 auto *CS = cast<CapturedStmt>(AStmt); 9321 // 1.2.2 OpenMP Language Terminology 9322 // Structured block - An executable statement with a single entry at the 9323 // top and a single exit at the bottom. 9324 // The point of exit cannot be a branch out of the structured block. 9325 // longjmp() and throw() must not violate the entry/exit criteria. 9326 CS->getCapturedDecl()->setNothrow(); 9327 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9328 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9329 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9330 // 1.2.2 OpenMP Language Terminology 9331 // Structured block - An executable statement with a single entry at the 9332 // top and a single exit at the bottom. 9333 // The point of exit cannot be a branch out of the structured block. 9334 // longjmp() and throw() must not violate the entry/exit criteria. 9335 CS->getCapturedDecl()->setNothrow(); 9336 } 9337 9338 OMPLoopDirective::HelperExprs B; 9339 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9340 // define the nested loops number. 9341 unsigned NestedLoopCount = 9342 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9343 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9344 VarsWithImplicitDSA, B); 9345 if (NestedLoopCount == 0) 9346 return StmtError(); 9347 9348 assert((CurContext->isDependentContext() || B.builtAll()) && 9349 "omp target parallel for loop exprs were not built"); 9350 9351 if (!CurContext->isDependentContext()) { 9352 // Finalize the clauses that need pre-built expressions for CodeGen. 9353 for (OMPClause *C : Clauses) { 9354 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9355 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9356 B.NumIterations, *this, CurScope, 9357 DSAStack)) 9358 return StmtError(); 9359 } 9360 } 9361 9362 setFunctionHasBranchProtectedScope(); 9363 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9364 NestedLoopCount, Clauses, AStmt, 9365 B, DSAStack->isCancelRegion()); 9366 } 9367 9368 /// Check for existence of a map clause in the list of clauses. 9369 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9370 const OpenMPClauseKind K) { 9371 return llvm::any_of( 9372 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9373 } 9374 9375 template <typename... Params> 9376 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9377 const Params... ClauseTypes) { 9378 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9379 } 9380 9381 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9382 Stmt *AStmt, 9383 SourceLocation StartLoc, 9384 SourceLocation EndLoc) { 9385 if (!AStmt) 9386 return StmtError(); 9387 9388 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9389 9390 // OpenMP [2.10.1, Restrictions, p. 97] 9391 // At least one map clause must appear on the directive. 9392 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9393 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9394 << "'map' or 'use_device_ptr'" 9395 << getOpenMPDirectiveName(OMPD_target_data); 9396 return StmtError(); 9397 } 9398 9399 setFunctionHasBranchProtectedScope(); 9400 9401 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9402 AStmt); 9403 } 9404 9405 StmtResult 9406 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9407 SourceLocation StartLoc, 9408 SourceLocation EndLoc, Stmt *AStmt) { 9409 if (!AStmt) 9410 return StmtError(); 9411 9412 auto *CS = cast<CapturedStmt>(AStmt); 9413 // 1.2.2 OpenMP Language Terminology 9414 // Structured block - An executable statement with a single entry at the 9415 // top and a single exit at the bottom. 9416 // The point of exit cannot be a branch out of the structured block. 9417 // longjmp() and throw() must not violate the entry/exit criteria. 9418 CS->getCapturedDecl()->setNothrow(); 9419 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9420 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9421 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9422 // 1.2.2 OpenMP Language Terminology 9423 // Structured block - An executable statement with a single entry at the 9424 // top and a single exit at the bottom. 9425 // The point of exit cannot be a branch out of the structured block. 9426 // longjmp() and throw() must not violate the entry/exit criteria. 9427 CS->getCapturedDecl()->setNothrow(); 9428 } 9429 9430 // OpenMP [2.10.2, Restrictions, p. 99] 9431 // At least one map clause must appear on the directive. 9432 if (!hasClauses(Clauses, OMPC_map)) { 9433 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9434 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9435 return StmtError(); 9436 } 9437 9438 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9439 AStmt); 9440 } 9441 9442 StmtResult 9443 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9444 SourceLocation StartLoc, 9445 SourceLocation EndLoc, Stmt *AStmt) { 9446 if (!AStmt) 9447 return StmtError(); 9448 9449 auto *CS = cast<CapturedStmt>(AStmt); 9450 // 1.2.2 OpenMP Language Terminology 9451 // Structured block - An executable statement with a single entry at the 9452 // top and a single exit at the bottom. 9453 // The point of exit cannot be a branch out of the structured block. 9454 // longjmp() and throw() must not violate the entry/exit criteria. 9455 CS->getCapturedDecl()->setNothrow(); 9456 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9457 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9458 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9459 // 1.2.2 OpenMP Language Terminology 9460 // Structured block - An executable statement with a single entry at the 9461 // top and a single exit at the bottom. 9462 // The point of exit cannot be a branch out of the structured block. 9463 // longjmp() and throw() must not violate the entry/exit criteria. 9464 CS->getCapturedDecl()->setNothrow(); 9465 } 9466 9467 // OpenMP [2.10.3, Restrictions, p. 102] 9468 // At least one map clause must appear on the directive. 9469 if (!hasClauses(Clauses, OMPC_map)) { 9470 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9471 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9472 return StmtError(); 9473 } 9474 9475 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9476 AStmt); 9477 } 9478 9479 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9480 SourceLocation StartLoc, 9481 SourceLocation EndLoc, 9482 Stmt *AStmt) { 9483 if (!AStmt) 9484 return StmtError(); 9485 9486 auto *CS = cast<CapturedStmt>(AStmt); 9487 // 1.2.2 OpenMP Language Terminology 9488 // Structured block - An executable statement with a single entry at the 9489 // top and a single exit at the bottom. 9490 // The point of exit cannot be a branch out of the structured block. 9491 // longjmp() and throw() must not violate the entry/exit criteria. 9492 CS->getCapturedDecl()->setNothrow(); 9493 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9494 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9495 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9496 // 1.2.2 OpenMP Language Terminology 9497 // Structured block - An executable statement with a single entry at the 9498 // top and a single exit at the bottom. 9499 // The point of exit cannot be a branch out of the structured block. 9500 // longjmp() and throw() must not violate the entry/exit criteria. 9501 CS->getCapturedDecl()->setNothrow(); 9502 } 9503 9504 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9505 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9506 return StmtError(); 9507 } 9508 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9509 AStmt); 9510 } 9511 9512 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9513 Stmt *AStmt, SourceLocation StartLoc, 9514 SourceLocation EndLoc) { 9515 if (!AStmt) 9516 return StmtError(); 9517 9518 auto *CS = cast<CapturedStmt>(AStmt); 9519 // 1.2.2 OpenMP Language Terminology 9520 // Structured block - An executable statement with a single entry at the 9521 // top and a single exit at the bottom. 9522 // The point of exit cannot be a branch out of the structured block. 9523 // longjmp() and throw() must not violate the entry/exit criteria. 9524 CS->getCapturedDecl()->setNothrow(); 9525 9526 setFunctionHasBranchProtectedScope(); 9527 9528 DSAStack->setParentTeamsRegionLoc(StartLoc); 9529 9530 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9531 } 9532 9533 StmtResult 9534 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9535 SourceLocation EndLoc, 9536 OpenMPDirectiveKind CancelRegion) { 9537 if (DSAStack->isParentNowaitRegion()) { 9538 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9539 return StmtError(); 9540 } 9541 if (DSAStack->isParentOrderedRegion()) { 9542 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9543 return StmtError(); 9544 } 9545 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9546 CancelRegion); 9547 } 9548 9549 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9550 SourceLocation StartLoc, 9551 SourceLocation EndLoc, 9552 OpenMPDirectiveKind CancelRegion) { 9553 if (DSAStack->isParentNowaitRegion()) { 9554 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9555 return StmtError(); 9556 } 9557 if (DSAStack->isParentOrderedRegion()) { 9558 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9559 return StmtError(); 9560 } 9561 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9562 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9563 CancelRegion); 9564 } 9565 9566 static bool checkGrainsizeNumTasksClauses(Sema &S, 9567 ArrayRef<OMPClause *> Clauses) { 9568 const OMPClause *PrevClause = nullptr; 9569 bool ErrorFound = false; 9570 for (const OMPClause *C : Clauses) { 9571 if (C->getClauseKind() == OMPC_grainsize || 9572 C->getClauseKind() == OMPC_num_tasks) { 9573 if (!PrevClause) 9574 PrevClause = C; 9575 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9576 S.Diag(C->getBeginLoc(), 9577 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9578 << getOpenMPClauseName(C->getClauseKind()) 9579 << getOpenMPClauseName(PrevClause->getClauseKind()); 9580 S.Diag(PrevClause->getBeginLoc(), 9581 diag::note_omp_previous_grainsize_num_tasks) 9582 << getOpenMPClauseName(PrevClause->getClauseKind()); 9583 ErrorFound = true; 9584 } 9585 } 9586 } 9587 return ErrorFound; 9588 } 9589 9590 static bool checkReductionClauseWithNogroup(Sema &S, 9591 ArrayRef<OMPClause *> Clauses) { 9592 const OMPClause *ReductionClause = nullptr; 9593 const OMPClause *NogroupClause = nullptr; 9594 for (const OMPClause *C : Clauses) { 9595 if (C->getClauseKind() == OMPC_reduction) { 9596 ReductionClause = C; 9597 if (NogroupClause) 9598 break; 9599 continue; 9600 } 9601 if (C->getClauseKind() == OMPC_nogroup) { 9602 NogroupClause = C; 9603 if (ReductionClause) 9604 break; 9605 continue; 9606 } 9607 } 9608 if (ReductionClause && NogroupClause) { 9609 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9610 << SourceRange(NogroupClause->getBeginLoc(), 9611 NogroupClause->getEndLoc()); 9612 return true; 9613 } 9614 return false; 9615 } 9616 9617 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9618 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9619 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9620 if (!AStmt) 9621 return StmtError(); 9622 9623 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9624 OMPLoopDirective::HelperExprs B; 9625 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9626 // define the nested loops number. 9627 unsigned NestedLoopCount = 9628 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9629 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9630 VarsWithImplicitDSA, B); 9631 if (NestedLoopCount == 0) 9632 return StmtError(); 9633 9634 assert((CurContext->isDependentContext() || B.builtAll()) && 9635 "omp for loop exprs were not built"); 9636 9637 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9638 // The grainsize clause and num_tasks clause are mutually exclusive and may 9639 // not appear on the same taskloop directive. 9640 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9641 return StmtError(); 9642 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9643 // If a reduction clause is present on the taskloop directive, the nogroup 9644 // clause must not be specified. 9645 if (checkReductionClauseWithNogroup(*this, Clauses)) 9646 return StmtError(); 9647 9648 setFunctionHasBranchProtectedScope(); 9649 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9650 NestedLoopCount, Clauses, AStmt, B); 9651 } 9652 9653 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9654 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9655 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9656 if (!AStmt) 9657 return StmtError(); 9658 9659 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9660 OMPLoopDirective::HelperExprs B; 9661 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9662 // define the nested loops number. 9663 unsigned NestedLoopCount = 9664 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9665 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9666 VarsWithImplicitDSA, B); 9667 if (NestedLoopCount == 0) 9668 return StmtError(); 9669 9670 assert((CurContext->isDependentContext() || B.builtAll()) && 9671 "omp for loop exprs were not built"); 9672 9673 if (!CurContext->isDependentContext()) { 9674 // Finalize the clauses that need pre-built expressions for CodeGen. 9675 for (OMPClause *C : Clauses) { 9676 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9677 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9678 B.NumIterations, *this, CurScope, 9679 DSAStack)) 9680 return StmtError(); 9681 } 9682 } 9683 9684 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9685 // The grainsize clause and num_tasks clause are mutually exclusive and may 9686 // not appear on the same taskloop directive. 9687 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9688 return StmtError(); 9689 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9690 // If a reduction clause is present on the taskloop directive, the nogroup 9691 // clause must not be specified. 9692 if (checkReductionClauseWithNogroup(*this, Clauses)) 9693 return StmtError(); 9694 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9695 return StmtError(); 9696 9697 setFunctionHasBranchProtectedScope(); 9698 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9699 NestedLoopCount, Clauses, AStmt, B); 9700 } 9701 9702 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9703 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9704 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9705 if (!AStmt) 9706 return StmtError(); 9707 9708 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9709 OMPLoopDirective::HelperExprs B; 9710 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9711 // define the nested loops number. 9712 unsigned NestedLoopCount = 9713 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9714 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9715 VarsWithImplicitDSA, B); 9716 if (NestedLoopCount == 0) 9717 return StmtError(); 9718 9719 assert((CurContext->isDependentContext() || B.builtAll()) && 9720 "omp for loop exprs were not built"); 9721 9722 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9723 // The grainsize clause and num_tasks clause are mutually exclusive and may 9724 // not appear on the same taskloop directive. 9725 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9726 return StmtError(); 9727 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9728 // If a reduction clause is present on the taskloop directive, the nogroup 9729 // clause must not be specified. 9730 if (checkReductionClauseWithNogroup(*this, Clauses)) 9731 return StmtError(); 9732 9733 setFunctionHasBranchProtectedScope(); 9734 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9735 NestedLoopCount, Clauses, AStmt, B); 9736 } 9737 9738 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9739 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9740 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9741 if (!AStmt) 9742 return StmtError(); 9743 9744 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9745 OMPLoopDirective::HelperExprs B; 9746 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9747 // define the nested loops number. 9748 unsigned NestedLoopCount = 9749 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9750 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9751 VarsWithImplicitDSA, B); 9752 if (NestedLoopCount == 0) 9753 return StmtError(); 9754 9755 assert((CurContext->isDependentContext() || B.builtAll()) && 9756 "omp for loop exprs were not built"); 9757 9758 if (!CurContext->isDependentContext()) { 9759 // Finalize the clauses that need pre-built expressions for CodeGen. 9760 for (OMPClause *C : Clauses) { 9761 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9762 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9763 B.NumIterations, *this, CurScope, 9764 DSAStack)) 9765 return StmtError(); 9766 } 9767 } 9768 9769 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9770 // The grainsize clause and num_tasks clause are mutually exclusive and may 9771 // not appear on the same taskloop directive. 9772 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9773 return StmtError(); 9774 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9775 // If a reduction clause is present on the taskloop directive, the nogroup 9776 // clause must not be specified. 9777 if (checkReductionClauseWithNogroup(*this, Clauses)) 9778 return StmtError(); 9779 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9780 return StmtError(); 9781 9782 setFunctionHasBranchProtectedScope(); 9783 return OMPMasterTaskLoopSimdDirective::Create( 9784 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9785 } 9786 9787 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9788 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9789 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9790 if (!AStmt) 9791 return StmtError(); 9792 9793 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9794 auto *CS = cast<CapturedStmt>(AStmt); 9795 // 1.2.2 OpenMP Language Terminology 9796 // Structured block - An executable statement with a single entry at the 9797 // top and a single exit at the bottom. 9798 // The point of exit cannot be a branch out of the structured block. 9799 // longjmp() and throw() must not violate the entry/exit criteria. 9800 CS->getCapturedDecl()->setNothrow(); 9801 for (int ThisCaptureLevel = 9802 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9803 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9804 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9805 // 1.2.2 OpenMP Language Terminology 9806 // Structured block - An executable statement with a single entry at the 9807 // top and a single exit at the bottom. 9808 // The point of exit cannot be a branch out of the structured block. 9809 // longjmp() and throw() must not violate the entry/exit criteria. 9810 CS->getCapturedDecl()->setNothrow(); 9811 } 9812 9813 OMPLoopDirective::HelperExprs B; 9814 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9815 // define the nested loops number. 9816 unsigned NestedLoopCount = checkOpenMPLoop( 9817 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9818 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9819 VarsWithImplicitDSA, B); 9820 if (NestedLoopCount == 0) 9821 return StmtError(); 9822 9823 assert((CurContext->isDependentContext() || B.builtAll()) && 9824 "omp for loop exprs were not built"); 9825 9826 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9827 // The grainsize clause and num_tasks clause are mutually exclusive and may 9828 // not appear on the same taskloop directive. 9829 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9830 return StmtError(); 9831 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9832 // If a reduction clause is present on the taskloop directive, the nogroup 9833 // clause must not be specified. 9834 if (checkReductionClauseWithNogroup(*this, Clauses)) 9835 return StmtError(); 9836 9837 setFunctionHasBranchProtectedScope(); 9838 return OMPParallelMasterTaskLoopDirective::Create( 9839 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9840 } 9841 9842 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9843 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9844 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9845 if (!AStmt) 9846 return StmtError(); 9847 9848 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9849 auto *CS = cast<CapturedStmt>(AStmt); 9850 // 1.2.2 OpenMP Language Terminology 9851 // Structured block - An executable statement with a single entry at the 9852 // top and a single exit at the bottom. 9853 // The point of exit cannot be a branch out of the structured block. 9854 // longjmp() and throw() must not violate the entry/exit criteria. 9855 CS->getCapturedDecl()->setNothrow(); 9856 for (int ThisCaptureLevel = 9857 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9858 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9859 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9860 // 1.2.2 OpenMP Language Terminology 9861 // Structured block - An executable statement with a single entry at the 9862 // top and a single exit at the bottom. 9863 // The point of exit cannot be a branch out of the structured block. 9864 // longjmp() and throw() must not violate the entry/exit criteria. 9865 CS->getCapturedDecl()->setNothrow(); 9866 } 9867 9868 OMPLoopDirective::HelperExprs B; 9869 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9870 // define the nested loops number. 9871 unsigned NestedLoopCount = checkOpenMPLoop( 9872 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9873 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9874 VarsWithImplicitDSA, B); 9875 if (NestedLoopCount == 0) 9876 return StmtError(); 9877 9878 assert((CurContext->isDependentContext() || B.builtAll()) && 9879 "omp for loop exprs were not built"); 9880 9881 if (!CurContext->isDependentContext()) { 9882 // Finalize the clauses that need pre-built expressions for CodeGen. 9883 for (OMPClause *C : Clauses) { 9884 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9885 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9886 B.NumIterations, *this, CurScope, 9887 DSAStack)) 9888 return StmtError(); 9889 } 9890 } 9891 9892 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9893 // The grainsize clause and num_tasks clause are mutually exclusive and may 9894 // not appear on the same taskloop directive. 9895 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9896 return StmtError(); 9897 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9898 // If a reduction clause is present on the taskloop directive, the nogroup 9899 // clause must not be specified. 9900 if (checkReductionClauseWithNogroup(*this, Clauses)) 9901 return StmtError(); 9902 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9903 return StmtError(); 9904 9905 setFunctionHasBranchProtectedScope(); 9906 return OMPParallelMasterTaskLoopSimdDirective::Create( 9907 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9908 } 9909 9910 StmtResult Sema::ActOnOpenMPDistributeDirective( 9911 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9912 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9913 if (!AStmt) 9914 return StmtError(); 9915 9916 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9917 OMPLoopDirective::HelperExprs B; 9918 // In presence of clause 'collapse' with number of loops, it will 9919 // define the nested loops number. 9920 unsigned NestedLoopCount = 9921 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9922 nullptr /*ordered not a clause on distribute*/, AStmt, 9923 *this, *DSAStack, VarsWithImplicitDSA, B); 9924 if (NestedLoopCount == 0) 9925 return StmtError(); 9926 9927 assert((CurContext->isDependentContext() || B.builtAll()) && 9928 "omp for loop exprs were not built"); 9929 9930 setFunctionHasBranchProtectedScope(); 9931 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9932 NestedLoopCount, Clauses, AStmt, B); 9933 } 9934 9935 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9936 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9937 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9938 if (!AStmt) 9939 return StmtError(); 9940 9941 auto *CS = cast<CapturedStmt>(AStmt); 9942 // 1.2.2 OpenMP Language Terminology 9943 // Structured block - An executable statement with a single entry at the 9944 // top and a single exit at the bottom. 9945 // The point of exit cannot be a branch out of the structured block. 9946 // longjmp() and throw() must not violate the entry/exit criteria. 9947 CS->getCapturedDecl()->setNothrow(); 9948 for (int ThisCaptureLevel = 9949 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9950 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9951 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9952 // 1.2.2 OpenMP Language Terminology 9953 // Structured block - An executable statement with a single entry at the 9954 // top and a single exit at the bottom. 9955 // The point of exit cannot be a branch out of the structured block. 9956 // longjmp() and throw() must not violate the entry/exit criteria. 9957 CS->getCapturedDecl()->setNothrow(); 9958 } 9959 9960 OMPLoopDirective::HelperExprs B; 9961 // In presence of clause 'collapse' with number of loops, it will 9962 // define the nested loops number. 9963 unsigned NestedLoopCount = checkOpenMPLoop( 9964 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9965 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9966 VarsWithImplicitDSA, B); 9967 if (NestedLoopCount == 0) 9968 return StmtError(); 9969 9970 assert((CurContext->isDependentContext() || B.builtAll()) && 9971 "omp for loop exprs were not built"); 9972 9973 setFunctionHasBranchProtectedScope(); 9974 return OMPDistributeParallelForDirective::Create( 9975 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9976 DSAStack->isCancelRegion()); 9977 } 9978 9979 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9980 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9981 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9982 if (!AStmt) 9983 return StmtError(); 9984 9985 auto *CS = cast<CapturedStmt>(AStmt); 9986 // 1.2.2 OpenMP Language Terminology 9987 // Structured block - An executable statement with a single entry at the 9988 // top and a single exit at the bottom. 9989 // The point of exit cannot be a branch out of the structured block. 9990 // longjmp() and throw() must not violate the entry/exit criteria. 9991 CS->getCapturedDecl()->setNothrow(); 9992 for (int ThisCaptureLevel = 9993 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9994 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9995 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9996 // 1.2.2 OpenMP Language Terminology 9997 // Structured block - An executable statement with a single entry at the 9998 // top and a single exit at the bottom. 9999 // The point of exit cannot be a branch out of the structured block. 10000 // longjmp() and throw() must not violate the entry/exit criteria. 10001 CS->getCapturedDecl()->setNothrow(); 10002 } 10003 10004 OMPLoopDirective::HelperExprs B; 10005 // In presence of clause 'collapse' with number of loops, it will 10006 // define the nested loops number. 10007 unsigned NestedLoopCount = checkOpenMPLoop( 10008 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10009 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10010 VarsWithImplicitDSA, B); 10011 if (NestedLoopCount == 0) 10012 return StmtError(); 10013 10014 assert((CurContext->isDependentContext() || B.builtAll()) && 10015 "omp for loop exprs were not built"); 10016 10017 if (!CurContext->isDependentContext()) { 10018 // Finalize the clauses that need pre-built expressions for CodeGen. 10019 for (OMPClause *C : Clauses) { 10020 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10021 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10022 B.NumIterations, *this, CurScope, 10023 DSAStack)) 10024 return StmtError(); 10025 } 10026 } 10027 10028 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10029 return StmtError(); 10030 10031 setFunctionHasBranchProtectedScope(); 10032 return OMPDistributeParallelForSimdDirective::Create( 10033 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10034 } 10035 10036 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10037 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10038 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10039 if (!AStmt) 10040 return StmtError(); 10041 10042 auto *CS = cast<CapturedStmt>(AStmt); 10043 // 1.2.2 OpenMP Language Terminology 10044 // Structured block - An executable statement with a single entry at the 10045 // top and a single exit at the bottom. 10046 // The point of exit cannot be a branch out of the structured block. 10047 // longjmp() and throw() must not violate the entry/exit criteria. 10048 CS->getCapturedDecl()->setNothrow(); 10049 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10050 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10051 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10052 // 1.2.2 OpenMP Language Terminology 10053 // Structured block - An executable statement with a single entry at the 10054 // top and a single exit at the bottom. 10055 // The point of exit cannot be a branch out of the structured block. 10056 // longjmp() and throw() must not violate the entry/exit criteria. 10057 CS->getCapturedDecl()->setNothrow(); 10058 } 10059 10060 OMPLoopDirective::HelperExprs B; 10061 // In presence of clause 'collapse' with number of loops, it will 10062 // define the nested loops number. 10063 unsigned NestedLoopCount = 10064 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10065 nullptr /*ordered not a clause on distribute*/, CS, *this, 10066 *DSAStack, VarsWithImplicitDSA, B); 10067 if (NestedLoopCount == 0) 10068 return StmtError(); 10069 10070 assert((CurContext->isDependentContext() || B.builtAll()) && 10071 "omp for loop exprs were not built"); 10072 10073 if (!CurContext->isDependentContext()) { 10074 // Finalize the clauses that need pre-built expressions for CodeGen. 10075 for (OMPClause *C : Clauses) { 10076 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10077 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10078 B.NumIterations, *this, CurScope, 10079 DSAStack)) 10080 return StmtError(); 10081 } 10082 } 10083 10084 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10085 return StmtError(); 10086 10087 setFunctionHasBranchProtectedScope(); 10088 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10089 NestedLoopCount, Clauses, AStmt, B); 10090 } 10091 10092 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10093 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10094 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10095 if (!AStmt) 10096 return StmtError(); 10097 10098 auto *CS = cast<CapturedStmt>(AStmt); 10099 // 1.2.2 OpenMP Language Terminology 10100 // Structured block - An executable statement with a single entry at the 10101 // top and a single exit at the bottom. 10102 // The point of exit cannot be a branch out of the structured block. 10103 // longjmp() and throw() must not violate the entry/exit criteria. 10104 CS->getCapturedDecl()->setNothrow(); 10105 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10106 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10107 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10108 // 1.2.2 OpenMP Language Terminology 10109 // Structured block - An executable statement with a single entry at the 10110 // top and a single exit at the bottom. 10111 // The point of exit cannot be a branch out of the structured block. 10112 // longjmp() and throw() must not violate the entry/exit criteria. 10113 CS->getCapturedDecl()->setNothrow(); 10114 } 10115 10116 OMPLoopDirective::HelperExprs B; 10117 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10118 // define the nested loops number. 10119 unsigned NestedLoopCount = checkOpenMPLoop( 10120 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10121 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10122 VarsWithImplicitDSA, B); 10123 if (NestedLoopCount == 0) 10124 return StmtError(); 10125 10126 assert((CurContext->isDependentContext() || B.builtAll()) && 10127 "omp target parallel for simd loop exprs were not built"); 10128 10129 if (!CurContext->isDependentContext()) { 10130 // Finalize the clauses that need pre-built expressions for CodeGen. 10131 for (OMPClause *C : Clauses) { 10132 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10133 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10134 B.NumIterations, *this, CurScope, 10135 DSAStack)) 10136 return StmtError(); 10137 } 10138 } 10139 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10140 return StmtError(); 10141 10142 setFunctionHasBranchProtectedScope(); 10143 return OMPTargetParallelForSimdDirective::Create( 10144 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10145 } 10146 10147 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10148 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10149 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10150 if (!AStmt) 10151 return StmtError(); 10152 10153 auto *CS = cast<CapturedStmt>(AStmt); 10154 // 1.2.2 OpenMP Language Terminology 10155 // Structured block - An executable statement with a single entry at the 10156 // top and a single exit at the bottom. 10157 // The point of exit cannot be a branch out of the structured block. 10158 // longjmp() and throw() must not violate the entry/exit criteria. 10159 CS->getCapturedDecl()->setNothrow(); 10160 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10161 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10162 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10163 // 1.2.2 OpenMP Language Terminology 10164 // Structured block - An executable statement with a single entry at the 10165 // top and a single exit at the bottom. 10166 // The point of exit cannot be a branch out of the structured block. 10167 // longjmp() and throw() must not violate the entry/exit criteria. 10168 CS->getCapturedDecl()->setNothrow(); 10169 } 10170 10171 OMPLoopDirective::HelperExprs B; 10172 // In presence of clause 'collapse' with number of loops, it will define the 10173 // nested loops number. 10174 unsigned NestedLoopCount = 10175 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10176 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10177 VarsWithImplicitDSA, B); 10178 if (NestedLoopCount == 0) 10179 return StmtError(); 10180 10181 assert((CurContext->isDependentContext() || B.builtAll()) && 10182 "omp target simd loop exprs were not built"); 10183 10184 if (!CurContext->isDependentContext()) { 10185 // Finalize the clauses that need pre-built expressions for CodeGen. 10186 for (OMPClause *C : Clauses) { 10187 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10188 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10189 B.NumIterations, *this, CurScope, 10190 DSAStack)) 10191 return StmtError(); 10192 } 10193 } 10194 10195 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10196 return StmtError(); 10197 10198 setFunctionHasBranchProtectedScope(); 10199 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10200 NestedLoopCount, Clauses, AStmt, B); 10201 } 10202 10203 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10204 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10205 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10206 if (!AStmt) 10207 return StmtError(); 10208 10209 auto *CS = cast<CapturedStmt>(AStmt); 10210 // 1.2.2 OpenMP Language Terminology 10211 // Structured block - An executable statement with a single entry at the 10212 // top and a single exit at the bottom. 10213 // The point of exit cannot be a branch out of the structured block. 10214 // longjmp() and throw() must not violate the entry/exit criteria. 10215 CS->getCapturedDecl()->setNothrow(); 10216 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10217 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10218 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10219 // 1.2.2 OpenMP Language Terminology 10220 // Structured block - An executable statement with a single entry at the 10221 // top and a single exit at the bottom. 10222 // The point of exit cannot be a branch out of the structured block. 10223 // longjmp() and throw() must not violate the entry/exit criteria. 10224 CS->getCapturedDecl()->setNothrow(); 10225 } 10226 10227 OMPLoopDirective::HelperExprs B; 10228 // In presence of clause 'collapse' with number of loops, it will 10229 // define the nested loops number. 10230 unsigned NestedLoopCount = 10231 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10232 nullptr /*ordered not a clause on distribute*/, CS, *this, 10233 *DSAStack, VarsWithImplicitDSA, B); 10234 if (NestedLoopCount == 0) 10235 return StmtError(); 10236 10237 assert((CurContext->isDependentContext() || B.builtAll()) && 10238 "omp teams distribute loop exprs were not built"); 10239 10240 setFunctionHasBranchProtectedScope(); 10241 10242 DSAStack->setParentTeamsRegionLoc(StartLoc); 10243 10244 return OMPTeamsDistributeDirective::Create( 10245 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10246 } 10247 10248 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10249 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10250 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10251 if (!AStmt) 10252 return StmtError(); 10253 10254 auto *CS = cast<CapturedStmt>(AStmt); 10255 // 1.2.2 OpenMP Language Terminology 10256 // Structured block - An executable statement with a single entry at the 10257 // top and a single exit at the bottom. 10258 // The point of exit cannot be a branch out of the structured block. 10259 // longjmp() and throw() must not violate the entry/exit criteria. 10260 CS->getCapturedDecl()->setNothrow(); 10261 for (int ThisCaptureLevel = 10262 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10263 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10264 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10265 // 1.2.2 OpenMP Language Terminology 10266 // Structured block - An executable statement with a single entry at the 10267 // top and a single exit at the bottom. 10268 // The point of exit cannot be a branch out of the structured block. 10269 // longjmp() and throw() must not violate the entry/exit criteria. 10270 CS->getCapturedDecl()->setNothrow(); 10271 } 10272 10273 10274 OMPLoopDirective::HelperExprs B; 10275 // In presence of clause 'collapse' with number of loops, it will 10276 // define the nested loops number. 10277 unsigned NestedLoopCount = checkOpenMPLoop( 10278 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10279 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10280 VarsWithImplicitDSA, B); 10281 10282 if (NestedLoopCount == 0) 10283 return StmtError(); 10284 10285 assert((CurContext->isDependentContext() || B.builtAll()) && 10286 "omp teams distribute simd loop exprs were not built"); 10287 10288 if (!CurContext->isDependentContext()) { 10289 // Finalize the clauses that need pre-built expressions for CodeGen. 10290 for (OMPClause *C : Clauses) { 10291 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10292 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10293 B.NumIterations, *this, CurScope, 10294 DSAStack)) 10295 return StmtError(); 10296 } 10297 } 10298 10299 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10300 return StmtError(); 10301 10302 setFunctionHasBranchProtectedScope(); 10303 10304 DSAStack->setParentTeamsRegionLoc(StartLoc); 10305 10306 return OMPTeamsDistributeSimdDirective::Create( 10307 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10308 } 10309 10310 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10311 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10312 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10313 if (!AStmt) 10314 return StmtError(); 10315 10316 auto *CS = cast<CapturedStmt>(AStmt); 10317 // 1.2.2 OpenMP Language Terminology 10318 // Structured block - An executable statement with a single entry at the 10319 // top and a single exit at the bottom. 10320 // The point of exit cannot be a branch out of the structured block. 10321 // longjmp() and throw() must not violate the entry/exit criteria. 10322 CS->getCapturedDecl()->setNothrow(); 10323 10324 for (int ThisCaptureLevel = 10325 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10326 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10327 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10328 // 1.2.2 OpenMP Language Terminology 10329 // Structured block - An executable statement with a single entry at the 10330 // top and a single exit at the bottom. 10331 // The point of exit cannot be a branch out of the structured block. 10332 // longjmp() and throw() must not violate the entry/exit criteria. 10333 CS->getCapturedDecl()->setNothrow(); 10334 } 10335 10336 OMPLoopDirective::HelperExprs B; 10337 // In presence of clause 'collapse' with number of loops, it will 10338 // define the nested loops number. 10339 unsigned NestedLoopCount = checkOpenMPLoop( 10340 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10341 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10342 VarsWithImplicitDSA, B); 10343 10344 if (NestedLoopCount == 0) 10345 return StmtError(); 10346 10347 assert((CurContext->isDependentContext() || B.builtAll()) && 10348 "omp for loop exprs were not built"); 10349 10350 if (!CurContext->isDependentContext()) { 10351 // Finalize the clauses that need pre-built expressions for CodeGen. 10352 for (OMPClause *C : Clauses) { 10353 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10354 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10355 B.NumIterations, *this, CurScope, 10356 DSAStack)) 10357 return StmtError(); 10358 } 10359 } 10360 10361 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10362 return StmtError(); 10363 10364 setFunctionHasBranchProtectedScope(); 10365 10366 DSAStack->setParentTeamsRegionLoc(StartLoc); 10367 10368 return OMPTeamsDistributeParallelForSimdDirective::Create( 10369 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10370 } 10371 10372 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10373 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10374 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10375 if (!AStmt) 10376 return StmtError(); 10377 10378 auto *CS = cast<CapturedStmt>(AStmt); 10379 // 1.2.2 OpenMP Language Terminology 10380 // Structured block - An executable statement with a single entry at the 10381 // top and a single exit at the bottom. 10382 // The point of exit cannot be a branch out of the structured block. 10383 // longjmp() and throw() must not violate the entry/exit criteria. 10384 CS->getCapturedDecl()->setNothrow(); 10385 10386 for (int ThisCaptureLevel = 10387 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10388 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10389 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10390 // 1.2.2 OpenMP Language Terminology 10391 // Structured block - An executable statement with a single entry at the 10392 // top and a single exit at the bottom. 10393 // The point of exit cannot be a branch out of the structured block. 10394 // longjmp() and throw() must not violate the entry/exit criteria. 10395 CS->getCapturedDecl()->setNothrow(); 10396 } 10397 10398 OMPLoopDirective::HelperExprs B; 10399 // In presence of clause 'collapse' with number of loops, it will 10400 // define the nested loops number. 10401 unsigned NestedLoopCount = checkOpenMPLoop( 10402 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10403 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10404 VarsWithImplicitDSA, B); 10405 10406 if (NestedLoopCount == 0) 10407 return StmtError(); 10408 10409 assert((CurContext->isDependentContext() || B.builtAll()) && 10410 "omp for loop exprs were not built"); 10411 10412 setFunctionHasBranchProtectedScope(); 10413 10414 DSAStack->setParentTeamsRegionLoc(StartLoc); 10415 10416 return OMPTeamsDistributeParallelForDirective::Create( 10417 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10418 DSAStack->isCancelRegion()); 10419 } 10420 10421 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10422 Stmt *AStmt, 10423 SourceLocation StartLoc, 10424 SourceLocation EndLoc) { 10425 if (!AStmt) 10426 return StmtError(); 10427 10428 auto *CS = cast<CapturedStmt>(AStmt); 10429 // 1.2.2 OpenMP Language Terminology 10430 // Structured block - An executable statement with a single entry at the 10431 // top and a single exit at the bottom. 10432 // The point of exit cannot be a branch out of the structured block. 10433 // longjmp() and throw() must not violate the entry/exit criteria. 10434 CS->getCapturedDecl()->setNothrow(); 10435 10436 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10437 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10438 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10439 // 1.2.2 OpenMP Language Terminology 10440 // Structured block - An executable statement with a single entry at the 10441 // top and a single exit at the bottom. 10442 // The point of exit cannot be a branch out of the structured block. 10443 // longjmp() and throw() must not violate the entry/exit criteria. 10444 CS->getCapturedDecl()->setNothrow(); 10445 } 10446 setFunctionHasBranchProtectedScope(); 10447 10448 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10449 AStmt); 10450 } 10451 10452 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10453 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10454 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10455 if (!AStmt) 10456 return StmtError(); 10457 10458 auto *CS = cast<CapturedStmt>(AStmt); 10459 // 1.2.2 OpenMP Language Terminology 10460 // Structured block - An executable statement with a single entry at the 10461 // top and a single exit at the bottom. 10462 // The point of exit cannot be a branch out of the structured block. 10463 // longjmp() and throw() must not violate the entry/exit criteria. 10464 CS->getCapturedDecl()->setNothrow(); 10465 for (int ThisCaptureLevel = 10466 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10467 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10468 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10469 // 1.2.2 OpenMP Language Terminology 10470 // Structured block - An executable statement with a single entry at the 10471 // top and a single exit at the bottom. 10472 // The point of exit cannot be a branch out of the structured block. 10473 // longjmp() and throw() must not violate the entry/exit criteria. 10474 CS->getCapturedDecl()->setNothrow(); 10475 } 10476 10477 OMPLoopDirective::HelperExprs B; 10478 // In presence of clause 'collapse' with number of loops, it will 10479 // define the nested loops number. 10480 unsigned NestedLoopCount = checkOpenMPLoop( 10481 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10482 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10483 VarsWithImplicitDSA, B); 10484 if (NestedLoopCount == 0) 10485 return StmtError(); 10486 10487 assert((CurContext->isDependentContext() || B.builtAll()) && 10488 "omp target teams distribute loop exprs were not built"); 10489 10490 setFunctionHasBranchProtectedScope(); 10491 return OMPTargetTeamsDistributeDirective::Create( 10492 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10493 } 10494 10495 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10496 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10497 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10498 if (!AStmt) 10499 return StmtError(); 10500 10501 auto *CS = cast<CapturedStmt>(AStmt); 10502 // 1.2.2 OpenMP Language Terminology 10503 // Structured block - An executable statement with a single entry at the 10504 // top and a single exit at the bottom. 10505 // The point of exit cannot be a branch out of the structured block. 10506 // longjmp() and throw() must not violate the entry/exit criteria. 10507 CS->getCapturedDecl()->setNothrow(); 10508 for (int ThisCaptureLevel = 10509 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10510 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10511 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10512 // 1.2.2 OpenMP Language Terminology 10513 // Structured block - An executable statement with a single entry at the 10514 // top and a single exit at the bottom. 10515 // The point of exit cannot be a branch out of the structured block. 10516 // longjmp() and throw() must not violate the entry/exit criteria. 10517 CS->getCapturedDecl()->setNothrow(); 10518 } 10519 10520 OMPLoopDirective::HelperExprs B; 10521 // In presence of clause 'collapse' with number of loops, it will 10522 // define the nested loops number. 10523 unsigned NestedLoopCount = checkOpenMPLoop( 10524 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10525 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10526 VarsWithImplicitDSA, B); 10527 if (NestedLoopCount == 0) 10528 return StmtError(); 10529 10530 assert((CurContext->isDependentContext() || B.builtAll()) && 10531 "omp target teams distribute parallel for loop exprs were not built"); 10532 10533 if (!CurContext->isDependentContext()) { 10534 // Finalize the clauses that need pre-built expressions for CodeGen. 10535 for (OMPClause *C : Clauses) { 10536 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10537 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10538 B.NumIterations, *this, CurScope, 10539 DSAStack)) 10540 return StmtError(); 10541 } 10542 } 10543 10544 setFunctionHasBranchProtectedScope(); 10545 return OMPTargetTeamsDistributeParallelForDirective::Create( 10546 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10547 DSAStack->isCancelRegion()); 10548 } 10549 10550 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10551 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10552 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10553 if (!AStmt) 10554 return StmtError(); 10555 10556 auto *CS = cast<CapturedStmt>(AStmt); 10557 // 1.2.2 OpenMP Language Terminology 10558 // Structured block - An executable statement with a single entry at the 10559 // top and a single exit at the bottom. 10560 // The point of exit cannot be a branch out of the structured block. 10561 // longjmp() and throw() must not violate the entry/exit criteria. 10562 CS->getCapturedDecl()->setNothrow(); 10563 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10564 OMPD_target_teams_distribute_parallel_for_simd); 10565 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10566 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10567 // 1.2.2 OpenMP Language Terminology 10568 // Structured block - An executable statement with a single entry at the 10569 // top and a single exit at the bottom. 10570 // The point of exit cannot be a branch out of the structured block. 10571 // longjmp() and throw() must not violate the entry/exit criteria. 10572 CS->getCapturedDecl()->setNothrow(); 10573 } 10574 10575 OMPLoopDirective::HelperExprs B; 10576 // In presence of clause 'collapse' with number of loops, it will 10577 // define the nested loops number. 10578 unsigned NestedLoopCount = 10579 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10580 getCollapseNumberExpr(Clauses), 10581 nullptr /*ordered not a clause on distribute*/, CS, *this, 10582 *DSAStack, VarsWithImplicitDSA, B); 10583 if (NestedLoopCount == 0) 10584 return StmtError(); 10585 10586 assert((CurContext->isDependentContext() || B.builtAll()) && 10587 "omp target teams distribute parallel for simd loop exprs were not " 10588 "built"); 10589 10590 if (!CurContext->isDependentContext()) { 10591 // Finalize the clauses that need pre-built expressions for CodeGen. 10592 for (OMPClause *C : Clauses) { 10593 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10594 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10595 B.NumIterations, *this, CurScope, 10596 DSAStack)) 10597 return StmtError(); 10598 } 10599 } 10600 10601 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10602 return StmtError(); 10603 10604 setFunctionHasBranchProtectedScope(); 10605 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10606 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10607 } 10608 10609 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10610 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10611 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10612 if (!AStmt) 10613 return StmtError(); 10614 10615 auto *CS = cast<CapturedStmt>(AStmt); 10616 // 1.2.2 OpenMP Language Terminology 10617 // Structured block - An executable statement with a single entry at the 10618 // top and a single exit at the bottom. 10619 // The point of exit cannot be a branch out of the structured block. 10620 // longjmp() and throw() must not violate the entry/exit criteria. 10621 CS->getCapturedDecl()->setNothrow(); 10622 for (int ThisCaptureLevel = 10623 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10624 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10625 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10626 // 1.2.2 OpenMP Language Terminology 10627 // Structured block - An executable statement with a single entry at the 10628 // top and a single exit at the bottom. 10629 // The point of exit cannot be a branch out of the structured block. 10630 // longjmp() and throw() must not violate the entry/exit criteria. 10631 CS->getCapturedDecl()->setNothrow(); 10632 } 10633 10634 OMPLoopDirective::HelperExprs B; 10635 // In presence of clause 'collapse' with number of loops, it will 10636 // define the nested loops number. 10637 unsigned NestedLoopCount = checkOpenMPLoop( 10638 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10639 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10640 VarsWithImplicitDSA, B); 10641 if (NestedLoopCount == 0) 10642 return StmtError(); 10643 10644 assert((CurContext->isDependentContext() || B.builtAll()) && 10645 "omp target teams distribute simd loop exprs were not built"); 10646 10647 if (!CurContext->isDependentContext()) { 10648 // Finalize the clauses that need pre-built expressions for CodeGen. 10649 for (OMPClause *C : Clauses) { 10650 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10651 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10652 B.NumIterations, *this, CurScope, 10653 DSAStack)) 10654 return StmtError(); 10655 } 10656 } 10657 10658 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10659 return StmtError(); 10660 10661 setFunctionHasBranchProtectedScope(); 10662 return OMPTargetTeamsDistributeSimdDirective::Create( 10663 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10664 } 10665 10666 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10667 SourceLocation StartLoc, 10668 SourceLocation LParenLoc, 10669 SourceLocation EndLoc) { 10670 OMPClause *Res = nullptr; 10671 switch (Kind) { 10672 case OMPC_final: 10673 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10674 break; 10675 case OMPC_num_threads: 10676 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10677 break; 10678 case OMPC_safelen: 10679 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10680 break; 10681 case OMPC_simdlen: 10682 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10683 break; 10684 case OMPC_allocator: 10685 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10686 break; 10687 case OMPC_collapse: 10688 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10689 break; 10690 case OMPC_ordered: 10691 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10692 break; 10693 case OMPC_device: 10694 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10695 break; 10696 case OMPC_num_teams: 10697 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10698 break; 10699 case OMPC_thread_limit: 10700 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10701 break; 10702 case OMPC_priority: 10703 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10704 break; 10705 case OMPC_grainsize: 10706 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10707 break; 10708 case OMPC_num_tasks: 10709 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10710 break; 10711 case OMPC_hint: 10712 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10713 break; 10714 case OMPC_if: 10715 case OMPC_default: 10716 case OMPC_proc_bind: 10717 case OMPC_schedule: 10718 case OMPC_private: 10719 case OMPC_firstprivate: 10720 case OMPC_lastprivate: 10721 case OMPC_shared: 10722 case OMPC_reduction: 10723 case OMPC_task_reduction: 10724 case OMPC_in_reduction: 10725 case OMPC_linear: 10726 case OMPC_aligned: 10727 case OMPC_copyin: 10728 case OMPC_copyprivate: 10729 case OMPC_nowait: 10730 case OMPC_untied: 10731 case OMPC_mergeable: 10732 case OMPC_threadprivate: 10733 case OMPC_allocate: 10734 case OMPC_flush: 10735 case OMPC_read: 10736 case OMPC_write: 10737 case OMPC_update: 10738 case OMPC_capture: 10739 case OMPC_seq_cst: 10740 case OMPC_depend: 10741 case OMPC_threads: 10742 case OMPC_simd: 10743 case OMPC_map: 10744 case OMPC_nogroup: 10745 case OMPC_dist_schedule: 10746 case OMPC_defaultmap: 10747 case OMPC_unknown: 10748 case OMPC_uniform: 10749 case OMPC_to: 10750 case OMPC_from: 10751 case OMPC_use_device_ptr: 10752 case OMPC_is_device_ptr: 10753 case OMPC_unified_address: 10754 case OMPC_unified_shared_memory: 10755 case OMPC_reverse_offload: 10756 case OMPC_dynamic_allocators: 10757 case OMPC_atomic_default_mem_order: 10758 case OMPC_device_type: 10759 case OMPC_match: 10760 case OMPC_nontemporal: 10761 llvm_unreachable("Clause is not allowed."); 10762 } 10763 return Res; 10764 } 10765 10766 // An OpenMP directive such as 'target parallel' has two captured regions: 10767 // for the 'target' and 'parallel' respectively. This function returns 10768 // the region in which to capture expressions associated with a clause. 10769 // A return value of OMPD_unknown signifies that the expression should not 10770 // be captured. 10771 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10772 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 10773 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10774 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10775 switch (CKind) { 10776 case OMPC_if: 10777 switch (DKind) { 10778 case OMPD_target_parallel_for_simd: 10779 if (OpenMPVersion >= 50 && 10780 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10781 CaptureRegion = OMPD_parallel; 10782 break; 10783 } 10784 LLVM_FALLTHROUGH; 10785 case OMPD_target_parallel: 10786 case OMPD_target_parallel_for: 10787 // If this clause applies to the nested 'parallel' region, capture within 10788 // the 'target' region, otherwise do not capture. 10789 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10790 CaptureRegion = OMPD_target; 10791 break; 10792 case OMPD_target_teams_distribute_parallel_for_simd: 10793 if (OpenMPVersion >= 50 && 10794 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10795 CaptureRegion = OMPD_parallel; 10796 break; 10797 } 10798 LLVM_FALLTHROUGH; 10799 case OMPD_target_teams_distribute_parallel_for: 10800 // If this clause applies to the nested 'parallel' region, capture within 10801 // the 'teams' region, otherwise do not capture. 10802 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10803 CaptureRegion = OMPD_teams; 10804 break; 10805 case OMPD_teams_distribute_parallel_for_simd: 10806 if (OpenMPVersion >= 50 && 10807 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10808 CaptureRegion = OMPD_parallel; 10809 break; 10810 } 10811 LLVM_FALLTHROUGH; 10812 case OMPD_teams_distribute_parallel_for: 10813 CaptureRegion = OMPD_teams; 10814 break; 10815 case OMPD_target_update: 10816 case OMPD_target_enter_data: 10817 case OMPD_target_exit_data: 10818 CaptureRegion = OMPD_task; 10819 break; 10820 case OMPD_parallel_master_taskloop: 10821 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10822 CaptureRegion = OMPD_parallel; 10823 break; 10824 case OMPD_parallel_master_taskloop_simd: 10825 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 10826 NameModifier == OMPD_taskloop) { 10827 CaptureRegion = OMPD_parallel; 10828 break; 10829 } 10830 if (OpenMPVersion <= 45) 10831 break; 10832 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10833 CaptureRegion = OMPD_taskloop; 10834 break; 10835 case OMPD_parallel_for_simd: 10836 if (OpenMPVersion <= 45) 10837 break; 10838 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10839 CaptureRegion = OMPD_parallel; 10840 break; 10841 case OMPD_taskloop_simd: 10842 case OMPD_master_taskloop_simd: 10843 if (OpenMPVersion <= 45) 10844 break; 10845 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10846 CaptureRegion = OMPD_taskloop; 10847 break; 10848 case OMPD_distribute_parallel_for_simd: 10849 if (OpenMPVersion <= 45) 10850 break; 10851 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10852 CaptureRegion = OMPD_parallel; 10853 break; 10854 case OMPD_target_simd: 10855 if (OpenMPVersion >= 50 && 10856 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10857 CaptureRegion = OMPD_target; 10858 break; 10859 case OMPD_teams_distribute_simd: 10860 case OMPD_target_teams_distribute_simd: 10861 if (OpenMPVersion >= 50 && 10862 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10863 CaptureRegion = OMPD_teams; 10864 break; 10865 case OMPD_cancel: 10866 case OMPD_parallel: 10867 case OMPD_parallel_master: 10868 case OMPD_parallel_sections: 10869 case OMPD_parallel_for: 10870 case OMPD_target: 10871 case OMPD_target_teams: 10872 case OMPD_target_teams_distribute: 10873 case OMPD_distribute_parallel_for: 10874 case OMPD_task: 10875 case OMPD_taskloop: 10876 case OMPD_master_taskloop: 10877 case OMPD_target_data: 10878 case OMPD_simd: 10879 case OMPD_for_simd: 10880 case OMPD_distribute_simd: 10881 // Do not capture if-clause expressions. 10882 break; 10883 case OMPD_threadprivate: 10884 case OMPD_allocate: 10885 case OMPD_taskyield: 10886 case OMPD_barrier: 10887 case OMPD_taskwait: 10888 case OMPD_cancellation_point: 10889 case OMPD_flush: 10890 case OMPD_declare_reduction: 10891 case OMPD_declare_mapper: 10892 case OMPD_declare_simd: 10893 case OMPD_declare_variant: 10894 case OMPD_declare_target: 10895 case OMPD_end_declare_target: 10896 case OMPD_teams: 10897 case OMPD_for: 10898 case OMPD_sections: 10899 case OMPD_section: 10900 case OMPD_single: 10901 case OMPD_master: 10902 case OMPD_critical: 10903 case OMPD_taskgroup: 10904 case OMPD_distribute: 10905 case OMPD_ordered: 10906 case OMPD_atomic: 10907 case OMPD_teams_distribute: 10908 case OMPD_requires: 10909 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10910 case OMPD_unknown: 10911 llvm_unreachable("Unknown OpenMP directive"); 10912 } 10913 break; 10914 case OMPC_num_threads: 10915 switch (DKind) { 10916 case OMPD_target_parallel: 10917 case OMPD_target_parallel_for: 10918 case OMPD_target_parallel_for_simd: 10919 CaptureRegion = OMPD_target; 10920 break; 10921 case OMPD_teams_distribute_parallel_for: 10922 case OMPD_teams_distribute_parallel_for_simd: 10923 case OMPD_target_teams_distribute_parallel_for: 10924 case OMPD_target_teams_distribute_parallel_for_simd: 10925 CaptureRegion = OMPD_teams; 10926 break; 10927 case OMPD_parallel: 10928 case OMPD_parallel_master: 10929 case OMPD_parallel_sections: 10930 case OMPD_parallel_for: 10931 case OMPD_parallel_for_simd: 10932 case OMPD_distribute_parallel_for: 10933 case OMPD_distribute_parallel_for_simd: 10934 case OMPD_parallel_master_taskloop: 10935 case OMPD_parallel_master_taskloop_simd: 10936 // Do not capture num_threads-clause expressions. 10937 break; 10938 case OMPD_target_data: 10939 case OMPD_target_enter_data: 10940 case OMPD_target_exit_data: 10941 case OMPD_target_update: 10942 case OMPD_target: 10943 case OMPD_target_simd: 10944 case OMPD_target_teams: 10945 case OMPD_target_teams_distribute: 10946 case OMPD_target_teams_distribute_simd: 10947 case OMPD_cancel: 10948 case OMPD_task: 10949 case OMPD_taskloop: 10950 case OMPD_taskloop_simd: 10951 case OMPD_master_taskloop: 10952 case OMPD_master_taskloop_simd: 10953 case OMPD_threadprivate: 10954 case OMPD_allocate: 10955 case OMPD_taskyield: 10956 case OMPD_barrier: 10957 case OMPD_taskwait: 10958 case OMPD_cancellation_point: 10959 case OMPD_flush: 10960 case OMPD_declare_reduction: 10961 case OMPD_declare_mapper: 10962 case OMPD_declare_simd: 10963 case OMPD_declare_variant: 10964 case OMPD_declare_target: 10965 case OMPD_end_declare_target: 10966 case OMPD_teams: 10967 case OMPD_simd: 10968 case OMPD_for: 10969 case OMPD_for_simd: 10970 case OMPD_sections: 10971 case OMPD_section: 10972 case OMPD_single: 10973 case OMPD_master: 10974 case OMPD_critical: 10975 case OMPD_taskgroup: 10976 case OMPD_distribute: 10977 case OMPD_ordered: 10978 case OMPD_atomic: 10979 case OMPD_distribute_simd: 10980 case OMPD_teams_distribute: 10981 case OMPD_teams_distribute_simd: 10982 case OMPD_requires: 10983 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10984 case OMPD_unknown: 10985 llvm_unreachable("Unknown OpenMP directive"); 10986 } 10987 break; 10988 case OMPC_num_teams: 10989 switch (DKind) { 10990 case OMPD_target_teams: 10991 case OMPD_target_teams_distribute: 10992 case OMPD_target_teams_distribute_simd: 10993 case OMPD_target_teams_distribute_parallel_for: 10994 case OMPD_target_teams_distribute_parallel_for_simd: 10995 CaptureRegion = OMPD_target; 10996 break; 10997 case OMPD_teams_distribute_parallel_for: 10998 case OMPD_teams_distribute_parallel_for_simd: 10999 case OMPD_teams: 11000 case OMPD_teams_distribute: 11001 case OMPD_teams_distribute_simd: 11002 // Do not capture num_teams-clause expressions. 11003 break; 11004 case OMPD_distribute_parallel_for: 11005 case OMPD_distribute_parallel_for_simd: 11006 case OMPD_task: 11007 case OMPD_taskloop: 11008 case OMPD_taskloop_simd: 11009 case OMPD_master_taskloop: 11010 case OMPD_master_taskloop_simd: 11011 case OMPD_parallel_master_taskloop: 11012 case OMPD_parallel_master_taskloop_simd: 11013 case OMPD_target_data: 11014 case OMPD_target_enter_data: 11015 case OMPD_target_exit_data: 11016 case OMPD_target_update: 11017 case OMPD_cancel: 11018 case OMPD_parallel: 11019 case OMPD_parallel_master: 11020 case OMPD_parallel_sections: 11021 case OMPD_parallel_for: 11022 case OMPD_parallel_for_simd: 11023 case OMPD_target: 11024 case OMPD_target_simd: 11025 case OMPD_target_parallel: 11026 case OMPD_target_parallel_for: 11027 case OMPD_target_parallel_for_simd: 11028 case OMPD_threadprivate: 11029 case OMPD_allocate: 11030 case OMPD_taskyield: 11031 case OMPD_barrier: 11032 case OMPD_taskwait: 11033 case OMPD_cancellation_point: 11034 case OMPD_flush: 11035 case OMPD_declare_reduction: 11036 case OMPD_declare_mapper: 11037 case OMPD_declare_simd: 11038 case OMPD_declare_variant: 11039 case OMPD_declare_target: 11040 case OMPD_end_declare_target: 11041 case OMPD_simd: 11042 case OMPD_for: 11043 case OMPD_for_simd: 11044 case OMPD_sections: 11045 case OMPD_section: 11046 case OMPD_single: 11047 case OMPD_master: 11048 case OMPD_critical: 11049 case OMPD_taskgroup: 11050 case OMPD_distribute: 11051 case OMPD_ordered: 11052 case OMPD_atomic: 11053 case OMPD_distribute_simd: 11054 case OMPD_requires: 11055 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11056 case OMPD_unknown: 11057 llvm_unreachable("Unknown OpenMP directive"); 11058 } 11059 break; 11060 case OMPC_thread_limit: 11061 switch (DKind) { 11062 case OMPD_target_teams: 11063 case OMPD_target_teams_distribute: 11064 case OMPD_target_teams_distribute_simd: 11065 case OMPD_target_teams_distribute_parallel_for: 11066 case OMPD_target_teams_distribute_parallel_for_simd: 11067 CaptureRegion = OMPD_target; 11068 break; 11069 case OMPD_teams_distribute_parallel_for: 11070 case OMPD_teams_distribute_parallel_for_simd: 11071 case OMPD_teams: 11072 case OMPD_teams_distribute: 11073 case OMPD_teams_distribute_simd: 11074 // Do not capture thread_limit-clause expressions. 11075 break; 11076 case OMPD_distribute_parallel_for: 11077 case OMPD_distribute_parallel_for_simd: 11078 case OMPD_task: 11079 case OMPD_taskloop: 11080 case OMPD_taskloop_simd: 11081 case OMPD_master_taskloop: 11082 case OMPD_master_taskloop_simd: 11083 case OMPD_parallel_master_taskloop: 11084 case OMPD_parallel_master_taskloop_simd: 11085 case OMPD_target_data: 11086 case OMPD_target_enter_data: 11087 case OMPD_target_exit_data: 11088 case OMPD_target_update: 11089 case OMPD_cancel: 11090 case OMPD_parallel: 11091 case OMPD_parallel_master: 11092 case OMPD_parallel_sections: 11093 case OMPD_parallel_for: 11094 case OMPD_parallel_for_simd: 11095 case OMPD_target: 11096 case OMPD_target_simd: 11097 case OMPD_target_parallel: 11098 case OMPD_target_parallel_for: 11099 case OMPD_target_parallel_for_simd: 11100 case OMPD_threadprivate: 11101 case OMPD_allocate: 11102 case OMPD_taskyield: 11103 case OMPD_barrier: 11104 case OMPD_taskwait: 11105 case OMPD_cancellation_point: 11106 case OMPD_flush: 11107 case OMPD_declare_reduction: 11108 case OMPD_declare_mapper: 11109 case OMPD_declare_simd: 11110 case OMPD_declare_variant: 11111 case OMPD_declare_target: 11112 case OMPD_end_declare_target: 11113 case OMPD_simd: 11114 case OMPD_for: 11115 case OMPD_for_simd: 11116 case OMPD_sections: 11117 case OMPD_section: 11118 case OMPD_single: 11119 case OMPD_master: 11120 case OMPD_critical: 11121 case OMPD_taskgroup: 11122 case OMPD_distribute: 11123 case OMPD_ordered: 11124 case OMPD_atomic: 11125 case OMPD_distribute_simd: 11126 case OMPD_requires: 11127 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11128 case OMPD_unknown: 11129 llvm_unreachable("Unknown OpenMP directive"); 11130 } 11131 break; 11132 case OMPC_schedule: 11133 switch (DKind) { 11134 case OMPD_parallel_for: 11135 case OMPD_parallel_for_simd: 11136 case OMPD_distribute_parallel_for: 11137 case OMPD_distribute_parallel_for_simd: 11138 case OMPD_teams_distribute_parallel_for: 11139 case OMPD_teams_distribute_parallel_for_simd: 11140 case OMPD_target_parallel_for: 11141 case OMPD_target_parallel_for_simd: 11142 case OMPD_target_teams_distribute_parallel_for: 11143 case OMPD_target_teams_distribute_parallel_for_simd: 11144 CaptureRegion = OMPD_parallel; 11145 break; 11146 case OMPD_for: 11147 case OMPD_for_simd: 11148 // Do not capture schedule-clause expressions. 11149 break; 11150 case OMPD_task: 11151 case OMPD_taskloop: 11152 case OMPD_taskloop_simd: 11153 case OMPD_master_taskloop: 11154 case OMPD_master_taskloop_simd: 11155 case OMPD_parallel_master_taskloop: 11156 case OMPD_parallel_master_taskloop_simd: 11157 case OMPD_target_data: 11158 case OMPD_target_enter_data: 11159 case OMPD_target_exit_data: 11160 case OMPD_target_update: 11161 case OMPD_teams: 11162 case OMPD_teams_distribute: 11163 case OMPD_teams_distribute_simd: 11164 case OMPD_target_teams_distribute: 11165 case OMPD_target_teams_distribute_simd: 11166 case OMPD_target: 11167 case OMPD_target_simd: 11168 case OMPD_target_parallel: 11169 case OMPD_cancel: 11170 case OMPD_parallel: 11171 case OMPD_parallel_master: 11172 case OMPD_parallel_sections: 11173 case OMPD_threadprivate: 11174 case OMPD_allocate: 11175 case OMPD_taskyield: 11176 case OMPD_barrier: 11177 case OMPD_taskwait: 11178 case OMPD_cancellation_point: 11179 case OMPD_flush: 11180 case OMPD_declare_reduction: 11181 case OMPD_declare_mapper: 11182 case OMPD_declare_simd: 11183 case OMPD_declare_variant: 11184 case OMPD_declare_target: 11185 case OMPD_end_declare_target: 11186 case OMPD_simd: 11187 case OMPD_sections: 11188 case OMPD_section: 11189 case OMPD_single: 11190 case OMPD_master: 11191 case OMPD_critical: 11192 case OMPD_taskgroup: 11193 case OMPD_distribute: 11194 case OMPD_ordered: 11195 case OMPD_atomic: 11196 case OMPD_distribute_simd: 11197 case OMPD_target_teams: 11198 case OMPD_requires: 11199 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11200 case OMPD_unknown: 11201 llvm_unreachable("Unknown OpenMP directive"); 11202 } 11203 break; 11204 case OMPC_dist_schedule: 11205 switch (DKind) { 11206 case OMPD_teams_distribute_parallel_for: 11207 case OMPD_teams_distribute_parallel_for_simd: 11208 case OMPD_teams_distribute: 11209 case OMPD_teams_distribute_simd: 11210 case OMPD_target_teams_distribute_parallel_for: 11211 case OMPD_target_teams_distribute_parallel_for_simd: 11212 case OMPD_target_teams_distribute: 11213 case OMPD_target_teams_distribute_simd: 11214 CaptureRegion = OMPD_teams; 11215 break; 11216 case OMPD_distribute_parallel_for: 11217 case OMPD_distribute_parallel_for_simd: 11218 case OMPD_distribute: 11219 case OMPD_distribute_simd: 11220 // Do not capture thread_limit-clause expressions. 11221 break; 11222 case OMPD_parallel_for: 11223 case OMPD_parallel_for_simd: 11224 case OMPD_target_parallel_for_simd: 11225 case OMPD_target_parallel_for: 11226 case OMPD_task: 11227 case OMPD_taskloop: 11228 case OMPD_taskloop_simd: 11229 case OMPD_master_taskloop: 11230 case OMPD_master_taskloop_simd: 11231 case OMPD_parallel_master_taskloop: 11232 case OMPD_parallel_master_taskloop_simd: 11233 case OMPD_target_data: 11234 case OMPD_target_enter_data: 11235 case OMPD_target_exit_data: 11236 case OMPD_target_update: 11237 case OMPD_teams: 11238 case OMPD_target: 11239 case OMPD_target_simd: 11240 case OMPD_target_parallel: 11241 case OMPD_cancel: 11242 case OMPD_parallel: 11243 case OMPD_parallel_master: 11244 case OMPD_parallel_sections: 11245 case OMPD_threadprivate: 11246 case OMPD_allocate: 11247 case OMPD_taskyield: 11248 case OMPD_barrier: 11249 case OMPD_taskwait: 11250 case OMPD_cancellation_point: 11251 case OMPD_flush: 11252 case OMPD_declare_reduction: 11253 case OMPD_declare_mapper: 11254 case OMPD_declare_simd: 11255 case OMPD_declare_variant: 11256 case OMPD_declare_target: 11257 case OMPD_end_declare_target: 11258 case OMPD_simd: 11259 case OMPD_for: 11260 case OMPD_for_simd: 11261 case OMPD_sections: 11262 case OMPD_section: 11263 case OMPD_single: 11264 case OMPD_master: 11265 case OMPD_critical: 11266 case OMPD_taskgroup: 11267 case OMPD_ordered: 11268 case OMPD_atomic: 11269 case OMPD_target_teams: 11270 case OMPD_requires: 11271 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11272 case OMPD_unknown: 11273 llvm_unreachable("Unknown OpenMP directive"); 11274 } 11275 break; 11276 case OMPC_device: 11277 switch (DKind) { 11278 case OMPD_target_update: 11279 case OMPD_target_enter_data: 11280 case OMPD_target_exit_data: 11281 case OMPD_target: 11282 case OMPD_target_simd: 11283 case OMPD_target_teams: 11284 case OMPD_target_parallel: 11285 case OMPD_target_teams_distribute: 11286 case OMPD_target_teams_distribute_simd: 11287 case OMPD_target_parallel_for: 11288 case OMPD_target_parallel_for_simd: 11289 case OMPD_target_teams_distribute_parallel_for: 11290 case OMPD_target_teams_distribute_parallel_for_simd: 11291 CaptureRegion = OMPD_task; 11292 break; 11293 case OMPD_target_data: 11294 // Do not capture device-clause expressions. 11295 break; 11296 case OMPD_teams_distribute_parallel_for: 11297 case OMPD_teams_distribute_parallel_for_simd: 11298 case OMPD_teams: 11299 case OMPD_teams_distribute: 11300 case OMPD_teams_distribute_simd: 11301 case OMPD_distribute_parallel_for: 11302 case OMPD_distribute_parallel_for_simd: 11303 case OMPD_task: 11304 case OMPD_taskloop: 11305 case OMPD_taskloop_simd: 11306 case OMPD_master_taskloop: 11307 case OMPD_master_taskloop_simd: 11308 case OMPD_parallel_master_taskloop: 11309 case OMPD_parallel_master_taskloop_simd: 11310 case OMPD_cancel: 11311 case OMPD_parallel: 11312 case OMPD_parallel_master: 11313 case OMPD_parallel_sections: 11314 case OMPD_parallel_for: 11315 case OMPD_parallel_for_simd: 11316 case OMPD_threadprivate: 11317 case OMPD_allocate: 11318 case OMPD_taskyield: 11319 case OMPD_barrier: 11320 case OMPD_taskwait: 11321 case OMPD_cancellation_point: 11322 case OMPD_flush: 11323 case OMPD_declare_reduction: 11324 case OMPD_declare_mapper: 11325 case OMPD_declare_simd: 11326 case OMPD_declare_variant: 11327 case OMPD_declare_target: 11328 case OMPD_end_declare_target: 11329 case OMPD_simd: 11330 case OMPD_for: 11331 case OMPD_for_simd: 11332 case OMPD_sections: 11333 case OMPD_section: 11334 case OMPD_single: 11335 case OMPD_master: 11336 case OMPD_critical: 11337 case OMPD_taskgroup: 11338 case OMPD_distribute: 11339 case OMPD_ordered: 11340 case OMPD_atomic: 11341 case OMPD_distribute_simd: 11342 case OMPD_requires: 11343 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11344 case OMPD_unknown: 11345 llvm_unreachable("Unknown OpenMP directive"); 11346 } 11347 break; 11348 case OMPC_grainsize: 11349 case OMPC_num_tasks: 11350 case OMPC_final: 11351 case OMPC_priority: 11352 switch (DKind) { 11353 case OMPD_task: 11354 case OMPD_taskloop: 11355 case OMPD_taskloop_simd: 11356 case OMPD_master_taskloop: 11357 case OMPD_master_taskloop_simd: 11358 break; 11359 case OMPD_parallel_master_taskloop: 11360 case OMPD_parallel_master_taskloop_simd: 11361 CaptureRegion = OMPD_parallel; 11362 break; 11363 case OMPD_target_update: 11364 case OMPD_target_enter_data: 11365 case OMPD_target_exit_data: 11366 case OMPD_target: 11367 case OMPD_target_simd: 11368 case OMPD_target_teams: 11369 case OMPD_target_parallel: 11370 case OMPD_target_teams_distribute: 11371 case OMPD_target_teams_distribute_simd: 11372 case OMPD_target_parallel_for: 11373 case OMPD_target_parallel_for_simd: 11374 case OMPD_target_teams_distribute_parallel_for: 11375 case OMPD_target_teams_distribute_parallel_for_simd: 11376 case OMPD_target_data: 11377 case OMPD_teams_distribute_parallel_for: 11378 case OMPD_teams_distribute_parallel_for_simd: 11379 case OMPD_teams: 11380 case OMPD_teams_distribute: 11381 case OMPD_teams_distribute_simd: 11382 case OMPD_distribute_parallel_for: 11383 case OMPD_distribute_parallel_for_simd: 11384 case OMPD_cancel: 11385 case OMPD_parallel: 11386 case OMPD_parallel_master: 11387 case OMPD_parallel_sections: 11388 case OMPD_parallel_for: 11389 case OMPD_parallel_for_simd: 11390 case OMPD_threadprivate: 11391 case OMPD_allocate: 11392 case OMPD_taskyield: 11393 case OMPD_barrier: 11394 case OMPD_taskwait: 11395 case OMPD_cancellation_point: 11396 case OMPD_flush: 11397 case OMPD_declare_reduction: 11398 case OMPD_declare_mapper: 11399 case OMPD_declare_simd: 11400 case OMPD_declare_variant: 11401 case OMPD_declare_target: 11402 case OMPD_end_declare_target: 11403 case OMPD_simd: 11404 case OMPD_for: 11405 case OMPD_for_simd: 11406 case OMPD_sections: 11407 case OMPD_section: 11408 case OMPD_single: 11409 case OMPD_master: 11410 case OMPD_critical: 11411 case OMPD_taskgroup: 11412 case OMPD_distribute: 11413 case OMPD_ordered: 11414 case OMPD_atomic: 11415 case OMPD_distribute_simd: 11416 case OMPD_requires: 11417 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11418 case OMPD_unknown: 11419 llvm_unreachable("Unknown OpenMP directive"); 11420 } 11421 break; 11422 case OMPC_firstprivate: 11423 case OMPC_lastprivate: 11424 case OMPC_reduction: 11425 case OMPC_task_reduction: 11426 case OMPC_in_reduction: 11427 case OMPC_linear: 11428 case OMPC_default: 11429 case OMPC_proc_bind: 11430 case OMPC_safelen: 11431 case OMPC_simdlen: 11432 case OMPC_allocator: 11433 case OMPC_collapse: 11434 case OMPC_private: 11435 case OMPC_shared: 11436 case OMPC_aligned: 11437 case OMPC_copyin: 11438 case OMPC_copyprivate: 11439 case OMPC_ordered: 11440 case OMPC_nowait: 11441 case OMPC_untied: 11442 case OMPC_mergeable: 11443 case OMPC_threadprivate: 11444 case OMPC_allocate: 11445 case OMPC_flush: 11446 case OMPC_read: 11447 case OMPC_write: 11448 case OMPC_update: 11449 case OMPC_capture: 11450 case OMPC_seq_cst: 11451 case OMPC_depend: 11452 case OMPC_threads: 11453 case OMPC_simd: 11454 case OMPC_map: 11455 case OMPC_nogroup: 11456 case OMPC_hint: 11457 case OMPC_defaultmap: 11458 case OMPC_unknown: 11459 case OMPC_uniform: 11460 case OMPC_to: 11461 case OMPC_from: 11462 case OMPC_use_device_ptr: 11463 case OMPC_is_device_ptr: 11464 case OMPC_unified_address: 11465 case OMPC_unified_shared_memory: 11466 case OMPC_reverse_offload: 11467 case OMPC_dynamic_allocators: 11468 case OMPC_atomic_default_mem_order: 11469 case OMPC_device_type: 11470 case OMPC_match: 11471 case OMPC_nontemporal: 11472 llvm_unreachable("Unexpected OpenMP clause."); 11473 } 11474 return CaptureRegion; 11475 } 11476 11477 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11478 Expr *Condition, SourceLocation StartLoc, 11479 SourceLocation LParenLoc, 11480 SourceLocation NameModifierLoc, 11481 SourceLocation ColonLoc, 11482 SourceLocation EndLoc) { 11483 Expr *ValExpr = Condition; 11484 Stmt *HelperValStmt = nullptr; 11485 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11486 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11487 !Condition->isInstantiationDependent() && 11488 !Condition->containsUnexpandedParameterPack()) { 11489 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11490 if (Val.isInvalid()) 11491 return nullptr; 11492 11493 ValExpr = Val.get(); 11494 11495 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11496 CaptureRegion = getOpenMPCaptureRegionForClause( 11497 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 11498 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11499 ValExpr = MakeFullExpr(ValExpr).get(); 11500 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11501 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11502 HelperValStmt = buildPreInits(Context, Captures); 11503 } 11504 } 11505 11506 return new (Context) 11507 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11508 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11509 } 11510 11511 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11512 SourceLocation StartLoc, 11513 SourceLocation LParenLoc, 11514 SourceLocation EndLoc) { 11515 Expr *ValExpr = Condition; 11516 Stmt *HelperValStmt = nullptr; 11517 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11518 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11519 !Condition->isInstantiationDependent() && 11520 !Condition->containsUnexpandedParameterPack()) { 11521 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11522 if (Val.isInvalid()) 11523 return nullptr; 11524 11525 ValExpr = MakeFullExpr(Val.get()).get(); 11526 11527 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11528 CaptureRegion = 11529 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 11530 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11531 ValExpr = MakeFullExpr(ValExpr).get(); 11532 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11533 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11534 HelperValStmt = buildPreInits(Context, Captures); 11535 } 11536 } 11537 11538 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11539 StartLoc, LParenLoc, EndLoc); 11540 } 11541 11542 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11543 Expr *Op) { 11544 if (!Op) 11545 return ExprError(); 11546 11547 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11548 public: 11549 IntConvertDiagnoser() 11550 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11551 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11552 QualType T) override { 11553 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11554 } 11555 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11556 QualType T) override { 11557 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11558 } 11559 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11560 QualType T, 11561 QualType ConvTy) override { 11562 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11563 } 11564 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11565 QualType ConvTy) override { 11566 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11567 << ConvTy->isEnumeralType() << ConvTy; 11568 } 11569 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11570 QualType T) override { 11571 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11572 } 11573 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11574 QualType ConvTy) override { 11575 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11576 << ConvTy->isEnumeralType() << ConvTy; 11577 } 11578 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11579 QualType) override { 11580 llvm_unreachable("conversion functions are permitted"); 11581 } 11582 } ConvertDiagnoser; 11583 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11584 } 11585 11586 static bool 11587 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11588 bool StrictlyPositive, bool BuildCapture = false, 11589 OpenMPDirectiveKind DKind = OMPD_unknown, 11590 OpenMPDirectiveKind *CaptureRegion = nullptr, 11591 Stmt **HelperValStmt = nullptr) { 11592 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11593 !ValExpr->isInstantiationDependent()) { 11594 SourceLocation Loc = ValExpr->getExprLoc(); 11595 ExprResult Value = 11596 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11597 if (Value.isInvalid()) 11598 return false; 11599 11600 ValExpr = Value.get(); 11601 // The expression must evaluate to a non-negative integer value. 11602 llvm::APSInt Result; 11603 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11604 Result.isSigned() && 11605 !((!StrictlyPositive && Result.isNonNegative()) || 11606 (StrictlyPositive && Result.isStrictlyPositive()))) { 11607 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11608 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11609 << ValExpr->getSourceRange(); 11610 return false; 11611 } 11612 if (!BuildCapture) 11613 return true; 11614 *CaptureRegion = 11615 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 11616 if (*CaptureRegion != OMPD_unknown && 11617 !SemaRef.CurContext->isDependentContext()) { 11618 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11619 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11620 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11621 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11622 } 11623 } 11624 return true; 11625 } 11626 11627 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11628 SourceLocation StartLoc, 11629 SourceLocation LParenLoc, 11630 SourceLocation EndLoc) { 11631 Expr *ValExpr = NumThreads; 11632 Stmt *HelperValStmt = nullptr; 11633 11634 // OpenMP [2.5, Restrictions] 11635 // The num_threads expression must evaluate to a positive integer value. 11636 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11637 /*StrictlyPositive=*/true)) 11638 return nullptr; 11639 11640 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11641 OpenMPDirectiveKind CaptureRegion = 11642 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 11643 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11644 ValExpr = MakeFullExpr(ValExpr).get(); 11645 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11646 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11647 HelperValStmt = buildPreInits(Context, Captures); 11648 } 11649 11650 return new (Context) OMPNumThreadsClause( 11651 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11652 } 11653 11654 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11655 OpenMPClauseKind CKind, 11656 bool StrictlyPositive) { 11657 if (!E) 11658 return ExprError(); 11659 if (E->isValueDependent() || E->isTypeDependent() || 11660 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11661 return E; 11662 llvm::APSInt Result; 11663 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11664 if (ICE.isInvalid()) 11665 return ExprError(); 11666 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11667 (!StrictlyPositive && !Result.isNonNegative())) { 11668 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11669 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11670 << E->getSourceRange(); 11671 return ExprError(); 11672 } 11673 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11674 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11675 << E->getSourceRange(); 11676 return ExprError(); 11677 } 11678 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11679 DSAStack->setAssociatedLoops(Result.getExtValue()); 11680 else if (CKind == OMPC_ordered) 11681 DSAStack->setAssociatedLoops(Result.getExtValue()); 11682 return ICE; 11683 } 11684 11685 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11686 SourceLocation LParenLoc, 11687 SourceLocation EndLoc) { 11688 // OpenMP [2.8.1, simd construct, Description] 11689 // The parameter of the safelen clause must be a constant 11690 // positive integer expression. 11691 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11692 if (Safelen.isInvalid()) 11693 return nullptr; 11694 return new (Context) 11695 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11696 } 11697 11698 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11699 SourceLocation LParenLoc, 11700 SourceLocation EndLoc) { 11701 // OpenMP [2.8.1, simd construct, Description] 11702 // The parameter of the simdlen clause must be a constant 11703 // positive integer expression. 11704 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11705 if (Simdlen.isInvalid()) 11706 return nullptr; 11707 return new (Context) 11708 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11709 } 11710 11711 /// Tries to find omp_allocator_handle_t type. 11712 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11713 DSAStackTy *Stack) { 11714 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11715 if (!OMPAllocatorHandleT.isNull()) 11716 return true; 11717 // Build the predefined allocator expressions. 11718 bool ErrorFound = false; 11719 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11720 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11721 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11722 StringRef Allocator = 11723 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11724 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11725 auto *VD = dyn_cast_or_null<ValueDecl>( 11726 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11727 if (!VD) { 11728 ErrorFound = true; 11729 break; 11730 } 11731 QualType AllocatorType = 11732 VD->getType().getNonLValueExprType(S.getASTContext()); 11733 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11734 if (!Res.isUsable()) { 11735 ErrorFound = true; 11736 break; 11737 } 11738 if (OMPAllocatorHandleT.isNull()) 11739 OMPAllocatorHandleT = AllocatorType; 11740 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11741 ErrorFound = true; 11742 break; 11743 } 11744 Stack->setAllocator(AllocatorKind, Res.get()); 11745 } 11746 if (ErrorFound) { 11747 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11748 return false; 11749 } 11750 OMPAllocatorHandleT.addConst(); 11751 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11752 return true; 11753 } 11754 11755 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11756 SourceLocation LParenLoc, 11757 SourceLocation EndLoc) { 11758 // OpenMP [2.11.3, allocate Directive, Description] 11759 // allocator is an expression of omp_allocator_handle_t type. 11760 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11761 return nullptr; 11762 11763 ExprResult Allocator = DefaultLvalueConversion(A); 11764 if (Allocator.isInvalid()) 11765 return nullptr; 11766 Allocator = PerformImplicitConversion(Allocator.get(), 11767 DSAStack->getOMPAllocatorHandleT(), 11768 Sema::AA_Initializing, 11769 /*AllowExplicit=*/true); 11770 if (Allocator.isInvalid()) 11771 return nullptr; 11772 return new (Context) 11773 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11774 } 11775 11776 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11777 SourceLocation StartLoc, 11778 SourceLocation LParenLoc, 11779 SourceLocation EndLoc) { 11780 // OpenMP [2.7.1, loop construct, Description] 11781 // OpenMP [2.8.1, simd construct, Description] 11782 // OpenMP [2.9.6, distribute construct, Description] 11783 // The parameter of the collapse clause must be a constant 11784 // positive integer expression. 11785 ExprResult NumForLoopsResult = 11786 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11787 if (NumForLoopsResult.isInvalid()) 11788 return nullptr; 11789 return new (Context) 11790 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11791 } 11792 11793 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11794 SourceLocation EndLoc, 11795 SourceLocation LParenLoc, 11796 Expr *NumForLoops) { 11797 // OpenMP [2.7.1, loop construct, Description] 11798 // OpenMP [2.8.1, simd construct, Description] 11799 // OpenMP [2.9.6, distribute construct, Description] 11800 // The parameter of the ordered clause must be a constant 11801 // positive integer expression if any. 11802 if (NumForLoops && LParenLoc.isValid()) { 11803 ExprResult NumForLoopsResult = 11804 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11805 if (NumForLoopsResult.isInvalid()) 11806 return nullptr; 11807 NumForLoops = NumForLoopsResult.get(); 11808 } else { 11809 NumForLoops = nullptr; 11810 } 11811 auto *Clause = OMPOrderedClause::Create( 11812 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11813 StartLoc, LParenLoc, EndLoc); 11814 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11815 return Clause; 11816 } 11817 11818 OMPClause *Sema::ActOnOpenMPSimpleClause( 11819 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11820 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11821 OMPClause *Res = nullptr; 11822 switch (Kind) { 11823 case OMPC_default: 11824 Res = 11825 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11826 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11827 break; 11828 case OMPC_proc_bind: 11829 Res = ActOnOpenMPProcBindClause( 11830 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11831 LParenLoc, EndLoc); 11832 break; 11833 case OMPC_atomic_default_mem_order: 11834 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11835 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11836 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11837 break; 11838 case OMPC_if: 11839 case OMPC_final: 11840 case OMPC_num_threads: 11841 case OMPC_safelen: 11842 case OMPC_simdlen: 11843 case OMPC_allocator: 11844 case OMPC_collapse: 11845 case OMPC_schedule: 11846 case OMPC_private: 11847 case OMPC_firstprivate: 11848 case OMPC_lastprivate: 11849 case OMPC_shared: 11850 case OMPC_reduction: 11851 case OMPC_task_reduction: 11852 case OMPC_in_reduction: 11853 case OMPC_linear: 11854 case OMPC_aligned: 11855 case OMPC_copyin: 11856 case OMPC_copyprivate: 11857 case OMPC_ordered: 11858 case OMPC_nowait: 11859 case OMPC_untied: 11860 case OMPC_mergeable: 11861 case OMPC_threadprivate: 11862 case OMPC_allocate: 11863 case OMPC_flush: 11864 case OMPC_read: 11865 case OMPC_write: 11866 case OMPC_update: 11867 case OMPC_capture: 11868 case OMPC_seq_cst: 11869 case OMPC_depend: 11870 case OMPC_device: 11871 case OMPC_threads: 11872 case OMPC_simd: 11873 case OMPC_map: 11874 case OMPC_num_teams: 11875 case OMPC_thread_limit: 11876 case OMPC_priority: 11877 case OMPC_grainsize: 11878 case OMPC_nogroup: 11879 case OMPC_num_tasks: 11880 case OMPC_hint: 11881 case OMPC_dist_schedule: 11882 case OMPC_defaultmap: 11883 case OMPC_unknown: 11884 case OMPC_uniform: 11885 case OMPC_to: 11886 case OMPC_from: 11887 case OMPC_use_device_ptr: 11888 case OMPC_is_device_ptr: 11889 case OMPC_unified_address: 11890 case OMPC_unified_shared_memory: 11891 case OMPC_reverse_offload: 11892 case OMPC_dynamic_allocators: 11893 case OMPC_device_type: 11894 case OMPC_match: 11895 case OMPC_nontemporal: 11896 llvm_unreachable("Clause is not allowed."); 11897 } 11898 return Res; 11899 } 11900 11901 static std::string 11902 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11903 ArrayRef<unsigned> Exclude = llvm::None) { 11904 SmallString<256> Buffer; 11905 llvm::raw_svector_ostream Out(Buffer); 11906 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11907 unsigned Skipped = Exclude.size(); 11908 auto S = Exclude.begin(), E = Exclude.end(); 11909 for (unsigned I = First; I < Last; ++I) { 11910 if (std::find(S, E, I) != E) { 11911 --Skipped; 11912 continue; 11913 } 11914 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11915 if (I == Bound - Skipped) 11916 Out << " or "; 11917 else if (I != Bound + 1 - Skipped) 11918 Out << ", "; 11919 } 11920 return Out.str(); 11921 } 11922 11923 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11924 SourceLocation KindKwLoc, 11925 SourceLocation StartLoc, 11926 SourceLocation LParenLoc, 11927 SourceLocation EndLoc) { 11928 if (Kind == OMPC_DEFAULT_unknown) { 11929 static_assert(OMPC_DEFAULT_unknown > 0, 11930 "OMPC_DEFAULT_unknown not greater than 0"); 11931 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11932 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11933 /*Last=*/OMPC_DEFAULT_unknown) 11934 << getOpenMPClauseName(OMPC_default); 11935 return nullptr; 11936 } 11937 switch (Kind) { 11938 case OMPC_DEFAULT_none: 11939 DSAStack->setDefaultDSANone(KindKwLoc); 11940 break; 11941 case OMPC_DEFAULT_shared: 11942 DSAStack->setDefaultDSAShared(KindKwLoc); 11943 break; 11944 case OMPC_DEFAULT_unknown: 11945 llvm_unreachable("Clause kind is not allowed."); 11946 break; 11947 } 11948 return new (Context) 11949 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11950 } 11951 11952 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11953 SourceLocation KindKwLoc, 11954 SourceLocation StartLoc, 11955 SourceLocation LParenLoc, 11956 SourceLocation EndLoc) { 11957 if (Kind == OMPC_PROC_BIND_unknown) { 11958 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11959 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11960 /*Last=*/OMPC_PROC_BIND_unknown) 11961 << getOpenMPClauseName(OMPC_proc_bind); 11962 return nullptr; 11963 } 11964 return new (Context) 11965 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11966 } 11967 11968 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11969 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11970 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11971 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11972 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11973 << getListOfPossibleValues( 11974 OMPC_atomic_default_mem_order, /*First=*/0, 11975 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11976 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11977 return nullptr; 11978 } 11979 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11980 LParenLoc, EndLoc); 11981 } 11982 11983 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11984 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11985 SourceLocation StartLoc, SourceLocation LParenLoc, 11986 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11987 SourceLocation EndLoc) { 11988 OMPClause *Res = nullptr; 11989 switch (Kind) { 11990 case OMPC_schedule: 11991 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11992 assert(Argument.size() == NumberOfElements && 11993 ArgumentLoc.size() == NumberOfElements); 11994 Res = ActOnOpenMPScheduleClause( 11995 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11996 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11997 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11998 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11999 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12000 break; 12001 case OMPC_if: 12002 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12003 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12004 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12005 DelimLoc, EndLoc); 12006 break; 12007 case OMPC_dist_schedule: 12008 Res = ActOnOpenMPDistScheduleClause( 12009 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12010 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12011 break; 12012 case OMPC_defaultmap: 12013 enum { Modifier, DefaultmapKind }; 12014 Res = ActOnOpenMPDefaultmapClause( 12015 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12016 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12017 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12018 EndLoc); 12019 break; 12020 case OMPC_final: 12021 case OMPC_num_threads: 12022 case OMPC_safelen: 12023 case OMPC_simdlen: 12024 case OMPC_allocator: 12025 case OMPC_collapse: 12026 case OMPC_default: 12027 case OMPC_proc_bind: 12028 case OMPC_private: 12029 case OMPC_firstprivate: 12030 case OMPC_lastprivate: 12031 case OMPC_shared: 12032 case OMPC_reduction: 12033 case OMPC_task_reduction: 12034 case OMPC_in_reduction: 12035 case OMPC_linear: 12036 case OMPC_aligned: 12037 case OMPC_copyin: 12038 case OMPC_copyprivate: 12039 case OMPC_ordered: 12040 case OMPC_nowait: 12041 case OMPC_untied: 12042 case OMPC_mergeable: 12043 case OMPC_threadprivate: 12044 case OMPC_allocate: 12045 case OMPC_flush: 12046 case OMPC_read: 12047 case OMPC_write: 12048 case OMPC_update: 12049 case OMPC_capture: 12050 case OMPC_seq_cst: 12051 case OMPC_depend: 12052 case OMPC_device: 12053 case OMPC_threads: 12054 case OMPC_simd: 12055 case OMPC_map: 12056 case OMPC_num_teams: 12057 case OMPC_thread_limit: 12058 case OMPC_priority: 12059 case OMPC_grainsize: 12060 case OMPC_nogroup: 12061 case OMPC_num_tasks: 12062 case OMPC_hint: 12063 case OMPC_unknown: 12064 case OMPC_uniform: 12065 case OMPC_to: 12066 case OMPC_from: 12067 case OMPC_use_device_ptr: 12068 case OMPC_is_device_ptr: 12069 case OMPC_unified_address: 12070 case OMPC_unified_shared_memory: 12071 case OMPC_reverse_offload: 12072 case OMPC_dynamic_allocators: 12073 case OMPC_atomic_default_mem_order: 12074 case OMPC_device_type: 12075 case OMPC_match: 12076 case OMPC_nontemporal: 12077 llvm_unreachable("Clause is not allowed."); 12078 } 12079 return Res; 12080 } 12081 12082 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12083 OpenMPScheduleClauseModifier M2, 12084 SourceLocation M1Loc, SourceLocation M2Loc) { 12085 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12086 SmallVector<unsigned, 2> Excluded; 12087 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12088 Excluded.push_back(M2); 12089 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12090 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12091 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12092 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12093 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12094 << getListOfPossibleValues(OMPC_schedule, 12095 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12096 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12097 Excluded) 12098 << getOpenMPClauseName(OMPC_schedule); 12099 return true; 12100 } 12101 return false; 12102 } 12103 12104 OMPClause *Sema::ActOnOpenMPScheduleClause( 12105 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12106 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12107 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12108 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12109 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12110 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12111 return nullptr; 12112 // OpenMP, 2.7.1, Loop Construct, Restrictions 12113 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12114 // but not both. 12115 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12116 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12117 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12118 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12119 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12120 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12121 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12122 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12123 return nullptr; 12124 } 12125 if (Kind == OMPC_SCHEDULE_unknown) { 12126 std::string Values; 12127 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12128 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12129 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12130 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12131 Exclude); 12132 } else { 12133 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12134 /*Last=*/OMPC_SCHEDULE_unknown); 12135 } 12136 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12137 << Values << getOpenMPClauseName(OMPC_schedule); 12138 return nullptr; 12139 } 12140 // OpenMP, 2.7.1, Loop Construct, Restrictions 12141 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12142 // schedule(guided). 12143 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12144 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12145 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12146 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12147 diag::err_omp_schedule_nonmonotonic_static); 12148 return nullptr; 12149 } 12150 Expr *ValExpr = ChunkSize; 12151 Stmt *HelperValStmt = nullptr; 12152 if (ChunkSize) { 12153 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12154 !ChunkSize->isInstantiationDependent() && 12155 !ChunkSize->containsUnexpandedParameterPack()) { 12156 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12157 ExprResult Val = 12158 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12159 if (Val.isInvalid()) 12160 return nullptr; 12161 12162 ValExpr = Val.get(); 12163 12164 // OpenMP [2.7.1, Restrictions] 12165 // chunk_size must be a loop invariant integer expression with a positive 12166 // value. 12167 llvm::APSInt Result; 12168 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12169 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12170 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12171 << "schedule" << 1 << ChunkSize->getSourceRange(); 12172 return nullptr; 12173 } 12174 } else if (getOpenMPCaptureRegionForClause( 12175 DSAStack->getCurrentDirective(), OMPC_schedule, 12176 LangOpts.OpenMP) != OMPD_unknown && 12177 !CurContext->isDependentContext()) { 12178 ValExpr = MakeFullExpr(ValExpr).get(); 12179 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12180 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12181 HelperValStmt = buildPreInits(Context, Captures); 12182 } 12183 } 12184 } 12185 12186 return new (Context) 12187 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12188 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12189 } 12190 12191 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12192 SourceLocation StartLoc, 12193 SourceLocation EndLoc) { 12194 OMPClause *Res = nullptr; 12195 switch (Kind) { 12196 case OMPC_ordered: 12197 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12198 break; 12199 case OMPC_nowait: 12200 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12201 break; 12202 case OMPC_untied: 12203 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12204 break; 12205 case OMPC_mergeable: 12206 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12207 break; 12208 case OMPC_read: 12209 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12210 break; 12211 case OMPC_write: 12212 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12213 break; 12214 case OMPC_update: 12215 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12216 break; 12217 case OMPC_capture: 12218 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12219 break; 12220 case OMPC_seq_cst: 12221 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12222 break; 12223 case OMPC_threads: 12224 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12225 break; 12226 case OMPC_simd: 12227 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12228 break; 12229 case OMPC_nogroup: 12230 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12231 break; 12232 case OMPC_unified_address: 12233 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12234 break; 12235 case OMPC_unified_shared_memory: 12236 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12237 break; 12238 case OMPC_reverse_offload: 12239 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12240 break; 12241 case OMPC_dynamic_allocators: 12242 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12243 break; 12244 case OMPC_if: 12245 case OMPC_final: 12246 case OMPC_num_threads: 12247 case OMPC_safelen: 12248 case OMPC_simdlen: 12249 case OMPC_allocator: 12250 case OMPC_collapse: 12251 case OMPC_schedule: 12252 case OMPC_private: 12253 case OMPC_firstprivate: 12254 case OMPC_lastprivate: 12255 case OMPC_shared: 12256 case OMPC_reduction: 12257 case OMPC_task_reduction: 12258 case OMPC_in_reduction: 12259 case OMPC_linear: 12260 case OMPC_aligned: 12261 case OMPC_copyin: 12262 case OMPC_copyprivate: 12263 case OMPC_default: 12264 case OMPC_proc_bind: 12265 case OMPC_threadprivate: 12266 case OMPC_allocate: 12267 case OMPC_flush: 12268 case OMPC_depend: 12269 case OMPC_device: 12270 case OMPC_map: 12271 case OMPC_num_teams: 12272 case OMPC_thread_limit: 12273 case OMPC_priority: 12274 case OMPC_grainsize: 12275 case OMPC_num_tasks: 12276 case OMPC_hint: 12277 case OMPC_dist_schedule: 12278 case OMPC_defaultmap: 12279 case OMPC_unknown: 12280 case OMPC_uniform: 12281 case OMPC_to: 12282 case OMPC_from: 12283 case OMPC_use_device_ptr: 12284 case OMPC_is_device_ptr: 12285 case OMPC_atomic_default_mem_order: 12286 case OMPC_device_type: 12287 case OMPC_match: 12288 case OMPC_nontemporal: 12289 llvm_unreachable("Clause is not allowed."); 12290 } 12291 return Res; 12292 } 12293 12294 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12295 SourceLocation EndLoc) { 12296 DSAStack->setNowaitRegion(); 12297 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12298 } 12299 12300 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12301 SourceLocation EndLoc) { 12302 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12303 } 12304 12305 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12306 SourceLocation EndLoc) { 12307 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12308 } 12309 12310 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12311 SourceLocation EndLoc) { 12312 return new (Context) OMPReadClause(StartLoc, EndLoc); 12313 } 12314 12315 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12316 SourceLocation EndLoc) { 12317 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12318 } 12319 12320 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12321 SourceLocation EndLoc) { 12322 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 12323 } 12324 12325 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12326 SourceLocation EndLoc) { 12327 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12328 } 12329 12330 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12331 SourceLocation EndLoc) { 12332 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12333 } 12334 12335 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12336 SourceLocation EndLoc) { 12337 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12338 } 12339 12340 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12341 SourceLocation EndLoc) { 12342 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12343 } 12344 12345 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12346 SourceLocation EndLoc) { 12347 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12348 } 12349 12350 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12351 SourceLocation EndLoc) { 12352 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12353 } 12354 12355 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12356 SourceLocation EndLoc) { 12357 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12358 } 12359 12360 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12361 SourceLocation EndLoc) { 12362 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12363 } 12364 12365 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12366 SourceLocation EndLoc) { 12367 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12368 } 12369 12370 OMPClause *Sema::ActOnOpenMPVarListClause( 12371 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12372 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12373 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12374 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 12375 OpenMPLinearClauseKind LinKind, 12376 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12377 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 12378 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 12379 SourceLocation StartLoc = Locs.StartLoc; 12380 SourceLocation LParenLoc = Locs.LParenLoc; 12381 SourceLocation EndLoc = Locs.EndLoc; 12382 OMPClause *Res = nullptr; 12383 switch (Kind) { 12384 case OMPC_private: 12385 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12386 break; 12387 case OMPC_firstprivate: 12388 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12389 break; 12390 case OMPC_lastprivate: 12391 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12392 break; 12393 case OMPC_shared: 12394 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12395 break; 12396 case OMPC_reduction: 12397 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12398 EndLoc, ReductionOrMapperIdScopeSpec, 12399 ReductionOrMapperId); 12400 break; 12401 case OMPC_task_reduction: 12402 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12403 EndLoc, ReductionOrMapperIdScopeSpec, 12404 ReductionOrMapperId); 12405 break; 12406 case OMPC_in_reduction: 12407 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12408 EndLoc, ReductionOrMapperIdScopeSpec, 12409 ReductionOrMapperId); 12410 break; 12411 case OMPC_linear: 12412 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 12413 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 12414 break; 12415 case OMPC_aligned: 12416 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12417 ColonLoc, EndLoc); 12418 break; 12419 case OMPC_copyin: 12420 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12421 break; 12422 case OMPC_copyprivate: 12423 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12424 break; 12425 case OMPC_flush: 12426 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12427 break; 12428 case OMPC_depend: 12429 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 12430 StartLoc, LParenLoc, EndLoc); 12431 break; 12432 case OMPC_map: 12433 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 12434 ReductionOrMapperIdScopeSpec, 12435 ReductionOrMapperId, MapType, IsMapTypeImplicit, 12436 DepLinMapLoc, ColonLoc, VarList, Locs); 12437 break; 12438 case OMPC_to: 12439 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12440 ReductionOrMapperId, Locs); 12441 break; 12442 case OMPC_from: 12443 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12444 ReductionOrMapperId, Locs); 12445 break; 12446 case OMPC_use_device_ptr: 12447 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12448 break; 12449 case OMPC_is_device_ptr: 12450 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12451 break; 12452 case OMPC_allocate: 12453 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12454 ColonLoc, EndLoc); 12455 break; 12456 case OMPC_nontemporal: 12457 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 12458 break; 12459 case OMPC_if: 12460 case OMPC_final: 12461 case OMPC_num_threads: 12462 case OMPC_safelen: 12463 case OMPC_simdlen: 12464 case OMPC_allocator: 12465 case OMPC_collapse: 12466 case OMPC_default: 12467 case OMPC_proc_bind: 12468 case OMPC_schedule: 12469 case OMPC_ordered: 12470 case OMPC_nowait: 12471 case OMPC_untied: 12472 case OMPC_mergeable: 12473 case OMPC_threadprivate: 12474 case OMPC_read: 12475 case OMPC_write: 12476 case OMPC_update: 12477 case OMPC_capture: 12478 case OMPC_seq_cst: 12479 case OMPC_device: 12480 case OMPC_threads: 12481 case OMPC_simd: 12482 case OMPC_num_teams: 12483 case OMPC_thread_limit: 12484 case OMPC_priority: 12485 case OMPC_grainsize: 12486 case OMPC_nogroup: 12487 case OMPC_num_tasks: 12488 case OMPC_hint: 12489 case OMPC_dist_schedule: 12490 case OMPC_defaultmap: 12491 case OMPC_unknown: 12492 case OMPC_uniform: 12493 case OMPC_unified_address: 12494 case OMPC_unified_shared_memory: 12495 case OMPC_reverse_offload: 12496 case OMPC_dynamic_allocators: 12497 case OMPC_atomic_default_mem_order: 12498 case OMPC_device_type: 12499 case OMPC_match: 12500 llvm_unreachable("Clause is not allowed."); 12501 } 12502 return Res; 12503 } 12504 12505 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12506 ExprObjectKind OK, SourceLocation Loc) { 12507 ExprResult Res = BuildDeclRefExpr( 12508 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12509 if (!Res.isUsable()) 12510 return ExprError(); 12511 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12512 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12513 if (!Res.isUsable()) 12514 return ExprError(); 12515 } 12516 if (VK != VK_LValue && Res.get()->isGLValue()) { 12517 Res = DefaultLvalueConversion(Res.get()); 12518 if (!Res.isUsable()) 12519 return ExprError(); 12520 } 12521 return Res; 12522 } 12523 12524 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12525 SourceLocation StartLoc, 12526 SourceLocation LParenLoc, 12527 SourceLocation EndLoc) { 12528 SmallVector<Expr *, 8> Vars; 12529 SmallVector<Expr *, 8> PrivateCopies; 12530 for (Expr *RefExpr : VarList) { 12531 assert(RefExpr && "NULL expr in OpenMP private clause."); 12532 SourceLocation ELoc; 12533 SourceRange ERange; 12534 Expr *SimpleRefExpr = RefExpr; 12535 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12536 if (Res.second) { 12537 // It will be analyzed later. 12538 Vars.push_back(RefExpr); 12539 PrivateCopies.push_back(nullptr); 12540 } 12541 ValueDecl *D = Res.first; 12542 if (!D) 12543 continue; 12544 12545 QualType Type = D->getType(); 12546 auto *VD = dyn_cast<VarDecl>(D); 12547 12548 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12549 // A variable that appears in a private clause must not have an incomplete 12550 // type or a reference type. 12551 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12552 continue; 12553 Type = Type.getNonReferenceType(); 12554 12555 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12556 // A variable that is privatized must not have a const-qualified type 12557 // unless it is of class type with a mutable member. This restriction does 12558 // not apply to the firstprivate clause. 12559 // 12560 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12561 // A variable that appears in a private clause must not have a 12562 // const-qualified type unless it is of class type with a mutable member. 12563 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12564 continue; 12565 12566 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12567 // in a Construct] 12568 // Variables with the predetermined data-sharing attributes may not be 12569 // listed in data-sharing attributes clauses, except for the cases 12570 // listed below. For these exceptions only, listing a predetermined 12571 // variable in a data-sharing attribute clause is allowed and overrides 12572 // the variable's predetermined data-sharing attributes. 12573 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12574 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12575 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12576 << getOpenMPClauseName(OMPC_private); 12577 reportOriginalDsa(*this, DSAStack, D, DVar); 12578 continue; 12579 } 12580 12581 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12582 // Variably modified types are not supported for tasks. 12583 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12584 isOpenMPTaskingDirective(CurrDir)) { 12585 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12586 << getOpenMPClauseName(OMPC_private) << Type 12587 << getOpenMPDirectiveName(CurrDir); 12588 bool IsDecl = 12589 !VD || 12590 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12591 Diag(D->getLocation(), 12592 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12593 << D; 12594 continue; 12595 } 12596 12597 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12598 // A list item cannot appear in both a map clause and a data-sharing 12599 // attribute clause on the same construct 12600 // 12601 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12602 // A list item cannot appear in both a map clause and a data-sharing 12603 // attribute clause on the same construct unless the construct is a 12604 // combined construct. 12605 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12606 CurrDir == OMPD_target) { 12607 OpenMPClauseKind ConflictKind; 12608 if (DSAStack->checkMappableExprComponentListsForDecl( 12609 VD, /*CurrentRegionOnly=*/true, 12610 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12611 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12612 ConflictKind = WhereFoundClauseKind; 12613 return true; 12614 })) { 12615 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12616 << getOpenMPClauseName(OMPC_private) 12617 << getOpenMPClauseName(ConflictKind) 12618 << getOpenMPDirectiveName(CurrDir); 12619 reportOriginalDsa(*this, DSAStack, D, DVar); 12620 continue; 12621 } 12622 } 12623 12624 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12625 // A variable of class type (or array thereof) that appears in a private 12626 // clause requires an accessible, unambiguous default constructor for the 12627 // class type. 12628 // Generate helper private variable and initialize it with the default 12629 // value. The address of the original variable is replaced by the address of 12630 // the new private variable in CodeGen. This new variable is not added to 12631 // IdResolver, so the code in the OpenMP region uses original variable for 12632 // proper diagnostics. 12633 Type = Type.getUnqualifiedType(); 12634 VarDecl *VDPrivate = 12635 buildVarDecl(*this, ELoc, Type, D->getName(), 12636 D->hasAttrs() ? &D->getAttrs() : nullptr, 12637 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12638 ActOnUninitializedDecl(VDPrivate); 12639 if (VDPrivate->isInvalidDecl()) 12640 continue; 12641 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12642 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12643 12644 DeclRefExpr *Ref = nullptr; 12645 if (!VD && !CurContext->isDependentContext()) 12646 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12647 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12648 Vars.push_back((VD || CurContext->isDependentContext()) 12649 ? RefExpr->IgnoreParens() 12650 : Ref); 12651 PrivateCopies.push_back(VDPrivateRefExpr); 12652 } 12653 12654 if (Vars.empty()) 12655 return nullptr; 12656 12657 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12658 PrivateCopies); 12659 } 12660 12661 namespace { 12662 class DiagsUninitializedSeveretyRAII { 12663 private: 12664 DiagnosticsEngine &Diags; 12665 SourceLocation SavedLoc; 12666 bool IsIgnored = false; 12667 12668 public: 12669 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12670 bool IsIgnored) 12671 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12672 if (!IsIgnored) { 12673 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12674 /*Map*/ diag::Severity::Ignored, Loc); 12675 } 12676 } 12677 ~DiagsUninitializedSeveretyRAII() { 12678 if (!IsIgnored) 12679 Diags.popMappings(SavedLoc); 12680 } 12681 }; 12682 } 12683 12684 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12685 SourceLocation StartLoc, 12686 SourceLocation LParenLoc, 12687 SourceLocation EndLoc) { 12688 SmallVector<Expr *, 8> Vars; 12689 SmallVector<Expr *, 8> PrivateCopies; 12690 SmallVector<Expr *, 8> Inits; 12691 SmallVector<Decl *, 4> ExprCaptures; 12692 bool IsImplicitClause = 12693 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12694 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12695 12696 for (Expr *RefExpr : VarList) { 12697 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12698 SourceLocation ELoc; 12699 SourceRange ERange; 12700 Expr *SimpleRefExpr = RefExpr; 12701 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12702 if (Res.second) { 12703 // It will be analyzed later. 12704 Vars.push_back(RefExpr); 12705 PrivateCopies.push_back(nullptr); 12706 Inits.push_back(nullptr); 12707 } 12708 ValueDecl *D = Res.first; 12709 if (!D) 12710 continue; 12711 12712 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12713 QualType Type = D->getType(); 12714 auto *VD = dyn_cast<VarDecl>(D); 12715 12716 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12717 // A variable that appears in a private clause must not have an incomplete 12718 // type or a reference type. 12719 if (RequireCompleteType(ELoc, Type, 12720 diag::err_omp_firstprivate_incomplete_type)) 12721 continue; 12722 Type = Type.getNonReferenceType(); 12723 12724 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12725 // A variable of class type (or array thereof) that appears in a private 12726 // clause requires an accessible, unambiguous copy constructor for the 12727 // class type. 12728 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12729 12730 // If an implicit firstprivate variable found it was checked already. 12731 DSAStackTy::DSAVarData TopDVar; 12732 if (!IsImplicitClause) { 12733 DSAStackTy::DSAVarData DVar = 12734 DSAStack->getTopDSA(D, /*FromParent=*/false); 12735 TopDVar = DVar; 12736 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12737 bool IsConstant = ElemType.isConstant(Context); 12738 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12739 // A list item that specifies a given variable may not appear in more 12740 // than one clause on the same directive, except that a variable may be 12741 // specified in both firstprivate and lastprivate clauses. 12742 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12743 // A list item may appear in a firstprivate or lastprivate clause but not 12744 // both. 12745 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12746 (isOpenMPDistributeDirective(CurrDir) || 12747 DVar.CKind != OMPC_lastprivate) && 12748 DVar.RefExpr) { 12749 Diag(ELoc, diag::err_omp_wrong_dsa) 12750 << getOpenMPClauseName(DVar.CKind) 12751 << getOpenMPClauseName(OMPC_firstprivate); 12752 reportOriginalDsa(*this, DSAStack, D, DVar); 12753 continue; 12754 } 12755 12756 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12757 // in a Construct] 12758 // Variables with the predetermined data-sharing attributes may not be 12759 // listed in data-sharing attributes clauses, except for the cases 12760 // listed below. For these exceptions only, listing a predetermined 12761 // variable in a data-sharing attribute clause is allowed and overrides 12762 // the variable's predetermined data-sharing attributes. 12763 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12764 // in a Construct, C/C++, p.2] 12765 // Variables with const-qualified type having no mutable member may be 12766 // listed in a firstprivate clause, even if they are static data members. 12767 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12768 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12769 Diag(ELoc, diag::err_omp_wrong_dsa) 12770 << getOpenMPClauseName(DVar.CKind) 12771 << getOpenMPClauseName(OMPC_firstprivate); 12772 reportOriginalDsa(*this, DSAStack, D, DVar); 12773 continue; 12774 } 12775 12776 // OpenMP [2.9.3.4, Restrictions, p.2] 12777 // A list item that is private within a parallel region must not appear 12778 // in a firstprivate clause on a worksharing construct if any of the 12779 // worksharing regions arising from the worksharing construct ever bind 12780 // to any of the parallel regions arising from the parallel construct. 12781 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12782 // A list item that is private within a teams region must not appear in a 12783 // firstprivate clause on a distribute construct if any of the distribute 12784 // regions arising from the distribute construct ever bind to any of the 12785 // teams regions arising from the teams construct. 12786 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12787 // A list item that appears in a reduction clause of a teams construct 12788 // must not appear in a firstprivate clause on a distribute construct if 12789 // any of the distribute regions arising from the distribute construct 12790 // ever bind to any of the teams regions arising from the teams construct. 12791 if ((isOpenMPWorksharingDirective(CurrDir) || 12792 isOpenMPDistributeDirective(CurrDir)) && 12793 !isOpenMPParallelDirective(CurrDir) && 12794 !isOpenMPTeamsDirective(CurrDir)) { 12795 DVar = DSAStack->getImplicitDSA(D, true); 12796 if (DVar.CKind != OMPC_shared && 12797 (isOpenMPParallelDirective(DVar.DKind) || 12798 isOpenMPTeamsDirective(DVar.DKind) || 12799 DVar.DKind == OMPD_unknown)) { 12800 Diag(ELoc, diag::err_omp_required_access) 12801 << getOpenMPClauseName(OMPC_firstprivate) 12802 << getOpenMPClauseName(OMPC_shared); 12803 reportOriginalDsa(*this, DSAStack, D, DVar); 12804 continue; 12805 } 12806 } 12807 // OpenMP [2.9.3.4, Restrictions, p.3] 12808 // A list item that appears in a reduction clause of a parallel construct 12809 // must not appear in a firstprivate clause on a worksharing or task 12810 // construct if any of the worksharing or task regions arising from the 12811 // worksharing or task construct ever bind to any of the parallel regions 12812 // arising from the parallel construct. 12813 // OpenMP [2.9.3.4, Restrictions, p.4] 12814 // A list item that appears in a reduction clause in worksharing 12815 // construct must not appear in a firstprivate clause in a task construct 12816 // encountered during execution of any of the worksharing regions arising 12817 // from the worksharing construct. 12818 if (isOpenMPTaskingDirective(CurrDir)) { 12819 DVar = DSAStack->hasInnermostDSA( 12820 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12821 [](OpenMPDirectiveKind K) { 12822 return isOpenMPParallelDirective(K) || 12823 isOpenMPWorksharingDirective(K) || 12824 isOpenMPTeamsDirective(K); 12825 }, 12826 /*FromParent=*/true); 12827 if (DVar.CKind == OMPC_reduction && 12828 (isOpenMPParallelDirective(DVar.DKind) || 12829 isOpenMPWorksharingDirective(DVar.DKind) || 12830 isOpenMPTeamsDirective(DVar.DKind))) { 12831 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12832 << getOpenMPDirectiveName(DVar.DKind); 12833 reportOriginalDsa(*this, DSAStack, D, DVar); 12834 continue; 12835 } 12836 } 12837 12838 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12839 // A list item cannot appear in both a map clause and a data-sharing 12840 // attribute clause on the same construct 12841 // 12842 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12843 // A list item cannot appear in both a map clause and a data-sharing 12844 // attribute clause on the same construct unless the construct is a 12845 // combined construct. 12846 if ((LangOpts.OpenMP <= 45 && 12847 isOpenMPTargetExecutionDirective(CurrDir)) || 12848 CurrDir == OMPD_target) { 12849 OpenMPClauseKind ConflictKind; 12850 if (DSAStack->checkMappableExprComponentListsForDecl( 12851 VD, /*CurrentRegionOnly=*/true, 12852 [&ConflictKind]( 12853 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12854 OpenMPClauseKind WhereFoundClauseKind) { 12855 ConflictKind = WhereFoundClauseKind; 12856 return true; 12857 })) { 12858 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12859 << getOpenMPClauseName(OMPC_firstprivate) 12860 << getOpenMPClauseName(ConflictKind) 12861 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12862 reportOriginalDsa(*this, DSAStack, D, DVar); 12863 continue; 12864 } 12865 } 12866 } 12867 12868 // Variably modified types are not supported for tasks. 12869 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12870 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12871 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12872 << getOpenMPClauseName(OMPC_firstprivate) << Type 12873 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12874 bool IsDecl = 12875 !VD || 12876 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12877 Diag(D->getLocation(), 12878 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12879 << D; 12880 continue; 12881 } 12882 12883 Type = Type.getUnqualifiedType(); 12884 VarDecl *VDPrivate = 12885 buildVarDecl(*this, ELoc, Type, D->getName(), 12886 D->hasAttrs() ? &D->getAttrs() : nullptr, 12887 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12888 // Generate helper private variable and initialize it with the value of the 12889 // original variable. The address of the original variable is replaced by 12890 // the address of the new private variable in the CodeGen. This new variable 12891 // is not added to IdResolver, so the code in the OpenMP region uses 12892 // original variable for proper diagnostics and variable capturing. 12893 Expr *VDInitRefExpr = nullptr; 12894 // For arrays generate initializer for single element and replace it by the 12895 // original array element in CodeGen. 12896 if (Type->isArrayType()) { 12897 VarDecl *VDInit = 12898 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12899 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12900 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12901 ElemType = ElemType.getUnqualifiedType(); 12902 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12903 ".firstprivate.temp"); 12904 InitializedEntity Entity = 12905 InitializedEntity::InitializeVariable(VDInitTemp); 12906 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12907 12908 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12909 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12910 if (Result.isInvalid()) 12911 VDPrivate->setInvalidDecl(); 12912 else 12913 VDPrivate->setInit(Result.getAs<Expr>()); 12914 // Remove temp variable declaration. 12915 Context.Deallocate(VDInitTemp); 12916 } else { 12917 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12918 ".firstprivate.temp"); 12919 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12920 RefExpr->getExprLoc()); 12921 AddInitializerToDecl(VDPrivate, 12922 DefaultLvalueConversion(VDInitRefExpr).get(), 12923 /*DirectInit=*/false); 12924 } 12925 if (VDPrivate->isInvalidDecl()) { 12926 if (IsImplicitClause) { 12927 Diag(RefExpr->getExprLoc(), 12928 diag::note_omp_task_predetermined_firstprivate_here); 12929 } 12930 continue; 12931 } 12932 CurContext->addDecl(VDPrivate); 12933 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12934 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12935 RefExpr->getExprLoc()); 12936 DeclRefExpr *Ref = nullptr; 12937 if (!VD && !CurContext->isDependentContext()) { 12938 if (TopDVar.CKind == OMPC_lastprivate) { 12939 Ref = TopDVar.PrivateCopy; 12940 } else { 12941 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12942 if (!isOpenMPCapturedDecl(D)) 12943 ExprCaptures.push_back(Ref->getDecl()); 12944 } 12945 } 12946 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12947 Vars.push_back((VD || CurContext->isDependentContext()) 12948 ? RefExpr->IgnoreParens() 12949 : Ref); 12950 PrivateCopies.push_back(VDPrivateRefExpr); 12951 Inits.push_back(VDInitRefExpr); 12952 } 12953 12954 if (Vars.empty()) 12955 return nullptr; 12956 12957 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12958 Vars, PrivateCopies, Inits, 12959 buildPreInits(Context, ExprCaptures)); 12960 } 12961 12962 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12963 SourceLocation StartLoc, 12964 SourceLocation LParenLoc, 12965 SourceLocation EndLoc) { 12966 SmallVector<Expr *, 8> Vars; 12967 SmallVector<Expr *, 8> SrcExprs; 12968 SmallVector<Expr *, 8> DstExprs; 12969 SmallVector<Expr *, 8> AssignmentOps; 12970 SmallVector<Decl *, 4> ExprCaptures; 12971 SmallVector<Expr *, 4> ExprPostUpdates; 12972 for (Expr *RefExpr : VarList) { 12973 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12974 SourceLocation ELoc; 12975 SourceRange ERange; 12976 Expr *SimpleRefExpr = RefExpr; 12977 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12978 if (Res.second) { 12979 // It will be analyzed later. 12980 Vars.push_back(RefExpr); 12981 SrcExprs.push_back(nullptr); 12982 DstExprs.push_back(nullptr); 12983 AssignmentOps.push_back(nullptr); 12984 } 12985 ValueDecl *D = Res.first; 12986 if (!D) 12987 continue; 12988 12989 QualType Type = D->getType(); 12990 auto *VD = dyn_cast<VarDecl>(D); 12991 12992 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12993 // A variable that appears in a lastprivate clause must not have an 12994 // incomplete type or a reference type. 12995 if (RequireCompleteType(ELoc, Type, 12996 diag::err_omp_lastprivate_incomplete_type)) 12997 continue; 12998 Type = Type.getNonReferenceType(); 12999 13000 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13001 // A variable that is privatized must not have a const-qualified type 13002 // unless it is of class type with a mutable member. This restriction does 13003 // not apply to the firstprivate clause. 13004 // 13005 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13006 // A variable that appears in a lastprivate clause must not have a 13007 // const-qualified type unless it is of class type with a mutable member. 13008 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13009 continue; 13010 13011 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13012 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13013 // in a Construct] 13014 // Variables with the predetermined data-sharing attributes may not be 13015 // listed in data-sharing attributes clauses, except for the cases 13016 // listed below. 13017 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13018 // A list item may appear in a firstprivate or lastprivate clause but not 13019 // both. 13020 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13021 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13022 (isOpenMPDistributeDirective(CurrDir) || 13023 DVar.CKind != OMPC_firstprivate) && 13024 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13025 Diag(ELoc, diag::err_omp_wrong_dsa) 13026 << getOpenMPClauseName(DVar.CKind) 13027 << getOpenMPClauseName(OMPC_lastprivate); 13028 reportOriginalDsa(*this, DSAStack, D, DVar); 13029 continue; 13030 } 13031 13032 // OpenMP [2.14.3.5, Restrictions, p.2] 13033 // A list item that is private within a parallel region, or that appears in 13034 // the reduction clause of a parallel construct, must not appear in a 13035 // lastprivate clause on a worksharing construct if any of the corresponding 13036 // worksharing regions ever binds to any of the corresponding parallel 13037 // regions. 13038 DSAStackTy::DSAVarData TopDVar = DVar; 13039 if (isOpenMPWorksharingDirective(CurrDir) && 13040 !isOpenMPParallelDirective(CurrDir) && 13041 !isOpenMPTeamsDirective(CurrDir)) { 13042 DVar = DSAStack->getImplicitDSA(D, true); 13043 if (DVar.CKind != OMPC_shared) { 13044 Diag(ELoc, diag::err_omp_required_access) 13045 << getOpenMPClauseName(OMPC_lastprivate) 13046 << getOpenMPClauseName(OMPC_shared); 13047 reportOriginalDsa(*this, DSAStack, D, DVar); 13048 continue; 13049 } 13050 } 13051 13052 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13053 // A variable of class type (or array thereof) that appears in a 13054 // lastprivate clause requires an accessible, unambiguous default 13055 // constructor for the class type, unless the list item is also specified 13056 // in a firstprivate clause. 13057 // A variable of class type (or array thereof) that appears in a 13058 // lastprivate clause requires an accessible, unambiguous copy assignment 13059 // operator for the class type. 13060 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13061 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13062 Type.getUnqualifiedType(), ".lastprivate.src", 13063 D->hasAttrs() ? &D->getAttrs() : nullptr); 13064 DeclRefExpr *PseudoSrcExpr = 13065 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13066 VarDecl *DstVD = 13067 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13068 D->hasAttrs() ? &D->getAttrs() : nullptr); 13069 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13070 // For arrays generate assignment operation for single element and replace 13071 // it by the original array element in CodeGen. 13072 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13073 PseudoDstExpr, PseudoSrcExpr); 13074 if (AssignmentOp.isInvalid()) 13075 continue; 13076 AssignmentOp = 13077 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13078 if (AssignmentOp.isInvalid()) 13079 continue; 13080 13081 DeclRefExpr *Ref = nullptr; 13082 if (!VD && !CurContext->isDependentContext()) { 13083 if (TopDVar.CKind == OMPC_firstprivate) { 13084 Ref = TopDVar.PrivateCopy; 13085 } else { 13086 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13087 if (!isOpenMPCapturedDecl(D)) 13088 ExprCaptures.push_back(Ref->getDecl()); 13089 } 13090 if (TopDVar.CKind == OMPC_firstprivate || 13091 (!isOpenMPCapturedDecl(D) && 13092 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13093 ExprResult RefRes = DefaultLvalueConversion(Ref); 13094 if (!RefRes.isUsable()) 13095 continue; 13096 ExprResult PostUpdateRes = 13097 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13098 RefRes.get()); 13099 if (!PostUpdateRes.isUsable()) 13100 continue; 13101 ExprPostUpdates.push_back( 13102 IgnoredValueConversions(PostUpdateRes.get()).get()); 13103 } 13104 } 13105 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13106 Vars.push_back((VD || CurContext->isDependentContext()) 13107 ? RefExpr->IgnoreParens() 13108 : Ref); 13109 SrcExprs.push_back(PseudoSrcExpr); 13110 DstExprs.push_back(PseudoDstExpr); 13111 AssignmentOps.push_back(AssignmentOp.get()); 13112 } 13113 13114 if (Vars.empty()) 13115 return nullptr; 13116 13117 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13118 Vars, SrcExprs, DstExprs, AssignmentOps, 13119 buildPreInits(Context, ExprCaptures), 13120 buildPostUpdate(*this, ExprPostUpdates)); 13121 } 13122 13123 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13124 SourceLocation StartLoc, 13125 SourceLocation LParenLoc, 13126 SourceLocation EndLoc) { 13127 SmallVector<Expr *, 8> Vars; 13128 for (Expr *RefExpr : VarList) { 13129 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13130 SourceLocation ELoc; 13131 SourceRange ERange; 13132 Expr *SimpleRefExpr = RefExpr; 13133 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13134 if (Res.second) { 13135 // It will be analyzed later. 13136 Vars.push_back(RefExpr); 13137 } 13138 ValueDecl *D = Res.first; 13139 if (!D) 13140 continue; 13141 13142 auto *VD = dyn_cast<VarDecl>(D); 13143 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13144 // in a Construct] 13145 // Variables with the predetermined data-sharing attributes may not be 13146 // listed in data-sharing attributes clauses, except for the cases 13147 // listed below. For these exceptions only, listing a predetermined 13148 // variable in a data-sharing attribute clause is allowed and overrides 13149 // the variable's predetermined data-sharing attributes. 13150 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13151 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13152 DVar.RefExpr) { 13153 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13154 << getOpenMPClauseName(OMPC_shared); 13155 reportOriginalDsa(*this, DSAStack, D, DVar); 13156 continue; 13157 } 13158 13159 DeclRefExpr *Ref = nullptr; 13160 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13161 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13162 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13163 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13164 ? RefExpr->IgnoreParens() 13165 : Ref); 13166 } 13167 13168 if (Vars.empty()) 13169 return nullptr; 13170 13171 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13172 } 13173 13174 namespace { 13175 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13176 DSAStackTy *Stack; 13177 13178 public: 13179 bool VisitDeclRefExpr(DeclRefExpr *E) { 13180 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13181 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13182 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13183 return false; 13184 if (DVar.CKind != OMPC_unknown) 13185 return true; 13186 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13187 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13188 /*FromParent=*/true); 13189 return DVarPrivate.CKind != OMPC_unknown; 13190 } 13191 return false; 13192 } 13193 bool VisitStmt(Stmt *S) { 13194 for (Stmt *Child : S->children()) { 13195 if (Child && Visit(Child)) 13196 return true; 13197 } 13198 return false; 13199 } 13200 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13201 }; 13202 } // namespace 13203 13204 namespace { 13205 // Transform MemberExpression for specified FieldDecl of current class to 13206 // DeclRefExpr to specified OMPCapturedExprDecl. 13207 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13208 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13209 ValueDecl *Field = nullptr; 13210 DeclRefExpr *CapturedExpr = nullptr; 13211 13212 public: 13213 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13214 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13215 13216 ExprResult TransformMemberExpr(MemberExpr *E) { 13217 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13218 E->getMemberDecl() == Field) { 13219 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13220 return CapturedExpr; 13221 } 13222 return BaseTransform::TransformMemberExpr(E); 13223 } 13224 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13225 }; 13226 } // namespace 13227 13228 template <typename T, typename U> 13229 static T filterLookupForUDReductionAndMapper( 13230 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13231 for (U &Set : Lookups) { 13232 for (auto *D : Set) { 13233 if (T Res = Gen(cast<ValueDecl>(D))) 13234 return Res; 13235 } 13236 } 13237 return T(); 13238 } 13239 13240 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13241 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13242 13243 for (auto RD : D->redecls()) { 13244 // Don't bother with extra checks if we already know this one isn't visible. 13245 if (RD == D) 13246 continue; 13247 13248 auto ND = cast<NamedDecl>(RD); 13249 if (LookupResult::isVisible(SemaRef, ND)) 13250 return ND; 13251 } 13252 13253 return nullptr; 13254 } 13255 13256 static void 13257 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13258 SourceLocation Loc, QualType Ty, 13259 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13260 // Find all of the associated namespaces and classes based on the 13261 // arguments we have. 13262 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13263 Sema::AssociatedClassSet AssociatedClasses; 13264 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13265 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13266 AssociatedClasses); 13267 13268 // C++ [basic.lookup.argdep]p3: 13269 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13270 // and let Y be the lookup set produced by argument dependent 13271 // lookup (defined as follows). If X contains [...] then Y is 13272 // empty. Otherwise Y is the set of declarations found in the 13273 // namespaces associated with the argument types as described 13274 // below. The set of declarations found by the lookup of the name 13275 // is the union of X and Y. 13276 // 13277 // Here, we compute Y and add its members to the overloaded 13278 // candidate set. 13279 for (auto *NS : AssociatedNamespaces) { 13280 // When considering an associated namespace, the lookup is the 13281 // same as the lookup performed when the associated namespace is 13282 // used as a qualifier (3.4.3.2) except that: 13283 // 13284 // -- Any using-directives in the associated namespace are 13285 // ignored. 13286 // 13287 // -- Any namespace-scope friend functions declared in 13288 // associated classes are visible within their respective 13289 // namespaces even if they are not visible during an ordinary 13290 // lookup (11.4). 13291 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13292 for (auto *D : R) { 13293 auto *Underlying = D; 13294 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13295 Underlying = USD->getTargetDecl(); 13296 13297 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13298 !isa<OMPDeclareMapperDecl>(Underlying)) 13299 continue; 13300 13301 if (!SemaRef.isVisible(D)) { 13302 D = findAcceptableDecl(SemaRef, D); 13303 if (!D) 13304 continue; 13305 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13306 Underlying = USD->getTargetDecl(); 13307 } 13308 Lookups.emplace_back(); 13309 Lookups.back().addDecl(Underlying); 13310 } 13311 } 13312 } 13313 13314 static ExprResult 13315 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13316 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13317 const DeclarationNameInfo &ReductionId, QualType Ty, 13318 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13319 if (ReductionIdScopeSpec.isInvalid()) 13320 return ExprError(); 13321 SmallVector<UnresolvedSet<8>, 4> Lookups; 13322 if (S) { 13323 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13324 Lookup.suppressDiagnostics(); 13325 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13326 NamedDecl *D = Lookup.getRepresentativeDecl(); 13327 do { 13328 S = S->getParent(); 13329 } while (S && !S->isDeclScope(D)); 13330 if (S) 13331 S = S->getParent(); 13332 Lookups.emplace_back(); 13333 Lookups.back().append(Lookup.begin(), Lookup.end()); 13334 Lookup.clear(); 13335 } 13336 } else if (auto *ULE = 13337 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13338 Lookups.push_back(UnresolvedSet<8>()); 13339 Decl *PrevD = nullptr; 13340 for (NamedDecl *D : ULE->decls()) { 13341 if (D == PrevD) 13342 Lookups.push_back(UnresolvedSet<8>()); 13343 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13344 Lookups.back().addDecl(DRD); 13345 PrevD = D; 13346 } 13347 } 13348 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13349 Ty->isInstantiationDependentType() || 13350 Ty->containsUnexpandedParameterPack() || 13351 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13352 return !D->isInvalidDecl() && 13353 (D->getType()->isDependentType() || 13354 D->getType()->isInstantiationDependentType() || 13355 D->getType()->containsUnexpandedParameterPack()); 13356 })) { 13357 UnresolvedSet<8> ResSet; 13358 for (const UnresolvedSet<8> &Set : Lookups) { 13359 if (Set.empty()) 13360 continue; 13361 ResSet.append(Set.begin(), Set.end()); 13362 // The last item marks the end of all declarations at the specified scope. 13363 ResSet.addDecl(Set[Set.size() - 1]); 13364 } 13365 return UnresolvedLookupExpr::Create( 13366 SemaRef.Context, /*NamingClass=*/nullptr, 13367 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13368 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13369 } 13370 // Lookup inside the classes. 13371 // C++ [over.match.oper]p3: 13372 // For a unary operator @ with an operand of a type whose 13373 // cv-unqualified version is T1, and for a binary operator @ with 13374 // a left operand of a type whose cv-unqualified version is T1 and 13375 // a right operand of a type whose cv-unqualified version is T2, 13376 // three sets of candidate functions, designated member 13377 // candidates, non-member candidates and built-in candidates, are 13378 // constructed as follows: 13379 // -- If T1 is a complete class type or a class currently being 13380 // defined, the set of member candidates is the result of the 13381 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13382 // the set of member candidates is empty. 13383 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13384 Lookup.suppressDiagnostics(); 13385 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13386 // Complete the type if it can be completed. 13387 // If the type is neither complete nor being defined, bail out now. 13388 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13389 TyRec->getDecl()->getDefinition()) { 13390 Lookup.clear(); 13391 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13392 if (Lookup.empty()) { 13393 Lookups.emplace_back(); 13394 Lookups.back().append(Lookup.begin(), Lookup.end()); 13395 } 13396 } 13397 } 13398 // Perform ADL. 13399 if (SemaRef.getLangOpts().CPlusPlus) 13400 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13401 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13402 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13403 if (!D->isInvalidDecl() && 13404 SemaRef.Context.hasSameType(D->getType(), Ty)) 13405 return D; 13406 return nullptr; 13407 })) 13408 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13409 VK_LValue, Loc); 13410 if (SemaRef.getLangOpts().CPlusPlus) { 13411 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13412 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13413 if (!D->isInvalidDecl() && 13414 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13415 !Ty.isMoreQualifiedThan(D->getType())) 13416 return D; 13417 return nullptr; 13418 })) { 13419 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13420 /*DetectVirtual=*/false); 13421 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13422 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13423 VD->getType().getUnqualifiedType()))) { 13424 if (SemaRef.CheckBaseClassAccess( 13425 Loc, VD->getType(), Ty, Paths.front(), 13426 /*DiagID=*/0) != Sema::AR_inaccessible) { 13427 SemaRef.BuildBasePathArray(Paths, BasePath); 13428 return SemaRef.BuildDeclRefExpr( 13429 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13430 } 13431 } 13432 } 13433 } 13434 } 13435 if (ReductionIdScopeSpec.isSet()) { 13436 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 13437 return ExprError(); 13438 } 13439 return ExprEmpty(); 13440 } 13441 13442 namespace { 13443 /// Data for the reduction-based clauses. 13444 struct ReductionData { 13445 /// List of original reduction items. 13446 SmallVector<Expr *, 8> Vars; 13447 /// List of private copies of the reduction items. 13448 SmallVector<Expr *, 8> Privates; 13449 /// LHS expressions for the reduction_op expressions. 13450 SmallVector<Expr *, 8> LHSs; 13451 /// RHS expressions for the reduction_op expressions. 13452 SmallVector<Expr *, 8> RHSs; 13453 /// Reduction operation expression. 13454 SmallVector<Expr *, 8> ReductionOps; 13455 /// Taskgroup descriptors for the corresponding reduction items in 13456 /// in_reduction clauses. 13457 SmallVector<Expr *, 8> TaskgroupDescriptors; 13458 /// List of captures for clause. 13459 SmallVector<Decl *, 4> ExprCaptures; 13460 /// List of postupdate expressions. 13461 SmallVector<Expr *, 4> ExprPostUpdates; 13462 ReductionData() = delete; 13463 /// Reserves required memory for the reduction data. 13464 ReductionData(unsigned Size) { 13465 Vars.reserve(Size); 13466 Privates.reserve(Size); 13467 LHSs.reserve(Size); 13468 RHSs.reserve(Size); 13469 ReductionOps.reserve(Size); 13470 TaskgroupDescriptors.reserve(Size); 13471 ExprCaptures.reserve(Size); 13472 ExprPostUpdates.reserve(Size); 13473 } 13474 /// Stores reduction item and reduction operation only (required for dependent 13475 /// reduction item). 13476 void push(Expr *Item, Expr *ReductionOp) { 13477 Vars.emplace_back(Item); 13478 Privates.emplace_back(nullptr); 13479 LHSs.emplace_back(nullptr); 13480 RHSs.emplace_back(nullptr); 13481 ReductionOps.emplace_back(ReductionOp); 13482 TaskgroupDescriptors.emplace_back(nullptr); 13483 } 13484 /// Stores reduction data. 13485 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13486 Expr *TaskgroupDescriptor) { 13487 Vars.emplace_back(Item); 13488 Privates.emplace_back(Private); 13489 LHSs.emplace_back(LHS); 13490 RHSs.emplace_back(RHS); 13491 ReductionOps.emplace_back(ReductionOp); 13492 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13493 } 13494 }; 13495 } // namespace 13496 13497 static bool checkOMPArraySectionConstantForReduction( 13498 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13499 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13500 const Expr *Length = OASE->getLength(); 13501 if (Length == nullptr) { 13502 // For array sections of the form [1:] or [:], we would need to analyze 13503 // the lower bound... 13504 if (OASE->getColonLoc().isValid()) 13505 return false; 13506 13507 // This is an array subscript which has implicit length 1! 13508 SingleElement = true; 13509 ArraySizes.push_back(llvm::APSInt::get(1)); 13510 } else { 13511 Expr::EvalResult Result; 13512 if (!Length->EvaluateAsInt(Result, Context)) 13513 return false; 13514 13515 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13516 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13517 ArraySizes.push_back(ConstantLengthValue); 13518 } 13519 13520 // Get the base of this array section and walk up from there. 13521 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13522 13523 // We require length = 1 for all array sections except the right-most to 13524 // guarantee that the memory region is contiguous and has no holes in it. 13525 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13526 Length = TempOASE->getLength(); 13527 if (Length == nullptr) { 13528 // For array sections of the form [1:] or [:], we would need to analyze 13529 // the lower bound... 13530 if (OASE->getColonLoc().isValid()) 13531 return false; 13532 13533 // This is an array subscript which has implicit length 1! 13534 ArraySizes.push_back(llvm::APSInt::get(1)); 13535 } else { 13536 Expr::EvalResult Result; 13537 if (!Length->EvaluateAsInt(Result, Context)) 13538 return false; 13539 13540 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13541 if (ConstantLengthValue.getSExtValue() != 1) 13542 return false; 13543 13544 ArraySizes.push_back(ConstantLengthValue); 13545 } 13546 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13547 } 13548 13549 // If we have a single element, we don't need to add the implicit lengths. 13550 if (!SingleElement) { 13551 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13552 // Has implicit length 1! 13553 ArraySizes.push_back(llvm::APSInt::get(1)); 13554 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13555 } 13556 } 13557 13558 // This array section can be privatized as a single value or as a constant 13559 // sized array. 13560 return true; 13561 } 13562 13563 static bool actOnOMPReductionKindClause( 13564 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13565 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13566 SourceLocation ColonLoc, SourceLocation EndLoc, 13567 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13568 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13569 DeclarationName DN = ReductionId.getName(); 13570 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13571 BinaryOperatorKind BOK = BO_Comma; 13572 13573 ASTContext &Context = S.Context; 13574 // OpenMP [2.14.3.6, reduction clause] 13575 // C 13576 // reduction-identifier is either an identifier or one of the following 13577 // operators: +, -, *, &, |, ^, && and || 13578 // C++ 13579 // reduction-identifier is either an id-expression or one of the following 13580 // operators: +, -, *, &, |, ^, && and || 13581 switch (OOK) { 13582 case OO_Plus: 13583 case OO_Minus: 13584 BOK = BO_Add; 13585 break; 13586 case OO_Star: 13587 BOK = BO_Mul; 13588 break; 13589 case OO_Amp: 13590 BOK = BO_And; 13591 break; 13592 case OO_Pipe: 13593 BOK = BO_Or; 13594 break; 13595 case OO_Caret: 13596 BOK = BO_Xor; 13597 break; 13598 case OO_AmpAmp: 13599 BOK = BO_LAnd; 13600 break; 13601 case OO_PipePipe: 13602 BOK = BO_LOr; 13603 break; 13604 case OO_New: 13605 case OO_Delete: 13606 case OO_Array_New: 13607 case OO_Array_Delete: 13608 case OO_Slash: 13609 case OO_Percent: 13610 case OO_Tilde: 13611 case OO_Exclaim: 13612 case OO_Equal: 13613 case OO_Less: 13614 case OO_Greater: 13615 case OO_LessEqual: 13616 case OO_GreaterEqual: 13617 case OO_PlusEqual: 13618 case OO_MinusEqual: 13619 case OO_StarEqual: 13620 case OO_SlashEqual: 13621 case OO_PercentEqual: 13622 case OO_CaretEqual: 13623 case OO_AmpEqual: 13624 case OO_PipeEqual: 13625 case OO_LessLess: 13626 case OO_GreaterGreater: 13627 case OO_LessLessEqual: 13628 case OO_GreaterGreaterEqual: 13629 case OO_EqualEqual: 13630 case OO_ExclaimEqual: 13631 case OO_Spaceship: 13632 case OO_PlusPlus: 13633 case OO_MinusMinus: 13634 case OO_Comma: 13635 case OO_ArrowStar: 13636 case OO_Arrow: 13637 case OO_Call: 13638 case OO_Subscript: 13639 case OO_Conditional: 13640 case OO_Coawait: 13641 case NUM_OVERLOADED_OPERATORS: 13642 llvm_unreachable("Unexpected reduction identifier"); 13643 case OO_None: 13644 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13645 if (II->isStr("max")) 13646 BOK = BO_GT; 13647 else if (II->isStr("min")) 13648 BOK = BO_LT; 13649 } 13650 break; 13651 } 13652 SourceRange ReductionIdRange; 13653 if (ReductionIdScopeSpec.isValid()) 13654 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13655 else 13656 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13657 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13658 13659 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13660 bool FirstIter = true; 13661 for (Expr *RefExpr : VarList) { 13662 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13663 // OpenMP [2.1, C/C++] 13664 // A list item is a variable or array section, subject to the restrictions 13665 // specified in Section 2.4 on page 42 and in each of the sections 13666 // describing clauses and directives for which a list appears. 13667 // OpenMP [2.14.3.3, Restrictions, p.1] 13668 // A variable that is part of another variable (as an array or 13669 // structure element) cannot appear in a private clause. 13670 if (!FirstIter && IR != ER) 13671 ++IR; 13672 FirstIter = false; 13673 SourceLocation ELoc; 13674 SourceRange ERange; 13675 Expr *SimpleRefExpr = RefExpr; 13676 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13677 /*AllowArraySection=*/true); 13678 if (Res.second) { 13679 // Try to find 'declare reduction' corresponding construct before using 13680 // builtin/overloaded operators. 13681 QualType Type = Context.DependentTy; 13682 CXXCastPath BasePath; 13683 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13684 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13685 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13686 Expr *ReductionOp = nullptr; 13687 if (S.CurContext->isDependentContext() && 13688 (DeclareReductionRef.isUnset() || 13689 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13690 ReductionOp = DeclareReductionRef.get(); 13691 // It will be analyzed later. 13692 RD.push(RefExpr, ReductionOp); 13693 } 13694 ValueDecl *D = Res.first; 13695 if (!D) 13696 continue; 13697 13698 Expr *TaskgroupDescriptor = nullptr; 13699 QualType Type; 13700 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13701 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13702 if (ASE) { 13703 Type = ASE->getType().getNonReferenceType(); 13704 } else if (OASE) { 13705 QualType BaseType = 13706 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13707 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13708 Type = ATy->getElementType(); 13709 else 13710 Type = BaseType->getPointeeType(); 13711 Type = Type.getNonReferenceType(); 13712 } else { 13713 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13714 } 13715 auto *VD = dyn_cast<VarDecl>(D); 13716 13717 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13718 // A variable that appears in a private clause must not have an incomplete 13719 // type or a reference type. 13720 if (S.RequireCompleteType(ELoc, D->getType(), 13721 diag::err_omp_reduction_incomplete_type)) 13722 continue; 13723 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13724 // A list item that appears in a reduction clause must not be 13725 // const-qualified. 13726 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13727 /*AcceptIfMutable*/ false, ASE || OASE)) 13728 continue; 13729 13730 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13731 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13732 // If a list-item is a reference type then it must bind to the same object 13733 // for all threads of the team. 13734 if (!ASE && !OASE) { 13735 if (VD) { 13736 VarDecl *VDDef = VD->getDefinition(); 13737 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13738 DSARefChecker Check(Stack); 13739 if (Check.Visit(VDDef->getInit())) { 13740 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13741 << getOpenMPClauseName(ClauseKind) << ERange; 13742 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13743 continue; 13744 } 13745 } 13746 } 13747 13748 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13749 // in a Construct] 13750 // Variables with the predetermined data-sharing attributes may not be 13751 // listed in data-sharing attributes clauses, except for the cases 13752 // listed below. For these exceptions only, listing a predetermined 13753 // variable in a data-sharing attribute clause is allowed and overrides 13754 // the variable's predetermined data-sharing attributes. 13755 // OpenMP [2.14.3.6, Restrictions, p.3] 13756 // Any number of reduction clauses can be specified on the directive, 13757 // but a list item can appear only once in the reduction clauses for that 13758 // directive. 13759 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13760 if (DVar.CKind == OMPC_reduction) { 13761 S.Diag(ELoc, diag::err_omp_once_referenced) 13762 << getOpenMPClauseName(ClauseKind); 13763 if (DVar.RefExpr) 13764 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13765 continue; 13766 } 13767 if (DVar.CKind != OMPC_unknown) { 13768 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13769 << getOpenMPClauseName(DVar.CKind) 13770 << getOpenMPClauseName(OMPC_reduction); 13771 reportOriginalDsa(S, Stack, D, DVar); 13772 continue; 13773 } 13774 13775 // OpenMP [2.14.3.6, Restrictions, p.1] 13776 // A list item that appears in a reduction clause of a worksharing 13777 // construct must be shared in the parallel regions to which any of the 13778 // worksharing regions arising from the worksharing construct bind. 13779 if (isOpenMPWorksharingDirective(CurrDir) && 13780 !isOpenMPParallelDirective(CurrDir) && 13781 !isOpenMPTeamsDirective(CurrDir)) { 13782 DVar = Stack->getImplicitDSA(D, true); 13783 if (DVar.CKind != OMPC_shared) { 13784 S.Diag(ELoc, diag::err_omp_required_access) 13785 << getOpenMPClauseName(OMPC_reduction) 13786 << getOpenMPClauseName(OMPC_shared); 13787 reportOriginalDsa(S, Stack, D, DVar); 13788 continue; 13789 } 13790 } 13791 } 13792 13793 // Try to find 'declare reduction' corresponding construct before using 13794 // builtin/overloaded operators. 13795 CXXCastPath BasePath; 13796 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13797 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13798 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13799 if (DeclareReductionRef.isInvalid()) 13800 continue; 13801 if (S.CurContext->isDependentContext() && 13802 (DeclareReductionRef.isUnset() || 13803 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13804 RD.push(RefExpr, DeclareReductionRef.get()); 13805 continue; 13806 } 13807 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13808 // Not allowed reduction identifier is found. 13809 S.Diag(ReductionId.getBeginLoc(), 13810 diag::err_omp_unknown_reduction_identifier) 13811 << Type << ReductionIdRange; 13812 continue; 13813 } 13814 13815 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13816 // The type of a list item that appears in a reduction clause must be valid 13817 // for the reduction-identifier. For a max or min reduction in C, the type 13818 // of the list item must be an allowed arithmetic data type: char, int, 13819 // float, double, or _Bool, possibly modified with long, short, signed, or 13820 // unsigned. For a max or min reduction in C++, the type of the list item 13821 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13822 // double, or bool, possibly modified with long, short, signed, or unsigned. 13823 if (DeclareReductionRef.isUnset()) { 13824 if ((BOK == BO_GT || BOK == BO_LT) && 13825 !(Type->isScalarType() || 13826 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13827 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13828 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13829 if (!ASE && !OASE) { 13830 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13831 VarDecl::DeclarationOnly; 13832 S.Diag(D->getLocation(), 13833 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13834 << D; 13835 } 13836 continue; 13837 } 13838 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13839 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13840 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13841 << getOpenMPClauseName(ClauseKind); 13842 if (!ASE && !OASE) { 13843 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13844 VarDecl::DeclarationOnly; 13845 S.Diag(D->getLocation(), 13846 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13847 << D; 13848 } 13849 continue; 13850 } 13851 } 13852 13853 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13854 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13855 D->hasAttrs() ? &D->getAttrs() : nullptr); 13856 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13857 D->hasAttrs() ? &D->getAttrs() : nullptr); 13858 QualType PrivateTy = Type; 13859 13860 // Try if we can determine constant lengths for all array sections and avoid 13861 // the VLA. 13862 bool ConstantLengthOASE = false; 13863 if (OASE) { 13864 bool SingleElement; 13865 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13866 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13867 Context, OASE, SingleElement, ArraySizes); 13868 13869 // If we don't have a single element, we must emit a constant array type. 13870 if (ConstantLengthOASE && !SingleElement) { 13871 for (llvm::APSInt &Size : ArraySizes) 13872 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13873 ArrayType::Normal, 13874 /*IndexTypeQuals=*/0); 13875 } 13876 } 13877 13878 if ((OASE && !ConstantLengthOASE) || 13879 (!OASE && !ASE && 13880 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13881 if (!Context.getTargetInfo().isVLASupported()) { 13882 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13883 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13884 S.Diag(ELoc, diag::note_vla_unsupported); 13885 } else { 13886 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13887 S.targetDiag(ELoc, diag::note_vla_unsupported); 13888 } 13889 continue; 13890 } 13891 // For arrays/array sections only: 13892 // Create pseudo array type for private copy. The size for this array will 13893 // be generated during codegen. 13894 // For array subscripts or single variables Private Ty is the same as Type 13895 // (type of the variable or single array element). 13896 PrivateTy = Context.getVariableArrayType( 13897 Type, 13898 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13899 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13900 } else if (!ASE && !OASE && 13901 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13902 PrivateTy = D->getType().getNonReferenceType(); 13903 } 13904 // Private copy. 13905 VarDecl *PrivateVD = 13906 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13907 D->hasAttrs() ? &D->getAttrs() : nullptr, 13908 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13909 // Add initializer for private variable. 13910 Expr *Init = nullptr; 13911 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13912 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13913 if (DeclareReductionRef.isUsable()) { 13914 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13915 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13916 if (DRD->getInitializer()) { 13917 Init = DRDRef; 13918 RHSVD->setInit(DRDRef); 13919 RHSVD->setInitStyle(VarDecl::CallInit); 13920 } 13921 } else { 13922 switch (BOK) { 13923 case BO_Add: 13924 case BO_Xor: 13925 case BO_Or: 13926 case BO_LOr: 13927 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13928 if (Type->isScalarType() || Type->isAnyComplexType()) 13929 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13930 break; 13931 case BO_Mul: 13932 case BO_LAnd: 13933 if (Type->isScalarType() || Type->isAnyComplexType()) { 13934 // '*' and '&&' reduction ops - initializer is '1'. 13935 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13936 } 13937 break; 13938 case BO_And: { 13939 // '&' reduction op - initializer is '~0'. 13940 QualType OrigType = Type; 13941 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13942 Type = ComplexTy->getElementType(); 13943 if (Type->isRealFloatingType()) { 13944 llvm::APFloat InitValue = 13945 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13946 /*isIEEE=*/true); 13947 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13948 Type, ELoc); 13949 } else if (Type->isScalarType()) { 13950 uint64_t Size = Context.getTypeSize(Type); 13951 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13952 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13953 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13954 } 13955 if (Init && OrigType->isAnyComplexType()) { 13956 // Init = 0xFFFF + 0xFFFFi; 13957 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13958 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13959 } 13960 Type = OrigType; 13961 break; 13962 } 13963 case BO_LT: 13964 case BO_GT: { 13965 // 'min' reduction op - initializer is 'Largest representable number in 13966 // the reduction list item type'. 13967 // 'max' reduction op - initializer is 'Least representable number in 13968 // the reduction list item type'. 13969 if (Type->isIntegerType() || Type->isPointerType()) { 13970 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13971 uint64_t Size = Context.getTypeSize(Type); 13972 QualType IntTy = 13973 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13974 llvm::APInt InitValue = 13975 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13976 : llvm::APInt::getMinValue(Size) 13977 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13978 : llvm::APInt::getMaxValue(Size); 13979 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13980 if (Type->isPointerType()) { 13981 // Cast to pointer type. 13982 ExprResult CastExpr = S.BuildCStyleCastExpr( 13983 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13984 if (CastExpr.isInvalid()) 13985 continue; 13986 Init = CastExpr.get(); 13987 } 13988 } else if (Type->isRealFloatingType()) { 13989 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13990 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13991 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13992 Type, ELoc); 13993 } 13994 break; 13995 } 13996 case BO_PtrMemD: 13997 case BO_PtrMemI: 13998 case BO_MulAssign: 13999 case BO_Div: 14000 case BO_Rem: 14001 case BO_Sub: 14002 case BO_Shl: 14003 case BO_Shr: 14004 case BO_LE: 14005 case BO_GE: 14006 case BO_EQ: 14007 case BO_NE: 14008 case BO_Cmp: 14009 case BO_AndAssign: 14010 case BO_XorAssign: 14011 case BO_OrAssign: 14012 case BO_Assign: 14013 case BO_AddAssign: 14014 case BO_SubAssign: 14015 case BO_DivAssign: 14016 case BO_RemAssign: 14017 case BO_ShlAssign: 14018 case BO_ShrAssign: 14019 case BO_Comma: 14020 llvm_unreachable("Unexpected reduction operation"); 14021 } 14022 } 14023 if (Init && DeclareReductionRef.isUnset()) 14024 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14025 else if (!Init) 14026 S.ActOnUninitializedDecl(RHSVD); 14027 if (RHSVD->isInvalidDecl()) 14028 continue; 14029 if (!RHSVD->hasInit() && 14030 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14031 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14032 << Type << ReductionIdRange; 14033 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14034 VarDecl::DeclarationOnly; 14035 S.Diag(D->getLocation(), 14036 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14037 << D; 14038 continue; 14039 } 14040 // Store initializer for single element in private copy. Will be used during 14041 // codegen. 14042 PrivateVD->setInit(RHSVD->getInit()); 14043 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14044 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14045 ExprResult ReductionOp; 14046 if (DeclareReductionRef.isUsable()) { 14047 QualType RedTy = DeclareReductionRef.get()->getType(); 14048 QualType PtrRedTy = Context.getPointerType(RedTy); 14049 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14050 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14051 if (!BasePath.empty()) { 14052 LHS = S.DefaultLvalueConversion(LHS.get()); 14053 RHS = S.DefaultLvalueConversion(RHS.get()); 14054 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14055 CK_UncheckedDerivedToBase, LHS.get(), 14056 &BasePath, LHS.get()->getValueKind()); 14057 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14058 CK_UncheckedDerivedToBase, RHS.get(), 14059 &BasePath, RHS.get()->getValueKind()); 14060 } 14061 FunctionProtoType::ExtProtoInfo EPI; 14062 QualType Params[] = {PtrRedTy, PtrRedTy}; 14063 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14064 auto *OVE = new (Context) OpaqueValueExpr( 14065 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14066 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14067 Expr *Args[] = {LHS.get(), RHS.get()}; 14068 ReductionOp = 14069 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14070 } else { 14071 ReductionOp = S.BuildBinOp( 14072 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14073 if (ReductionOp.isUsable()) { 14074 if (BOK != BO_LT && BOK != BO_GT) { 14075 ReductionOp = 14076 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14077 BO_Assign, LHSDRE, ReductionOp.get()); 14078 } else { 14079 auto *ConditionalOp = new (Context) 14080 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14081 Type, VK_LValue, OK_Ordinary); 14082 ReductionOp = 14083 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14084 BO_Assign, LHSDRE, ConditionalOp); 14085 } 14086 if (ReductionOp.isUsable()) 14087 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14088 /*DiscardedValue*/ false); 14089 } 14090 if (!ReductionOp.isUsable()) 14091 continue; 14092 } 14093 14094 // OpenMP [2.15.4.6, Restrictions, p.2] 14095 // A list item that appears in an in_reduction clause of a task construct 14096 // must appear in a task_reduction clause of a construct associated with a 14097 // taskgroup region that includes the participating task in its taskgroup 14098 // set. The construct associated with the innermost region that meets this 14099 // condition must specify the same reduction-identifier as the in_reduction 14100 // clause. 14101 if (ClauseKind == OMPC_in_reduction) { 14102 SourceRange ParentSR; 14103 BinaryOperatorKind ParentBOK; 14104 const Expr *ParentReductionOp; 14105 Expr *ParentBOKTD, *ParentReductionOpTD; 14106 DSAStackTy::DSAVarData ParentBOKDSA = 14107 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14108 ParentBOKTD); 14109 DSAStackTy::DSAVarData ParentReductionOpDSA = 14110 Stack->getTopMostTaskgroupReductionData( 14111 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14112 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14113 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14114 if (!IsParentBOK && !IsParentReductionOp) { 14115 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 14116 continue; 14117 } 14118 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14119 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 14120 IsParentReductionOp) { 14121 bool EmitError = true; 14122 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14123 llvm::FoldingSetNodeID RedId, ParentRedId; 14124 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14125 DeclareReductionRef.get()->Profile(RedId, Context, 14126 /*Canonical=*/true); 14127 EmitError = RedId != ParentRedId; 14128 } 14129 if (EmitError) { 14130 S.Diag(ReductionId.getBeginLoc(), 14131 diag::err_omp_reduction_identifier_mismatch) 14132 << ReductionIdRange << RefExpr->getSourceRange(); 14133 S.Diag(ParentSR.getBegin(), 14134 diag::note_omp_previous_reduction_identifier) 14135 << ParentSR 14136 << (IsParentBOK ? ParentBOKDSA.RefExpr 14137 : ParentReductionOpDSA.RefExpr) 14138 ->getSourceRange(); 14139 continue; 14140 } 14141 } 14142 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14143 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 14144 } 14145 14146 DeclRefExpr *Ref = nullptr; 14147 Expr *VarsExpr = RefExpr->IgnoreParens(); 14148 if (!VD && !S.CurContext->isDependentContext()) { 14149 if (ASE || OASE) { 14150 TransformExprToCaptures RebuildToCapture(S, D); 14151 VarsExpr = 14152 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14153 Ref = RebuildToCapture.getCapturedExpr(); 14154 } else { 14155 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14156 } 14157 if (!S.isOpenMPCapturedDecl(D)) { 14158 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14159 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14160 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14161 if (!RefRes.isUsable()) 14162 continue; 14163 ExprResult PostUpdateRes = 14164 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14165 RefRes.get()); 14166 if (!PostUpdateRes.isUsable()) 14167 continue; 14168 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14169 Stack->getCurrentDirective() == OMPD_taskgroup) { 14170 S.Diag(RefExpr->getExprLoc(), 14171 diag::err_omp_reduction_non_addressable_expression) 14172 << RefExpr->getSourceRange(); 14173 continue; 14174 } 14175 RD.ExprPostUpdates.emplace_back( 14176 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14177 } 14178 } 14179 } 14180 // All reduction items are still marked as reduction (to do not increase 14181 // code base size). 14182 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 14183 if (CurrDir == OMPD_taskgroup) { 14184 if (DeclareReductionRef.isUsable()) 14185 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14186 DeclareReductionRef.get()); 14187 else 14188 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14189 } 14190 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14191 TaskgroupDescriptor); 14192 } 14193 return RD.Vars.empty(); 14194 } 14195 14196 OMPClause *Sema::ActOnOpenMPReductionClause( 14197 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14198 SourceLocation ColonLoc, SourceLocation EndLoc, 14199 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14200 ArrayRef<Expr *> UnresolvedReductions) { 14201 ReductionData RD(VarList.size()); 14202 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14203 StartLoc, LParenLoc, ColonLoc, EndLoc, 14204 ReductionIdScopeSpec, ReductionId, 14205 UnresolvedReductions, RD)) 14206 return nullptr; 14207 14208 return OMPReductionClause::Create( 14209 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14210 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14211 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14212 buildPreInits(Context, RD.ExprCaptures), 14213 buildPostUpdate(*this, RD.ExprPostUpdates)); 14214 } 14215 14216 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14217 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14218 SourceLocation ColonLoc, SourceLocation EndLoc, 14219 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14220 ArrayRef<Expr *> UnresolvedReductions) { 14221 ReductionData RD(VarList.size()); 14222 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14223 StartLoc, LParenLoc, ColonLoc, EndLoc, 14224 ReductionIdScopeSpec, ReductionId, 14225 UnresolvedReductions, RD)) 14226 return nullptr; 14227 14228 return OMPTaskReductionClause::Create( 14229 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14230 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14231 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14232 buildPreInits(Context, RD.ExprCaptures), 14233 buildPostUpdate(*this, RD.ExprPostUpdates)); 14234 } 14235 14236 OMPClause *Sema::ActOnOpenMPInReductionClause( 14237 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14238 SourceLocation ColonLoc, SourceLocation EndLoc, 14239 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14240 ArrayRef<Expr *> UnresolvedReductions) { 14241 ReductionData RD(VarList.size()); 14242 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14243 StartLoc, LParenLoc, ColonLoc, EndLoc, 14244 ReductionIdScopeSpec, ReductionId, 14245 UnresolvedReductions, RD)) 14246 return nullptr; 14247 14248 return OMPInReductionClause::Create( 14249 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14250 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14251 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14252 buildPreInits(Context, RD.ExprCaptures), 14253 buildPostUpdate(*this, RD.ExprPostUpdates)); 14254 } 14255 14256 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14257 SourceLocation LinLoc) { 14258 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14259 LinKind == OMPC_LINEAR_unknown) { 14260 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14261 return true; 14262 } 14263 return false; 14264 } 14265 14266 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14267 OpenMPLinearClauseKind LinKind, 14268 QualType Type) { 14269 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14270 // A variable must not have an incomplete type or a reference type. 14271 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14272 return true; 14273 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14274 !Type->isReferenceType()) { 14275 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14276 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14277 return true; 14278 } 14279 Type = Type.getNonReferenceType(); 14280 14281 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14282 // A variable that is privatized must not have a const-qualified type 14283 // unless it is of class type with a mutable member. This restriction does 14284 // not apply to the firstprivate clause. 14285 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14286 return true; 14287 14288 // A list item must be of integral or pointer type. 14289 Type = Type.getUnqualifiedType().getCanonicalType(); 14290 const auto *Ty = Type.getTypePtrOrNull(); 14291 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 14292 !Ty->isPointerType())) { 14293 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14294 if (D) { 14295 bool IsDecl = 14296 !VD || 14297 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14298 Diag(D->getLocation(), 14299 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14300 << D; 14301 } 14302 return true; 14303 } 14304 return false; 14305 } 14306 14307 OMPClause *Sema::ActOnOpenMPLinearClause( 14308 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14309 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14310 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14311 SmallVector<Expr *, 8> Vars; 14312 SmallVector<Expr *, 8> Privates; 14313 SmallVector<Expr *, 8> Inits; 14314 SmallVector<Decl *, 4> ExprCaptures; 14315 SmallVector<Expr *, 4> ExprPostUpdates; 14316 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14317 LinKind = OMPC_LINEAR_val; 14318 for (Expr *RefExpr : VarList) { 14319 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14320 SourceLocation ELoc; 14321 SourceRange ERange; 14322 Expr *SimpleRefExpr = RefExpr; 14323 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14324 if (Res.second) { 14325 // It will be analyzed later. 14326 Vars.push_back(RefExpr); 14327 Privates.push_back(nullptr); 14328 Inits.push_back(nullptr); 14329 } 14330 ValueDecl *D = Res.first; 14331 if (!D) 14332 continue; 14333 14334 QualType Type = D->getType(); 14335 auto *VD = dyn_cast<VarDecl>(D); 14336 14337 // OpenMP [2.14.3.7, linear clause] 14338 // A list-item cannot appear in more than one linear clause. 14339 // A list-item that appears in a linear clause cannot appear in any 14340 // other data-sharing attribute clause. 14341 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14342 if (DVar.RefExpr) { 14343 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14344 << getOpenMPClauseName(OMPC_linear); 14345 reportOriginalDsa(*this, DSAStack, D, DVar); 14346 continue; 14347 } 14348 14349 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14350 continue; 14351 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14352 14353 // Build private copy of original var. 14354 VarDecl *Private = 14355 buildVarDecl(*this, ELoc, Type, D->getName(), 14356 D->hasAttrs() ? &D->getAttrs() : nullptr, 14357 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14358 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14359 // Build var to save initial value. 14360 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14361 Expr *InitExpr; 14362 DeclRefExpr *Ref = nullptr; 14363 if (!VD && !CurContext->isDependentContext()) { 14364 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14365 if (!isOpenMPCapturedDecl(D)) { 14366 ExprCaptures.push_back(Ref->getDecl()); 14367 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14368 ExprResult RefRes = DefaultLvalueConversion(Ref); 14369 if (!RefRes.isUsable()) 14370 continue; 14371 ExprResult PostUpdateRes = 14372 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14373 SimpleRefExpr, RefRes.get()); 14374 if (!PostUpdateRes.isUsable()) 14375 continue; 14376 ExprPostUpdates.push_back( 14377 IgnoredValueConversions(PostUpdateRes.get()).get()); 14378 } 14379 } 14380 } 14381 if (LinKind == OMPC_LINEAR_uval) 14382 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14383 else 14384 InitExpr = VD ? SimpleRefExpr : Ref; 14385 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14386 /*DirectInit=*/false); 14387 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14388 14389 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14390 Vars.push_back((VD || CurContext->isDependentContext()) 14391 ? RefExpr->IgnoreParens() 14392 : Ref); 14393 Privates.push_back(PrivateRef); 14394 Inits.push_back(InitRef); 14395 } 14396 14397 if (Vars.empty()) 14398 return nullptr; 14399 14400 Expr *StepExpr = Step; 14401 Expr *CalcStepExpr = nullptr; 14402 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14403 !Step->isInstantiationDependent() && 14404 !Step->containsUnexpandedParameterPack()) { 14405 SourceLocation StepLoc = Step->getBeginLoc(); 14406 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14407 if (Val.isInvalid()) 14408 return nullptr; 14409 StepExpr = Val.get(); 14410 14411 // Build var to save the step value. 14412 VarDecl *SaveVar = 14413 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14414 ExprResult SaveRef = 14415 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14416 ExprResult CalcStep = 14417 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14418 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14419 14420 // Warn about zero linear step (it would be probably better specified as 14421 // making corresponding variables 'const'). 14422 llvm::APSInt Result; 14423 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14424 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14425 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14426 << (Vars.size() > 1); 14427 if (!IsConstant && CalcStep.isUsable()) { 14428 // Calculate the step beforehand instead of doing this on each iteration. 14429 // (This is not used if the number of iterations may be kfold-ed). 14430 CalcStepExpr = CalcStep.get(); 14431 } 14432 } 14433 14434 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14435 ColonLoc, EndLoc, Vars, Privates, Inits, 14436 StepExpr, CalcStepExpr, 14437 buildPreInits(Context, ExprCaptures), 14438 buildPostUpdate(*this, ExprPostUpdates)); 14439 } 14440 14441 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14442 Expr *NumIterations, Sema &SemaRef, 14443 Scope *S, DSAStackTy *Stack) { 14444 // Walk the vars and build update/final expressions for the CodeGen. 14445 SmallVector<Expr *, 8> Updates; 14446 SmallVector<Expr *, 8> Finals; 14447 SmallVector<Expr *, 8> UsedExprs; 14448 Expr *Step = Clause.getStep(); 14449 Expr *CalcStep = Clause.getCalcStep(); 14450 // OpenMP [2.14.3.7, linear clause] 14451 // If linear-step is not specified it is assumed to be 1. 14452 if (!Step) 14453 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14454 else if (CalcStep) 14455 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14456 bool HasErrors = false; 14457 auto CurInit = Clause.inits().begin(); 14458 auto CurPrivate = Clause.privates().begin(); 14459 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14460 for (Expr *RefExpr : Clause.varlists()) { 14461 SourceLocation ELoc; 14462 SourceRange ERange; 14463 Expr *SimpleRefExpr = RefExpr; 14464 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14465 ValueDecl *D = Res.first; 14466 if (Res.second || !D) { 14467 Updates.push_back(nullptr); 14468 Finals.push_back(nullptr); 14469 HasErrors = true; 14470 continue; 14471 } 14472 auto &&Info = Stack->isLoopControlVariable(D); 14473 // OpenMP [2.15.11, distribute simd Construct] 14474 // A list item may not appear in a linear clause, unless it is the loop 14475 // iteration variable. 14476 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14477 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14478 SemaRef.Diag(ELoc, 14479 diag::err_omp_linear_distribute_var_non_loop_iteration); 14480 Updates.push_back(nullptr); 14481 Finals.push_back(nullptr); 14482 HasErrors = true; 14483 continue; 14484 } 14485 Expr *InitExpr = *CurInit; 14486 14487 // Build privatized reference to the current linear var. 14488 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14489 Expr *CapturedRef; 14490 if (LinKind == OMPC_LINEAR_uval) 14491 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14492 else 14493 CapturedRef = 14494 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14495 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14496 /*RefersToCapture=*/true); 14497 14498 // Build update: Var = InitExpr + IV * Step 14499 ExprResult Update; 14500 if (!Info.first) 14501 Update = buildCounterUpdate( 14502 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14503 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14504 else 14505 Update = *CurPrivate; 14506 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14507 /*DiscardedValue*/ false); 14508 14509 // Build final: Var = InitExpr + NumIterations * Step 14510 ExprResult Final; 14511 if (!Info.first) 14512 Final = 14513 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14514 InitExpr, NumIterations, Step, /*Subtract=*/false, 14515 /*IsNonRectangularLB=*/false); 14516 else 14517 Final = *CurPrivate; 14518 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14519 /*DiscardedValue*/ false); 14520 14521 if (!Update.isUsable() || !Final.isUsable()) { 14522 Updates.push_back(nullptr); 14523 Finals.push_back(nullptr); 14524 UsedExprs.push_back(nullptr); 14525 HasErrors = true; 14526 } else { 14527 Updates.push_back(Update.get()); 14528 Finals.push_back(Final.get()); 14529 if (!Info.first) 14530 UsedExprs.push_back(SimpleRefExpr); 14531 } 14532 ++CurInit; 14533 ++CurPrivate; 14534 } 14535 if (Expr *S = Clause.getStep()) 14536 UsedExprs.push_back(S); 14537 // Fill the remaining part with the nullptr. 14538 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14539 Clause.setUpdates(Updates); 14540 Clause.setFinals(Finals); 14541 Clause.setUsedExprs(UsedExprs); 14542 return HasErrors; 14543 } 14544 14545 OMPClause *Sema::ActOnOpenMPAlignedClause( 14546 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14547 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14548 SmallVector<Expr *, 8> Vars; 14549 for (Expr *RefExpr : VarList) { 14550 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14551 SourceLocation ELoc; 14552 SourceRange ERange; 14553 Expr *SimpleRefExpr = RefExpr; 14554 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14555 if (Res.second) { 14556 // It will be analyzed later. 14557 Vars.push_back(RefExpr); 14558 } 14559 ValueDecl *D = Res.first; 14560 if (!D) 14561 continue; 14562 14563 QualType QType = D->getType(); 14564 auto *VD = dyn_cast<VarDecl>(D); 14565 14566 // OpenMP [2.8.1, simd construct, Restrictions] 14567 // The type of list items appearing in the aligned clause must be 14568 // array, pointer, reference to array, or reference to pointer. 14569 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14570 const Type *Ty = QType.getTypePtrOrNull(); 14571 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14572 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14573 << QType << getLangOpts().CPlusPlus << ERange; 14574 bool IsDecl = 14575 !VD || 14576 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14577 Diag(D->getLocation(), 14578 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14579 << D; 14580 continue; 14581 } 14582 14583 // OpenMP [2.8.1, simd construct, Restrictions] 14584 // A list-item cannot appear in more than one aligned clause. 14585 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14586 Diag(ELoc, diag::err_omp_used_in_clause_twice) 14587 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 14588 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14589 << getOpenMPClauseName(OMPC_aligned); 14590 continue; 14591 } 14592 14593 DeclRefExpr *Ref = nullptr; 14594 if (!VD && isOpenMPCapturedDecl(D)) 14595 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14596 Vars.push_back(DefaultFunctionArrayConversion( 14597 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14598 .get()); 14599 } 14600 14601 // OpenMP [2.8.1, simd construct, Description] 14602 // The parameter of the aligned clause, alignment, must be a constant 14603 // positive integer expression. 14604 // If no optional parameter is specified, implementation-defined default 14605 // alignments for SIMD instructions on the target platforms are assumed. 14606 if (Alignment != nullptr) { 14607 ExprResult AlignResult = 14608 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14609 if (AlignResult.isInvalid()) 14610 return nullptr; 14611 Alignment = AlignResult.get(); 14612 } 14613 if (Vars.empty()) 14614 return nullptr; 14615 14616 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14617 EndLoc, Vars, Alignment); 14618 } 14619 14620 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14621 SourceLocation StartLoc, 14622 SourceLocation LParenLoc, 14623 SourceLocation EndLoc) { 14624 SmallVector<Expr *, 8> Vars; 14625 SmallVector<Expr *, 8> SrcExprs; 14626 SmallVector<Expr *, 8> DstExprs; 14627 SmallVector<Expr *, 8> AssignmentOps; 14628 for (Expr *RefExpr : VarList) { 14629 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14630 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14631 // It will be analyzed later. 14632 Vars.push_back(RefExpr); 14633 SrcExprs.push_back(nullptr); 14634 DstExprs.push_back(nullptr); 14635 AssignmentOps.push_back(nullptr); 14636 continue; 14637 } 14638 14639 SourceLocation ELoc = RefExpr->getExprLoc(); 14640 // OpenMP [2.1, C/C++] 14641 // A list item is a variable name. 14642 // OpenMP [2.14.4.1, Restrictions, p.1] 14643 // A list item that appears in a copyin clause must be threadprivate. 14644 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14645 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14646 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14647 << 0 << RefExpr->getSourceRange(); 14648 continue; 14649 } 14650 14651 Decl *D = DE->getDecl(); 14652 auto *VD = cast<VarDecl>(D); 14653 14654 QualType Type = VD->getType(); 14655 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14656 // It will be analyzed later. 14657 Vars.push_back(DE); 14658 SrcExprs.push_back(nullptr); 14659 DstExprs.push_back(nullptr); 14660 AssignmentOps.push_back(nullptr); 14661 continue; 14662 } 14663 14664 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14665 // A list item that appears in a copyin clause must be threadprivate. 14666 if (!DSAStack->isThreadPrivate(VD)) { 14667 Diag(ELoc, diag::err_omp_required_access) 14668 << getOpenMPClauseName(OMPC_copyin) 14669 << getOpenMPDirectiveName(OMPD_threadprivate); 14670 continue; 14671 } 14672 14673 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14674 // A variable of class type (or array thereof) that appears in a 14675 // copyin clause requires an accessible, unambiguous copy assignment 14676 // operator for the class type. 14677 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14678 VarDecl *SrcVD = 14679 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14680 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14681 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14682 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14683 VarDecl *DstVD = 14684 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14685 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14686 DeclRefExpr *PseudoDstExpr = 14687 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14688 // For arrays generate assignment operation for single element and replace 14689 // it by the original array element in CodeGen. 14690 ExprResult AssignmentOp = 14691 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14692 PseudoSrcExpr); 14693 if (AssignmentOp.isInvalid()) 14694 continue; 14695 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14696 /*DiscardedValue*/ false); 14697 if (AssignmentOp.isInvalid()) 14698 continue; 14699 14700 DSAStack->addDSA(VD, DE, OMPC_copyin); 14701 Vars.push_back(DE); 14702 SrcExprs.push_back(PseudoSrcExpr); 14703 DstExprs.push_back(PseudoDstExpr); 14704 AssignmentOps.push_back(AssignmentOp.get()); 14705 } 14706 14707 if (Vars.empty()) 14708 return nullptr; 14709 14710 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14711 SrcExprs, DstExprs, AssignmentOps); 14712 } 14713 14714 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14715 SourceLocation StartLoc, 14716 SourceLocation LParenLoc, 14717 SourceLocation EndLoc) { 14718 SmallVector<Expr *, 8> Vars; 14719 SmallVector<Expr *, 8> SrcExprs; 14720 SmallVector<Expr *, 8> DstExprs; 14721 SmallVector<Expr *, 8> AssignmentOps; 14722 for (Expr *RefExpr : VarList) { 14723 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14724 SourceLocation ELoc; 14725 SourceRange ERange; 14726 Expr *SimpleRefExpr = RefExpr; 14727 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14728 if (Res.second) { 14729 // It will be analyzed later. 14730 Vars.push_back(RefExpr); 14731 SrcExprs.push_back(nullptr); 14732 DstExprs.push_back(nullptr); 14733 AssignmentOps.push_back(nullptr); 14734 } 14735 ValueDecl *D = Res.first; 14736 if (!D) 14737 continue; 14738 14739 QualType Type = D->getType(); 14740 auto *VD = dyn_cast<VarDecl>(D); 14741 14742 // OpenMP [2.14.4.2, Restrictions, p.2] 14743 // A list item that appears in a copyprivate clause may not appear in a 14744 // private or firstprivate clause on the single construct. 14745 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14746 DSAStackTy::DSAVarData DVar = 14747 DSAStack->getTopDSA(D, /*FromParent=*/false); 14748 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14749 DVar.RefExpr) { 14750 Diag(ELoc, diag::err_omp_wrong_dsa) 14751 << getOpenMPClauseName(DVar.CKind) 14752 << getOpenMPClauseName(OMPC_copyprivate); 14753 reportOriginalDsa(*this, DSAStack, D, DVar); 14754 continue; 14755 } 14756 14757 // OpenMP [2.11.4.2, Restrictions, p.1] 14758 // All list items that appear in a copyprivate clause must be either 14759 // threadprivate or private in the enclosing context. 14760 if (DVar.CKind == OMPC_unknown) { 14761 DVar = DSAStack->getImplicitDSA(D, false); 14762 if (DVar.CKind == OMPC_shared) { 14763 Diag(ELoc, diag::err_omp_required_access) 14764 << getOpenMPClauseName(OMPC_copyprivate) 14765 << "threadprivate or private in the enclosing context"; 14766 reportOriginalDsa(*this, DSAStack, D, DVar); 14767 continue; 14768 } 14769 } 14770 } 14771 14772 // Variably modified types are not supported. 14773 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14774 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14775 << getOpenMPClauseName(OMPC_copyprivate) << Type 14776 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14777 bool IsDecl = 14778 !VD || 14779 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14780 Diag(D->getLocation(), 14781 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14782 << D; 14783 continue; 14784 } 14785 14786 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14787 // A variable of class type (or array thereof) that appears in a 14788 // copyin clause requires an accessible, unambiguous copy assignment 14789 // operator for the class type. 14790 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14791 .getUnqualifiedType(); 14792 VarDecl *SrcVD = 14793 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14794 D->hasAttrs() ? &D->getAttrs() : nullptr); 14795 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14796 VarDecl *DstVD = 14797 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14798 D->hasAttrs() ? &D->getAttrs() : nullptr); 14799 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14800 ExprResult AssignmentOp = BuildBinOp( 14801 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14802 if (AssignmentOp.isInvalid()) 14803 continue; 14804 AssignmentOp = 14805 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14806 if (AssignmentOp.isInvalid()) 14807 continue; 14808 14809 // No need to mark vars as copyprivate, they are already threadprivate or 14810 // implicitly private. 14811 assert(VD || isOpenMPCapturedDecl(D)); 14812 Vars.push_back( 14813 VD ? RefExpr->IgnoreParens() 14814 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14815 SrcExprs.push_back(PseudoSrcExpr); 14816 DstExprs.push_back(PseudoDstExpr); 14817 AssignmentOps.push_back(AssignmentOp.get()); 14818 } 14819 14820 if (Vars.empty()) 14821 return nullptr; 14822 14823 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14824 Vars, SrcExprs, DstExprs, AssignmentOps); 14825 } 14826 14827 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14828 SourceLocation StartLoc, 14829 SourceLocation LParenLoc, 14830 SourceLocation EndLoc) { 14831 if (VarList.empty()) 14832 return nullptr; 14833 14834 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14835 } 14836 14837 OMPClause * 14838 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14839 SourceLocation DepLoc, SourceLocation ColonLoc, 14840 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14841 SourceLocation LParenLoc, SourceLocation EndLoc) { 14842 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14843 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14844 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14845 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14846 return nullptr; 14847 } 14848 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14849 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14850 DepKind == OMPC_DEPEND_sink)) { 14851 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14852 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14853 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14854 /*Last=*/OMPC_DEPEND_unknown, Except) 14855 << getOpenMPClauseName(OMPC_depend); 14856 return nullptr; 14857 } 14858 SmallVector<Expr *, 8> Vars; 14859 DSAStackTy::OperatorOffsetTy OpsOffs; 14860 llvm::APSInt DepCounter(/*BitWidth=*/32); 14861 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14862 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14863 if (const Expr *OrderedCountExpr = 14864 DSAStack->getParentOrderedRegionParam().first) { 14865 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14866 TotalDepCount.setIsUnsigned(/*Val=*/true); 14867 } 14868 } 14869 for (Expr *RefExpr : VarList) { 14870 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14871 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14872 // It will be analyzed later. 14873 Vars.push_back(RefExpr); 14874 continue; 14875 } 14876 14877 SourceLocation ELoc = RefExpr->getExprLoc(); 14878 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14879 if (DepKind == OMPC_DEPEND_sink) { 14880 if (DSAStack->getParentOrderedRegionParam().first && 14881 DepCounter >= TotalDepCount) { 14882 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14883 continue; 14884 } 14885 ++DepCounter; 14886 // OpenMP [2.13.9, Summary] 14887 // depend(dependence-type : vec), where dependence-type is: 14888 // 'sink' and where vec is the iteration vector, which has the form: 14889 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14890 // where n is the value specified by the ordered clause in the loop 14891 // directive, xi denotes the loop iteration variable of the i-th nested 14892 // loop associated with the loop directive, and di is a constant 14893 // non-negative integer. 14894 if (CurContext->isDependentContext()) { 14895 // It will be analyzed later. 14896 Vars.push_back(RefExpr); 14897 continue; 14898 } 14899 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14900 OverloadedOperatorKind OOK = OO_None; 14901 SourceLocation OOLoc; 14902 Expr *LHS = SimpleExpr; 14903 Expr *RHS = nullptr; 14904 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14905 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14906 OOLoc = BO->getOperatorLoc(); 14907 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14908 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14909 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14910 OOK = OCE->getOperator(); 14911 OOLoc = OCE->getOperatorLoc(); 14912 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14913 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14914 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14915 OOK = MCE->getMethodDecl() 14916 ->getNameInfo() 14917 .getName() 14918 .getCXXOverloadedOperator(); 14919 OOLoc = MCE->getCallee()->getExprLoc(); 14920 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14921 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14922 } 14923 SourceLocation ELoc; 14924 SourceRange ERange; 14925 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14926 if (Res.second) { 14927 // It will be analyzed later. 14928 Vars.push_back(RefExpr); 14929 } 14930 ValueDecl *D = Res.first; 14931 if (!D) 14932 continue; 14933 14934 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14935 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14936 continue; 14937 } 14938 if (RHS) { 14939 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14940 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14941 if (RHSRes.isInvalid()) 14942 continue; 14943 } 14944 if (!CurContext->isDependentContext() && 14945 DSAStack->getParentOrderedRegionParam().first && 14946 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14947 const ValueDecl *VD = 14948 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14949 if (VD) 14950 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14951 << 1 << VD; 14952 else 14953 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14954 continue; 14955 } 14956 OpsOffs.emplace_back(RHS, OOK); 14957 } else { 14958 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14959 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14960 (ASE && 14961 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14962 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14963 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14964 << RefExpr->getSourceRange(); 14965 continue; 14966 } 14967 14968 ExprResult Res; 14969 { 14970 Sema::TentativeAnalysisScope Trap(*this); 14971 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14972 RefExpr->IgnoreParenImpCasts()); 14973 } 14974 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14975 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14976 << RefExpr->getSourceRange(); 14977 continue; 14978 } 14979 } 14980 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14981 } 14982 14983 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14984 TotalDepCount > VarList.size() && 14985 DSAStack->getParentOrderedRegionParam().first && 14986 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14987 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14988 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14989 } 14990 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14991 Vars.empty()) 14992 return nullptr; 14993 14994 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14995 DepKind, DepLoc, ColonLoc, Vars, 14996 TotalDepCount.getZExtValue()); 14997 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14998 DSAStack->isParentOrderedRegion()) 14999 DSAStack->addDoacrossDependClause(C, OpsOffs); 15000 return C; 15001 } 15002 15003 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 15004 SourceLocation LParenLoc, 15005 SourceLocation EndLoc) { 15006 Expr *ValExpr = Device; 15007 Stmt *HelperValStmt = nullptr; 15008 15009 // OpenMP [2.9.1, Restrictions] 15010 // The device expression must evaluate to a non-negative integer value. 15011 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15012 /*StrictlyPositive=*/false)) 15013 return nullptr; 15014 15015 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15016 OpenMPDirectiveKind CaptureRegion = 15017 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15018 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15019 ValExpr = MakeFullExpr(ValExpr).get(); 15020 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15021 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15022 HelperValStmt = buildPreInits(Context, Captures); 15023 } 15024 15025 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 15026 StartLoc, LParenLoc, EndLoc); 15027 } 15028 15029 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15030 DSAStackTy *Stack, QualType QTy, 15031 bool FullCheck = true) { 15032 NamedDecl *ND; 15033 if (QTy->isIncompleteType(&ND)) { 15034 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15035 return false; 15036 } 15037 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15038 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15039 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15040 return true; 15041 } 15042 15043 /// Return true if it can be proven that the provided array expression 15044 /// (array section or array subscript) does NOT specify the whole size of the 15045 /// array whose base type is \a BaseQTy. 15046 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15047 const Expr *E, 15048 QualType BaseQTy) { 15049 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15050 15051 // If this is an array subscript, it refers to the whole size if the size of 15052 // the dimension is constant and equals 1. Also, an array section assumes the 15053 // format of an array subscript if no colon is used. 15054 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15055 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15056 return ATy->getSize().getSExtValue() != 1; 15057 // Size can't be evaluated statically. 15058 return false; 15059 } 15060 15061 assert(OASE && "Expecting array section if not an array subscript."); 15062 const Expr *LowerBound = OASE->getLowerBound(); 15063 const Expr *Length = OASE->getLength(); 15064 15065 // If there is a lower bound that does not evaluates to zero, we are not 15066 // covering the whole dimension. 15067 if (LowerBound) { 15068 Expr::EvalResult Result; 15069 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15070 return false; // Can't get the integer value as a constant. 15071 15072 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15073 if (ConstLowerBound.getSExtValue()) 15074 return true; 15075 } 15076 15077 // If we don't have a length we covering the whole dimension. 15078 if (!Length) 15079 return false; 15080 15081 // If the base is a pointer, we don't have a way to get the size of the 15082 // pointee. 15083 if (BaseQTy->isPointerType()) 15084 return false; 15085 15086 // We can only check if the length is the same as the size of the dimension 15087 // if we have a constant array. 15088 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15089 if (!CATy) 15090 return false; 15091 15092 Expr::EvalResult Result; 15093 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15094 return false; // Can't get the integer value as a constant. 15095 15096 llvm::APSInt ConstLength = Result.Val.getInt(); 15097 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15098 } 15099 15100 // Return true if it can be proven that the provided array expression (array 15101 // section or array subscript) does NOT specify a single element of the array 15102 // whose base type is \a BaseQTy. 15103 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15104 const Expr *E, 15105 QualType BaseQTy) { 15106 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15107 15108 // An array subscript always refer to a single element. Also, an array section 15109 // assumes the format of an array subscript if no colon is used. 15110 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 15111 return false; 15112 15113 assert(OASE && "Expecting array section if not an array subscript."); 15114 const Expr *Length = OASE->getLength(); 15115 15116 // If we don't have a length we have to check if the array has unitary size 15117 // for this dimension. Also, we should always expect a length if the base type 15118 // is pointer. 15119 if (!Length) { 15120 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15121 return ATy->getSize().getSExtValue() != 1; 15122 // We cannot assume anything. 15123 return false; 15124 } 15125 15126 // Check if the length evaluates to 1. 15127 Expr::EvalResult Result; 15128 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15129 return false; // Can't get the integer value as a constant. 15130 15131 llvm::APSInt ConstLength = Result.Val.getInt(); 15132 return ConstLength.getSExtValue() != 1; 15133 } 15134 15135 // Return the expression of the base of the mappable expression or null if it 15136 // cannot be determined and do all the necessary checks to see if the expression 15137 // is valid as a standalone mappable expression. In the process, record all the 15138 // components of the expression. 15139 static const Expr *checkMapClauseExpressionBase( 15140 Sema &SemaRef, Expr *E, 15141 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 15142 OpenMPClauseKind CKind, bool NoDiagnose) { 15143 SourceLocation ELoc = E->getExprLoc(); 15144 SourceRange ERange = E->getSourceRange(); 15145 15146 // The base of elements of list in a map clause have to be either: 15147 // - a reference to variable or field. 15148 // - a member expression. 15149 // - an array expression. 15150 // 15151 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 15152 // reference to 'r'. 15153 // 15154 // If we have: 15155 // 15156 // struct SS { 15157 // Bla S; 15158 // foo() { 15159 // #pragma omp target map (S.Arr[:12]); 15160 // } 15161 // } 15162 // 15163 // We want to retrieve the member expression 'this->S'; 15164 15165 const Expr *RelevantExpr = nullptr; 15166 15167 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 15168 // If a list item is an array section, it must specify contiguous storage. 15169 // 15170 // For this restriction it is sufficient that we make sure only references 15171 // to variables or fields and array expressions, and that no array sections 15172 // exist except in the rightmost expression (unless they cover the whole 15173 // dimension of the array). E.g. these would be invalid: 15174 // 15175 // r.ArrS[3:5].Arr[6:7] 15176 // 15177 // r.ArrS[3:5].x 15178 // 15179 // but these would be valid: 15180 // r.ArrS[3].Arr[6:7] 15181 // 15182 // r.ArrS[3].x 15183 15184 bool AllowUnitySizeArraySection = true; 15185 bool AllowWholeSizeArraySection = true; 15186 15187 while (!RelevantExpr) { 15188 E = E->IgnoreParenImpCasts(); 15189 15190 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 15191 if (!isa<VarDecl>(CurE->getDecl())) 15192 return nullptr; 15193 15194 RelevantExpr = CurE; 15195 15196 // If we got a reference to a declaration, we should not expect any array 15197 // section before that. 15198 AllowUnitySizeArraySection = false; 15199 AllowWholeSizeArraySection = false; 15200 15201 // Record the component. 15202 CurComponents.emplace_back(CurE, CurE->getDecl()); 15203 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 15204 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 15205 15206 if (isa<CXXThisExpr>(BaseE)) 15207 // We found a base expression: this->Val. 15208 RelevantExpr = CurE; 15209 else 15210 E = BaseE; 15211 15212 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 15213 if (!NoDiagnose) { 15214 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15215 << CurE->getSourceRange(); 15216 return nullptr; 15217 } 15218 if (RelevantExpr) 15219 return nullptr; 15220 continue; 15221 } 15222 15223 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 15224 15225 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15226 // A bit-field cannot appear in a map clause. 15227 // 15228 if (FD->isBitField()) { 15229 if (!NoDiagnose) { 15230 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15231 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 15232 return nullptr; 15233 } 15234 if (RelevantExpr) 15235 return nullptr; 15236 continue; 15237 } 15238 15239 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15240 // If the type of a list item is a reference to a type T then the type 15241 // will be considered to be T for all purposes of this clause. 15242 QualType CurType = BaseE->getType().getNonReferenceType(); 15243 15244 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15245 // A list item cannot be a variable that is a member of a structure with 15246 // a union type. 15247 // 15248 if (CurType->isUnionType()) { 15249 if (!NoDiagnose) { 15250 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15251 << CurE->getSourceRange(); 15252 return nullptr; 15253 } 15254 continue; 15255 } 15256 15257 // If we got a member expression, we should not expect any array section 15258 // before that: 15259 // 15260 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15261 // If a list item is an element of a structure, only the rightmost symbol 15262 // of the variable reference can be an array section. 15263 // 15264 AllowUnitySizeArraySection = false; 15265 AllowWholeSizeArraySection = false; 15266 15267 // Record the component. 15268 CurComponents.emplace_back(CurE, FD); 15269 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 15270 E = CurE->getBase()->IgnoreParenImpCasts(); 15271 15272 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15273 if (!NoDiagnose) { 15274 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15275 << 0 << CurE->getSourceRange(); 15276 return nullptr; 15277 } 15278 continue; 15279 } 15280 15281 // If we got an array subscript that express the whole dimension we 15282 // can have any array expressions before. If it only expressing part of 15283 // the dimension, we can only have unitary-size array expressions. 15284 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 15285 E->getType())) 15286 AllowWholeSizeArraySection = false; 15287 15288 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15289 Expr::EvalResult Result; 15290 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 15291 if (!Result.Val.getInt().isNullValue()) { 15292 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15293 diag::err_omp_invalid_map_this_expr); 15294 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15295 diag::note_omp_invalid_subscript_on_this_ptr_map); 15296 } 15297 } 15298 RelevantExpr = TE; 15299 } 15300 15301 // Record the component - we don't have any declaration associated. 15302 CurComponents.emplace_back(CurE, nullptr); 15303 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 15304 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15305 E = CurE->getBase()->IgnoreParenImpCasts(); 15306 15307 QualType CurType = 15308 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15309 15310 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15311 // If the type of a list item is a reference to a type T then the type 15312 // will be considered to be T for all purposes of this clause. 15313 if (CurType->isReferenceType()) 15314 CurType = CurType->getPointeeType(); 15315 15316 bool IsPointer = CurType->isAnyPointerType(); 15317 15318 if (!IsPointer && !CurType->isArrayType()) { 15319 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15320 << 0 << CurE->getSourceRange(); 15321 return nullptr; 15322 } 15323 15324 bool NotWhole = 15325 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 15326 bool NotUnity = 15327 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 15328 15329 if (AllowWholeSizeArraySection) { 15330 // Any array section is currently allowed. Allowing a whole size array 15331 // section implies allowing a unity array section as well. 15332 // 15333 // If this array section refers to the whole dimension we can still 15334 // accept other array sections before this one, except if the base is a 15335 // pointer. Otherwise, only unitary sections are accepted. 15336 if (NotWhole || IsPointer) 15337 AllowWholeSizeArraySection = false; 15338 } else if (AllowUnitySizeArraySection && NotUnity) { 15339 // A unity or whole array section is not allowed and that is not 15340 // compatible with the properties of the current array section. 15341 SemaRef.Diag( 15342 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15343 << CurE->getSourceRange(); 15344 return nullptr; 15345 } 15346 15347 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15348 Expr::EvalResult ResultR; 15349 Expr::EvalResult ResultL; 15350 if (CurE->getLength()->EvaluateAsInt(ResultR, 15351 SemaRef.getASTContext())) { 15352 if (!ResultR.Val.getInt().isOneValue()) { 15353 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15354 diag::err_omp_invalid_map_this_expr); 15355 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15356 diag::note_omp_invalid_length_on_this_ptr_mapping); 15357 } 15358 } 15359 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 15360 ResultL, SemaRef.getASTContext())) { 15361 if (!ResultL.Val.getInt().isNullValue()) { 15362 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15363 diag::err_omp_invalid_map_this_expr); 15364 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15365 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15366 } 15367 } 15368 RelevantExpr = TE; 15369 } 15370 15371 // Record the component - we don't have any declaration associated. 15372 CurComponents.emplace_back(CurE, nullptr); 15373 } else { 15374 if (!NoDiagnose) { 15375 // If nothing else worked, this is not a valid map clause expression. 15376 SemaRef.Diag( 15377 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15378 << ERange; 15379 } 15380 return nullptr; 15381 } 15382 } 15383 15384 return RelevantExpr; 15385 } 15386 15387 // Return true if expression E associated with value VD has conflicts with other 15388 // map information. 15389 static bool checkMapConflicts( 15390 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15391 bool CurrentRegionOnly, 15392 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15393 OpenMPClauseKind CKind) { 15394 assert(VD && E); 15395 SourceLocation ELoc = E->getExprLoc(); 15396 SourceRange ERange = E->getSourceRange(); 15397 15398 // In order to easily check the conflicts we need to match each component of 15399 // the expression under test with the components of the expressions that are 15400 // already in the stack. 15401 15402 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15403 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15404 "Map clause expression with unexpected base!"); 15405 15406 // Variables to help detecting enclosing problems in data environment nests. 15407 bool IsEnclosedByDataEnvironmentExpr = false; 15408 const Expr *EnclosingExpr = nullptr; 15409 15410 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15411 VD, CurrentRegionOnly, 15412 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15413 ERange, CKind, &EnclosingExpr, 15414 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15415 StackComponents, 15416 OpenMPClauseKind) { 15417 assert(!StackComponents.empty() && 15418 "Map clause expression with no components!"); 15419 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15420 "Map clause expression with unexpected base!"); 15421 (void)VD; 15422 15423 // The whole expression in the stack. 15424 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15425 15426 // Expressions must start from the same base. Here we detect at which 15427 // point both expressions diverge from each other and see if we can 15428 // detect if the memory referred to both expressions is contiguous and 15429 // do not overlap. 15430 auto CI = CurComponents.rbegin(); 15431 auto CE = CurComponents.rend(); 15432 auto SI = StackComponents.rbegin(); 15433 auto SE = StackComponents.rend(); 15434 for (; CI != CE && SI != SE; ++CI, ++SI) { 15435 15436 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15437 // At most one list item can be an array item derived from a given 15438 // variable in map clauses of the same construct. 15439 if (CurrentRegionOnly && 15440 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15441 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15442 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15443 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15444 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15445 diag::err_omp_multiple_array_items_in_map_clause) 15446 << CI->getAssociatedExpression()->getSourceRange(); 15447 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15448 diag::note_used_here) 15449 << SI->getAssociatedExpression()->getSourceRange(); 15450 return true; 15451 } 15452 15453 // Do both expressions have the same kind? 15454 if (CI->getAssociatedExpression()->getStmtClass() != 15455 SI->getAssociatedExpression()->getStmtClass()) 15456 break; 15457 15458 // Are we dealing with different variables/fields? 15459 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15460 break; 15461 } 15462 // Check if the extra components of the expressions in the enclosing 15463 // data environment are redundant for the current base declaration. 15464 // If they are, the maps completely overlap, which is legal. 15465 for (; SI != SE; ++SI) { 15466 QualType Type; 15467 if (const auto *ASE = 15468 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15469 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15470 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15471 SI->getAssociatedExpression())) { 15472 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15473 Type = 15474 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15475 } 15476 if (Type.isNull() || Type->isAnyPointerType() || 15477 checkArrayExpressionDoesNotReferToWholeSize( 15478 SemaRef, SI->getAssociatedExpression(), Type)) 15479 break; 15480 } 15481 15482 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15483 // List items of map clauses in the same construct must not share 15484 // original storage. 15485 // 15486 // If the expressions are exactly the same or one is a subset of the 15487 // other, it means they are sharing storage. 15488 if (CI == CE && SI == SE) { 15489 if (CurrentRegionOnly) { 15490 if (CKind == OMPC_map) { 15491 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15492 } else { 15493 assert(CKind == OMPC_to || CKind == OMPC_from); 15494 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15495 << ERange; 15496 } 15497 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15498 << RE->getSourceRange(); 15499 return true; 15500 } 15501 // If we find the same expression in the enclosing data environment, 15502 // that is legal. 15503 IsEnclosedByDataEnvironmentExpr = true; 15504 return false; 15505 } 15506 15507 QualType DerivedType = 15508 std::prev(CI)->getAssociatedDeclaration()->getType(); 15509 SourceLocation DerivedLoc = 15510 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15511 15512 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15513 // If the type of a list item is a reference to a type T then the type 15514 // will be considered to be T for all purposes of this clause. 15515 DerivedType = DerivedType.getNonReferenceType(); 15516 15517 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15518 // A variable for which the type is pointer and an array section 15519 // derived from that variable must not appear as list items of map 15520 // clauses of the same construct. 15521 // 15522 // Also, cover one of the cases in: 15523 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15524 // If any part of the original storage of a list item has corresponding 15525 // storage in the device data environment, all of the original storage 15526 // must have corresponding storage in the device data environment. 15527 // 15528 if (DerivedType->isAnyPointerType()) { 15529 if (CI == CE || SI == SE) { 15530 SemaRef.Diag( 15531 DerivedLoc, 15532 diag::err_omp_pointer_mapped_along_with_derived_section) 15533 << DerivedLoc; 15534 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15535 << RE->getSourceRange(); 15536 return true; 15537 } 15538 if (CI->getAssociatedExpression()->getStmtClass() != 15539 SI->getAssociatedExpression()->getStmtClass() || 15540 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15541 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15542 assert(CI != CE && SI != SE); 15543 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15544 << DerivedLoc; 15545 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15546 << RE->getSourceRange(); 15547 return true; 15548 } 15549 } 15550 15551 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15552 // List items of map clauses in the same construct must not share 15553 // original storage. 15554 // 15555 // An expression is a subset of the other. 15556 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15557 if (CKind == OMPC_map) { 15558 if (CI != CE || SI != SE) { 15559 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15560 // a pointer. 15561 auto Begin = 15562 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15563 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15564 auto It = Begin; 15565 while (It != End && !It->getAssociatedDeclaration()) 15566 std::advance(It, 1); 15567 assert(It != End && 15568 "Expected at least one component with the declaration."); 15569 if (It != Begin && It->getAssociatedDeclaration() 15570 ->getType() 15571 .getCanonicalType() 15572 ->isAnyPointerType()) { 15573 IsEnclosedByDataEnvironmentExpr = false; 15574 EnclosingExpr = nullptr; 15575 return false; 15576 } 15577 } 15578 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15579 } else { 15580 assert(CKind == OMPC_to || CKind == OMPC_from); 15581 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15582 << ERange; 15583 } 15584 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15585 << RE->getSourceRange(); 15586 return true; 15587 } 15588 15589 // The current expression uses the same base as other expression in the 15590 // data environment but does not contain it completely. 15591 if (!CurrentRegionOnly && SI != SE) 15592 EnclosingExpr = RE; 15593 15594 // The current expression is a subset of the expression in the data 15595 // environment. 15596 IsEnclosedByDataEnvironmentExpr |= 15597 (!CurrentRegionOnly && CI != CE && SI == SE); 15598 15599 return false; 15600 }); 15601 15602 if (CurrentRegionOnly) 15603 return FoundError; 15604 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 must 15608 // have corresponding storage in the device data environment. 15609 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15610 // If a list item is an element of a structure, and a different element of 15611 // the structure has a corresponding list item in the device data environment 15612 // prior to a task encountering the construct associated with the map clause, 15613 // then the list item must also have a corresponding list item in the device 15614 // data environment prior to the task encountering the construct. 15615 // 15616 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15617 SemaRef.Diag(ELoc, 15618 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15619 << ERange; 15620 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15621 << EnclosingExpr->getSourceRange(); 15622 return true; 15623 } 15624 15625 return FoundError; 15626 } 15627 15628 // Look up the user-defined mapper given the mapper name and mapped type, and 15629 // build a reference to it. 15630 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15631 CXXScopeSpec &MapperIdScopeSpec, 15632 const DeclarationNameInfo &MapperId, 15633 QualType Type, 15634 Expr *UnresolvedMapper) { 15635 if (MapperIdScopeSpec.isInvalid()) 15636 return ExprError(); 15637 // Get the actual type for the array type. 15638 if (Type->isArrayType()) { 15639 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15640 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15641 } 15642 // Find all user-defined mappers with the given MapperId. 15643 SmallVector<UnresolvedSet<8>, 4> Lookups; 15644 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15645 Lookup.suppressDiagnostics(); 15646 if (S) { 15647 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15648 NamedDecl *D = Lookup.getRepresentativeDecl(); 15649 while (S && !S->isDeclScope(D)) 15650 S = S->getParent(); 15651 if (S) 15652 S = S->getParent(); 15653 Lookups.emplace_back(); 15654 Lookups.back().append(Lookup.begin(), Lookup.end()); 15655 Lookup.clear(); 15656 } 15657 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15658 // Extract the user-defined mappers with the given MapperId. 15659 Lookups.push_back(UnresolvedSet<8>()); 15660 for (NamedDecl *D : ULE->decls()) { 15661 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15662 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15663 Lookups.back().addDecl(DMD); 15664 } 15665 } 15666 // Defer the lookup for dependent types. The results will be passed through 15667 // UnresolvedMapper on instantiation. 15668 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15669 Type->isInstantiationDependentType() || 15670 Type->containsUnexpandedParameterPack() || 15671 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15672 return !D->isInvalidDecl() && 15673 (D->getType()->isDependentType() || 15674 D->getType()->isInstantiationDependentType() || 15675 D->getType()->containsUnexpandedParameterPack()); 15676 })) { 15677 UnresolvedSet<8> URS; 15678 for (const UnresolvedSet<8> &Set : Lookups) { 15679 if (Set.empty()) 15680 continue; 15681 URS.append(Set.begin(), Set.end()); 15682 } 15683 return UnresolvedLookupExpr::Create( 15684 SemaRef.Context, /*NamingClass=*/nullptr, 15685 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15686 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15687 } 15688 SourceLocation Loc = MapperId.getLoc(); 15689 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15690 // The type must be of struct, union or class type in C and C++ 15691 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15692 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15693 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15694 return ExprError(); 15695 } 15696 // Perform argument dependent lookup. 15697 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15698 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15699 // Return the first user-defined mapper with the desired type. 15700 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15701 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15702 if (!D->isInvalidDecl() && 15703 SemaRef.Context.hasSameType(D->getType(), Type)) 15704 return D; 15705 return nullptr; 15706 })) 15707 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15708 // Find the first user-defined mapper with a type derived from the desired 15709 // type. 15710 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15711 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15712 if (!D->isInvalidDecl() && 15713 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15714 !Type.isMoreQualifiedThan(D->getType())) 15715 return D; 15716 return nullptr; 15717 })) { 15718 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15719 /*DetectVirtual=*/false); 15720 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15721 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15722 VD->getType().getUnqualifiedType()))) { 15723 if (SemaRef.CheckBaseClassAccess( 15724 Loc, VD->getType(), Type, Paths.front(), 15725 /*DiagID=*/0) != Sema::AR_inaccessible) { 15726 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15727 } 15728 } 15729 } 15730 } 15731 // Report error if a mapper is specified, but cannot be found. 15732 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15733 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15734 << Type << MapperId.getName(); 15735 return ExprError(); 15736 } 15737 return ExprEmpty(); 15738 } 15739 15740 namespace { 15741 // Utility struct that gathers all the related lists associated with a mappable 15742 // expression. 15743 struct MappableVarListInfo { 15744 // The list of expressions. 15745 ArrayRef<Expr *> VarList; 15746 // The list of processed expressions. 15747 SmallVector<Expr *, 16> ProcessedVarList; 15748 // The mappble components for each expression. 15749 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15750 // The base declaration of the variable. 15751 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15752 // The reference to the user-defined mapper associated with every expression. 15753 SmallVector<Expr *, 16> UDMapperList; 15754 15755 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15756 // We have a list of components and base declarations for each entry in the 15757 // variable list. 15758 VarComponents.reserve(VarList.size()); 15759 VarBaseDeclarations.reserve(VarList.size()); 15760 } 15761 }; 15762 } 15763 15764 // Check the validity of the provided variable list for the provided clause kind 15765 // \a CKind. In the check process the valid expressions, mappable expression 15766 // components, variables, and user-defined mappers are extracted and used to 15767 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15768 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15769 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15770 static void checkMappableExpressionList( 15771 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15772 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15773 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15774 ArrayRef<Expr *> UnresolvedMappers, 15775 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15776 bool IsMapTypeImplicit = false) { 15777 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15778 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15779 "Unexpected clause kind with mappable expressions!"); 15780 15781 // If the identifier of user-defined mapper is not specified, it is "default". 15782 // We do not change the actual name in this clause to distinguish whether a 15783 // mapper is specified explicitly, i.e., it is not explicitly specified when 15784 // MapperId.getName() is empty. 15785 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15786 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15787 MapperId.setName(DeclNames.getIdentifier( 15788 &SemaRef.getASTContext().Idents.get("default"))); 15789 } 15790 15791 // Iterators to find the current unresolved mapper expression. 15792 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15793 bool UpdateUMIt = false; 15794 Expr *UnresolvedMapper = nullptr; 15795 15796 // Keep track of the mappable components and base declarations in this clause. 15797 // Each entry in the list is going to have a list of components associated. We 15798 // record each set of the components so that we can build the clause later on. 15799 // In the end we should have the same amount of declarations and component 15800 // lists. 15801 15802 for (Expr *RE : MVLI.VarList) { 15803 assert(RE && "Null expr in omp to/from/map clause"); 15804 SourceLocation ELoc = RE->getExprLoc(); 15805 15806 // Find the current unresolved mapper expression. 15807 if (UpdateUMIt && UMIt != UMEnd) { 15808 UMIt++; 15809 assert( 15810 UMIt != UMEnd && 15811 "Expect the size of UnresolvedMappers to match with that of VarList"); 15812 } 15813 UpdateUMIt = true; 15814 if (UMIt != UMEnd) 15815 UnresolvedMapper = *UMIt; 15816 15817 const Expr *VE = RE->IgnoreParenLValueCasts(); 15818 15819 if (VE->isValueDependent() || VE->isTypeDependent() || 15820 VE->isInstantiationDependent() || 15821 VE->containsUnexpandedParameterPack()) { 15822 // Try to find the associated user-defined mapper. 15823 ExprResult ER = buildUserDefinedMapperRef( 15824 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15825 VE->getType().getCanonicalType(), UnresolvedMapper); 15826 if (ER.isInvalid()) 15827 continue; 15828 MVLI.UDMapperList.push_back(ER.get()); 15829 // We can only analyze this information once the missing information is 15830 // resolved. 15831 MVLI.ProcessedVarList.push_back(RE); 15832 continue; 15833 } 15834 15835 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15836 15837 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15838 SemaRef.Diag(ELoc, 15839 diag::err_omp_expected_named_var_member_or_array_expression) 15840 << RE->getSourceRange(); 15841 continue; 15842 } 15843 15844 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15845 ValueDecl *CurDeclaration = nullptr; 15846 15847 // Obtain the array or member expression bases if required. Also, fill the 15848 // components array with all the components identified in the process. 15849 const Expr *BE = checkMapClauseExpressionBase( 15850 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15851 if (!BE) 15852 continue; 15853 15854 assert(!CurComponents.empty() && 15855 "Invalid mappable expression information."); 15856 15857 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15858 // Add store "this" pointer to class in DSAStackTy for future checking 15859 DSAS->addMappedClassesQualTypes(TE->getType()); 15860 // Try to find the associated user-defined mapper. 15861 ExprResult ER = buildUserDefinedMapperRef( 15862 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15863 VE->getType().getCanonicalType(), UnresolvedMapper); 15864 if (ER.isInvalid()) 15865 continue; 15866 MVLI.UDMapperList.push_back(ER.get()); 15867 // Skip restriction checking for variable or field declarations 15868 MVLI.ProcessedVarList.push_back(RE); 15869 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15870 MVLI.VarComponents.back().append(CurComponents.begin(), 15871 CurComponents.end()); 15872 MVLI.VarBaseDeclarations.push_back(nullptr); 15873 continue; 15874 } 15875 15876 // For the following checks, we rely on the base declaration which is 15877 // expected to be associated with the last component. The declaration is 15878 // expected to be a variable or a field (if 'this' is being mapped). 15879 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15880 assert(CurDeclaration && "Null decl on map clause."); 15881 assert( 15882 CurDeclaration->isCanonicalDecl() && 15883 "Expecting components to have associated only canonical declarations."); 15884 15885 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15886 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15887 15888 assert((VD || FD) && "Only variables or fields are expected here!"); 15889 (void)FD; 15890 15891 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15892 // threadprivate variables cannot appear in a map clause. 15893 // OpenMP 4.5 [2.10.5, target update Construct] 15894 // threadprivate variables cannot appear in a from clause. 15895 if (VD && DSAS->isThreadPrivate(VD)) { 15896 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15897 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15898 << getOpenMPClauseName(CKind); 15899 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15900 continue; 15901 } 15902 15903 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15904 // A list item cannot appear in both a map clause and a data-sharing 15905 // attribute clause on the same construct. 15906 15907 // Check conflicts with other map clause expressions. We check the conflicts 15908 // with the current construct separately from the enclosing data 15909 // environment, because the restrictions are different. We only have to 15910 // check conflicts across regions for the map clauses. 15911 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15912 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15913 break; 15914 if (CKind == OMPC_map && 15915 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15916 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15917 break; 15918 15919 // OpenMP 4.5 [2.10.5, target update Construct] 15920 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15921 // If the type of a list item is a reference to a type T then the type will 15922 // be considered to be T for all purposes of this clause. 15923 auto I = llvm::find_if( 15924 CurComponents, 15925 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15926 return MC.getAssociatedDeclaration(); 15927 }); 15928 assert(I != CurComponents.end() && "Null decl on map clause."); 15929 QualType Type = 15930 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15931 15932 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15933 // A list item in a to or from clause must have a mappable type. 15934 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15935 // A list item must have a mappable type. 15936 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15937 DSAS, Type)) 15938 continue; 15939 15940 if (CKind == OMPC_map) { 15941 // target enter data 15942 // OpenMP [2.10.2, Restrictions, p. 99] 15943 // A map-type must be specified in all map clauses and must be either 15944 // to or alloc. 15945 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15946 if (DKind == OMPD_target_enter_data && 15947 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15948 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15949 << (IsMapTypeImplicit ? 1 : 0) 15950 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15951 << getOpenMPDirectiveName(DKind); 15952 continue; 15953 } 15954 15955 // target exit_data 15956 // OpenMP [2.10.3, Restrictions, p. 102] 15957 // A map-type must be specified in all map clauses and must be either 15958 // from, release, or delete. 15959 if (DKind == OMPD_target_exit_data && 15960 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15961 MapType == OMPC_MAP_delete)) { 15962 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15963 << (IsMapTypeImplicit ? 1 : 0) 15964 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15965 << getOpenMPDirectiveName(DKind); 15966 continue; 15967 } 15968 15969 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15970 // A list item cannot appear in both a map clause and a data-sharing 15971 // attribute clause on the same construct 15972 // 15973 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15974 // A list item cannot appear in both a map clause and a data-sharing 15975 // attribute clause on the same construct unless the construct is a 15976 // combined construct. 15977 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15978 isOpenMPTargetExecutionDirective(DKind)) || 15979 DKind == OMPD_target)) { 15980 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15981 if (isOpenMPPrivate(DVar.CKind)) { 15982 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15983 << getOpenMPClauseName(DVar.CKind) 15984 << getOpenMPClauseName(OMPC_map) 15985 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15986 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15987 continue; 15988 } 15989 } 15990 } 15991 15992 // Try to find the associated user-defined mapper. 15993 ExprResult ER = buildUserDefinedMapperRef( 15994 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15995 Type.getCanonicalType(), UnresolvedMapper); 15996 if (ER.isInvalid()) 15997 continue; 15998 MVLI.UDMapperList.push_back(ER.get()); 15999 16000 // Save the current expression. 16001 MVLI.ProcessedVarList.push_back(RE); 16002 16003 // Store the components in the stack so that they can be used to check 16004 // against other clauses later on. 16005 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 16006 /*WhereFoundClauseKind=*/OMPC_map); 16007 16008 // Save the components and declaration to create the clause. For purposes of 16009 // the clause creation, any component list that has has base 'this' uses 16010 // null as base declaration. 16011 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16012 MVLI.VarComponents.back().append(CurComponents.begin(), 16013 CurComponents.end()); 16014 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 16015 : CurDeclaration); 16016 } 16017 } 16018 16019 OMPClause *Sema::ActOnOpenMPMapClause( 16020 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 16021 ArrayRef<SourceLocation> MapTypeModifiersLoc, 16022 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 16023 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 16024 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 16025 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 16026 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 16027 OMPC_MAP_MODIFIER_unknown, 16028 OMPC_MAP_MODIFIER_unknown}; 16029 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 16030 16031 // Process map-type-modifiers, flag errors for duplicate modifiers. 16032 unsigned Count = 0; 16033 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 16034 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 16035 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 16036 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 16037 continue; 16038 } 16039 assert(Count < OMPMapClause::NumberOfModifiers && 16040 "Modifiers exceed the allowed number of map type modifiers"); 16041 Modifiers[Count] = MapTypeModifiers[I]; 16042 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 16043 ++Count; 16044 } 16045 16046 MappableVarListInfo MVLI(VarList); 16047 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 16048 MapperIdScopeSpec, MapperId, UnresolvedMappers, 16049 MapType, IsMapTypeImplicit); 16050 16051 // We need to produce a map clause even if we don't have variables so that 16052 // other diagnostics related with non-existing map clauses are accurate. 16053 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 16054 MVLI.VarBaseDeclarations, MVLI.VarComponents, 16055 MVLI.UDMapperList, Modifiers, ModifiersLoc, 16056 MapperIdScopeSpec.getWithLocInContext(Context), 16057 MapperId, MapType, IsMapTypeImplicit, MapLoc); 16058 } 16059 16060 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 16061 TypeResult ParsedType) { 16062 assert(ParsedType.isUsable()); 16063 16064 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 16065 if (ReductionType.isNull()) 16066 return QualType(); 16067 16068 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 16069 // A type name in a declare reduction directive cannot be a function type, an 16070 // array type, a reference type, or a type qualified with const, volatile or 16071 // restrict. 16072 if (ReductionType.hasQualifiers()) { 16073 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 16074 return QualType(); 16075 } 16076 16077 if (ReductionType->isFunctionType()) { 16078 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 16079 return QualType(); 16080 } 16081 if (ReductionType->isReferenceType()) { 16082 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 16083 return QualType(); 16084 } 16085 if (ReductionType->isArrayType()) { 16086 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 16087 return QualType(); 16088 } 16089 return ReductionType; 16090 } 16091 16092 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 16093 Scope *S, DeclContext *DC, DeclarationName Name, 16094 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 16095 AccessSpecifier AS, Decl *PrevDeclInScope) { 16096 SmallVector<Decl *, 8> Decls; 16097 Decls.reserve(ReductionTypes.size()); 16098 16099 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 16100 forRedeclarationInCurContext()); 16101 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 16102 // A reduction-identifier may not be re-declared in the current scope for the 16103 // same type or for a type that is compatible according to the base language 16104 // rules. 16105 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16106 OMPDeclareReductionDecl *PrevDRD = nullptr; 16107 bool InCompoundScope = true; 16108 if (S != nullptr) { 16109 // Find previous declaration with the same name not referenced in other 16110 // declarations. 16111 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16112 InCompoundScope = 16113 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16114 LookupName(Lookup, S); 16115 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16116 /*AllowInlineNamespace=*/false); 16117 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 16118 LookupResult::Filter Filter = Lookup.makeFilter(); 16119 while (Filter.hasNext()) { 16120 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 16121 if (InCompoundScope) { 16122 auto I = UsedAsPrevious.find(PrevDecl); 16123 if (I == UsedAsPrevious.end()) 16124 UsedAsPrevious[PrevDecl] = false; 16125 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 16126 UsedAsPrevious[D] = true; 16127 } 16128 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16129 PrevDecl->getLocation(); 16130 } 16131 Filter.done(); 16132 if (InCompoundScope) { 16133 for (const auto &PrevData : UsedAsPrevious) { 16134 if (!PrevData.second) { 16135 PrevDRD = PrevData.first; 16136 break; 16137 } 16138 } 16139 } 16140 } else if (PrevDeclInScope != nullptr) { 16141 auto *PrevDRDInScope = PrevDRD = 16142 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 16143 do { 16144 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 16145 PrevDRDInScope->getLocation(); 16146 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 16147 } while (PrevDRDInScope != nullptr); 16148 } 16149 for (const auto &TyData : ReductionTypes) { 16150 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 16151 bool Invalid = false; 16152 if (I != PreviousRedeclTypes.end()) { 16153 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 16154 << TyData.first; 16155 Diag(I->second, diag::note_previous_definition); 16156 Invalid = true; 16157 } 16158 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 16159 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 16160 Name, TyData.first, PrevDRD); 16161 DC->addDecl(DRD); 16162 DRD->setAccess(AS); 16163 Decls.push_back(DRD); 16164 if (Invalid) 16165 DRD->setInvalidDecl(); 16166 else 16167 PrevDRD = DRD; 16168 } 16169 16170 return DeclGroupPtrTy::make( 16171 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 16172 } 16173 16174 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 16175 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16176 16177 // Enter new function scope. 16178 PushFunctionScope(); 16179 setFunctionHasBranchProtectedScope(); 16180 getCurFunction()->setHasOMPDeclareReductionCombiner(); 16181 16182 if (S != nullptr) 16183 PushDeclContext(S, DRD); 16184 else 16185 CurContext = DRD; 16186 16187 PushExpressionEvaluationContext( 16188 ExpressionEvaluationContext::PotentiallyEvaluated); 16189 16190 QualType ReductionType = DRD->getType(); 16191 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 16192 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 16193 // uses semantics of argument handles by value, but it should be passed by 16194 // reference. C lang does not support references, so pass all parameters as 16195 // pointers. 16196 // Create 'T omp_in;' variable. 16197 VarDecl *OmpInParm = 16198 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16199 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16200 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16201 // uses semantics of argument handles by value, but it should be passed by 16202 // reference. C lang does not support references, so pass all parameters as 16203 // pointers. 16204 // Create 'T omp_out;' variable. 16205 VarDecl *OmpOutParm = 16206 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16207 if (S != nullptr) { 16208 PushOnScopeChains(OmpInParm, S); 16209 PushOnScopeChains(OmpOutParm, S); 16210 } else { 16211 DRD->addDecl(OmpInParm); 16212 DRD->addDecl(OmpOutParm); 16213 } 16214 Expr *InE = 16215 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16216 Expr *OutE = 16217 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16218 DRD->setCombinerData(InE, OutE); 16219 } 16220 16221 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16222 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16223 DiscardCleanupsInEvaluationContext(); 16224 PopExpressionEvaluationContext(); 16225 16226 PopDeclContext(); 16227 PopFunctionScopeInfo(); 16228 16229 if (Combiner != nullptr) 16230 DRD->setCombiner(Combiner); 16231 else 16232 DRD->setInvalidDecl(); 16233 } 16234 16235 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16236 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16237 16238 // Enter new function scope. 16239 PushFunctionScope(); 16240 setFunctionHasBranchProtectedScope(); 16241 16242 if (S != nullptr) 16243 PushDeclContext(S, DRD); 16244 else 16245 CurContext = DRD; 16246 16247 PushExpressionEvaluationContext( 16248 ExpressionEvaluationContext::PotentiallyEvaluated); 16249 16250 QualType ReductionType = DRD->getType(); 16251 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16252 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16253 // uses semantics of argument handles by value, but it should be passed by 16254 // reference. C lang does not support references, so pass all parameters as 16255 // pointers. 16256 // Create 'T omp_priv;' variable. 16257 VarDecl *OmpPrivParm = 16258 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16259 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16260 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16261 // uses semantics of argument handles by value, but it should be passed by 16262 // reference. C lang does not support references, so pass all parameters as 16263 // pointers. 16264 // Create 'T omp_orig;' variable. 16265 VarDecl *OmpOrigParm = 16266 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16267 if (S != nullptr) { 16268 PushOnScopeChains(OmpPrivParm, S); 16269 PushOnScopeChains(OmpOrigParm, S); 16270 } else { 16271 DRD->addDecl(OmpPrivParm); 16272 DRD->addDecl(OmpOrigParm); 16273 } 16274 Expr *OrigE = 16275 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16276 Expr *PrivE = 16277 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16278 DRD->setInitializerData(OrigE, PrivE); 16279 return OmpPrivParm; 16280 } 16281 16282 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16283 VarDecl *OmpPrivParm) { 16284 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16285 DiscardCleanupsInEvaluationContext(); 16286 PopExpressionEvaluationContext(); 16287 16288 PopDeclContext(); 16289 PopFunctionScopeInfo(); 16290 16291 if (Initializer != nullptr) { 16292 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16293 } else if (OmpPrivParm->hasInit()) { 16294 DRD->setInitializer(OmpPrivParm->getInit(), 16295 OmpPrivParm->isDirectInit() 16296 ? OMPDeclareReductionDecl::DirectInit 16297 : OMPDeclareReductionDecl::CopyInit); 16298 } else { 16299 DRD->setInvalidDecl(); 16300 } 16301 } 16302 16303 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16304 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16305 for (Decl *D : DeclReductions.get()) { 16306 if (IsValid) { 16307 if (S) 16308 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16309 /*AddToContext=*/false); 16310 } else { 16311 D->setInvalidDecl(); 16312 } 16313 } 16314 return DeclReductions; 16315 } 16316 16317 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16318 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16319 QualType T = TInfo->getType(); 16320 if (D.isInvalidType()) 16321 return true; 16322 16323 if (getLangOpts().CPlusPlus) { 16324 // Check that there are no default arguments (C++ only). 16325 CheckExtraCXXDefaultArguments(D); 16326 } 16327 16328 return CreateParsedType(T, TInfo); 16329 } 16330 16331 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16332 TypeResult ParsedType) { 16333 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16334 16335 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16336 assert(!MapperType.isNull() && "Expect valid mapper type"); 16337 16338 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16339 // The type must be of struct, union or class type in C and C++ 16340 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16341 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16342 return QualType(); 16343 } 16344 return MapperType; 16345 } 16346 16347 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16348 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16349 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16350 Decl *PrevDeclInScope) { 16351 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16352 forRedeclarationInCurContext()); 16353 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16354 // A mapper-identifier may not be redeclared in the current scope for the 16355 // same type or for a type that is compatible according to the base language 16356 // rules. 16357 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16358 OMPDeclareMapperDecl *PrevDMD = nullptr; 16359 bool InCompoundScope = true; 16360 if (S != nullptr) { 16361 // Find previous declaration with the same name not referenced in other 16362 // declarations. 16363 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16364 InCompoundScope = 16365 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16366 LookupName(Lookup, S); 16367 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16368 /*AllowInlineNamespace=*/false); 16369 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16370 LookupResult::Filter Filter = Lookup.makeFilter(); 16371 while (Filter.hasNext()) { 16372 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16373 if (InCompoundScope) { 16374 auto I = UsedAsPrevious.find(PrevDecl); 16375 if (I == UsedAsPrevious.end()) 16376 UsedAsPrevious[PrevDecl] = false; 16377 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16378 UsedAsPrevious[D] = true; 16379 } 16380 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16381 PrevDecl->getLocation(); 16382 } 16383 Filter.done(); 16384 if (InCompoundScope) { 16385 for (const auto &PrevData : UsedAsPrevious) { 16386 if (!PrevData.second) { 16387 PrevDMD = PrevData.first; 16388 break; 16389 } 16390 } 16391 } 16392 } else if (PrevDeclInScope) { 16393 auto *PrevDMDInScope = PrevDMD = 16394 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16395 do { 16396 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16397 PrevDMDInScope->getLocation(); 16398 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16399 } while (PrevDMDInScope != nullptr); 16400 } 16401 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16402 bool Invalid = false; 16403 if (I != PreviousRedeclTypes.end()) { 16404 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16405 << MapperType << Name; 16406 Diag(I->second, diag::note_previous_definition); 16407 Invalid = true; 16408 } 16409 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16410 MapperType, VN, PrevDMD); 16411 DC->addDecl(DMD); 16412 DMD->setAccess(AS); 16413 if (Invalid) 16414 DMD->setInvalidDecl(); 16415 16416 // Enter new function scope. 16417 PushFunctionScope(); 16418 setFunctionHasBranchProtectedScope(); 16419 16420 CurContext = DMD; 16421 16422 return DMD; 16423 } 16424 16425 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16426 Scope *S, 16427 QualType MapperType, 16428 SourceLocation StartLoc, 16429 DeclarationName VN) { 16430 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16431 if (S) 16432 PushOnScopeChains(VD, S); 16433 else 16434 DMD->addDecl(VD); 16435 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16436 DMD->setMapperVarRef(MapperVarRefExpr); 16437 } 16438 16439 Sema::DeclGroupPtrTy 16440 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16441 ArrayRef<OMPClause *> ClauseList) { 16442 PopDeclContext(); 16443 PopFunctionScopeInfo(); 16444 16445 if (D) { 16446 if (S) 16447 PushOnScopeChains(D, S, /*AddToContext=*/false); 16448 D->CreateClauses(Context, ClauseList); 16449 } 16450 16451 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16452 } 16453 16454 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16455 SourceLocation StartLoc, 16456 SourceLocation LParenLoc, 16457 SourceLocation EndLoc) { 16458 Expr *ValExpr = NumTeams; 16459 Stmt *HelperValStmt = nullptr; 16460 16461 // OpenMP [teams Constrcut, Restrictions] 16462 // The num_teams expression must evaluate to a positive integer value. 16463 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16464 /*StrictlyPositive=*/true)) 16465 return nullptr; 16466 16467 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16468 OpenMPDirectiveKind CaptureRegion = 16469 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 16470 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16471 ValExpr = MakeFullExpr(ValExpr).get(); 16472 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16473 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16474 HelperValStmt = buildPreInits(Context, Captures); 16475 } 16476 16477 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16478 StartLoc, LParenLoc, EndLoc); 16479 } 16480 16481 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16482 SourceLocation StartLoc, 16483 SourceLocation LParenLoc, 16484 SourceLocation EndLoc) { 16485 Expr *ValExpr = ThreadLimit; 16486 Stmt *HelperValStmt = nullptr; 16487 16488 // OpenMP [teams Constrcut, Restrictions] 16489 // The thread_limit expression must evaluate to a positive integer value. 16490 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16491 /*StrictlyPositive=*/true)) 16492 return nullptr; 16493 16494 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16495 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 16496 DKind, OMPC_thread_limit, LangOpts.OpenMP); 16497 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16498 ValExpr = MakeFullExpr(ValExpr).get(); 16499 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16500 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16501 HelperValStmt = buildPreInits(Context, Captures); 16502 } 16503 16504 return new (Context) OMPThreadLimitClause( 16505 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16506 } 16507 16508 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16509 SourceLocation StartLoc, 16510 SourceLocation LParenLoc, 16511 SourceLocation EndLoc) { 16512 Expr *ValExpr = Priority; 16513 Stmt *HelperValStmt = nullptr; 16514 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16515 16516 // OpenMP [2.9.1, task Constrcut] 16517 // The priority-value is a non-negative numerical scalar expression. 16518 if (!isNonNegativeIntegerValue( 16519 ValExpr, *this, OMPC_priority, 16520 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16521 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16522 return nullptr; 16523 16524 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16525 StartLoc, LParenLoc, EndLoc); 16526 } 16527 16528 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16529 SourceLocation StartLoc, 16530 SourceLocation LParenLoc, 16531 SourceLocation EndLoc) { 16532 Expr *ValExpr = Grainsize; 16533 Stmt *HelperValStmt = nullptr; 16534 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16535 16536 // OpenMP [2.9.2, taskloop Constrcut] 16537 // The parameter of the grainsize clause must be a positive integer 16538 // expression. 16539 if (!isNonNegativeIntegerValue( 16540 ValExpr, *this, OMPC_grainsize, 16541 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16542 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16543 return nullptr; 16544 16545 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16546 StartLoc, LParenLoc, EndLoc); 16547 } 16548 16549 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16550 SourceLocation StartLoc, 16551 SourceLocation LParenLoc, 16552 SourceLocation EndLoc) { 16553 Expr *ValExpr = NumTasks; 16554 Stmt *HelperValStmt = nullptr; 16555 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16556 16557 // OpenMP [2.9.2, taskloop Constrcut] 16558 // The parameter of the num_tasks clause must be a positive integer 16559 // expression. 16560 if (!isNonNegativeIntegerValue( 16561 ValExpr, *this, OMPC_num_tasks, 16562 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16563 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16564 return nullptr; 16565 16566 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16567 StartLoc, LParenLoc, EndLoc); 16568 } 16569 16570 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16571 SourceLocation LParenLoc, 16572 SourceLocation EndLoc) { 16573 // OpenMP [2.13.2, critical construct, Description] 16574 // ... where hint-expression is an integer constant expression that evaluates 16575 // to a valid lock hint. 16576 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16577 if (HintExpr.isInvalid()) 16578 return nullptr; 16579 return new (Context) 16580 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16581 } 16582 16583 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16584 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16585 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16586 SourceLocation EndLoc) { 16587 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16588 std::string Values; 16589 Values += "'"; 16590 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16591 Values += "'"; 16592 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16593 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16594 return nullptr; 16595 } 16596 Expr *ValExpr = ChunkSize; 16597 Stmt *HelperValStmt = nullptr; 16598 if (ChunkSize) { 16599 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16600 !ChunkSize->isInstantiationDependent() && 16601 !ChunkSize->containsUnexpandedParameterPack()) { 16602 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16603 ExprResult Val = 16604 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16605 if (Val.isInvalid()) 16606 return nullptr; 16607 16608 ValExpr = Val.get(); 16609 16610 // OpenMP [2.7.1, Restrictions] 16611 // chunk_size must be a loop invariant integer expression with a positive 16612 // value. 16613 llvm::APSInt Result; 16614 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16615 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16616 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16617 << "dist_schedule" << ChunkSize->getSourceRange(); 16618 return nullptr; 16619 } 16620 } else if (getOpenMPCaptureRegionForClause( 16621 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 16622 LangOpts.OpenMP) != OMPD_unknown && 16623 !CurContext->isDependentContext()) { 16624 ValExpr = MakeFullExpr(ValExpr).get(); 16625 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16626 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16627 HelperValStmt = buildPreInits(Context, Captures); 16628 } 16629 } 16630 } 16631 16632 return new (Context) 16633 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16634 Kind, ValExpr, HelperValStmt); 16635 } 16636 16637 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16638 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16639 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16640 SourceLocation KindLoc, SourceLocation EndLoc) { 16641 if (getLangOpts().OpenMP < 50) { 16642 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 16643 Kind != OMPC_DEFAULTMAP_scalar) { 16644 std::string Value; 16645 SourceLocation Loc; 16646 Value += "'"; 16647 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16648 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16649 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16650 Loc = MLoc; 16651 } else { 16652 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16653 OMPC_DEFAULTMAP_scalar); 16654 Loc = KindLoc; 16655 } 16656 Value += "'"; 16657 Diag(Loc, diag::err_omp_unexpected_clause_value) 16658 << Value << getOpenMPClauseName(OMPC_defaultmap); 16659 return nullptr; 16660 } 16661 } else { 16662 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 16663 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 16664 if (!isDefaultmapKind || !isDefaultmapModifier) { 16665 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 16666 "'firstprivate', 'none', 'default'"; 16667 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 16668 if (!isDefaultmapKind && isDefaultmapModifier) { 16669 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16670 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16671 } else if (isDefaultmapKind && !isDefaultmapModifier) { 16672 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16673 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16674 } else { 16675 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16676 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16677 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16678 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16679 } 16680 return nullptr; 16681 } 16682 16683 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 16684 // At most one defaultmap clause for each category can appear on the 16685 // directive. 16686 if (DSAStack->checkDefaultmapCategory(Kind)) { 16687 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 16688 return nullptr; 16689 } 16690 } 16691 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 16692 16693 return new (Context) 16694 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16695 } 16696 16697 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16698 DeclContext *CurLexicalContext = getCurLexicalContext(); 16699 if (!CurLexicalContext->isFileContext() && 16700 !CurLexicalContext->isExternCContext() && 16701 !CurLexicalContext->isExternCXXContext() && 16702 !isa<CXXRecordDecl>(CurLexicalContext) && 16703 !isa<ClassTemplateDecl>(CurLexicalContext) && 16704 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16705 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16706 Diag(Loc, diag::err_omp_region_not_file_context); 16707 return false; 16708 } 16709 ++DeclareTargetNestingLevel; 16710 return true; 16711 } 16712 16713 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16714 assert(DeclareTargetNestingLevel > 0 && 16715 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16716 --DeclareTargetNestingLevel; 16717 } 16718 16719 NamedDecl * 16720 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16721 const DeclarationNameInfo &Id, 16722 NamedDeclSetType &SameDirectiveDecls) { 16723 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16724 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16725 16726 if (Lookup.isAmbiguous()) 16727 return nullptr; 16728 Lookup.suppressDiagnostics(); 16729 16730 if (!Lookup.isSingleResult()) { 16731 VarOrFuncDeclFilterCCC CCC(*this); 16732 if (TypoCorrection Corrected = 16733 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16734 CTK_ErrorRecovery)) { 16735 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16736 << Id.getName()); 16737 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16738 return nullptr; 16739 } 16740 16741 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16742 return nullptr; 16743 } 16744 16745 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16746 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16747 !isa<FunctionTemplateDecl>(ND)) { 16748 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16749 return nullptr; 16750 } 16751 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16752 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16753 return ND; 16754 } 16755 16756 void Sema::ActOnOpenMPDeclareTargetName( 16757 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16758 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16759 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16760 isa<FunctionTemplateDecl>(ND)) && 16761 "Expected variable, function or function template."); 16762 16763 // Diagnose marking after use as it may lead to incorrect diagnosis and 16764 // codegen. 16765 if (LangOpts.OpenMP >= 50 && 16766 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16767 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16768 16769 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16770 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16771 if (DevTy.hasValue() && *DevTy != DT) { 16772 Diag(Loc, diag::err_omp_device_type_mismatch) 16773 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16774 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16775 return; 16776 } 16777 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16778 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16779 if (!Res) { 16780 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16781 SourceRange(Loc, Loc)); 16782 ND->addAttr(A); 16783 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16784 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16785 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16786 } else if (*Res != MT) { 16787 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16788 } 16789 } 16790 16791 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16792 Sema &SemaRef, Decl *D) { 16793 if (!D || !isa<VarDecl>(D)) 16794 return; 16795 auto *VD = cast<VarDecl>(D); 16796 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16797 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16798 if (SemaRef.LangOpts.OpenMP >= 50 && 16799 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16800 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16801 VD->hasGlobalStorage()) { 16802 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16803 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16804 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16805 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16806 // If a lambda declaration and definition appears between a 16807 // declare target directive and the matching end declare target 16808 // directive, all variables that are captured by the lambda 16809 // expression must also appear in a to clause. 16810 SemaRef.Diag(VD->getLocation(), 16811 diag::err_omp_lambda_capture_in_declare_target_not_to); 16812 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16813 << VD << 0 << SR; 16814 return; 16815 } 16816 } 16817 if (MapTy.hasValue()) 16818 return; 16819 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16820 SemaRef.Diag(SL, diag::note_used_here) << SR; 16821 } 16822 16823 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16824 Sema &SemaRef, DSAStackTy *Stack, 16825 ValueDecl *VD) { 16826 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16827 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16828 /*FullCheck=*/false); 16829 } 16830 16831 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16832 SourceLocation IdLoc) { 16833 if (!D || D->isInvalidDecl()) 16834 return; 16835 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16836 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16837 if (auto *VD = dyn_cast<VarDecl>(D)) { 16838 // Only global variables can be marked as declare target. 16839 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16840 !VD->isStaticDataMember()) 16841 return; 16842 // 2.10.6: threadprivate variable cannot appear in a declare target 16843 // directive. 16844 if (DSAStack->isThreadPrivate(VD)) { 16845 Diag(SL, diag::err_omp_threadprivate_in_target); 16846 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16847 return; 16848 } 16849 } 16850 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16851 D = FTD->getTemplatedDecl(); 16852 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16853 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16854 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16855 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16856 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16857 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16858 return; 16859 } 16860 // Mark the function as must be emitted for the device. 16861 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16862 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16863 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16864 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16865 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16866 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16867 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16868 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16869 } 16870 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16871 // Problem if any with var declared with incomplete type will be reported 16872 // as normal, so no need to check it here. 16873 if ((E || !VD->getType()->isIncompleteType()) && 16874 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16875 return; 16876 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16877 // Checking declaration inside declare target region. 16878 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16879 isa<FunctionTemplateDecl>(D)) { 16880 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16881 Context, OMPDeclareTargetDeclAttr::MT_To, 16882 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16883 D->addAttr(A); 16884 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16885 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16886 } 16887 return; 16888 } 16889 } 16890 if (!E) 16891 return; 16892 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16893 } 16894 16895 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16896 CXXScopeSpec &MapperIdScopeSpec, 16897 DeclarationNameInfo &MapperId, 16898 const OMPVarListLocTy &Locs, 16899 ArrayRef<Expr *> UnresolvedMappers) { 16900 MappableVarListInfo MVLI(VarList); 16901 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16902 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16903 if (MVLI.ProcessedVarList.empty()) 16904 return nullptr; 16905 16906 return OMPToClause::Create( 16907 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16908 MVLI.VarComponents, MVLI.UDMapperList, 16909 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16910 } 16911 16912 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16913 CXXScopeSpec &MapperIdScopeSpec, 16914 DeclarationNameInfo &MapperId, 16915 const OMPVarListLocTy &Locs, 16916 ArrayRef<Expr *> UnresolvedMappers) { 16917 MappableVarListInfo MVLI(VarList); 16918 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16919 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16920 if (MVLI.ProcessedVarList.empty()) 16921 return nullptr; 16922 16923 return OMPFromClause::Create( 16924 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16925 MVLI.VarComponents, MVLI.UDMapperList, 16926 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16927 } 16928 16929 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16930 const OMPVarListLocTy &Locs) { 16931 MappableVarListInfo MVLI(VarList); 16932 SmallVector<Expr *, 8> PrivateCopies; 16933 SmallVector<Expr *, 8> Inits; 16934 16935 for (Expr *RefExpr : VarList) { 16936 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16937 SourceLocation ELoc; 16938 SourceRange ERange; 16939 Expr *SimpleRefExpr = RefExpr; 16940 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16941 if (Res.second) { 16942 // It will be analyzed later. 16943 MVLI.ProcessedVarList.push_back(RefExpr); 16944 PrivateCopies.push_back(nullptr); 16945 Inits.push_back(nullptr); 16946 } 16947 ValueDecl *D = Res.first; 16948 if (!D) 16949 continue; 16950 16951 QualType Type = D->getType(); 16952 Type = Type.getNonReferenceType().getUnqualifiedType(); 16953 16954 auto *VD = dyn_cast<VarDecl>(D); 16955 16956 // Item should be a pointer or reference to pointer. 16957 if (!Type->isPointerType()) { 16958 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16959 << 0 << RefExpr->getSourceRange(); 16960 continue; 16961 } 16962 16963 // Build the private variable and the expression that refers to it. 16964 auto VDPrivate = 16965 buildVarDecl(*this, ELoc, Type, D->getName(), 16966 D->hasAttrs() ? &D->getAttrs() : nullptr, 16967 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16968 if (VDPrivate->isInvalidDecl()) 16969 continue; 16970 16971 CurContext->addDecl(VDPrivate); 16972 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16973 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16974 16975 // Add temporary variable to initialize the private copy of the pointer. 16976 VarDecl *VDInit = 16977 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16978 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16979 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16980 AddInitializerToDecl(VDPrivate, 16981 DefaultLvalueConversion(VDInitRefExpr).get(), 16982 /*DirectInit=*/false); 16983 16984 // If required, build a capture to implement the privatization initialized 16985 // with the current list item value. 16986 DeclRefExpr *Ref = nullptr; 16987 if (!VD) 16988 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16989 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16990 PrivateCopies.push_back(VDPrivateRefExpr); 16991 Inits.push_back(VDInitRefExpr); 16992 16993 // We need to add a data sharing attribute for this variable to make sure it 16994 // is correctly captured. A variable that shows up in a use_device_ptr has 16995 // similar properties of a first private variable. 16996 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16997 16998 // Create a mappable component for the list item. List items in this clause 16999 // only need a component. 17000 MVLI.VarBaseDeclarations.push_back(D); 17001 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17002 MVLI.VarComponents.back().push_back( 17003 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 17004 } 17005 17006 if (MVLI.ProcessedVarList.empty()) 17007 return nullptr; 17008 17009 return OMPUseDevicePtrClause::Create( 17010 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 17011 MVLI.VarBaseDeclarations, MVLI.VarComponents); 17012 } 17013 17014 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 17015 const OMPVarListLocTy &Locs) { 17016 MappableVarListInfo MVLI(VarList); 17017 for (Expr *RefExpr : VarList) { 17018 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 17019 SourceLocation ELoc; 17020 SourceRange ERange; 17021 Expr *SimpleRefExpr = RefExpr; 17022 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17023 if (Res.second) { 17024 // It will be analyzed later. 17025 MVLI.ProcessedVarList.push_back(RefExpr); 17026 } 17027 ValueDecl *D = Res.first; 17028 if (!D) 17029 continue; 17030 17031 QualType Type = D->getType(); 17032 // item should be a pointer or array or reference to pointer or array 17033 if (!Type.getNonReferenceType()->isPointerType() && 17034 !Type.getNonReferenceType()->isArrayType()) { 17035 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 17036 << 0 << RefExpr->getSourceRange(); 17037 continue; 17038 } 17039 17040 // Check if the declaration in the clause does not show up in any data 17041 // sharing attribute. 17042 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17043 if (isOpenMPPrivate(DVar.CKind)) { 17044 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17045 << getOpenMPClauseName(DVar.CKind) 17046 << getOpenMPClauseName(OMPC_is_device_ptr) 17047 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17048 reportOriginalDsa(*this, DSAStack, D, DVar); 17049 continue; 17050 } 17051 17052 const Expr *ConflictExpr; 17053 if (DSAStack->checkMappableExprComponentListsForDecl( 17054 D, /*CurrentRegionOnly=*/true, 17055 [&ConflictExpr]( 17056 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 17057 OpenMPClauseKind) -> bool { 17058 ConflictExpr = R.front().getAssociatedExpression(); 17059 return true; 17060 })) { 17061 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 17062 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 17063 << ConflictExpr->getSourceRange(); 17064 continue; 17065 } 17066 17067 // Store the components in the stack so that they can be used to check 17068 // against other clauses later on. 17069 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 17070 DSAStack->addMappableExpressionComponents( 17071 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 17072 17073 // Record the expression we've just processed. 17074 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 17075 17076 // Create a mappable component for the list item. List items in this clause 17077 // only need a component. We use a null declaration to signal fields in 17078 // 'this'. 17079 assert((isa<DeclRefExpr>(SimpleRefExpr) || 17080 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 17081 "Unexpected device pointer expression!"); 17082 MVLI.VarBaseDeclarations.push_back( 17083 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 17084 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17085 MVLI.VarComponents.back().push_back(MC); 17086 } 17087 17088 if (MVLI.ProcessedVarList.empty()) 17089 return nullptr; 17090 17091 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 17092 MVLI.VarBaseDeclarations, 17093 MVLI.VarComponents); 17094 } 17095 17096 OMPClause *Sema::ActOnOpenMPAllocateClause( 17097 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17098 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17099 if (Allocator) { 17100 // OpenMP [2.11.4 allocate Clause, Description] 17101 // allocator is an expression of omp_allocator_handle_t type. 17102 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 17103 return nullptr; 17104 17105 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 17106 if (AllocatorRes.isInvalid()) 17107 return nullptr; 17108 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 17109 DSAStack->getOMPAllocatorHandleT(), 17110 Sema::AA_Initializing, 17111 /*AllowExplicit=*/true); 17112 if (AllocatorRes.isInvalid()) 17113 return nullptr; 17114 Allocator = AllocatorRes.get(); 17115 } else { 17116 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 17117 // allocate clauses that appear on a target construct or on constructs in a 17118 // target region must specify an allocator expression unless a requires 17119 // directive with the dynamic_allocators clause is present in the same 17120 // compilation unit. 17121 if (LangOpts.OpenMPIsDevice && 17122 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 17123 targetDiag(StartLoc, diag::err_expected_allocator_expression); 17124 } 17125 // Analyze and build list of variables. 17126 SmallVector<Expr *, 8> Vars; 17127 for (Expr *RefExpr : VarList) { 17128 assert(RefExpr && "NULL expr in OpenMP private clause."); 17129 SourceLocation ELoc; 17130 SourceRange ERange; 17131 Expr *SimpleRefExpr = RefExpr; 17132 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17133 if (Res.second) { 17134 // It will be analyzed later. 17135 Vars.push_back(RefExpr); 17136 } 17137 ValueDecl *D = Res.first; 17138 if (!D) 17139 continue; 17140 17141 auto *VD = dyn_cast<VarDecl>(D); 17142 DeclRefExpr *Ref = nullptr; 17143 if (!VD && !CurContext->isDependentContext()) 17144 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17145 Vars.push_back((VD || CurContext->isDependentContext()) 17146 ? RefExpr->IgnoreParens() 17147 : Ref); 17148 } 17149 17150 if (Vars.empty()) 17151 return nullptr; 17152 17153 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 17154 ColonLoc, EndLoc, Vars); 17155 } 17156 17157 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 17158 SourceLocation StartLoc, 17159 SourceLocation LParenLoc, 17160 SourceLocation EndLoc) { 17161 SmallVector<Expr *, 8> Vars; 17162 for (Expr *RefExpr : VarList) { 17163 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 17164 SourceLocation ELoc; 17165 SourceRange ERange; 17166 Expr *SimpleRefExpr = RefExpr; 17167 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17168 if (Res.second) 17169 // It will be analyzed later. 17170 Vars.push_back(RefExpr); 17171 ValueDecl *D = Res.first; 17172 if (!D) 17173 continue; 17174 17175 auto *VD = dyn_cast<VarDecl>(D); 17176 17177 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 17178 // A list-item cannot appear in more than one nontemporal clause. 17179 if (const Expr *PrevRef = 17180 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 17181 Diag(ELoc, diag::err_omp_used_in_clause_twice) 17182 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 17183 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 17184 << getOpenMPClauseName(OMPC_nontemporal); 17185 continue; 17186 } 17187 17188 DeclRefExpr *Ref = nullptr; 17189 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 17190 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17191 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 17192 ? RefExpr->IgnoreParens() 17193 : Ref); 17194 } 17195 17196 if (Vars.empty()) 17197 return nullptr; 17198 17199 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17200 Vars); 17201 } 17202