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/DiagnosticSema.h" 26 #include "clang/Basic/OpenMPKinds.h" 27 #include "clang/Basic/PartialDiagnostic.h" 28 #include "clang/Sema/Initialization.h" 29 #include "clang/Sema/Lookup.h" 30 #include "clang/Sema/Scope.h" 31 #include "clang/Sema/ScopeInfo.h" 32 #include "clang/Sema/SemaInternal.h" 33 #include "llvm/ADT/IndexedMap.h" 34 #include "llvm/ADT/PointerEmbeddedInt.h" 35 #include "llvm/ADT/STLExtras.h" 36 #include "llvm/Frontend/OpenMP/OMPConstants.h" 37 using namespace clang; 38 using namespace llvm::omp; 39 40 //===----------------------------------------------------------------------===// 41 // Stack of data-sharing attributes for variables 42 //===----------------------------------------------------------------------===// 43 44 static const Expr *checkMapClauseExpressionBase( 45 Sema &SemaRef, Expr *E, 46 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 47 OpenMPClauseKind CKind, bool NoDiagnose); 48 49 namespace { 50 /// Default data sharing attributes, which can be applied to directive. 51 enum DefaultDataSharingAttributes { 52 DSA_unspecified = 0, /// Data sharing attribute not specified. 53 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 54 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 struct DefaultmapInfo { 119 OpenMPDefaultmapClauseModifier ImplicitBehavior = 120 OMPC_DEFAULTMAP_MODIFIER_unknown; 121 SourceLocation SLoc; 122 DefaultmapInfo() = default; 123 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 124 : ImplicitBehavior(M), SLoc(Loc) {} 125 }; 126 127 struct SharingMapTy { 128 DeclSAMapTy SharingMap; 129 DeclReductionMapTy ReductionMap; 130 UsedRefMapTy AlignedMap; 131 UsedRefMapTy NontemporalMap; 132 MappedExprComponentsTy MappedExprComponents; 133 LoopControlVariablesMapTy LCVMap; 134 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 135 SourceLocation DefaultAttrLoc; 136 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 137 OpenMPDirectiveKind Directive = OMPD_unknown; 138 DeclarationNameInfo DirectiveName; 139 Scope *CurScope = nullptr; 140 SourceLocation ConstructLoc; 141 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 142 /// get the data (loop counters etc.) about enclosing loop-based construct. 143 /// This data is required during codegen. 144 DoacrossDependMapTy DoacrossDepends; 145 /// First argument (Expr *) contains optional argument of the 146 /// 'ordered' clause, the second one is true if the regions has 'ordered' 147 /// clause, false otherwise. 148 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 149 unsigned AssociatedLoops = 1; 150 bool HasMutipleLoops = false; 151 const Decl *PossiblyLoopCounter = nullptr; 152 bool NowaitRegion = false; 153 bool CancelRegion = false; 154 bool LoopStart = false; 155 bool BodyComplete = false; 156 SourceLocation InnerTeamsRegionLoc; 157 /// Reference to the taskgroup task_reduction reference expression. 158 Expr *TaskgroupReductionRef = nullptr; 159 llvm::DenseSet<QualType> MappedClassesQualTypes; 160 SmallVector<Expr *, 4> InnerUsedAllocators; 161 /// List of globals marked as declare target link in this target region 162 /// (isOpenMPTargetExecutionDirective(Directive) == true). 163 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 164 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 165 Scope *CurScope, SourceLocation Loc) 166 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 167 ConstructLoc(Loc) {} 168 SharingMapTy() = default; 169 }; 170 171 using StackTy = SmallVector<SharingMapTy, 4>; 172 173 /// Stack of used declaration and their data-sharing attributes. 174 DeclSAMapTy Threadprivates; 175 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 176 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 177 /// true, if check for DSA must be from parent directive, false, if 178 /// from current directive. 179 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 180 Sema &SemaRef; 181 bool ForceCapturing = false; 182 /// true if all the variables in the target executable directives must be 183 /// captured by reference. 184 bool ForceCaptureByReferenceInTargetExecutable = false; 185 CriticalsWithHintsTy Criticals; 186 unsigned IgnoredStackElements = 0; 187 188 /// Iterators over the stack iterate in order from innermost to outermost 189 /// directive. 190 using const_iterator = StackTy::const_reverse_iterator; 191 const_iterator begin() const { 192 return Stack.empty() ? const_iterator() 193 : Stack.back().first.rbegin() + IgnoredStackElements; 194 } 195 const_iterator end() const { 196 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 197 } 198 using iterator = StackTy::reverse_iterator; 199 iterator begin() { 200 return Stack.empty() ? iterator() 201 : Stack.back().first.rbegin() + IgnoredStackElements; 202 } 203 iterator end() { 204 return Stack.empty() ? iterator() : Stack.back().first.rend(); 205 } 206 207 // Convenience operations to get at the elements of the stack. 208 209 bool isStackEmpty() const { 210 return Stack.empty() || 211 Stack.back().second != CurrentNonCapturingFunctionScope || 212 Stack.back().first.size() <= IgnoredStackElements; 213 } 214 size_t getStackSize() const { 215 return isStackEmpty() ? 0 216 : Stack.back().first.size() - IgnoredStackElements; 217 } 218 219 SharingMapTy *getTopOfStackOrNull() { 220 size_t Size = getStackSize(); 221 if (Size == 0) 222 return nullptr; 223 return &Stack.back().first[Size - 1]; 224 } 225 const SharingMapTy *getTopOfStackOrNull() const { 226 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 227 } 228 SharingMapTy &getTopOfStack() { 229 assert(!isStackEmpty() && "no current directive"); 230 return *getTopOfStackOrNull(); 231 } 232 const SharingMapTy &getTopOfStack() const { 233 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 234 } 235 236 SharingMapTy *getSecondOnStackOrNull() { 237 size_t Size = getStackSize(); 238 if (Size <= 1) 239 return nullptr; 240 return &Stack.back().first[Size - 2]; 241 } 242 const SharingMapTy *getSecondOnStackOrNull() const { 243 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 244 } 245 246 /// Get the stack element at a certain level (previously returned by 247 /// \c getNestingLevel). 248 /// 249 /// Note that nesting levels count from outermost to innermost, and this is 250 /// the reverse of our iteration order where new inner levels are pushed at 251 /// the front of the stack. 252 SharingMapTy &getStackElemAtLevel(unsigned Level) { 253 assert(Level < getStackSize() && "no such stack element"); 254 return Stack.back().first[Level]; 255 } 256 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 257 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 258 } 259 260 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 261 262 /// Checks if the variable is a local for OpenMP region. 263 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 264 265 /// Vector of previously declared requires directives 266 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 267 /// omp_allocator_handle_t type. 268 QualType OMPAllocatorHandleT; 269 /// Expression for the predefined allocators. 270 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 271 nullptr}; 272 /// Vector of previously encountered target directives 273 SmallVector<SourceLocation, 2> TargetLocations; 274 SourceLocation AtomicLocation; 275 276 public: 277 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 278 279 /// Sets omp_allocator_handle_t type. 280 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 281 /// Gets omp_allocator_handle_t type. 282 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 283 /// Sets the given default allocator. 284 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 285 Expr *Allocator) { 286 OMPPredefinedAllocators[AllocatorKind] = Allocator; 287 } 288 /// Returns the specified default allocator. 289 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 290 return OMPPredefinedAllocators[AllocatorKind]; 291 } 292 293 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 294 OpenMPClauseKind getClauseParsingMode() const { 295 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 296 return ClauseKindMode; 297 } 298 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 299 300 bool isBodyComplete() const { 301 const SharingMapTy *Top = getTopOfStackOrNull(); 302 return Top && Top->BodyComplete; 303 } 304 void setBodyComplete() { 305 getTopOfStack().BodyComplete = true; 306 } 307 308 bool isForceVarCapturing() const { return ForceCapturing; } 309 void setForceVarCapturing(bool V) { ForceCapturing = V; } 310 311 void setForceCaptureByReferenceInTargetExecutable(bool V) { 312 ForceCaptureByReferenceInTargetExecutable = V; 313 } 314 bool isForceCaptureByReferenceInTargetExecutable() const { 315 return ForceCaptureByReferenceInTargetExecutable; 316 } 317 318 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 319 Scope *CurScope, SourceLocation Loc) { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 if (Stack.empty() || 323 Stack.back().second != CurrentNonCapturingFunctionScope) 324 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 325 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 326 Stack.back().first.back().DefaultAttrLoc = Loc; 327 } 328 329 void pop() { 330 assert(!IgnoredStackElements && 331 "cannot change stack while ignoring elements"); 332 assert(!Stack.back().first.empty() && 333 "Data-sharing attributes stack is empty!"); 334 Stack.back().first.pop_back(); 335 } 336 337 /// RAII object to temporarily leave the scope of a directive when we want to 338 /// logically operate in its parent. 339 class ParentDirectiveScope { 340 DSAStackTy &Self; 341 bool Active; 342 public: 343 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 344 : Self(Self), Active(false) { 345 if (Activate) 346 enable(); 347 } 348 ~ParentDirectiveScope() { disable(); } 349 void disable() { 350 if (Active) { 351 --Self.IgnoredStackElements; 352 Active = false; 353 } 354 } 355 void enable() { 356 if (!Active) { 357 ++Self.IgnoredStackElements; 358 Active = true; 359 } 360 } 361 }; 362 363 /// Marks that we're started loop parsing. 364 void loopInit() { 365 assert(isOpenMPLoopDirective(getCurrentDirective()) && 366 "Expected loop-based directive."); 367 getTopOfStack().LoopStart = true; 368 } 369 /// Start capturing of the variables in the loop context. 370 void loopStart() { 371 assert(isOpenMPLoopDirective(getCurrentDirective()) && 372 "Expected loop-based directive."); 373 getTopOfStack().LoopStart = false; 374 } 375 /// true, if variables are captured, false otherwise. 376 bool isLoopStarted() const { 377 assert(isOpenMPLoopDirective(getCurrentDirective()) && 378 "Expected loop-based directive."); 379 return !getTopOfStack().LoopStart; 380 } 381 /// Marks (or clears) declaration as possibly loop counter. 382 void resetPossibleLoopCounter(const Decl *D = nullptr) { 383 getTopOfStack().PossiblyLoopCounter = 384 D ? D->getCanonicalDecl() : D; 385 } 386 /// Gets the possible loop counter decl. 387 const Decl *getPossiblyLoopCunter() const { 388 return getTopOfStack().PossiblyLoopCounter; 389 } 390 /// Start new OpenMP region stack in new non-capturing function. 391 void pushFunction() { 392 assert(!IgnoredStackElements && 393 "cannot change stack while ignoring elements"); 394 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 395 assert(!isa<CapturingScopeInfo>(CurFnScope)); 396 CurrentNonCapturingFunctionScope = CurFnScope; 397 } 398 /// Pop region stack for non-capturing function. 399 void popFunction(const FunctionScopeInfo *OldFSI) { 400 assert(!IgnoredStackElements && 401 "cannot change stack while ignoring elements"); 402 if (!Stack.empty() && Stack.back().second == OldFSI) { 403 assert(Stack.back().first.empty()); 404 Stack.pop_back(); 405 } 406 CurrentNonCapturingFunctionScope = nullptr; 407 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 408 if (!isa<CapturingScopeInfo>(FSI)) { 409 CurrentNonCapturingFunctionScope = FSI; 410 break; 411 } 412 } 413 } 414 415 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 416 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 417 } 418 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 419 getCriticalWithHint(const DeclarationNameInfo &Name) const { 420 auto I = Criticals.find(Name.getAsString()); 421 if (I != Criticals.end()) 422 return I->second; 423 return std::make_pair(nullptr, llvm::APSInt()); 424 } 425 /// If 'aligned' 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 *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 429 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 430 /// add it and return NULL; otherwise return previous occurrence's expression 431 /// for diagnostics. 432 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 433 434 /// Register specified variable as loop control variable. 435 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 436 /// Check if the specified variable is a loop control variable for 437 /// current region. 438 /// \return The index of the loop control variable in the list of associated 439 /// for-loops (from outer to inner). 440 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 441 /// Check if the specified variable is a loop control variable for 442 /// parent region. 443 /// \return The index of the loop control variable in the list of associated 444 /// for-loops (from outer to inner). 445 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 446 /// Get the loop control variable for the I-th loop (or nullptr) in 447 /// parent directive. 448 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 449 450 /// Adds explicit data sharing attribute to the specified declaration. 451 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 452 DeclRefExpr *PrivateCopy = nullptr); 453 454 /// Adds additional information for the reduction items with the reduction id 455 /// represented as an operator. 456 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 457 BinaryOperatorKind BOK); 458 /// Adds additional information for the reduction items with the reduction id 459 /// represented as reduction identifier. 460 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 461 const Expr *ReductionRef); 462 /// Returns the location and reduction operation from the innermost parent 463 /// region for the given \p D. 464 const DSAVarData 465 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 466 BinaryOperatorKind &BOK, 467 Expr *&TaskgroupDescriptor) const; 468 /// Returns the location and reduction operation from the innermost parent 469 /// region for the given \p D. 470 const DSAVarData 471 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 472 const Expr *&ReductionRef, 473 Expr *&TaskgroupDescriptor) const; 474 /// Return reduction reference expression for the current taskgroup. 475 Expr *getTaskgroupReductionRef() const { 476 assert(getTopOfStack().Directive == OMPD_taskgroup && 477 "taskgroup reference expression requested for non taskgroup " 478 "directive."); 479 return getTopOfStack().TaskgroupReductionRef; 480 } 481 /// Checks if the given \p VD declaration is actually a taskgroup reduction 482 /// descriptor variable at the \p Level of OpenMP regions. 483 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 484 return getStackElemAtLevel(Level).TaskgroupReductionRef && 485 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 486 ->getDecl() == VD; 487 } 488 489 /// Returns data sharing attributes from top of the stack for the 490 /// specified declaration. 491 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 492 /// Returns data-sharing attributes for the specified declaration. 493 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 494 /// Checks if the specified variables has data-sharing attributes which 495 /// match specified \a CPred predicate in any directive which matches \a DPred 496 /// predicate. 497 const DSAVarData 498 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 499 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 500 bool FromParent) const; 501 /// Checks if the specified variables has data-sharing attributes which 502 /// match specified \a CPred predicate in any innermost directive which 503 /// matches \a DPred predicate. 504 const DSAVarData 505 hasInnermostDSA(ValueDecl *D, 506 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 507 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 508 bool FromParent) const; 509 /// Checks if the specified variables has explicit data-sharing 510 /// attributes which match specified \a CPred predicate at the specified 511 /// OpenMP region. 512 bool hasExplicitDSA(const ValueDecl *D, 513 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 514 unsigned Level, bool NotLastprivate = false) const; 515 516 /// Returns true if the directive at level \Level matches in the 517 /// specified \a DPred predicate. 518 bool hasExplicitDirective( 519 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 520 unsigned Level) const; 521 522 /// Finds a directive which matches specified \a DPred predicate. 523 bool hasDirective( 524 const llvm::function_ref<bool( 525 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 526 DPred, 527 bool FromParent) const; 528 529 /// Returns currently analyzed directive. 530 OpenMPDirectiveKind getCurrentDirective() const { 531 const SharingMapTy *Top = getTopOfStackOrNull(); 532 return Top ? Top->Directive : OMPD_unknown; 533 } 534 /// Returns directive kind at specified level. 535 OpenMPDirectiveKind getDirective(unsigned Level) const { 536 assert(!isStackEmpty() && "No directive at specified level."); 537 return getStackElemAtLevel(Level).Directive; 538 } 539 /// Returns the capture region at the specified level. 540 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 541 unsigned OpenMPCaptureLevel) const { 542 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 543 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 544 return CaptureRegions[OpenMPCaptureLevel]; 545 } 546 /// Returns parent directive. 547 OpenMPDirectiveKind getParentDirective() const { 548 const SharingMapTy *Parent = getSecondOnStackOrNull(); 549 return Parent ? Parent->Directive : OMPD_unknown; 550 } 551 552 /// Add requires decl to internal vector 553 void addRequiresDecl(OMPRequiresDecl *RD) { 554 RequiresDecls.push_back(RD); 555 } 556 557 /// Checks if the defined 'requires' directive has specified type of clause. 558 template <typename ClauseType> 559 bool hasRequiresDeclWithClause() const { 560 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 561 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 562 return isa<ClauseType>(C); 563 }); 564 }); 565 } 566 567 /// Checks for a duplicate clause amongst previously declared requires 568 /// directives 569 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 570 bool IsDuplicate = false; 571 for (OMPClause *CNew : ClauseList) { 572 for (const OMPRequiresDecl *D : RequiresDecls) { 573 for (const OMPClause *CPrev : D->clauselists()) { 574 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 575 SemaRef.Diag(CNew->getBeginLoc(), 576 diag::err_omp_requires_clause_redeclaration) 577 << getOpenMPClauseName(CNew->getClauseKind()); 578 SemaRef.Diag(CPrev->getBeginLoc(), 579 diag::note_omp_requires_previous_clause) 580 << getOpenMPClauseName(CPrev->getClauseKind()); 581 IsDuplicate = true; 582 } 583 } 584 } 585 } 586 return IsDuplicate; 587 } 588 589 /// Add location of previously encountered target to internal vector 590 void addTargetDirLocation(SourceLocation LocStart) { 591 TargetLocations.push_back(LocStart); 592 } 593 594 /// Add location for the first encountered atomicc directive. 595 void addAtomicDirectiveLoc(SourceLocation Loc) { 596 if (AtomicLocation.isInvalid()) 597 AtomicLocation = Loc; 598 } 599 600 /// Returns the location of the first encountered atomic directive in the 601 /// module. 602 SourceLocation getAtomicDirectiveLoc() const { 603 return AtomicLocation; 604 } 605 606 // Return previously encountered target region locations. 607 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 608 return TargetLocations; 609 } 610 611 /// Set default data sharing attribute to none. 612 void setDefaultDSANone(SourceLocation Loc) { 613 getTopOfStack().DefaultAttr = DSA_none; 614 getTopOfStack().DefaultAttrLoc = Loc; 615 } 616 /// Set default data sharing attribute to shared. 617 void setDefaultDSAShared(SourceLocation Loc) { 618 getTopOfStack().DefaultAttr = DSA_shared; 619 getTopOfStack().DefaultAttrLoc = Loc; 620 } 621 /// Set default data mapping attribute to Modifier:Kind 622 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 623 OpenMPDefaultmapClauseKind Kind, 624 SourceLocation Loc) { 625 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 626 DMI.ImplicitBehavior = M; 627 DMI.SLoc = Loc; 628 } 629 /// Check whether the implicit-behavior has been set in defaultmap 630 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 631 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 632 OMPC_DEFAULTMAP_MODIFIER_unknown; 633 } 634 635 DefaultDataSharingAttributes getDefaultDSA() const { 636 return isStackEmpty() ? DSA_unspecified 637 : getTopOfStack().DefaultAttr; 638 } 639 SourceLocation getDefaultDSALocation() const { 640 return isStackEmpty() ? SourceLocation() 641 : getTopOfStack().DefaultAttrLoc; 642 } 643 OpenMPDefaultmapClauseModifier 644 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 645 return isStackEmpty() 646 ? OMPC_DEFAULTMAP_MODIFIER_unknown 647 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 648 } 649 OpenMPDefaultmapClauseModifier 650 getDefaultmapModifierAtLevel(unsigned Level, 651 OpenMPDefaultmapClauseKind Kind) const { 652 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 653 } 654 bool isDefaultmapCapturedByRef(unsigned Level, 655 OpenMPDefaultmapClauseKind Kind) const { 656 OpenMPDefaultmapClauseModifier M = 657 getDefaultmapModifierAtLevel(Level, Kind); 658 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 659 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 660 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 661 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 662 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 663 } 664 return true; 665 } 666 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 667 OpenMPDefaultmapClauseKind Kind) { 668 switch (Kind) { 669 case OMPC_DEFAULTMAP_scalar: 670 case OMPC_DEFAULTMAP_pointer: 671 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 672 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 673 (M == OMPC_DEFAULTMAP_MODIFIER_default); 674 case OMPC_DEFAULTMAP_aggregate: 675 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 676 default: 677 break; 678 } 679 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 680 } 681 bool mustBeFirstprivateAtLevel(unsigned Level, 682 OpenMPDefaultmapClauseKind Kind) const { 683 OpenMPDefaultmapClauseModifier M = 684 getDefaultmapModifierAtLevel(Level, Kind); 685 return mustBeFirstprivateBase(M, Kind); 686 } 687 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 688 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 689 return mustBeFirstprivateBase(M, Kind); 690 } 691 692 /// Checks if the specified variable is a threadprivate. 693 bool isThreadPrivate(VarDecl *D) { 694 const DSAVarData DVar = getTopDSA(D, false); 695 return isOpenMPThreadPrivate(DVar.CKind); 696 } 697 698 /// Marks current region as ordered (it has an 'ordered' clause). 699 void setOrderedRegion(bool IsOrdered, const Expr *Param, 700 OMPOrderedClause *Clause) { 701 if (IsOrdered) 702 getTopOfStack().OrderedRegion.emplace(Param, Clause); 703 else 704 getTopOfStack().OrderedRegion.reset(); 705 } 706 /// Returns true, if region is ordered (has associated 'ordered' clause), 707 /// false - otherwise. 708 bool isOrderedRegion() const { 709 if (const SharingMapTy *Top = getTopOfStackOrNull()) 710 return Top->OrderedRegion.hasValue(); 711 return false; 712 } 713 /// Returns optional parameter for the ordered region. 714 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 715 if (const SharingMapTy *Top = getTopOfStackOrNull()) 716 if (Top->OrderedRegion.hasValue()) 717 return Top->OrderedRegion.getValue(); 718 return std::make_pair(nullptr, nullptr); 719 } 720 /// Returns true, if parent region is ordered (has associated 721 /// 'ordered' clause), false - otherwise. 722 bool isParentOrderedRegion() const { 723 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 724 return Parent->OrderedRegion.hasValue(); 725 return false; 726 } 727 /// Returns optional parameter for the ordered region. 728 std::pair<const Expr *, OMPOrderedClause *> 729 getParentOrderedRegionParam() const { 730 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 731 if (Parent->OrderedRegion.hasValue()) 732 return Parent->OrderedRegion.getValue(); 733 return std::make_pair(nullptr, nullptr); 734 } 735 /// Marks current region as nowait (it has a 'nowait' clause). 736 void setNowaitRegion(bool IsNowait = true) { 737 getTopOfStack().NowaitRegion = IsNowait; 738 } 739 /// Returns true, if parent region is nowait (has associated 740 /// 'nowait' clause), false - otherwise. 741 bool isParentNowaitRegion() const { 742 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 743 return Parent->NowaitRegion; 744 return false; 745 } 746 /// Marks parent region as cancel region. 747 void setParentCancelRegion(bool Cancel = true) { 748 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 749 Parent->CancelRegion |= Cancel; 750 } 751 /// Return true if current region has inner cancel construct. 752 bool isCancelRegion() const { 753 const SharingMapTy *Top = getTopOfStackOrNull(); 754 return Top ? Top->CancelRegion : false; 755 } 756 757 /// Set collapse value for the region. 758 void setAssociatedLoops(unsigned Val) { 759 getTopOfStack().AssociatedLoops = Val; 760 if (Val > 1) 761 getTopOfStack().HasMutipleLoops = true; 762 } 763 /// Return collapse value for region. 764 unsigned getAssociatedLoops() const { 765 const SharingMapTy *Top = getTopOfStackOrNull(); 766 return Top ? Top->AssociatedLoops : 0; 767 } 768 /// Returns true if the construct is associated with multiple loops. 769 bool hasMutipleLoops() const { 770 const SharingMapTy *Top = getTopOfStackOrNull(); 771 return Top ? Top->HasMutipleLoops : false; 772 } 773 774 /// Marks current target region as one with closely nested teams 775 /// region. 776 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 777 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 778 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 779 } 780 /// Returns true, if current region has closely nested teams region. 781 bool hasInnerTeamsRegion() const { 782 return getInnerTeamsRegionLoc().isValid(); 783 } 784 /// Returns location of the nested teams region (if any). 785 SourceLocation getInnerTeamsRegionLoc() const { 786 const SharingMapTy *Top = getTopOfStackOrNull(); 787 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 788 } 789 790 Scope *getCurScope() const { 791 const SharingMapTy *Top = getTopOfStackOrNull(); 792 return Top ? Top->CurScope : nullptr; 793 } 794 SourceLocation getConstructLoc() const { 795 const SharingMapTy *Top = getTopOfStackOrNull(); 796 return Top ? Top->ConstructLoc : SourceLocation(); 797 } 798 799 /// Do the check specified in \a Check to all component lists and return true 800 /// if any issue is found. 801 bool checkMappableExprComponentListsForDecl( 802 const ValueDecl *VD, bool CurrentRegionOnly, 803 const llvm::function_ref< 804 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 805 OpenMPClauseKind)> 806 Check) const { 807 if (isStackEmpty()) 808 return false; 809 auto SI = begin(); 810 auto SE = end(); 811 812 if (SI == SE) 813 return false; 814 815 if (CurrentRegionOnly) 816 SE = std::next(SI); 817 else 818 std::advance(SI, 1); 819 820 for (; SI != SE; ++SI) { 821 auto MI = SI->MappedExprComponents.find(VD); 822 if (MI != SI->MappedExprComponents.end()) 823 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 824 MI->second.Components) 825 if (Check(L, MI->second.Kind)) 826 return true; 827 } 828 return false; 829 } 830 831 /// Do the check specified in \a Check to all component lists at a given level 832 /// and return true if any issue is found. 833 bool checkMappableExprComponentListsForDeclAtLevel( 834 const ValueDecl *VD, unsigned Level, 835 const llvm::function_ref< 836 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 837 OpenMPClauseKind)> 838 Check) const { 839 if (getStackSize() <= Level) 840 return false; 841 842 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 843 auto MI = StackElem.MappedExprComponents.find(VD); 844 if (MI != StackElem.MappedExprComponents.end()) 845 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 846 MI->second.Components) 847 if (Check(L, MI->second.Kind)) 848 return true; 849 return false; 850 } 851 852 /// Create a new mappable expression component list associated with a given 853 /// declaration and initialize it with the provided list of components. 854 void addMappableExpressionComponents( 855 const ValueDecl *VD, 856 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 857 OpenMPClauseKind WhereFoundClauseKind) { 858 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 859 // Create new entry and append the new components there. 860 MEC.Components.resize(MEC.Components.size() + 1); 861 MEC.Components.back().append(Components.begin(), Components.end()); 862 MEC.Kind = WhereFoundClauseKind; 863 } 864 865 unsigned getNestingLevel() const { 866 assert(!isStackEmpty()); 867 return getStackSize() - 1; 868 } 869 void addDoacrossDependClause(OMPDependClause *C, 870 const OperatorOffsetTy &OpsOffs) { 871 SharingMapTy *Parent = getSecondOnStackOrNull(); 872 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 873 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 874 } 875 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 876 getDoacrossDependClauses() const { 877 const SharingMapTy &StackElem = getTopOfStack(); 878 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 879 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 880 return llvm::make_range(Ref.begin(), Ref.end()); 881 } 882 return llvm::make_range(StackElem.DoacrossDepends.end(), 883 StackElem.DoacrossDepends.end()); 884 } 885 886 // Store types of classes which have been explicitly mapped 887 void addMappedClassesQualTypes(QualType QT) { 888 SharingMapTy &StackElem = getTopOfStack(); 889 StackElem.MappedClassesQualTypes.insert(QT); 890 } 891 892 // Return set of mapped classes types 893 bool isClassPreviouslyMapped(QualType QT) const { 894 const SharingMapTy &StackElem = getTopOfStack(); 895 return StackElem.MappedClassesQualTypes.count(QT) != 0; 896 } 897 898 /// Adds global declare target to the parent target region. 899 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 900 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 901 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 902 "Expected declare target link global."); 903 for (auto &Elem : *this) { 904 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 905 Elem.DeclareTargetLinkVarDecls.push_back(E); 906 return; 907 } 908 } 909 } 910 911 /// Returns the list of globals with declare target link if current directive 912 /// is target. 913 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 914 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 915 "Expected target executable directive."); 916 return getTopOfStack().DeclareTargetLinkVarDecls; 917 } 918 919 /// Adds list of allocators expressions. 920 void addInnerAllocatorExpr(Expr *E) { 921 getTopOfStack().InnerUsedAllocators.push_back(E); 922 } 923 /// Return list of used allocators. 924 ArrayRef<Expr *> getInnerAllocators() const { 925 return getTopOfStack().InnerUsedAllocators; 926 } 927 }; 928 929 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 930 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 931 } 932 933 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 934 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 935 DKind == OMPD_unknown; 936 } 937 938 } // namespace 939 940 static const Expr *getExprAsWritten(const Expr *E) { 941 if (const auto *FE = dyn_cast<FullExpr>(E)) 942 E = FE->getSubExpr(); 943 944 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 945 E = MTE->getSubExpr(); 946 947 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 948 E = Binder->getSubExpr(); 949 950 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 951 E = ICE->getSubExprAsWritten(); 952 return E->IgnoreParens(); 953 } 954 955 static Expr *getExprAsWritten(Expr *E) { 956 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 957 } 958 959 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 960 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 961 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 962 D = ME->getMemberDecl(); 963 const auto *VD = dyn_cast<VarDecl>(D); 964 const auto *FD = dyn_cast<FieldDecl>(D); 965 if (VD != nullptr) { 966 VD = VD->getCanonicalDecl(); 967 D = VD; 968 } else { 969 assert(FD); 970 FD = FD->getCanonicalDecl(); 971 D = FD; 972 } 973 return D; 974 } 975 976 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 977 return const_cast<ValueDecl *>( 978 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 979 } 980 981 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 982 ValueDecl *D) const { 983 D = getCanonicalDecl(D); 984 auto *VD = dyn_cast<VarDecl>(D); 985 const auto *FD = dyn_cast<FieldDecl>(D); 986 DSAVarData DVar; 987 if (Iter == end()) { 988 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 989 // in a region but not in construct] 990 // File-scope or namespace-scope variables referenced in called routines 991 // in the region are shared unless they appear in a threadprivate 992 // directive. 993 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 994 DVar.CKind = OMPC_shared; 995 996 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 997 // in a region but not in construct] 998 // Variables with static storage duration that are declared in called 999 // routines in the region are shared. 1000 if (VD && VD->hasGlobalStorage()) 1001 DVar.CKind = OMPC_shared; 1002 1003 // Non-static data members are shared by default. 1004 if (FD) 1005 DVar.CKind = OMPC_shared; 1006 1007 return DVar; 1008 } 1009 1010 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1011 // in a Construct, C/C++, predetermined, p.1] 1012 // Variables with automatic storage duration that are declared in a scope 1013 // inside the construct are private. 1014 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1015 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1016 DVar.CKind = OMPC_private; 1017 return DVar; 1018 } 1019 1020 DVar.DKind = Iter->Directive; 1021 // Explicitly specified attributes and local variables with predetermined 1022 // attributes. 1023 if (Iter->SharingMap.count(D)) { 1024 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1025 DVar.RefExpr = Data.RefExpr.getPointer(); 1026 DVar.PrivateCopy = Data.PrivateCopy; 1027 DVar.CKind = Data.Attributes; 1028 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1029 return DVar; 1030 } 1031 1032 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1033 // in a Construct, C/C++, implicitly determined, p.1] 1034 // In a parallel or task construct, the data-sharing attributes of these 1035 // variables are determined by the default clause, if present. 1036 switch (Iter->DefaultAttr) { 1037 case DSA_shared: 1038 DVar.CKind = OMPC_shared; 1039 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1040 return DVar; 1041 case DSA_none: 1042 return DVar; 1043 case DSA_unspecified: 1044 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1045 // in a Construct, implicitly determined, p.2] 1046 // In a parallel construct, if no default clause is present, these 1047 // variables are shared. 1048 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1049 if ((isOpenMPParallelDirective(DVar.DKind) && 1050 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1051 isOpenMPTeamsDirective(DVar.DKind)) { 1052 DVar.CKind = OMPC_shared; 1053 return DVar; 1054 } 1055 1056 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1057 // in a Construct, implicitly determined, p.4] 1058 // In a task construct, if no default clause is present, a variable that in 1059 // the enclosing context is determined to be shared by all implicit tasks 1060 // bound to the current team is shared. 1061 if (isOpenMPTaskingDirective(DVar.DKind)) { 1062 DSAVarData DVarTemp; 1063 const_iterator I = Iter, E = end(); 1064 do { 1065 ++I; 1066 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1067 // Referenced in a Construct, implicitly determined, p.6] 1068 // In a task construct, if no default clause is present, a variable 1069 // whose data-sharing attribute is not determined by the rules above is 1070 // firstprivate. 1071 DVarTemp = getDSA(I, D); 1072 if (DVarTemp.CKind != OMPC_shared) { 1073 DVar.RefExpr = nullptr; 1074 DVar.CKind = OMPC_firstprivate; 1075 return DVar; 1076 } 1077 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1078 DVar.CKind = 1079 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1080 return DVar; 1081 } 1082 } 1083 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1084 // in a Construct, implicitly determined, p.3] 1085 // For constructs other than task, if no default clause is present, these 1086 // variables inherit their data-sharing attributes from the enclosing 1087 // context. 1088 return getDSA(++Iter, D); 1089 } 1090 1091 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1092 const Expr *NewDE) { 1093 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1094 D = getCanonicalDecl(D); 1095 SharingMapTy &StackElem = getTopOfStack(); 1096 auto It = StackElem.AlignedMap.find(D); 1097 if (It == StackElem.AlignedMap.end()) { 1098 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1099 StackElem.AlignedMap[D] = NewDE; 1100 return nullptr; 1101 } 1102 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1103 return It->second; 1104 } 1105 1106 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1107 const Expr *NewDE) { 1108 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1109 D = getCanonicalDecl(D); 1110 SharingMapTy &StackElem = getTopOfStack(); 1111 auto It = StackElem.NontemporalMap.find(D); 1112 if (It == StackElem.NontemporalMap.end()) { 1113 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1114 StackElem.NontemporalMap[D] = NewDE; 1115 return nullptr; 1116 } 1117 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1118 return It->second; 1119 } 1120 1121 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1122 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1123 D = getCanonicalDecl(D); 1124 SharingMapTy &StackElem = getTopOfStack(); 1125 StackElem.LCVMap.try_emplace( 1126 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1127 } 1128 1129 const DSAStackTy::LCDeclInfo 1130 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1131 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1132 D = getCanonicalDecl(D); 1133 const SharingMapTy &StackElem = getTopOfStack(); 1134 auto It = StackElem.LCVMap.find(D); 1135 if (It != StackElem.LCVMap.end()) 1136 return It->second; 1137 return {0, nullptr}; 1138 } 1139 1140 const DSAStackTy::LCDeclInfo 1141 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1142 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1143 assert(Parent && "Data-sharing attributes stack is empty"); 1144 D = getCanonicalDecl(D); 1145 auto It = Parent->LCVMap.find(D); 1146 if (It != Parent->LCVMap.end()) 1147 return It->second; 1148 return {0, nullptr}; 1149 } 1150 1151 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1152 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1153 assert(Parent && "Data-sharing attributes stack is empty"); 1154 if (Parent->LCVMap.size() < I) 1155 return nullptr; 1156 for (const auto &Pair : Parent->LCVMap) 1157 if (Pair.second.first == I) 1158 return Pair.first; 1159 return nullptr; 1160 } 1161 1162 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1163 DeclRefExpr *PrivateCopy) { 1164 D = getCanonicalDecl(D); 1165 if (A == OMPC_threadprivate) { 1166 DSAInfo &Data = Threadprivates[D]; 1167 Data.Attributes = A; 1168 Data.RefExpr.setPointer(E); 1169 Data.PrivateCopy = nullptr; 1170 } else { 1171 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1172 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1173 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1174 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1175 (isLoopControlVariable(D).first && A == OMPC_private)); 1176 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1177 Data.RefExpr.setInt(/*IntVal=*/true); 1178 return; 1179 } 1180 const bool IsLastprivate = 1181 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1182 Data.Attributes = A; 1183 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1184 Data.PrivateCopy = PrivateCopy; 1185 if (PrivateCopy) { 1186 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1187 Data.Attributes = A; 1188 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1189 Data.PrivateCopy = nullptr; 1190 } 1191 } 1192 } 1193 1194 /// Build a variable declaration for OpenMP loop iteration variable. 1195 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1196 StringRef Name, const AttrVec *Attrs = nullptr, 1197 DeclRefExpr *OrigRef = nullptr) { 1198 DeclContext *DC = SemaRef.CurContext; 1199 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1200 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1201 auto *Decl = 1202 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1203 if (Attrs) { 1204 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1205 I != E; ++I) 1206 Decl->addAttr(*I); 1207 } 1208 Decl->setImplicit(); 1209 if (OrigRef) { 1210 Decl->addAttr( 1211 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1212 } 1213 return Decl; 1214 } 1215 1216 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1217 SourceLocation Loc, 1218 bool RefersToCapture = false) { 1219 D->setReferenced(); 1220 D->markUsed(S.Context); 1221 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1222 SourceLocation(), D, RefersToCapture, Loc, Ty, 1223 VK_LValue); 1224 } 1225 1226 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1227 BinaryOperatorKind BOK) { 1228 D = getCanonicalDecl(D); 1229 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1230 assert( 1231 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1232 "Additional reduction info may be specified only for reduction items."); 1233 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1234 assert(ReductionData.ReductionRange.isInvalid() && 1235 getTopOfStack().Directive == OMPD_taskgroup && 1236 "Additional reduction info may be specified only once for reduction " 1237 "items."); 1238 ReductionData.set(BOK, SR); 1239 Expr *&TaskgroupReductionRef = 1240 getTopOfStack().TaskgroupReductionRef; 1241 if (!TaskgroupReductionRef) { 1242 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1243 SemaRef.Context.VoidPtrTy, ".task_red."); 1244 TaskgroupReductionRef = 1245 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1246 } 1247 } 1248 1249 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1250 const Expr *ReductionRef) { 1251 D = getCanonicalDecl(D); 1252 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1253 assert( 1254 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1255 "Additional reduction info may be specified only for reduction items."); 1256 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1257 assert(ReductionData.ReductionRange.isInvalid() && 1258 getTopOfStack().Directive == OMPD_taskgroup && 1259 "Additional reduction info may be specified only once for reduction " 1260 "items."); 1261 ReductionData.set(ReductionRef, SR); 1262 Expr *&TaskgroupReductionRef = 1263 getTopOfStack().TaskgroupReductionRef; 1264 if (!TaskgroupReductionRef) { 1265 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1266 SemaRef.Context.VoidPtrTy, ".task_red."); 1267 TaskgroupReductionRef = 1268 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1269 } 1270 } 1271 1272 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1273 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 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 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 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 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1298 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1299 Expr *&TaskgroupDescriptor) const { 1300 D = getCanonicalDecl(D); 1301 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1302 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1303 const DSAInfo &Data = I->SharingMap.lookup(D); 1304 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1305 continue; 1306 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1307 if (!ReductionData.ReductionOp || 1308 !ReductionData.ReductionOp.is<const Expr *>()) 1309 return DSAVarData(); 1310 SR = ReductionData.ReductionRange; 1311 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1312 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1313 "expression for the descriptor is not " 1314 "set."); 1315 TaskgroupDescriptor = I->TaskgroupReductionRef; 1316 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1317 Data.PrivateCopy, I->DefaultAttrLoc); 1318 } 1319 return DSAVarData(); 1320 } 1321 1322 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1323 D = D->getCanonicalDecl(); 1324 for (const_iterator E = end(); I != E; ++I) { 1325 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1326 isOpenMPTargetExecutionDirective(I->Directive)) { 1327 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1328 Scope *CurScope = getCurScope(); 1329 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1330 CurScope = CurScope->getParent(); 1331 return CurScope != TopScope; 1332 } 1333 } 1334 return false; 1335 } 1336 1337 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1338 bool AcceptIfMutable = true, 1339 bool *IsClassType = nullptr) { 1340 ASTContext &Context = SemaRef.getASTContext(); 1341 Type = Type.getNonReferenceType().getCanonicalType(); 1342 bool IsConstant = Type.isConstant(Context); 1343 Type = Context.getBaseElementType(Type); 1344 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1345 ? Type->getAsCXXRecordDecl() 1346 : nullptr; 1347 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1348 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1349 RD = CTD->getTemplatedDecl(); 1350 if (IsClassType) 1351 *IsClassType = RD; 1352 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1353 RD->hasDefinition() && RD->hasMutableFields()); 1354 } 1355 1356 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1357 QualType Type, OpenMPClauseKind CKind, 1358 SourceLocation ELoc, 1359 bool AcceptIfMutable = true, 1360 bool ListItemNotVar = false) { 1361 ASTContext &Context = SemaRef.getASTContext(); 1362 bool IsClassType; 1363 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1364 unsigned Diag = ListItemNotVar 1365 ? diag::err_omp_const_list_item 1366 : IsClassType ? diag::err_omp_const_not_mutable_variable 1367 : diag::err_omp_const_variable; 1368 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1369 if (!ListItemNotVar && D) { 1370 const VarDecl *VD = dyn_cast<VarDecl>(D); 1371 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1372 VarDecl::DeclarationOnly; 1373 SemaRef.Diag(D->getLocation(), 1374 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1375 << D; 1376 } 1377 return true; 1378 } 1379 return false; 1380 } 1381 1382 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1383 bool FromParent) { 1384 D = getCanonicalDecl(D); 1385 DSAVarData DVar; 1386 1387 auto *VD = dyn_cast<VarDecl>(D); 1388 auto TI = Threadprivates.find(D); 1389 if (TI != Threadprivates.end()) { 1390 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1391 DVar.CKind = OMPC_threadprivate; 1392 return DVar; 1393 } 1394 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1395 DVar.RefExpr = buildDeclRefExpr( 1396 SemaRef, VD, D->getType().getNonReferenceType(), 1397 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1398 DVar.CKind = OMPC_threadprivate; 1399 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1400 return DVar; 1401 } 1402 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1403 // in a Construct, C/C++, predetermined, p.1] 1404 // Variables appearing in threadprivate directives are threadprivate. 1405 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1406 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1407 SemaRef.getLangOpts().OpenMPUseTLS && 1408 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1409 (VD && VD->getStorageClass() == SC_Register && 1410 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1411 DVar.RefExpr = buildDeclRefExpr( 1412 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1413 DVar.CKind = OMPC_threadprivate; 1414 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1415 return DVar; 1416 } 1417 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1418 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1419 !isLoopControlVariable(D).first) { 1420 const_iterator IterTarget = 1421 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1422 return isOpenMPTargetExecutionDirective(Data.Directive); 1423 }); 1424 if (IterTarget != end()) { 1425 const_iterator ParentIterTarget = IterTarget + 1; 1426 for (const_iterator Iter = begin(); 1427 Iter != ParentIterTarget; ++Iter) { 1428 if (isOpenMPLocal(VD, Iter)) { 1429 DVar.RefExpr = 1430 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1431 D->getLocation()); 1432 DVar.CKind = OMPC_threadprivate; 1433 return DVar; 1434 } 1435 } 1436 if (!isClauseParsingMode() || IterTarget != begin()) { 1437 auto DSAIter = IterTarget->SharingMap.find(D); 1438 if (DSAIter != IterTarget->SharingMap.end() && 1439 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1440 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1441 DVar.CKind = OMPC_threadprivate; 1442 return DVar; 1443 } 1444 const_iterator End = end(); 1445 if (!SemaRef.isOpenMPCapturedByRef( 1446 D, std::distance(ParentIterTarget, End), 1447 /*OpenMPCaptureLevel=*/0)) { 1448 DVar.RefExpr = 1449 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1450 IterTarget->ConstructLoc); 1451 DVar.CKind = OMPC_threadprivate; 1452 return DVar; 1453 } 1454 } 1455 } 1456 } 1457 1458 if (isStackEmpty()) 1459 // Not in OpenMP execution region and top scope was already checked. 1460 return DVar; 1461 1462 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1463 // in a Construct, C/C++, predetermined, p.4] 1464 // Static data members are shared. 1465 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1466 // in a Construct, C/C++, predetermined, p.7] 1467 // Variables with static storage duration that are declared in a scope 1468 // inside the construct are shared. 1469 if (VD && VD->isStaticDataMember()) { 1470 // Check for explicitly specified attributes. 1471 const_iterator I = begin(); 1472 const_iterator EndI = end(); 1473 if (FromParent && I != EndI) 1474 ++I; 1475 auto It = I->SharingMap.find(D); 1476 if (It != I->SharingMap.end()) { 1477 const DSAInfo &Data = It->getSecond(); 1478 DVar.RefExpr = Data.RefExpr.getPointer(); 1479 DVar.PrivateCopy = Data.PrivateCopy; 1480 DVar.CKind = Data.Attributes; 1481 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1482 DVar.DKind = I->Directive; 1483 return DVar; 1484 } 1485 1486 DVar.CKind = OMPC_shared; 1487 return DVar; 1488 } 1489 1490 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1491 // The predetermined shared attribute for const-qualified types having no 1492 // mutable members was removed after OpenMP 3.1. 1493 if (SemaRef.LangOpts.OpenMP <= 31) { 1494 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1495 // in a Construct, C/C++, predetermined, p.6] 1496 // Variables with const qualified type having no mutable member are 1497 // shared. 1498 if (isConstNotMutableType(SemaRef, D->getType())) { 1499 // Variables with const-qualified type having no mutable member may be 1500 // listed in a firstprivate clause, even if they are static data members. 1501 DSAVarData DVarTemp = hasInnermostDSA( 1502 D, 1503 [](OpenMPClauseKind C) { 1504 return C == OMPC_firstprivate || C == OMPC_shared; 1505 }, 1506 MatchesAlways, FromParent); 1507 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1508 return DVarTemp; 1509 1510 DVar.CKind = OMPC_shared; 1511 return DVar; 1512 } 1513 } 1514 1515 // Explicitly specified attributes and local variables with predetermined 1516 // attributes. 1517 const_iterator I = begin(); 1518 const_iterator EndI = end(); 1519 if (FromParent && I != EndI) 1520 ++I; 1521 auto It = I->SharingMap.find(D); 1522 if (It != I->SharingMap.end()) { 1523 const DSAInfo &Data = It->getSecond(); 1524 DVar.RefExpr = Data.RefExpr.getPointer(); 1525 DVar.PrivateCopy = Data.PrivateCopy; 1526 DVar.CKind = Data.Attributes; 1527 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1528 DVar.DKind = I->Directive; 1529 } 1530 1531 return DVar; 1532 } 1533 1534 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1535 bool FromParent) const { 1536 if (isStackEmpty()) { 1537 const_iterator I; 1538 return getDSA(I, D); 1539 } 1540 D = getCanonicalDecl(D); 1541 const_iterator StartI = begin(); 1542 const_iterator EndI = end(); 1543 if (FromParent && StartI != EndI) 1544 ++StartI; 1545 return getDSA(StartI, D); 1546 } 1547 1548 const DSAStackTy::DSAVarData 1549 DSAStackTy::hasDSA(ValueDecl *D, 1550 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1551 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1552 bool FromParent) const { 1553 if (isStackEmpty()) 1554 return {}; 1555 D = getCanonicalDecl(D); 1556 const_iterator I = begin(); 1557 const_iterator EndI = end(); 1558 if (FromParent && I != EndI) 1559 ++I; 1560 for (; I != EndI; ++I) { 1561 if (!DPred(I->Directive) && 1562 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1563 continue; 1564 const_iterator NewI = I; 1565 DSAVarData DVar = getDSA(NewI, D); 1566 if (I == NewI && CPred(DVar.CKind)) 1567 return DVar; 1568 } 1569 return {}; 1570 } 1571 1572 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1573 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1574 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1575 bool FromParent) const { 1576 if (isStackEmpty()) 1577 return {}; 1578 D = getCanonicalDecl(D); 1579 const_iterator StartI = begin(); 1580 const_iterator EndI = end(); 1581 if (FromParent && StartI != EndI) 1582 ++StartI; 1583 if (StartI == EndI || !DPred(StartI->Directive)) 1584 return {}; 1585 const_iterator NewI = StartI; 1586 DSAVarData DVar = getDSA(NewI, D); 1587 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1588 } 1589 1590 bool DSAStackTy::hasExplicitDSA( 1591 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1592 unsigned Level, bool NotLastprivate) const { 1593 if (getStackSize() <= Level) 1594 return false; 1595 D = getCanonicalDecl(D); 1596 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1597 auto I = StackElem.SharingMap.find(D); 1598 if (I != StackElem.SharingMap.end() && 1599 I->getSecond().RefExpr.getPointer() && 1600 CPred(I->getSecond().Attributes) && 1601 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1602 return true; 1603 // Check predetermined rules for the loop control variables. 1604 auto LI = StackElem.LCVMap.find(D); 1605 if (LI != StackElem.LCVMap.end()) 1606 return CPred(OMPC_private); 1607 return false; 1608 } 1609 1610 bool DSAStackTy::hasExplicitDirective( 1611 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1612 unsigned Level) const { 1613 if (getStackSize() <= Level) 1614 return false; 1615 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1616 return DPred(StackElem.Directive); 1617 } 1618 1619 bool DSAStackTy::hasDirective( 1620 const llvm::function_ref<bool(OpenMPDirectiveKind, 1621 const DeclarationNameInfo &, SourceLocation)> 1622 DPred, 1623 bool FromParent) const { 1624 // We look only in the enclosing region. 1625 size_t Skip = FromParent ? 2 : 1; 1626 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1627 I != E; ++I) { 1628 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1629 return true; 1630 } 1631 return false; 1632 } 1633 1634 void Sema::InitDataSharingAttributesStack() { 1635 VarDataSharingAttributesStack = new DSAStackTy(*this); 1636 } 1637 1638 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1639 1640 void Sema::pushOpenMPFunctionRegion() { 1641 DSAStack->pushFunction(); 1642 } 1643 1644 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1645 DSAStack->popFunction(OldFSI); 1646 } 1647 1648 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1649 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1650 "Expected OpenMP device compilation."); 1651 return !S.isInOpenMPTargetExecutionDirective() && 1652 !S.isInOpenMPDeclareTargetContext(); 1653 } 1654 1655 namespace { 1656 /// Status of the function emission on the host/device. 1657 enum class FunctionEmissionStatus { 1658 Emitted, 1659 Discarded, 1660 Unknown, 1661 }; 1662 } // anonymous namespace 1663 1664 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1665 unsigned DiagID) { 1666 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1667 "Expected OpenMP device compilation."); 1668 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1669 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1670 switch (FES) { 1671 case FunctionEmissionStatus::Emitted: 1672 Kind = DeviceDiagBuilder::K_Immediate; 1673 break; 1674 case FunctionEmissionStatus::Unknown: 1675 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1676 : DeviceDiagBuilder::K_Immediate; 1677 break; 1678 case FunctionEmissionStatus::TemplateDiscarded: 1679 case FunctionEmissionStatus::OMPDiscarded: 1680 Kind = DeviceDiagBuilder::K_Nop; 1681 break; 1682 case FunctionEmissionStatus::CUDADiscarded: 1683 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1684 break; 1685 } 1686 1687 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1688 } 1689 1690 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1691 unsigned DiagID) { 1692 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1693 "Expected OpenMP host compilation."); 1694 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1695 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1696 switch (FES) { 1697 case FunctionEmissionStatus::Emitted: 1698 Kind = DeviceDiagBuilder::K_Immediate; 1699 break; 1700 case FunctionEmissionStatus::Unknown: 1701 Kind = DeviceDiagBuilder::K_Deferred; 1702 break; 1703 case FunctionEmissionStatus::TemplateDiscarded: 1704 case FunctionEmissionStatus::OMPDiscarded: 1705 case FunctionEmissionStatus::CUDADiscarded: 1706 Kind = DeviceDiagBuilder::K_Nop; 1707 break; 1708 } 1709 1710 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1711 } 1712 1713 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1714 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1715 "OpenMP device compilation mode is expected."); 1716 QualType Ty = E->getType(); 1717 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1718 ((Ty->isFloat128Type() || 1719 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1720 !Context.getTargetInfo().hasFloat128Type()) || 1721 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1722 !Context.getTargetInfo().hasInt128Type())) 1723 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1724 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1725 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1726 } 1727 1728 static OpenMPDefaultmapClauseKind 1729 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1730 if (LO.OpenMP <= 45) { 1731 if (VD->getType().getNonReferenceType()->isScalarType()) 1732 return OMPC_DEFAULTMAP_scalar; 1733 return OMPC_DEFAULTMAP_aggregate; 1734 } 1735 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1736 return OMPC_DEFAULTMAP_pointer; 1737 if (VD->getType().getNonReferenceType()->isScalarType()) 1738 return OMPC_DEFAULTMAP_scalar; 1739 return OMPC_DEFAULTMAP_aggregate; 1740 } 1741 1742 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1743 unsigned OpenMPCaptureLevel) const { 1744 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1745 1746 ASTContext &Ctx = getASTContext(); 1747 bool IsByRef = true; 1748 1749 // Find the directive that is associated with the provided scope. 1750 D = cast<ValueDecl>(D->getCanonicalDecl()); 1751 QualType Ty = D->getType(); 1752 1753 bool IsVariableUsedInMapClause = false; 1754 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1755 // This table summarizes how a given variable should be passed to the device 1756 // given its type and the clauses where it appears. This table is based on 1757 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1758 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1759 // 1760 // ========================================================================= 1761 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1762 // | |(tofrom:scalar)| | pvt | | | | 1763 // ========================================================================= 1764 // | scl | | | | - | | bycopy| 1765 // | scl | | - | x | - | - | bycopy| 1766 // | scl | | x | - | - | - | null | 1767 // | scl | x | | | - | | byref | 1768 // | scl | x | - | x | - | - | bycopy| 1769 // | scl | x | x | - | - | - | null | 1770 // | scl | | - | - | - | x | byref | 1771 // | scl | x | - | - | - | x | byref | 1772 // 1773 // | agg | n.a. | | | - | | byref | 1774 // | agg | n.a. | - | x | - | - | byref | 1775 // | agg | n.a. | x | - | - | - | null | 1776 // | agg | n.a. | - | - | - | x | byref | 1777 // | agg | n.a. | - | - | - | x[] | byref | 1778 // 1779 // | ptr | n.a. | | | - | | bycopy| 1780 // | ptr | n.a. | - | x | - | - | bycopy| 1781 // | ptr | n.a. | x | - | - | - | null | 1782 // | ptr | n.a. | - | - | - | x | byref | 1783 // | ptr | n.a. | - | - | - | x[] | bycopy| 1784 // | ptr | n.a. | - | - | x | | bycopy| 1785 // | ptr | n.a. | - | - | x | x | bycopy| 1786 // | ptr | n.a. | - | - | x | x[] | bycopy| 1787 // ========================================================================= 1788 // Legend: 1789 // scl - scalar 1790 // ptr - pointer 1791 // agg - aggregate 1792 // x - applies 1793 // - - invalid in this combination 1794 // [] - mapped with an array section 1795 // byref - should be mapped by reference 1796 // byval - should be mapped by value 1797 // null - initialize a local variable to null on the device 1798 // 1799 // Observations: 1800 // - All scalar declarations that show up in a map clause have to be passed 1801 // by reference, because they may have been mapped in the enclosing data 1802 // environment. 1803 // - If the scalar value does not fit the size of uintptr, it has to be 1804 // passed by reference, regardless the result in the table above. 1805 // - For pointers mapped by value that have either an implicit map or an 1806 // array section, the runtime library may pass the NULL value to the 1807 // device instead of the value passed to it by the compiler. 1808 1809 if (Ty->isReferenceType()) 1810 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1811 1812 // Locate map clauses and see if the variable being captured is referred to 1813 // in any of those clauses. Here we only care about variables, not fields, 1814 // because fields are part of aggregates. 1815 bool IsVariableAssociatedWithSection = false; 1816 1817 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1818 D, Level, 1819 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1820 OMPClauseMappableExprCommon::MappableExprComponentListRef 1821 MapExprComponents, 1822 OpenMPClauseKind WhereFoundClauseKind) { 1823 // Only the map clause information influences how a variable is 1824 // captured. E.g. is_device_ptr does not require changing the default 1825 // behavior. 1826 if (WhereFoundClauseKind != OMPC_map) 1827 return false; 1828 1829 auto EI = MapExprComponents.rbegin(); 1830 auto EE = MapExprComponents.rend(); 1831 1832 assert(EI != EE && "Invalid map expression!"); 1833 1834 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1835 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1836 1837 ++EI; 1838 if (EI == EE) 1839 return false; 1840 1841 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1842 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1843 isa<MemberExpr>(EI->getAssociatedExpression())) { 1844 IsVariableAssociatedWithSection = true; 1845 // There is nothing more we need to know about this variable. 1846 return true; 1847 } 1848 1849 // Keep looking for more map info. 1850 return false; 1851 }); 1852 1853 if (IsVariableUsedInMapClause) { 1854 // If variable is identified in a map clause it is always captured by 1855 // reference except if it is a pointer that is dereferenced somehow. 1856 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1857 } else { 1858 // By default, all the data that has a scalar type is mapped by copy 1859 // (except for reduction variables). 1860 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1861 IsByRef = 1862 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1863 !Ty->isAnyPointerType()) || 1864 !Ty->isScalarType() || 1865 DSAStack->isDefaultmapCapturedByRef( 1866 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1867 DSAStack->hasExplicitDSA( 1868 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1869 } 1870 } 1871 1872 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1873 IsByRef = 1874 ((IsVariableUsedInMapClause && 1875 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1876 OMPD_target) || 1877 !DSAStack->hasExplicitDSA( 1878 D, 1879 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1880 Level, /*NotLastprivate=*/true)) && 1881 // If the variable is artificial and must be captured by value - try to 1882 // capture by value. 1883 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1884 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1885 } 1886 1887 // When passing data by copy, we need to make sure it fits the uintptr size 1888 // and alignment, because the runtime library only deals with uintptr types. 1889 // If it does not fit the uintptr size, we need to pass the data by reference 1890 // instead. 1891 if (!IsByRef && 1892 (Ctx.getTypeSizeInChars(Ty) > 1893 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1894 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1895 IsByRef = true; 1896 } 1897 1898 return IsByRef; 1899 } 1900 1901 unsigned Sema::getOpenMPNestingLevel() const { 1902 assert(getLangOpts().OpenMP); 1903 return DSAStack->getNestingLevel(); 1904 } 1905 1906 bool Sema::isInOpenMPTargetExecutionDirective() const { 1907 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1908 !DSAStack->isClauseParsingMode()) || 1909 DSAStack->hasDirective( 1910 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1911 SourceLocation) -> bool { 1912 return isOpenMPTargetExecutionDirective(K); 1913 }, 1914 false); 1915 } 1916 1917 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1918 unsigned StopAt) { 1919 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1920 D = getCanonicalDecl(D); 1921 1922 auto *VD = dyn_cast<VarDecl>(D); 1923 // Do not capture constexpr variables. 1924 if (VD && VD->isConstexpr()) 1925 return nullptr; 1926 1927 // If we want to determine whether the variable should be captured from the 1928 // perspective of the current capturing scope, and we've already left all the 1929 // capturing scopes of the top directive on the stack, check from the 1930 // perspective of its parent directive (if any) instead. 1931 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1932 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1933 1934 // If we are attempting to capture a global variable in a directive with 1935 // 'target' we return true so that this global is also mapped to the device. 1936 // 1937 if (VD && !VD->hasLocalStorage() && 1938 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1939 if (isInOpenMPDeclareTargetContext()) { 1940 // Try to mark variable as declare target if it is used in capturing 1941 // regions. 1942 if (LangOpts.OpenMP <= 45 && 1943 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1944 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1945 return nullptr; 1946 } else if (isInOpenMPTargetExecutionDirective()) { 1947 // If the declaration is enclosed in a 'declare target' directive, 1948 // then it should not be captured. 1949 // 1950 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1951 return nullptr; 1952 CapturedRegionScopeInfo *CSI = nullptr; 1953 for (FunctionScopeInfo *FSI : llvm::drop_begin( 1954 llvm::reverse(FunctionScopes), 1955 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 1956 if (!isa<CapturingScopeInfo>(FSI)) 1957 return nullptr; 1958 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1959 if (RSI->CapRegionKind == CR_OpenMP) { 1960 CSI = RSI; 1961 break; 1962 } 1963 } 1964 SmallVector<OpenMPDirectiveKind, 4> Regions; 1965 getOpenMPCaptureRegions(Regions, 1966 DSAStack->getDirective(CSI->OpenMPLevel)); 1967 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 1968 return VD; 1969 } 1970 } 1971 1972 if (CheckScopeInfo) { 1973 bool OpenMPFound = false; 1974 for (unsigned I = StopAt + 1; I > 0; --I) { 1975 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1976 if(!isa<CapturingScopeInfo>(FSI)) 1977 return nullptr; 1978 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1979 if (RSI->CapRegionKind == CR_OpenMP) { 1980 OpenMPFound = true; 1981 break; 1982 } 1983 } 1984 if (!OpenMPFound) 1985 return nullptr; 1986 } 1987 1988 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1989 (!DSAStack->isClauseParsingMode() || 1990 DSAStack->getParentDirective() != OMPD_unknown)) { 1991 auto &&Info = DSAStack->isLoopControlVariable(D); 1992 if (Info.first || 1993 (VD && VD->hasLocalStorage() && 1994 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1995 (VD && DSAStack->isForceVarCapturing())) 1996 return VD ? VD : Info.second; 1997 DSAStackTy::DSAVarData DVarPrivate = 1998 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1999 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2000 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2001 // Threadprivate variables must not be captured. 2002 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2003 return nullptr; 2004 // The variable is not private or it is the variable in the directive with 2005 // default(none) clause and not used in any clause. 2006 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2007 [](OpenMPDirectiveKind) { return true; }, 2008 DSAStack->isClauseParsingMode()); 2009 if (DVarPrivate.CKind != OMPC_unknown || 2010 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2011 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2012 } 2013 return nullptr; 2014 } 2015 2016 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2017 unsigned Level) const { 2018 SmallVector<OpenMPDirectiveKind, 4> Regions; 2019 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2020 FunctionScopesIndex -= Regions.size(); 2021 } 2022 2023 void Sema::startOpenMPLoop() { 2024 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2025 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2026 DSAStack->loopInit(); 2027 } 2028 2029 void Sema::startOpenMPCXXRangeFor() { 2030 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2031 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2032 DSAStack->resetPossibleLoopCounter(); 2033 DSAStack->loopStart(); 2034 } 2035 } 2036 2037 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2038 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2039 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2040 if (DSAStack->getAssociatedLoops() > 0 && 2041 !DSAStack->isLoopStarted()) { 2042 DSAStack->resetPossibleLoopCounter(D); 2043 DSAStack->loopStart(); 2044 return true; 2045 } 2046 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2047 DSAStack->isLoopControlVariable(D).first) && 2048 !DSAStack->hasExplicitDSA( 2049 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2050 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2051 return true; 2052 } 2053 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2054 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2055 DSAStack->isForceVarCapturing() && 2056 !DSAStack->hasExplicitDSA( 2057 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2058 return true; 2059 } 2060 return DSAStack->hasExplicitDSA( 2061 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2062 (DSAStack->isClauseParsingMode() && 2063 DSAStack->getClauseParsingMode() == OMPC_private) || 2064 // Consider taskgroup reduction descriptor variable a private to avoid 2065 // possible capture in the region. 2066 (DSAStack->hasExplicitDirective( 2067 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2068 Level) && 2069 DSAStack->isTaskgroupReductionRef(D, Level)); 2070 } 2071 2072 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2073 unsigned Level) { 2074 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2075 D = getCanonicalDecl(D); 2076 OpenMPClauseKind OMPC = OMPC_unknown; 2077 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2078 const unsigned NewLevel = I - 1; 2079 if (DSAStack->hasExplicitDSA(D, 2080 [&OMPC](const OpenMPClauseKind K) { 2081 if (isOpenMPPrivate(K)) { 2082 OMPC = K; 2083 return true; 2084 } 2085 return false; 2086 }, 2087 NewLevel)) 2088 break; 2089 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2090 D, NewLevel, 2091 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2092 OpenMPClauseKind) { return true; })) { 2093 OMPC = OMPC_map; 2094 break; 2095 } 2096 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2097 NewLevel)) { 2098 OMPC = OMPC_map; 2099 if (DSAStack->mustBeFirstprivateAtLevel( 2100 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2101 OMPC = OMPC_firstprivate; 2102 break; 2103 } 2104 } 2105 if (OMPC != OMPC_unknown) 2106 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2107 } 2108 2109 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2110 unsigned CaptureLevel) const { 2111 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2112 // Return true if the current level is no longer enclosed in a target region. 2113 2114 SmallVector<OpenMPDirectiveKind, 4> Regions; 2115 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2116 const auto *VD = dyn_cast<VarDecl>(D); 2117 return VD && !VD->hasLocalStorage() && 2118 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2119 Level) && 2120 Regions[CaptureLevel] != OMPD_task; 2121 } 2122 2123 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2124 2125 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2126 const FunctionDecl *Callee, 2127 SourceLocation Loc) { 2128 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2129 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2130 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2131 // Ignore host functions during device analyzis. 2132 if (LangOpts.OpenMPIsDevice && DevTy && 2133 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2134 return; 2135 // Ignore nohost functions during host analyzis. 2136 if (!LangOpts.OpenMPIsDevice && DevTy && 2137 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2138 return; 2139 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2140 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2141 if (LangOpts.OpenMPIsDevice && DevTy && 2142 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2143 // Diagnose host function called during device codegen. 2144 StringRef HostDevTy = 2145 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2146 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2147 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2148 diag::note_omp_marked_device_type_here) 2149 << HostDevTy; 2150 return; 2151 } 2152 if (!LangOpts.OpenMPIsDevice && DevTy && 2153 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2154 // Diagnose nohost function called during host codegen. 2155 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2156 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2157 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2158 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2159 diag::note_omp_marked_device_type_here) 2160 << NoHostDevTy; 2161 } 2162 } 2163 2164 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2165 const DeclarationNameInfo &DirName, 2166 Scope *CurScope, SourceLocation Loc) { 2167 DSAStack->push(DKind, DirName, CurScope, Loc); 2168 PushExpressionEvaluationContext( 2169 ExpressionEvaluationContext::PotentiallyEvaluated); 2170 } 2171 2172 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2173 DSAStack->setClauseParsingMode(K); 2174 } 2175 2176 void Sema::EndOpenMPClause() { 2177 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2178 } 2179 2180 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2181 ArrayRef<OMPClause *> Clauses); 2182 static std::pair<ValueDecl *, bool> 2183 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2184 SourceRange &ERange, bool AllowArraySection = false); 2185 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2186 bool WithInit); 2187 2188 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2189 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2190 // A variable of class type (or array thereof) that appears in a lastprivate 2191 // clause requires an accessible, unambiguous default constructor for the 2192 // class type, unless the list item is also specified in a firstprivate 2193 // clause. 2194 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2195 for (OMPClause *C : D->clauses()) { 2196 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2197 SmallVector<Expr *, 8> PrivateCopies; 2198 for (Expr *DE : Clause->varlists()) { 2199 if (DE->isValueDependent() || DE->isTypeDependent()) { 2200 PrivateCopies.push_back(nullptr); 2201 continue; 2202 } 2203 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2204 auto *VD = cast<VarDecl>(DRE->getDecl()); 2205 QualType Type = VD->getType().getNonReferenceType(); 2206 const DSAStackTy::DSAVarData DVar = 2207 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2208 if (DVar.CKind == OMPC_lastprivate) { 2209 // Generate helper private variable and initialize it with the 2210 // default value. The address of the original variable is replaced 2211 // by the address of the new private variable in CodeGen. This new 2212 // variable is not added to IdResolver, so the code in the OpenMP 2213 // region uses original variable for proper diagnostics. 2214 VarDecl *VDPrivate = buildVarDecl( 2215 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2216 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2217 ActOnUninitializedDecl(VDPrivate); 2218 if (VDPrivate->isInvalidDecl()) { 2219 PrivateCopies.push_back(nullptr); 2220 continue; 2221 } 2222 PrivateCopies.push_back(buildDeclRefExpr( 2223 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2224 } else { 2225 // The variable is also a firstprivate, so initialization sequence 2226 // for private copy is generated already. 2227 PrivateCopies.push_back(nullptr); 2228 } 2229 } 2230 Clause->setPrivateCopies(PrivateCopies); 2231 continue; 2232 } 2233 // Finalize nontemporal clause by handling private copies, if any. 2234 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2235 SmallVector<Expr *, 8> PrivateRefs; 2236 for (Expr *RefExpr : Clause->varlists()) { 2237 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2238 SourceLocation ELoc; 2239 SourceRange ERange; 2240 Expr *SimpleRefExpr = RefExpr; 2241 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2242 if (Res.second) 2243 // It will be analyzed later. 2244 PrivateRefs.push_back(RefExpr); 2245 ValueDecl *D = Res.first; 2246 if (!D) 2247 continue; 2248 2249 const DSAStackTy::DSAVarData DVar = 2250 DSAStack->getTopDSA(D, /*FromParent=*/false); 2251 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2252 : SimpleRefExpr); 2253 } 2254 Clause->setPrivateRefs(PrivateRefs); 2255 continue; 2256 } 2257 } 2258 // Check allocate clauses. 2259 if (!CurContext->isDependentContext()) 2260 checkAllocateClauses(*this, DSAStack, D->clauses()); 2261 } 2262 2263 DSAStack->pop(); 2264 DiscardCleanupsInEvaluationContext(); 2265 PopExpressionEvaluationContext(); 2266 } 2267 2268 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2269 Expr *NumIterations, Sema &SemaRef, 2270 Scope *S, DSAStackTy *Stack); 2271 2272 namespace { 2273 2274 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2275 private: 2276 Sema &SemaRef; 2277 2278 public: 2279 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2280 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2281 NamedDecl *ND = Candidate.getCorrectionDecl(); 2282 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2283 return VD->hasGlobalStorage() && 2284 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2285 SemaRef.getCurScope()); 2286 } 2287 return false; 2288 } 2289 2290 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2291 return std::make_unique<VarDeclFilterCCC>(*this); 2292 } 2293 2294 }; 2295 2296 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2297 private: 2298 Sema &SemaRef; 2299 2300 public: 2301 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2302 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2303 NamedDecl *ND = Candidate.getCorrectionDecl(); 2304 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2305 isa<FunctionDecl>(ND))) { 2306 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2307 SemaRef.getCurScope()); 2308 } 2309 return false; 2310 } 2311 2312 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2313 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2314 } 2315 }; 2316 2317 } // namespace 2318 2319 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2320 CXXScopeSpec &ScopeSpec, 2321 const DeclarationNameInfo &Id, 2322 OpenMPDirectiveKind Kind) { 2323 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2324 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2325 2326 if (Lookup.isAmbiguous()) 2327 return ExprError(); 2328 2329 VarDecl *VD; 2330 if (!Lookup.isSingleResult()) { 2331 VarDeclFilterCCC CCC(*this); 2332 if (TypoCorrection Corrected = 2333 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2334 CTK_ErrorRecovery)) { 2335 diagnoseTypo(Corrected, 2336 PDiag(Lookup.empty() 2337 ? diag::err_undeclared_var_use_suggest 2338 : diag::err_omp_expected_var_arg_suggest) 2339 << Id.getName()); 2340 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2341 } else { 2342 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2343 : diag::err_omp_expected_var_arg) 2344 << Id.getName(); 2345 return ExprError(); 2346 } 2347 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2348 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2349 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2350 return ExprError(); 2351 } 2352 Lookup.suppressDiagnostics(); 2353 2354 // OpenMP [2.9.2, Syntax, C/C++] 2355 // Variables must be file-scope, namespace-scope, or static block-scope. 2356 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2357 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2358 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2359 bool IsDecl = 2360 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2361 Diag(VD->getLocation(), 2362 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2363 << VD; 2364 return ExprError(); 2365 } 2366 2367 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2368 NamedDecl *ND = CanonicalVD; 2369 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2370 // A threadprivate directive for file-scope variables must appear outside 2371 // any definition or declaration. 2372 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2373 !getCurLexicalContext()->isTranslationUnit()) { 2374 Diag(Id.getLoc(), diag::err_omp_var_scope) 2375 << getOpenMPDirectiveName(Kind) << VD; 2376 bool IsDecl = 2377 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2378 Diag(VD->getLocation(), 2379 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2380 << VD; 2381 return ExprError(); 2382 } 2383 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2384 // A threadprivate directive for static class member variables must appear 2385 // in the class definition, in the same scope in which the member 2386 // variables are declared. 2387 if (CanonicalVD->isStaticDataMember() && 2388 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2389 Diag(Id.getLoc(), diag::err_omp_var_scope) 2390 << getOpenMPDirectiveName(Kind) << VD; 2391 bool IsDecl = 2392 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2393 Diag(VD->getLocation(), 2394 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2395 << VD; 2396 return ExprError(); 2397 } 2398 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2399 // A threadprivate directive for namespace-scope variables must appear 2400 // outside any definition or declaration other than the namespace 2401 // definition itself. 2402 if (CanonicalVD->getDeclContext()->isNamespace() && 2403 (!getCurLexicalContext()->isFileContext() || 2404 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2405 Diag(Id.getLoc(), diag::err_omp_var_scope) 2406 << getOpenMPDirectiveName(Kind) << VD; 2407 bool IsDecl = 2408 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2409 Diag(VD->getLocation(), 2410 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2411 << VD; 2412 return ExprError(); 2413 } 2414 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2415 // A threadprivate directive for static block-scope variables must appear 2416 // in the scope of the variable and not in a nested scope. 2417 if (CanonicalVD->isLocalVarDecl() && CurScope && 2418 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2419 Diag(Id.getLoc(), diag::err_omp_var_scope) 2420 << getOpenMPDirectiveName(Kind) << VD; 2421 bool IsDecl = 2422 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2423 Diag(VD->getLocation(), 2424 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2425 << VD; 2426 return ExprError(); 2427 } 2428 2429 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2430 // A threadprivate directive must lexically precede all references to any 2431 // of the variables in its list. 2432 if (Kind == OMPD_threadprivate && VD->isUsed() && 2433 !DSAStack->isThreadPrivate(VD)) { 2434 Diag(Id.getLoc(), diag::err_omp_var_used) 2435 << getOpenMPDirectiveName(Kind) << VD; 2436 return ExprError(); 2437 } 2438 2439 QualType ExprType = VD->getType().getNonReferenceType(); 2440 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2441 SourceLocation(), VD, 2442 /*RefersToEnclosingVariableOrCapture=*/false, 2443 Id.getLoc(), ExprType, VK_LValue); 2444 } 2445 2446 Sema::DeclGroupPtrTy 2447 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2448 ArrayRef<Expr *> VarList) { 2449 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2450 CurContext->addDecl(D); 2451 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2452 } 2453 return nullptr; 2454 } 2455 2456 namespace { 2457 class LocalVarRefChecker final 2458 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2459 Sema &SemaRef; 2460 2461 public: 2462 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2463 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2464 if (VD->hasLocalStorage()) { 2465 SemaRef.Diag(E->getBeginLoc(), 2466 diag::err_omp_local_var_in_threadprivate_init) 2467 << E->getSourceRange(); 2468 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2469 << VD << VD->getSourceRange(); 2470 return true; 2471 } 2472 } 2473 return false; 2474 } 2475 bool VisitStmt(const Stmt *S) { 2476 for (const Stmt *Child : S->children()) { 2477 if (Child && Visit(Child)) 2478 return true; 2479 } 2480 return false; 2481 } 2482 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2483 }; 2484 } // namespace 2485 2486 OMPThreadPrivateDecl * 2487 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2488 SmallVector<Expr *, 8> Vars; 2489 for (Expr *RefExpr : VarList) { 2490 auto *DE = cast<DeclRefExpr>(RefExpr); 2491 auto *VD = cast<VarDecl>(DE->getDecl()); 2492 SourceLocation ILoc = DE->getExprLoc(); 2493 2494 // Mark variable as used. 2495 VD->setReferenced(); 2496 VD->markUsed(Context); 2497 2498 QualType QType = VD->getType(); 2499 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2500 // It will be analyzed later. 2501 Vars.push_back(DE); 2502 continue; 2503 } 2504 2505 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2506 // A threadprivate variable must not have an incomplete type. 2507 if (RequireCompleteType(ILoc, VD->getType(), 2508 diag::err_omp_threadprivate_incomplete_type)) { 2509 continue; 2510 } 2511 2512 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2513 // A threadprivate variable must not have a reference type. 2514 if (VD->getType()->isReferenceType()) { 2515 Diag(ILoc, diag::err_omp_ref_type_arg) 2516 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2517 bool IsDecl = 2518 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2519 Diag(VD->getLocation(), 2520 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2521 << VD; 2522 continue; 2523 } 2524 2525 // Check if this is a TLS variable. If TLS is not being supported, produce 2526 // the corresponding diagnostic. 2527 if ((VD->getTLSKind() != VarDecl::TLS_None && 2528 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2529 getLangOpts().OpenMPUseTLS && 2530 getASTContext().getTargetInfo().isTLSSupported())) || 2531 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2532 !VD->isLocalVarDecl())) { 2533 Diag(ILoc, diag::err_omp_var_thread_local) 2534 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2535 bool IsDecl = 2536 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2537 Diag(VD->getLocation(), 2538 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2539 << VD; 2540 continue; 2541 } 2542 2543 // Check if initial value of threadprivate variable reference variable with 2544 // local storage (it is not supported by runtime). 2545 if (const Expr *Init = VD->getAnyInitializer()) { 2546 LocalVarRefChecker Checker(*this); 2547 if (Checker.Visit(Init)) 2548 continue; 2549 } 2550 2551 Vars.push_back(RefExpr); 2552 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2553 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2554 Context, SourceRange(Loc, Loc))); 2555 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2556 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2557 } 2558 OMPThreadPrivateDecl *D = nullptr; 2559 if (!Vars.empty()) { 2560 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2561 Vars); 2562 D->setAccess(AS_public); 2563 } 2564 return D; 2565 } 2566 2567 static OMPAllocateDeclAttr::AllocatorTypeTy 2568 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2569 if (!Allocator) 2570 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2571 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2572 Allocator->isInstantiationDependent() || 2573 Allocator->containsUnexpandedParameterPack()) 2574 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2575 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2576 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2577 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2578 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2579 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2580 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2581 llvm::FoldingSetNodeID AEId, DAEId; 2582 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2583 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2584 if (AEId == DAEId) { 2585 AllocatorKindRes = AllocatorKind; 2586 break; 2587 } 2588 } 2589 return AllocatorKindRes; 2590 } 2591 2592 static bool checkPreviousOMPAllocateAttribute( 2593 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2594 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2595 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2596 return false; 2597 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2598 Expr *PrevAllocator = A->getAllocator(); 2599 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2600 getAllocatorKind(S, Stack, PrevAllocator); 2601 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2602 if (AllocatorsMatch && 2603 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2604 Allocator && PrevAllocator) { 2605 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2606 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2607 llvm::FoldingSetNodeID AEId, PAEId; 2608 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2609 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2610 AllocatorsMatch = AEId == PAEId; 2611 } 2612 if (!AllocatorsMatch) { 2613 SmallString<256> AllocatorBuffer; 2614 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2615 if (Allocator) 2616 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2617 SmallString<256> PrevAllocatorBuffer; 2618 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2619 if (PrevAllocator) 2620 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2621 S.getPrintingPolicy()); 2622 2623 SourceLocation AllocatorLoc = 2624 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2625 SourceRange AllocatorRange = 2626 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2627 SourceLocation PrevAllocatorLoc = 2628 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2629 SourceRange PrevAllocatorRange = 2630 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2631 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2632 << (Allocator ? 1 : 0) << AllocatorStream.str() 2633 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2634 << AllocatorRange; 2635 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2636 << PrevAllocatorRange; 2637 return true; 2638 } 2639 return false; 2640 } 2641 2642 static void 2643 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2644 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2645 Expr *Allocator, SourceRange SR) { 2646 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2647 return; 2648 if (Allocator && 2649 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2650 Allocator->isInstantiationDependent() || 2651 Allocator->containsUnexpandedParameterPack())) 2652 return; 2653 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2654 Allocator, SR); 2655 VD->addAttr(A); 2656 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2657 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2658 } 2659 2660 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2661 SourceLocation Loc, ArrayRef<Expr *> VarList, 2662 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2663 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2664 Expr *Allocator = nullptr; 2665 if (Clauses.empty()) { 2666 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2667 // allocate directives that appear in a target region must specify an 2668 // allocator clause unless a requires directive with the dynamic_allocators 2669 // clause is present in the same compilation unit. 2670 if (LangOpts.OpenMPIsDevice && 2671 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2672 targetDiag(Loc, diag::err_expected_allocator_clause); 2673 } else { 2674 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2675 } 2676 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2677 getAllocatorKind(*this, DSAStack, Allocator); 2678 SmallVector<Expr *, 8> Vars; 2679 for (Expr *RefExpr : VarList) { 2680 auto *DE = cast<DeclRefExpr>(RefExpr); 2681 auto *VD = cast<VarDecl>(DE->getDecl()); 2682 2683 // Check if this is a TLS variable or global register. 2684 if (VD->getTLSKind() != VarDecl::TLS_None || 2685 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2686 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2687 !VD->isLocalVarDecl())) 2688 continue; 2689 2690 // If the used several times in the allocate directive, the same allocator 2691 // must be used. 2692 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2693 AllocatorKind, Allocator)) 2694 continue; 2695 2696 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2697 // If a list item has a static storage type, the allocator expression in the 2698 // allocator clause must be a constant expression that evaluates to one of 2699 // the predefined memory allocator values. 2700 if (Allocator && VD->hasGlobalStorage()) { 2701 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2702 Diag(Allocator->getExprLoc(), 2703 diag::err_omp_expected_predefined_allocator) 2704 << Allocator->getSourceRange(); 2705 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2706 VarDecl::DeclarationOnly; 2707 Diag(VD->getLocation(), 2708 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2709 << VD; 2710 continue; 2711 } 2712 } 2713 2714 Vars.push_back(RefExpr); 2715 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2716 DE->getSourceRange()); 2717 } 2718 if (Vars.empty()) 2719 return nullptr; 2720 if (!Owner) 2721 Owner = getCurLexicalContext(); 2722 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2723 D->setAccess(AS_public); 2724 Owner->addDecl(D); 2725 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2726 } 2727 2728 Sema::DeclGroupPtrTy 2729 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2730 ArrayRef<OMPClause *> ClauseList) { 2731 OMPRequiresDecl *D = nullptr; 2732 if (!CurContext->isFileContext()) { 2733 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2734 } else { 2735 D = CheckOMPRequiresDecl(Loc, ClauseList); 2736 if (D) { 2737 CurContext->addDecl(D); 2738 DSAStack->addRequiresDecl(D); 2739 } 2740 } 2741 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2742 } 2743 2744 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2745 ArrayRef<OMPClause *> ClauseList) { 2746 /// For target specific clauses, the requires directive cannot be 2747 /// specified after the handling of any of the target regions in the 2748 /// current compilation unit. 2749 ArrayRef<SourceLocation> TargetLocations = 2750 DSAStack->getEncounteredTargetLocs(); 2751 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 2752 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 2753 for (const OMPClause *CNew : ClauseList) { 2754 // Check if any of the requires clauses affect target regions. 2755 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2756 isa<OMPUnifiedAddressClause>(CNew) || 2757 isa<OMPReverseOffloadClause>(CNew) || 2758 isa<OMPDynamicAllocatorsClause>(CNew)) { 2759 Diag(Loc, diag::err_omp_directive_before_requires) 2760 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 2761 for (SourceLocation TargetLoc : TargetLocations) { 2762 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 2763 << "target"; 2764 } 2765 } else if (!AtomicLoc.isInvalid() && 2766 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 2767 Diag(Loc, diag::err_omp_directive_before_requires) 2768 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 2769 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 2770 << "atomic"; 2771 } 2772 } 2773 } 2774 2775 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2776 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2777 ClauseList); 2778 return nullptr; 2779 } 2780 2781 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2782 const ValueDecl *D, 2783 const DSAStackTy::DSAVarData &DVar, 2784 bool IsLoopIterVar = false) { 2785 if (DVar.RefExpr) { 2786 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2787 << getOpenMPClauseName(DVar.CKind); 2788 return; 2789 } 2790 enum { 2791 PDSA_StaticMemberShared, 2792 PDSA_StaticLocalVarShared, 2793 PDSA_LoopIterVarPrivate, 2794 PDSA_LoopIterVarLinear, 2795 PDSA_LoopIterVarLastprivate, 2796 PDSA_ConstVarShared, 2797 PDSA_GlobalVarShared, 2798 PDSA_TaskVarFirstprivate, 2799 PDSA_LocalVarPrivate, 2800 PDSA_Implicit 2801 } Reason = PDSA_Implicit; 2802 bool ReportHint = false; 2803 auto ReportLoc = D->getLocation(); 2804 auto *VD = dyn_cast<VarDecl>(D); 2805 if (IsLoopIterVar) { 2806 if (DVar.CKind == OMPC_private) 2807 Reason = PDSA_LoopIterVarPrivate; 2808 else if (DVar.CKind == OMPC_lastprivate) 2809 Reason = PDSA_LoopIterVarLastprivate; 2810 else 2811 Reason = PDSA_LoopIterVarLinear; 2812 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2813 DVar.CKind == OMPC_firstprivate) { 2814 Reason = PDSA_TaskVarFirstprivate; 2815 ReportLoc = DVar.ImplicitDSALoc; 2816 } else if (VD && VD->isStaticLocal()) 2817 Reason = PDSA_StaticLocalVarShared; 2818 else if (VD && VD->isStaticDataMember()) 2819 Reason = PDSA_StaticMemberShared; 2820 else if (VD && VD->isFileVarDecl()) 2821 Reason = PDSA_GlobalVarShared; 2822 else if (D->getType().isConstant(SemaRef.getASTContext())) 2823 Reason = PDSA_ConstVarShared; 2824 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2825 ReportHint = true; 2826 Reason = PDSA_LocalVarPrivate; 2827 } 2828 if (Reason != PDSA_Implicit) { 2829 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2830 << Reason << ReportHint 2831 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2832 } else if (DVar.ImplicitDSALoc.isValid()) { 2833 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2834 << getOpenMPClauseName(DVar.CKind); 2835 } 2836 } 2837 2838 static OpenMPMapClauseKind 2839 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 2840 bool IsAggregateOrDeclareTarget) { 2841 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 2842 switch (M) { 2843 case OMPC_DEFAULTMAP_MODIFIER_alloc: 2844 Kind = OMPC_MAP_alloc; 2845 break; 2846 case OMPC_DEFAULTMAP_MODIFIER_to: 2847 Kind = OMPC_MAP_to; 2848 break; 2849 case OMPC_DEFAULTMAP_MODIFIER_from: 2850 Kind = OMPC_MAP_from; 2851 break; 2852 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 2853 Kind = OMPC_MAP_tofrom; 2854 break; 2855 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 2856 case OMPC_DEFAULTMAP_MODIFIER_last: 2857 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2858 case OMPC_DEFAULTMAP_MODIFIER_none: 2859 case OMPC_DEFAULTMAP_MODIFIER_default: 2860 case OMPC_DEFAULTMAP_MODIFIER_unknown: 2861 // IsAggregateOrDeclareTarget could be true if: 2862 // 1. the implicit behavior for aggregate is tofrom 2863 // 2. it's a declare target link 2864 if (IsAggregateOrDeclareTarget) { 2865 Kind = OMPC_MAP_tofrom; 2866 break; 2867 } 2868 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2869 } 2870 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 2871 return Kind; 2872 } 2873 2874 namespace { 2875 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2876 DSAStackTy *Stack; 2877 Sema &SemaRef; 2878 bool ErrorFound = false; 2879 bool TryCaptureCXXThisMembers = false; 2880 CapturedStmt *CS = nullptr; 2881 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2882 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 2883 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2884 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2885 2886 void VisitSubCaptures(OMPExecutableDirective *S) { 2887 // Check implicitly captured variables. 2888 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2889 return; 2890 visitSubCaptures(S->getInnermostCapturedStmt()); 2891 // Try to capture inner this->member references to generate correct mappings 2892 // and diagnostics. 2893 if (TryCaptureCXXThisMembers || 2894 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2895 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2896 [](const CapturedStmt::Capture &C) { 2897 return C.capturesThis(); 2898 }))) { 2899 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2900 TryCaptureCXXThisMembers = true; 2901 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2902 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2903 } 2904 } 2905 2906 public: 2907 void VisitDeclRefExpr(DeclRefExpr *E) { 2908 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 2909 E->isValueDependent() || E->containsUnexpandedParameterPack() || 2910 E->isInstantiationDependent()) 2911 return; 2912 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2913 // Check the datasharing rules for the expressions in the clauses. 2914 if (!CS) { 2915 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2916 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2917 Visit(CED->getInit()); 2918 return; 2919 } 2920 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2921 // Do not analyze internal variables and do not enclose them into 2922 // implicit clauses. 2923 return; 2924 VD = VD->getCanonicalDecl(); 2925 // Skip internally declared variables. 2926 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2927 return; 2928 2929 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2930 // Check if the variable has explicit DSA set and stop analysis if it so. 2931 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2932 return; 2933 2934 // Skip internally declared static variables. 2935 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2936 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2937 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2938 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2939 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2940 return; 2941 2942 SourceLocation ELoc = E->getExprLoc(); 2943 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2944 // The default(none) clause requires that each variable that is referenced 2945 // in the construct, and does not have a predetermined data-sharing 2946 // attribute, must have its data-sharing attribute explicitly determined 2947 // by being listed in a data-sharing attribute clause. 2948 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2949 isImplicitOrExplicitTaskingRegion(DKind) && 2950 VarsWithInheritedDSA.count(VD) == 0) { 2951 VarsWithInheritedDSA[VD] = E; 2952 return; 2953 } 2954 2955 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 2956 // If implicit-behavior is none, each variable referenced in the 2957 // construct that does not have a predetermined data-sharing attribute 2958 // and does not appear in a to or link clause on a declare target 2959 // directive must be listed in a data-mapping attribute clause, a 2960 // data-haring attribute clause (including a data-sharing attribute 2961 // clause on a combined construct where target. is one of the 2962 // constituent constructs), or an is_device_ptr clause. 2963 OpenMPDefaultmapClauseKind ClauseKind = 2964 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 2965 if (SemaRef.getLangOpts().OpenMP >= 50) { 2966 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 2967 OMPC_DEFAULTMAP_MODIFIER_none; 2968 if (DVar.CKind == OMPC_unknown && IsModifierNone && 2969 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 2970 // Only check for data-mapping attribute and is_device_ptr here 2971 // since we have already make sure that the declaration does not 2972 // have a data-sharing attribute above 2973 if (!Stack->checkMappableExprComponentListsForDecl( 2974 VD, /*CurrentRegionOnly=*/true, 2975 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 2976 MapExprComponents, 2977 OpenMPClauseKind) { 2978 auto MI = MapExprComponents.rbegin(); 2979 auto ME = MapExprComponents.rend(); 2980 return MI != ME && MI->getAssociatedDeclaration() == VD; 2981 })) { 2982 VarsWithInheritedDSA[VD] = E; 2983 return; 2984 } 2985 } 2986 } 2987 2988 if (isOpenMPTargetExecutionDirective(DKind) && 2989 !Stack->isLoopControlVariable(VD).first) { 2990 if (!Stack->checkMappableExprComponentListsForDecl( 2991 VD, /*CurrentRegionOnly=*/true, 2992 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2993 StackComponents, 2994 OpenMPClauseKind) { 2995 // Variable is used if it has been marked as an array, array 2996 // section or the variable iself. 2997 return StackComponents.size() == 1 || 2998 std::all_of( 2999 std::next(StackComponents.rbegin()), 3000 StackComponents.rend(), 3001 [](const OMPClauseMappableExprCommon:: 3002 MappableComponent &MC) { 3003 return MC.getAssociatedDeclaration() == 3004 nullptr && 3005 (isa<OMPArraySectionExpr>( 3006 MC.getAssociatedExpression()) || 3007 isa<ArraySubscriptExpr>( 3008 MC.getAssociatedExpression())); 3009 }); 3010 })) { 3011 bool IsFirstprivate = false; 3012 // By default lambdas are captured as firstprivates. 3013 if (const auto *RD = 3014 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3015 IsFirstprivate = RD->isLambda(); 3016 IsFirstprivate = 3017 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3018 if (IsFirstprivate) { 3019 ImplicitFirstprivate.emplace_back(E); 3020 } else { 3021 OpenMPDefaultmapClauseModifier M = 3022 Stack->getDefaultmapModifier(ClauseKind); 3023 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3024 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3025 ImplicitMap[Kind].emplace_back(E); 3026 } 3027 return; 3028 } 3029 } 3030 3031 // OpenMP [2.9.3.6, Restrictions, p.2] 3032 // A list item that appears in a reduction clause of the innermost 3033 // enclosing worksharing or parallel construct may not be accessed in an 3034 // explicit task. 3035 DVar = Stack->hasInnermostDSA( 3036 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3037 [](OpenMPDirectiveKind K) { 3038 return isOpenMPParallelDirective(K) || 3039 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3040 }, 3041 /*FromParent=*/true); 3042 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3043 ErrorFound = true; 3044 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3045 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3046 return; 3047 } 3048 3049 // Define implicit data-sharing attributes for task. 3050 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3051 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3052 !Stack->isLoopControlVariable(VD).first) { 3053 ImplicitFirstprivate.push_back(E); 3054 return; 3055 } 3056 3057 // Store implicitly used globals with declare target link for parent 3058 // target. 3059 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3060 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3061 Stack->addToParentTargetRegionLinkGlobals(E); 3062 return; 3063 } 3064 } 3065 } 3066 void VisitMemberExpr(MemberExpr *E) { 3067 if (E->isTypeDependent() || E->isValueDependent() || 3068 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3069 return; 3070 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3071 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3072 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 3073 if (!FD) 3074 return; 3075 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3076 // Check if the variable has explicit DSA set and stop analysis if it 3077 // so. 3078 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3079 return; 3080 3081 if (isOpenMPTargetExecutionDirective(DKind) && 3082 !Stack->isLoopControlVariable(FD).first && 3083 !Stack->checkMappableExprComponentListsForDecl( 3084 FD, /*CurrentRegionOnly=*/true, 3085 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3086 StackComponents, 3087 OpenMPClauseKind) { 3088 return isa<CXXThisExpr>( 3089 cast<MemberExpr>( 3090 StackComponents.back().getAssociatedExpression()) 3091 ->getBase() 3092 ->IgnoreParens()); 3093 })) { 3094 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3095 // A bit-field cannot appear in a map clause. 3096 // 3097 if (FD->isBitField()) 3098 return; 3099 3100 // Check to see if the member expression is referencing a class that 3101 // has already been explicitly mapped 3102 if (Stack->isClassPreviouslyMapped(TE->getType())) 3103 return; 3104 3105 OpenMPDefaultmapClauseModifier Modifier = 3106 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3107 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3108 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3109 ImplicitMap[Kind].emplace_back(E); 3110 return; 3111 } 3112 3113 SourceLocation ELoc = E->getExprLoc(); 3114 // OpenMP [2.9.3.6, Restrictions, p.2] 3115 // A list item that appears in a reduction clause of the innermost 3116 // enclosing worksharing or parallel construct may not be accessed in 3117 // an explicit task. 3118 DVar = Stack->hasInnermostDSA( 3119 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3120 [](OpenMPDirectiveKind K) { 3121 return isOpenMPParallelDirective(K) || 3122 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3123 }, 3124 /*FromParent=*/true); 3125 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3126 ErrorFound = true; 3127 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3128 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3129 return; 3130 } 3131 3132 // Define implicit data-sharing attributes for task. 3133 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3134 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3135 !Stack->isLoopControlVariable(FD).first) { 3136 // Check if there is a captured expression for the current field in the 3137 // region. Do not mark it as firstprivate unless there is no captured 3138 // expression. 3139 // TODO: try to make it firstprivate. 3140 if (DVar.CKind != OMPC_unknown) 3141 ImplicitFirstprivate.push_back(E); 3142 } 3143 return; 3144 } 3145 if (isOpenMPTargetExecutionDirective(DKind)) { 3146 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3147 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3148 /*NoDiagnose=*/true)) 3149 return; 3150 const auto *VD = cast<ValueDecl>( 3151 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3152 if (!Stack->checkMappableExprComponentListsForDecl( 3153 VD, /*CurrentRegionOnly=*/true, 3154 [&CurComponents]( 3155 OMPClauseMappableExprCommon::MappableExprComponentListRef 3156 StackComponents, 3157 OpenMPClauseKind) { 3158 auto CCI = CurComponents.rbegin(); 3159 auto CCE = CurComponents.rend(); 3160 for (const auto &SC : llvm::reverse(StackComponents)) { 3161 // Do both expressions have the same kind? 3162 if (CCI->getAssociatedExpression()->getStmtClass() != 3163 SC.getAssociatedExpression()->getStmtClass()) 3164 if (!(isa<OMPArraySectionExpr>( 3165 SC.getAssociatedExpression()) && 3166 isa<ArraySubscriptExpr>( 3167 CCI->getAssociatedExpression()))) 3168 return false; 3169 3170 const Decl *CCD = CCI->getAssociatedDeclaration(); 3171 const Decl *SCD = SC.getAssociatedDeclaration(); 3172 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3173 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3174 if (SCD != CCD) 3175 return false; 3176 std::advance(CCI, 1); 3177 if (CCI == CCE) 3178 break; 3179 } 3180 return true; 3181 })) { 3182 Visit(E->getBase()); 3183 } 3184 } else if (!TryCaptureCXXThisMembers) { 3185 Visit(E->getBase()); 3186 } 3187 } 3188 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3189 for (OMPClause *C : S->clauses()) { 3190 // Skip analysis of arguments of implicitly defined firstprivate clause 3191 // for task|target directives. 3192 // Skip analysis of arguments of implicitly defined map clause for target 3193 // directives. 3194 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3195 C->isImplicit())) { 3196 for (Stmt *CC : C->children()) { 3197 if (CC) 3198 Visit(CC); 3199 } 3200 } 3201 } 3202 // Check implicitly captured variables. 3203 VisitSubCaptures(S); 3204 } 3205 void VisitStmt(Stmt *S) { 3206 for (Stmt *C : S->children()) { 3207 if (C) { 3208 // Check implicitly captured variables in the task-based directives to 3209 // check if they must be firstprivatized. 3210 Visit(C); 3211 } 3212 } 3213 } 3214 3215 void visitSubCaptures(CapturedStmt *S) { 3216 for (const CapturedStmt::Capture &Cap : S->captures()) { 3217 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3218 continue; 3219 VarDecl *VD = Cap.getCapturedVar(); 3220 // Do not try to map the variable if it or its sub-component was mapped 3221 // already. 3222 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3223 Stack->checkMappableExprComponentListsForDecl( 3224 VD, /*CurrentRegionOnly=*/true, 3225 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3226 OpenMPClauseKind) { return true; })) 3227 continue; 3228 DeclRefExpr *DRE = buildDeclRefExpr( 3229 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3230 Cap.getLocation(), /*RefersToCapture=*/true); 3231 Visit(DRE); 3232 } 3233 } 3234 bool isErrorFound() const { return ErrorFound; } 3235 ArrayRef<Expr *> getImplicitFirstprivate() const { 3236 return ImplicitFirstprivate; 3237 } 3238 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3239 return ImplicitMap[Kind]; 3240 } 3241 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3242 return VarsWithInheritedDSA; 3243 } 3244 3245 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3246 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3247 // Process declare target link variables for the target directives. 3248 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3249 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3250 Visit(E); 3251 } 3252 } 3253 }; 3254 } // namespace 3255 3256 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3257 switch (DKind) { 3258 case OMPD_parallel: 3259 case OMPD_parallel_for: 3260 case OMPD_parallel_for_simd: 3261 case OMPD_parallel_sections: 3262 case OMPD_parallel_master: 3263 case OMPD_teams: 3264 case OMPD_teams_distribute: 3265 case OMPD_teams_distribute_simd: { 3266 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3267 QualType KmpInt32PtrTy = 3268 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3269 Sema::CapturedParamNameType Params[] = { 3270 std::make_pair(".global_tid.", KmpInt32PtrTy), 3271 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3272 std::make_pair(StringRef(), QualType()) // __context with shared vars 3273 }; 3274 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3275 Params); 3276 break; 3277 } 3278 case OMPD_target_teams: 3279 case OMPD_target_parallel: 3280 case OMPD_target_parallel_for: 3281 case OMPD_target_parallel_for_simd: 3282 case OMPD_target_teams_distribute: 3283 case OMPD_target_teams_distribute_simd: { 3284 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3285 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3286 QualType KmpInt32PtrTy = 3287 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3288 QualType Args[] = {VoidPtrTy}; 3289 FunctionProtoType::ExtProtoInfo EPI; 3290 EPI.Variadic = true; 3291 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3292 Sema::CapturedParamNameType Params[] = { 3293 std::make_pair(".global_tid.", KmpInt32Ty), 3294 std::make_pair(".part_id.", KmpInt32PtrTy), 3295 std::make_pair(".privates.", VoidPtrTy), 3296 std::make_pair( 3297 ".copy_fn.", 3298 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3299 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3300 std::make_pair(StringRef(), QualType()) // __context with shared vars 3301 }; 3302 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3303 Params, /*OpenMPCaptureLevel=*/0); 3304 // Mark this captured region as inlined, because we don't use outlined 3305 // function directly. 3306 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3307 AlwaysInlineAttr::CreateImplicit( 3308 Context, {}, AttributeCommonInfo::AS_Keyword, 3309 AlwaysInlineAttr::Keyword_forceinline)); 3310 Sema::CapturedParamNameType ParamsTarget[] = { 3311 std::make_pair(StringRef(), QualType()) // __context with shared vars 3312 }; 3313 // Start a captured region for 'target' with no implicit parameters. 3314 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3315 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3316 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3317 std::make_pair(".global_tid.", KmpInt32PtrTy), 3318 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3319 std::make_pair(StringRef(), QualType()) // __context with shared vars 3320 }; 3321 // Start a captured region for 'teams' or 'parallel'. Both regions have 3322 // the same implicit parameters. 3323 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3324 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3325 break; 3326 } 3327 case OMPD_target: 3328 case OMPD_target_simd: { 3329 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3330 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3331 QualType KmpInt32PtrTy = 3332 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3333 QualType Args[] = {VoidPtrTy}; 3334 FunctionProtoType::ExtProtoInfo EPI; 3335 EPI.Variadic = true; 3336 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3337 Sema::CapturedParamNameType Params[] = { 3338 std::make_pair(".global_tid.", KmpInt32Ty), 3339 std::make_pair(".part_id.", KmpInt32PtrTy), 3340 std::make_pair(".privates.", VoidPtrTy), 3341 std::make_pair( 3342 ".copy_fn.", 3343 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3344 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3345 std::make_pair(StringRef(), QualType()) // __context with shared vars 3346 }; 3347 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3348 Params, /*OpenMPCaptureLevel=*/0); 3349 // Mark this captured region as inlined, because we don't use outlined 3350 // function directly. 3351 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3352 AlwaysInlineAttr::CreateImplicit( 3353 Context, {}, AttributeCommonInfo::AS_Keyword, 3354 AlwaysInlineAttr::Keyword_forceinline)); 3355 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3356 std::make_pair(StringRef(), QualType()), 3357 /*OpenMPCaptureLevel=*/1); 3358 break; 3359 } 3360 case OMPD_simd: 3361 case OMPD_for: 3362 case OMPD_for_simd: 3363 case OMPD_sections: 3364 case OMPD_section: 3365 case OMPD_single: 3366 case OMPD_master: 3367 case OMPD_critical: 3368 case OMPD_taskgroup: 3369 case OMPD_distribute: 3370 case OMPD_distribute_simd: 3371 case OMPD_ordered: 3372 case OMPD_atomic: 3373 case OMPD_target_data: { 3374 Sema::CapturedParamNameType Params[] = { 3375 std::make_pair(StringRef(), QualType()) // __context with shared vars 3376 }; 3377 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3378 Params); 3379 break; 3380 } 3381 case OMPD_task: { 3382 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3383 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3384 QualType KmpInt32PtrTy = 3385 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3386 QualType Args[] = {VoidPtrTy}; 3387 FunctionProtoType::ExtProtoInfo EPI; 3388 EPI.Variadic = true; 3389 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3390 Sema::CapturedParamNameType Params[] = { 3391 std::make_pair(".global_tid.", KmpInt32Ty), 3392 std::make_pair(".part_id.", KmpInt32PtrTy), 3393 std::make_pair(".privates.", VoidPtrTy), 3394 std::make_pair( 3395 ".copy_fn.", 3396 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3397 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3398 std::make_pair(StringRef(), QualType()) // __context with shared vars 3399 }; 3400 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3401 Params); 3402 // Mark this captured region as inlined, because we don't use outlined 3403 // function directly. 3404 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3405 AlwaysInlineAttr::CreateImplicit( 3406 Context, {}, AttributeCommonInfo::AS_Keyword, 3407 AlwaysInlineAttr::Keyword_forceinline)); 3408 break; 3409 } 3410 case OMPD_taskloop: 3411 case OMPD_taskloop_simd: 3412 case OMPD_master_taskloop: 3413 case OMPD_master_taskloop_simd: { 3414 QualType KmpInt32Ty = 3415 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3416 .withConst(); 3417 QualType KmpUInt64Ty = 3418 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3419 .withConst(); 3420 QualType KmpInt64Ty = 3421 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3422 .withConst(); 3423 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3424 QualType KmpInt32PtrTy = 3425 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3426 QualType Args[] = {VoidPtrTy}; 3427 FunctionProtoType::ExtProtoInfo EPI; 3428 EPI.Variadic = true; 3429 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3430 Sema::CapturedParamNameType Params[] = { 3431 std::make_pair(".global_tid.", KmpInt32Ty), 3432 std::make_pair(".part_id.", KmpInt32PtrTy), 3433 std::make_pair(".privates.", VoidPtrTy), 3434 std::make_pair( 3435 ".copy_fn.", 3436 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3437 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3438 std::make_pair(".lb.", KmpUInt64Ty), 3439 std::make_pair(".ub.", KmpUInt64Ty), 3440 std::make_pair(".st.", KmpInt64Ty), 3441 std::make_pair(".liter.", KmpInt32Ty), 3442 std::make_pair(".reductions.", VoidPtrTy), 3443 std::make_pair(StringRef(), QualType()) // __context with shared vars 3444 }; 3445 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3446 Params); 3447 // Mark this captured region as inlined, because we don't use outlined 3448 // function directly. 3449 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3450 AlwaysInlineAttr::CreateImplicit( 3451 Context, {}, AttributeCommonInfo::AS_Keyword, 3452 AlwaysInlineAttr::Keyword_forceinline)); 3453 break; 3454 } 3455 case OMPD_parallel_master_taskloop: 3456 case OMPD_parallel_master_taskloop_simd: { 3457 QualType KmpInt32Ty = 3458 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3459 .withConst(); 3460 QualType KmpUInt64Ty = 3461 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3462 .withConst(); 3463 QualType KmpInt64Ty = 3464 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3465 .withConst(); 3466 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3467 QualType KmpInt32PtrTy = 3468 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3469 Sema::CapturedParamNameType ParamsParallel[] = { 3470 std::make_pair(".global_tid.", KmpInt32PtrTy), 3471 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3472 std::make_pair(StringRef(), QualType()) // __context with shared vars 3473 }; 3474 // Start a captured region for 'parallel'. 3475 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3476 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3477 QualType Args[] = {VoidPtrTy}; 3478 FunctionProtoType::ExtProtoInfo EPI; 3479 EPI.Variadic = true; 3480 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3481 Sema::CapturedParamNameType Params[] = { 3482 std::make_pair(".global_tid.", KmpInt32Ty), 3483 std::make_pair(".part_id.", KmpInt32PtrTy), 3484 std::make_pair(".privates.", VoidPtrTy), 3485 std::make_pair( 3486 ".copy_fn.", 3487 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3488 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3489 std::make_pair(".lb.", KmpUInt64Ty), 3490 std::make_pair(".ub.", KmpUInt64Ty), 3491 std::make_pair(".st.", KmpInt64Ty), 3492 std::make_pair(".liter.", KmpInt32Ty), 3493 std::make_pair(".reductions.", VoidPtrTy), 3494 std::make_pair(StringRef(), QualType()) // __context with shared vars 3495 }; 3496 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3497 Params, /*OpenMPCaptureLevel=*/2); 3498 // Mark this captured region as inlined, because we don't use outlined 3499 // function directly. 3500 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3501 AlwaysInlineAttr::CreateImplicit( 3502 Context, {}, AttributeCommonInfo::AS_Keyword, 3503 AlwaysInlineAttr::Keyword_forceinline)); 3504 break; 3505 } 3506 case OMPD_distribute_parallel_for_simd: 3507 case OMPD_distribute_parallel_for: { 3508 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3509 QualType KmpInt32PtrTy = 3510 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3511 Sema::CapturedParamNameType Params[] = { 3512 std::make_pair(".global_tid.", KmpInt32PtrTy), 3513 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3514 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3515 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3516 std::make_pair(StringRef(), QualType()) // __context with shared vars 3517 }; 3518 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3519 Params); 3520 break; 3521 } 3522 case OMPD_target_teams_distribute_parallel_for: 3523 case OMPD_target_teams_distribute_parallel_for_simd: { 3524 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3525 QualType KmpInt32PtrTy = 3526 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3527 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3528 3529 QualType Args[] = {VoidPtrTy}; 3530 FunctionProtoType::ExtProtoInfo EPI; 3531 EPI.Variadic = true; 3532 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3533 Sema::CapturedParamNameType Params[] = { 3534 std::make_pair(".global_tid.", KmpInt32Ty), 3535 std::make_pair(".part_id.", KmpInt32PtrTy), 3536 std::make_pair(".privates.", VoidPtrTy), 3537 std::make_pair( 3538 ".copy_fn.", 3539 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3540 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3541 std::make_pair(StringRef(), QualType()) // __context with shared vars 3542 }; 3543 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3544 Params, /*OpenMPCaptureLevel=*/0); 3545 // Mark this captured region as inlined, because we don't use outlined 3546 // function directly. 3547 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3548 AlwaysInlineAttr::CreateImplicit( 3549 Context, {}, AttributeCommonInfo::AS_Keyword, 3550 AlwaysInlineAttr::Keyword_forceinline)); 3551 Sema::CapturedParamNameType ParamsTarget[] = { 3552 std::make_pair(StringRef(), QualType()) // __context with shared vars 3553 }; 3554 // Start a captured region for 'target' with no implicit parameters. 3555 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3556 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3557 3558 Sema::CapturedParamNameType ParamsTeams[] = { 3559 std::make_pair(".global_tid.", KmpInt32PtrTy), 3560 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3561 std::make_pair(StringRef(), QualType()) // __context with shared vars 3562 }; 3563 // Start a captured region for 'target' with no implicit parameters. 3564 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3565 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3566 3567 Sema::CapturedParamNameType ParamsParallel[] = { 3568 std::make_pair(".global_tid.", KmpInt32PtrTy), 3569 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3570 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3571 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3572 std::make_pair(StringRef(), QualType()) // __context with shared vars 3573 }; 3574 // Start a captured region for 'teams' or 'parallel'. Both regions have 3575 // the same implicit parameters. 3576 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3577 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3578 break; 3579 } 3580 3581 case OMPD_teams_distribute_parallel_for: 3582 case OMPD_teams_distribute_parallel_for_simd: { 3583 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3584 QualType KmpInt32PtrTy = 3585 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3586 3587 Sema::CapturedParamNameType ParamsTeams[] = { 3588 std::make_pair(".global_tid.", KmpInt32PtrTy), 3589 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3590 std::make_pair(StringRef(), QualType()) // __context with shared vars 3591 }; 3592 // Start a captured region for 'target' with no implicit parameters. 3593 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3594 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3595 3596 Sema::CapturedParamNameType ParamsParallel[] = { 3597 std::make_pair(".global_tid.", KmpInt32PtrTy), 3598 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3599 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3600 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3601 std::make_pair(StringRef(), QualType()) // __context with shared vars 3602 }; 3603 // Start a captured region for 'teams' or 'parallel'. Both regions have 3604 // the same implicit parameters. 3605 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3606 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3607 break; 3608 } 3609 case OMPD_target_update: 3610 case OMPD_target_enter_data: 3611 case OMPD_target_exit_data: { 3612 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3613 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3614 QualType KmpInt32PtrTy = 3615 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3616 QualType Args[] = {VoidPtrTy}; 3617 FunctionProtoType::ExtProtoInfo EPI; 3618 EPI.Variadic = true; 3619 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3620 Sema::CapturedParamNameType Params[] = { 3621 std::make_pair(".global_tid.", KmpInt32Ty), 3622 std::make_pair(".part_id.", KmpInt32PtrTy), 3623 std::make_pair(".privates.", VoidPtrTy), 3624 std::make_pair( 3625 ".copy_fn.", 3626 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3627 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3628 std::make_pair(StringRef(), QualType()) // __context with shared vars 3629 }; 3630 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3631 Params); 3632 // Mark this captured region as inlined, because we don't use outlined 3633 // function directly. 3634 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3635 AlwaysInlineAttr::CreateImplicit( 3636 Context, {}, AttributeCommonInfo::AS_Keyword, 3637 AlwaysInlineAttr::Keyword_forceinline)); 3638 break; 3639 } 3640 case OMPD_threadprivate: 3641 case OMPD_allocate: 3642 case OMPD_taskyield: 3643 case OMPD_barrier: 3644 case OMPD_taskwait: 3645 case OMPD_cancellation_point: 3646 case OMPD_cancel: 3647 case OMPD_flush: 3648 case OMPD_declare_reduction: 3649 case OMPD_declare_mapper: 3650 case OMPD_declare_simd: 3651 case OMPD_declare_target: 3652 case OMPD_end_declare_target: 3653 case OMPD_requires: 3654 case OMPD_declare_variant: 3655 llvm_unreachable("OpenMP Directive is not allowed"); 3656 case OMPD_unknown: 3657 llvm_unreachable("Unknown OpenMP directive"); 3658 } 3659 } 3660 3661 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3662 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3663 } 3664 3665 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3666 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3667 getOpenMPCaptureRegions(CaptureRegions, DKind); 3668 return CaptureRegions.size(); 3669 } 3670 3671 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3672 Expr *CaptureExpr, bool WithInit, 3673 bool AsExpression) { 3674 assert(CaptureExpr); 3675 ASTContext &C = S.getASTContext(); 3676 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3677 QualType Ty = Init->getType(); 3678 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3679 if (S.getLangOpts().CPlusPlus) { 3680 Ty = C.getLValueReferenceType(Ty); 3681 } else { 3682 Ty = C.getPointerType(Ty); 3683 ExprResult Res = 3684 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3685 if (!Res.isUsable()) 3686 return nullptr; 3687 Init = Res.get(); 3688 } 3689 WithInit = true; 3690 } 3691 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3692 CaptureExpr->getBeginLoc()); 3693 if (!WithInit) 3694 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3695 S.CurContext->addHiddenDecl(CED); 3696 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3697 return CED; 3698 } 3699 3700 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3701 bool WithInit) { 3702 OMPCapturedExprDecl *CD; 3703 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3704 CD = cast<OMPCapturedExprDecl>(VD); 3705 else 3706 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3707 /*AsExpression=*/false); 3708 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3709 CaptureExpr->getExprLoc()); 3710 } 3711 3712 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3713 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3714 if (!Ref) { 3715 OMPCapturedExprDecl *CD = buildCaptureDecl( 3716 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3717 /*WithInit=*/true, /*AsExpression=*/true); 3718 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3719 CaptureExpr->getExprLoc()); 3720 } 3721 ExprResult Res = Ref; 3722 if (!S.getLangOpts().CPlusPlus && 3723 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3724 Ref->getType()->isPointerType()) { 3725 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3726 if (!Res.isUsable()) 3727 return ExprError(); 3728 } 3729 return S.DefaultLvalueConversion(Res.get()); 3730 } 3731 3732 namespace { 3733 // OpenMP directives parsed in this section are represented as a 3734 // CapturedStatement with an associated statement. If a syntax error 3735 // is detected during the parsing of the associated statement, the 3736 // compiler must abort processing and close the CapturedStatement. 3737 // 3738 // Combined directives such as 'target parallel' have more than one 3739 // nested CapturedStatements. This RAII ensures that we unwind out 3740 // of all the nested CapturedStatements when an error is found. 3741 class CaptureRegionUnwinderRAII { 3742 private: 3743 Sema &S; 3744 bool &ErrorFound; 3745 OpenMPDirectiveKind DKind = OMPD_unknown; 3746 3747 public: 3748 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3749 OpenMPDirectiveKind DKind) 3750 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3751 ~CaptureRegionUnwinderRAII() { 3752 if (ErrorFound) { 3753 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3754 while (--ThisCaptureLevel >= 0) 3755 S.ActOnCapturedRegionError(); 3756 } 3757 } 3758 }; 3759 } // namespace 3760 3761 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3762 // Capture variables captured by reference in lambdas for target-based 3763 // directives. 3764 if (!CurContext->isDependentContext() && 3765 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3766 isOpenMPTargetDataManagementDirective( 3767 DSAStack->getCurrentDirective()))) { 3768 QualType Type = V->getType(); 3769 if (const auto *RD = Type.getCanonicalType() 3770 .getNonReferenceType() 3771 ->getAsCXXRecordDecl()) { 3772 bool SavedForceCaptureByReferenceInTargetExecutable = 3773 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3774 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3775 /*V=*/true); 3776 if (RD->isLambda()) { 3777 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3778 FieldDecl *ThisCapture; 3779 RD->getCaptureFields(Captures, ThisCapture); 3780 for (const LambdaCapture &LC : RD->captures()) { 3781 if (LC.getCaptureKind() == LCK_ByRef) { 3782 VarDecl *VD = LC.getCapturedVar(); 3783 DeclContext *VDC = VD->getDeclContext(); 3784 if (!VDC->Encloses(CurContext)) 3785 continue; 3786 MarkVariableReferenced(LC.getLocation(), VD); 3787 } else if (LC.getCaptureKind() == LCK_This) { 3788 QualType ThisTy = getCurrentThisType(); 3789 if (!ThisTy.isNull() && 3790 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3791 CheckCXXThisCapture(LC.getLocation()); 3792 } 3793 } 3794 } 3795 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3796 SavedForceCaptureByReferenceInTargetExecutable); 3797 } 3798 } 3799 } 3800 3801 static bool checkOrderedOrderSpecified(Sema &S, 3802 const ArrayRef<OMPClause *> Clauses) { 3803 const OMPOrderedClause *Ordered = nullptr; 3804 const OMPOrderClause *Order = nullptr; 3805 3806 for (const OMPClause *Clause : Clauses) { 3807 if (Clause->getClauseKind() == OMPC_ordered) 3808 Ordered = cast<OMPOrderedClause>(Clause); 3809 else if (Clause->getClauseKind() == OMPC_order) { 3810 Order = cast<OMPOrderClause>(Clause); 3811 if (Order->getKind() != OMPC_ORDER_concurrent) 3812 Order = nullptr; 3813 } 3814 if (Ordered && Order) 3815 break; 3816 } 3817 3818 if (Ordered && Order) { 3819 S.Diag(Order->getKindKwLoc(), 3820 diag::err_omp_simple_clause_incompatible_with_ordered) 3821 << getOpenMPClauseName(OMPC_order) 3822 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 3823 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 3824 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 3825 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 3826 return true; 3827 } 3828 return false; 3829 } 3830 3831 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3832 ArrayRef<OMPClause *> Clauses) { 3833 bool ErrorFound = false; 3834 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3835 *this, ErrorFound, DSAStack->getCurrentDirective()); 3836 if (!S.isUsable()) { 3837 ErrorFound = true; 3838 return StmtError(); 3839 } 3840 3841 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3842 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3843 OMPOrderedClause *OC = nullptr; 3844 OMPScheduleClause *SC = nullptr; 3845 SmallVector<const OMPLinearClause *, 4> LCs; 3846 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3847 // This is required for proper codegen. 3848 for (OMPClause *Clause : Clauses) { 3849 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3850 Clause->getClauseKind() == OMPC_in_reduction) { 3851 // Capture taskgroup task_reduction descriptors inside the tasking regions 3852 // with the corresponding in_reduction items. 3853 auto *IRC = cast<OMPInReductionClause>(Clause); 3854 for (Expr *E : IRC->taskgroup_descriptors()) 3855 if (E) 3856 MarkDeclarationsReferencedInExpr(E); 3857 } 3858 if (isOpenMPPrivate(Clause->getClauseKind()) || 3859 Clause->getClauseKind() == OMPC_copyprivate || 3860 (getLangOpts().OpenMPUseTLS && 3861 getASTContext().getTargetInfo().isTLSSupported() && 3862 Clause->getClauseKind() == OMPC_copyin)) { 3863 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3864 // Mark all variables in private list clauses as used in inner region. 3865 for (Stmt *VarRef : Clause->children()) { 3866 if (auto *E = cast_or_null<Expr>(VarRef)) { 3867 MarkDeclarationsReferencedInExpr(E); 3868 } 3869 } 3870 DSAStack->setForceVarCapturing(/*V=*/false); 3871 } else if (CaptureRegions.size() > 1 || 3872 CaptureRegions.back() != OMPD_unknown) { 3873 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3874 PICs.push_back(C); 3875 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3876 if (Expr *E = C->getPostUpdateExpr()) 3877 MarkDeclarationsReferencedInExpr(E); 3878 } 3879 } 3880 if (Clause->getClauseKind() == OMPC_schedule) 3881 SC = cast<OMPScheduleClause>(Clause); 3882 else if (Clause->getClauseKind() == OMPC_ordered) 3883 OC = cast<OMPOrderedClause>(Clause); 3884 else if (Clause->getClauseKind() == OMPC_linear) 3885 LCs.push_back(cast<OMPLinearClause>(Clause)); 3886 } 3887 // Capture allocator expressions if used. 3888 for (Expr *E : DSAStack->getInnerAllocators()) 3889 MarkDeclarationsReferencedInExpr(E); 3890 // OpenMP, 2.7.1 Loop Construct, Restrictions 3891 // The nonmonotonic modifier cannot be specified if an ordered clause is 3892 // specified. 3893 if (SC && 3894 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3895 SC->getSecondScheduleModifier() == 3896 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3897 OC) { 3898 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3899 ? SC->getFirstScheduleModifierLoc() 3900 : SC->getSecondScheduleModifierLoc(), 3901 diag::err_omp_simple_clause_incompatible_with_ordered) 3902 << getOpenMPClauseName(OMPC_schedule) 3903 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 3904 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 3905 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3906 ErrorFound = true; 3907 } 3908 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 3909 // If an order(concurrent) clause is present, an ordered clause may not appear 3910 // on the same directive. 3911 if (checkOrderedOrderSpecified(*this, Clauses)) 3912 ErrorFound = true; 3913 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3914 for (const OMPLinearClause *C : LCs) { 3915 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3916 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3917 } 3918 ErrorFound = true; 3919 } 3920 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3921 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3922 OC->getNumForLoops()) { 3923 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3924 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3925 ErrorFound = true; 3926 } 3927 if (ErrorFound) { 3928 return StmtError(); 3929 } 3930 StmtResult SR = S; 3931 unsigned CompletedRegions = 0; 3932 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3933 // Mark all variables in private list clauses as used in inner region. 3934 // Required for proper codegen of combined directives. 3935 // TODO: add processing for other clauses. 3936 if (ThisCaptureRegion != OMPD_unknown) { 3937 for (const clang::OMPClauseWithPreInit *C : PICs) { 3938 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3939 // Find the particular capture region for the clause if the 3940 // directive is a combined one with multiple capture regions. 3941 // If the directive is not a combined one, the capture region 3942 // associated with the clause is OMPD_unknown and is generated 3943 // only once. 3944 if (CaptureRegion == ThisCaptureRegion || 3945 CaptureRegion == OMPD_unknown) { 3946 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3947 for (Decl *D : DS->decls()) 3948 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3949 } 3950 } 3951 } 3952 } 3953 if (++CompletedRegions == CaptureRegions.size()) 3954 DSAStack->setBodyComplete(); 3955 SR = ActOnCapturedRegionEnd(SR.get()); 3956 } 3957 return SR; 3958 } 3959 3960 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3961 OpenMPDirectiveKind CancelRegion, 3962 SourceLocation StartLoc) { 3963 // CancelRegion is only needed for cancel and cancellation_point. 3964 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3965 return false; 3966 3967 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3968 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3969 return false; 3970 3971 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3972 << getOpenMPDirectiveName(CancelRegion); 3973 return true; 3974 } 3975 3976 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3977 OpenMPDirectiveKind CurrentRegion, 3978 const DeclarationNameInfo &CurrentName, 3979 OpenMPDirectiveKind CancelRegion, 3980 SourceLocation StartLoc) { 3981 if (Stack->getCurScope()) { 3982 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3983 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3984 bool NestingProhibited = false; 3985 bool CloseNesting = true; 3986 bool OrphanSeen = false; 3987 enum { 3988 NoRecommend, 3989 ShouldBeInParallelRegion, 3990 ShouldBeInOrderedRegion, 3991 ShouldBeInTargetRegion, 3992 ShouldBeInTeamsRegion 3993 } Recommend = NoRecommend; 3994 if (isOpenMPSimdDirective(ParentRegion) && 3995 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 3996 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 3997 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 3998 // OpenMP [2.16, Nesting of Regions] 3999 // OpenMP constructs may not be nested inside a simd region. 4000 // OpenMP [2.8.1,simd Construct, Restrictions] 4001 // An ordered construct with the simd clause is the only OpenMP 4002 // construct that can appear in the simd region. 4003 // Allowing a SIMD construct nested in another SIMD construct is an 4004 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4005 // message. 4006 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4007 // The only OpenMP constructs that can be encountered during execution of 4008 // a simd region are the atomic construct, the loop construct, the simd 4009 // construct and the ordered construct with the simd clause. 4010 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4011 ? diag::err_omp_prohibited_region_simd 4012 : diag::warn_omp_nesting_simd) 4013 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4014 return CurrentRegion != OMPD_simd; 4015 } 4016 if (ParentRegion == OMPD_atomic) { 4017 // OpenMP [2.16, Nesting of Regions] 4018 // OpenMP constructs may not be nested inside an atomic region. 4019 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4020 return true; 4021 } 4022 if (CurrentRegion == OMPD_section) { 4023 // OpenMP [2.7.2, sections Construct, Restrictions] 4024 // Orphaned section directives are prohibited. That is, the section 4025 // directives must appear within the sections construct and must not be 4026 // encountered elsewhere in the sections region. 4027 if (ParentRegion != OMPD_sections && 4028 ParentRegion != OMPD_parallel_sections) { 4029 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4030 << (ParentRegion != OMPD_unknown) 4031 << getOpenMPDirectiveName(ParentRegion); 4032 return true; 4033 } 4034 return false; 4035 } 4036 // Allow some constructs (except teams and cancellation constructs) to be 4037 // orphaned (they could be used in functions, called from OpenMP regions 4038 // with the required preconditions). 4039 if (ParentRegion == OMPD_unknown && 4040 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4041 CurrentRegion != OMPD_cancellation_point && 4042 CurrentRegion != OMPD_cancel) 4043 return false; 4044 if (CurrentRegion == OMPD_cancellation_point || 4045 CurrentRegion == OMPD_cancel) { 4046 // OpenMP [2.16, Nesting of Regions] 4047 // A cancellation point construct for which construct-type-clause is 4048 // taskgroup must be nested inside a task construct. A cancellation 4049 // point construct for which construct-type-clause is not taskgroup must 4050 // be closely nested inside an OpenMP construct that matches the type 4051 // specified in construct-type-clause. 4052 // A cancel construct for which construct-type-clause is taskgroup must be 4053 // nested inside a task construct. A cancel construct for which 4054 // construct-type-clause is not taskgroup must be closely nested inside an 4055 // OpenMP construct that matches the type specified in 4056 // construct-type-clause. 4057 NestingProhibited = 4058 !((CancelRegion == OMPD_parallel && 4059 (ParentRegion == OMPD_parallel || 4060 ParentRegion == OMPD_target_parallel)) || 4061 (CancelRegion == OMPD_for && 4062 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4063 ParentRegion == OMPD_target_parallel_for || 4064 ParentRegion == OMPD_distribute_parallel_for || 4065 ParentRegion == OMPD_teams_distribute_parallel_for || 4066 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4067 (CancelRegion == OMPD_taskgroup && 4068 (ParentRegion == OMPD_task || 4069 (SemaRef.getLangOpts().OpenMP >= 50 && 4070 (ParentRegion == OMPD_taskloop || 4071 ParentRegion == OMPD_master_taskloop || 4072 ParentRegion == OMPD_parallel_master_taskloop)))) || 4073 (CancelRegion == OMPD_sections && 4074 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4075 ParentRegion == OMPD_parallel_sections))); 4076 OrphanSeen = ParentRegion == OMPD_unknown; 4077 } else if (CurrentRegion == OMPD_master) { 4078 // OpenMP [2.16, Nesting of Regions] 4079 // A master region may not be closely nested inside a worksharing, 4080 // atomic, or explicit task region. 4081 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4082 isOpenMPTaskingDirective(ParentRegion); 4083 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4084 // OpenMP [2.16, Nesting of Regions] 4085 // A critical region may not be nested (closely or otherwise) inside a 4086 // critical region with the same name. Note that this restriction is not 4087 // sufficient to prevent deadlock. 4088 SourceLocation PreviousCriticalLoc; 4089 bool DeadLock = Stack->hasDirective( 4090 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4091 const DeclarationNameInfo &DNI, 4092 SourceLocation Loc) { 4093 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4094 PreviousCriticalLoc = Loc; 4095 return true; 4096 } 4097 return false; 4098 }, 4099 false /* skip top directive */); 4100 if (DeadLock) { 4101 SemaRef.Diag(StartLoc, 4102 diag::err_omp_prohibited_region_critical_same_name) 4103 << CurrentName.getName(); 4104 if (PreviousCriticalLoc.isValid()) 4105 SemaRef.Diag(PreviousCriticalLoc, 4106 diag::note_omp_previous_critical_region); 4107 return true; 4108 } 4109 } else if (CurrentRegion == OMPD_barrier) { 4110 // OpenMP [2.16, Nesting of Regions] 4111 // A barrier region may not be closely nested inside a worksharing, 4112 // explicit task, critical, ordered, atomic, or master region. 4113 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4114 isOpenMPTaskingDirective(ParentRegion) || 4115 ParentRegion == OMPD_master || 4116 ParentRegion == OMPD_parallel_master || 4117 ParentRegion == OMPD_critical || 4118 ParentRegion == OMPD_ordered; 4119 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4120 !isOpenMPParallelDirective(CurrentRegion) && 4121 !isOpenMPTeamsDirective(CurrentRegion)) { 4122 // OpenMP [2.16, Nesting of Regions] 4123 // A worksharing region may not be closely nested inside a worksharing, 4124 // explicit task, critical, ordered, atomic, or master region. 4125 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4126 isOpenMPTaskingDirective(ParentRegion) || 4127 ParentRegion == OMPD_master || 4128 ParentRegion == OMPD_parallel_master || 4129 ParentRegion == OMPD_critical || 4130 ParentRegion == OMPD_ordered; 4131 Recommend = ShouldBeInParallelRegion; 4132 } else if (CurrentRegion == OMPD_ordered) { 4133 // OpenMP [2.16, Nesting of Regions] 4134 // An ordered region may not be closely nested inside a critical, 4135 // atomic, or explicit task region. 4136 // An ordered region must be closely nested inside a loop region (or 4137 // parallel loop region) with an ordered clause. 4138 // OpenMP [2.8.1,simd Construct, Restrictions] 4139 // An ordered construct with the simd clause is the only OpenMP construct 4140 // that can appear in the simd region. 4141 NestingProhibited = ParentRegion == OMPD_critical || 4142 isOpenMPTaskingDirective(ParentRegion) || 4143 !(isOpenMPSimdDirective(ParentRegion) || 4144 Stack->isParentOrderedRegion()); 4145 Recommend = ShouldBeInOrderedRegion; 4146 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4147 // OpenMP [2.16, Nesting of Regions] 4148 // If specified, a teams construct must be contained within a target 4149 // construct. 4150 NestingProhibited = 4151 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4152 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4153 ParentRegion != OMPD_target); 4154 OrphanSeen = ParentRegion == OMPD_unknown; 4155 Recommend = ShouldBeInTargetRegion; 4156 } 4157 if (!NestingProhibited && 4158 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4159 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4160 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4161 // OpenMP [2.16, Nesting of Regions] 4162 // distribute, parallel, parallel sections, parallel workshare, and the 4163 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4164 // constructs that can be closely nested in the teams region. 4165 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4166 !isOpenMPDistributeDirective(CurrentRegion); 4167 Recommend = ShouldBeInParallelRegion; 4168 } 4169 if (!NestingProhibited && 4170 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4171 // OpenMP 4.5 [2.17 Nesting of Regions] 4172 // The region associated with the distribute construct must be strictly 4173 // nested inside a teams region 4174 NestingProhibited = 4175 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4176 Recommend = ShouldBeInTeamsRegion; 4177 } 4178 if (!NestingProhibited && 4179 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4180 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4181 // OpenMP 4.5 [2.17 Nesting of Regions] 4182 // If a target, target update, target data, target enter data, or 4183 // target exit data construct is encountered during execution of a 4184 // target region, the behavior is unspecified. 4185 NestingProhibited = Stack->hasDirective( 4186 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4187 SourceLocation) { 4188 if (isOpenMPTargetExecutionDirective(K)) { 4189 OffendingRegion = K; 4190 return true; 4191 } 4192 return false; 4193 }, 4194 false /* don't skip top directive */); 4195 CloseNesting = false; 4196 } 4197 if (NestingProhibited) { 4198 if (OrphanSeen) { 4199 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4200 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4201 } else { 4202 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4203 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4204 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4205 } 4206 return true; 4207 } 4208 } 4209 return false; 4210 } 4211 4212 struct Kind2Unsigned { 4213 using argument_type = OpenMPDirectiveKind; 4214 unsigned operator()(argument_type DK) { return unsigned(DK); } 4215 }; 4216 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4217 ArrayRef<OMPClause *> Clauses, 4218 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4219 bool ErrorFound = false; 4220 unsigned NamedModifiersNumber = 0; 4221 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4222 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4223 SmallVector<SourceLocation, 4> NameModifierLoc; 4224 for (const OMPClause *C : Clauses) { 4225 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4226 // At most one if clause without a directive-name-modifier can appear on 4227 // the directive. 4228 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4229 if (FoundNameModifiers[CurNM]) { 4230 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4231 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4232 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4233 ErrorFound = true; 4234 } else if (CurNM != OMPD_unknown) { 4235 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4236 ++NamedModifiersNumber; 4237 } 4238 FoundNameModifiers[CurNM] = IC; 4239 if (CurNM == OMPD_unknown) 4240 continue; 4241 // Check if the specified name modifier is allowed for the current 4242 // directive. 4243 // At most one if clause with the particular directive-name-modifier can 4244 // appear on the directive. 4245 bool MatchFound = false; 4246 for (auto NM : AllowedNameModifiers) { 4247 if (CurNM == NM) { 4248 MatchFound = true; 4249 break; 4250 } 4251 } 4252 if (!MatchFound) { 4253 S.Diag(IC->getNameModifierLoc(), 4254 diag::err_omp_wrong_if_directive_name_modifier) 4255 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4256 ErrorFound = true; 4257 } 4258 } 4259 } 4260 // If any if clause on the directive includes a directive-name-modifier then 4261 // all if clauses on the directive must include a directive-name-modifier. 4262 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4263 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4264 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4265 diag::err_omp_no_more_if_clause); 4266 } else { 4267 std::string Values; 4268 std::string Sep(", "); 4269 unsigned AllowedCnt = 0; 4270 unsigned TotalAllowedNum = 4271 AllowedNameModifiers.size() - NamedModifiersNumber; 4272 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4273 ++Cnt) { 4274 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4275 if (!FoundNameModifiers[NM]) { 4276 Values += "'"; 4277 Values += getOpenMPDirectiveName(NM); 4278 Values += "'"; 4279 if (AllowedCnt + 2 == TotalAllowedNum) 4280 Values += " or "; 4281 else if (AllowedCnt + 1 != TotalAllowedNum) 4282 Values += Sep; 4283 ++AllowedCnt; 4284 } 4285 } 4286 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4287 diag::err_omp_unnamed_if_clause) 4288 << (TotalAllowedNum > 1) << Values; 4289 } 4290 for (SourceLocation Loc : NameModifierLoc) { 4291 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4292 } 4293 ErrorFound = true; 4294 } 4295 return ErrorFound; 4296 } 4297 4298 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4299 SourceLocation &ELoc, 4300 SourceRange &ERange, 4301 bool AllowArraySection) { 4302 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4303 RefExpr->containsUnexpandedParameterPack()) 4304 return std::make_pair(nullptr, true); 4305 4306 // OpenMP [3.1, C/C++] 4307 // A list item is a variable name. 4308 // OpenMP [2.9.3.3, Restrictions, p.1] 4309 // A variable that is part of another variable (as an array or 4310 // structure element) cannot appear in a private clause. 4311 RefExpr = RefExpr->IgnoreParens(); 4312 enum { 4313 NoArrayExpr = -1, 4314 ArraySubscript = 0, 4315 OMPArraySection = 1 4316 } IsArrayExpr = NoArrayExpr; 4317 if (AllowArraySection) { 4318 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4319 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4320 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4321 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4322 RefExpr = Base; 4323 IsArrayExpr = ArraySubscript; 4324 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4325 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4326 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4327 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4328 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4329 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4330 RefExpr = Base; 4331 IsArrayExpr = OMPArraySection; 4332 } 4333 } 4334 ELoc = RefExpr->getExprLoc(); 4335 ERange = RefExpr->getSourceRange(); 4336 RefExpr = RefExpr->IgnoreParenImpCasts(); 4337 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4338 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4339 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4340 (S.getCurrentThisType().isNull() || !ME || 4341 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4342 !isa<FieldDecl>(ME->getMemberDecl()))) { 4343 if (IsArrayExpr != NoArrayExpr) { 4344 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4345 << ERange; 4346 } else { 4347 S.Diag(ELoc, 4348 AllowArraySection 4349 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4350 : diag::err_omp_expected_var_name_member_expr) 4351 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4352 } 4353 return std::make_pair(nullptr, false); 4354 } 4355 return std::make_pair( 4356 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4357 } 4358 4359 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4360 ArrayRef<OMPClause *> Clauses) { 4361 assert(!S.CurContext->isDependentContext() && 4362 "Expected non-dependent context."); 4363 auto AllocateRange = 4364 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4365 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4366 DeclToCopy; 4367 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4368 return isOpenMPPrivate(C->getClauseKind()); 4369 }); 4370 for (OMPClause *Cl : PrivateRange) { 4371 MutableArrayRef<Expr *>::iterator I, It, Et; 4372 if (Cl->getClauseKind() == OMPC_private) { 4373 auto *PC = cast<OMPPrivateClause>(Cl); 4374 I = PC->private_copies().begin(); 4375 It = PC->varlist_begin(); 4376 Et = PC->varlist_end(); 4377 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4378 auto *PC = cast<OMPFirstprivateClause>(Cl); 4379 I = PC->private_copies().begin(); 4380 It = PC->varlist_begin(); 4381 Et = PC->varlist_end(); 4382 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4383 auto *PC = cast<OMPLastprivateClause>(Cl); 4384 I = PC->private_copies().begin(); 4385 It = PC->varlist_begin(); 4386 Et = PC->varlist_end(); 4387 } else if (Cl->getClauseKind() == OMPC_linear) { 4388 auto *PC = cast<OMPLinearClause>(Cl); 4389 I = PC->privates().begin(); 4390 It = PC->varlist_begin(); 4391 Et = PC->varlist_end(); 4392 } else if (Cl->getClauseKind() == OMPC_reduction) { 4393 auto *PC = cast<OMPReductionClause>(Cl); 4394 I = PC->privates().begin(); 4395 It = PC->varlist_begin(); 4396 Et = PC->varlist_end(); 4397 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4398 auto *PC = cast<OMPTaskReductionClause>(Cl); 4399 I = PC->privates().begin(); 4400 It = PC->varlist_begin(); 4401 Et = PC->varlist_end(); 4402 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4403 auto *PC = cast<OMPInReductionClause>(Cl); 4404 I = PC->privates().begin(); 4405 It = PC->varlist_begin(); 4406 Et = PC->varlist_end(); 4407 } else { 4408 llvm_unreachable("Expected private clause."); 4409 } 4410 for (Expr *E : llvm::make_range(It, Et)) { 4411 if (!*I) { 4412 ++I; 4413 continue; 4414 } 4415 SourceLocation ELoc; 4416 SourceRange ERange; 4417 Expr *SimpleRefExpr = E; 4418 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4419 /*AllowArraySection=*/true); 4420 DeclToCopy.try_emplace(Res.first, 4421 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4422 ++I; 4423 } 4424 } 4425 for (OMPClause *C : AllocateRange) { 4426 auto *AC = cast<OMPAllocateClause>(C); 4427 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4428 getAllocatorKind(S, Stack, AC->getAllocator()); 4429 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4430 // For task, taskloop or target directives, allocation requests to memory 4431 // allocators with the trait access set to thread result in unspecified 4432 // behavior. 4433 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4434 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4435 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4436 S.Diag(AC->getAllocator()->getExprLoc(), 4437 diag::warn_omp_allocate_thread_on_task_target_directive) 4438 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4439 } 4440 for (Expr *E : AC->varlists()) { 4441 SourceLocation ELoc; 4442 SourceRange ERange; 4443 Expr *SimpleRefExpr = E; 4444 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4445 ValueDecl *VD = Res.first; 4446 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4447 if (!isOpenMPPrivate(Data.CKind)) { 4448 S.Diag(E->getExprLoc(), 4449 diag::err_omp_expected_private_copy_for_allocate); 4450 continue; 4451 } 4452 VarDecl *PrivateVD = DeclToCopy[VD]; 4453 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4454 AllocatorKind, AC->getAllocator())) 4455 continue; 4456 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4457 E->getSourceRange()); 4458 } 4459 } 4460 } 4461 4462 StmtResult Sema::ActOnOpenMPExecutableDirective( 4463 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4464 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4465 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4466 StmtResult Res = StmtError(); 4467 // First check CancelRegion which is then used in checkNestingOfRegions. 4468 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4469 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4470 StartLoc)) 4471 return StmtError(); 4472 4473 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4474 VarsWithInheritedDSAType VarsWithInheritedDSA; 4475 bool ErrorFound = false; 4476 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4477 if (AStmt && !CurContext->isDependentContext()) { 4478 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4479 4480 // Check default data sharing attributes for referenced variables. 4481 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4482 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4483 Stmt *S = AStmt; 4484 while (--ThisCaptureLevel >= 0) 4485 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4486 DSAChecker.Visit(S); 4487 if (!isOpenMPTargetDataManagementDirective(Kind) && 4488 !isOpenMPTaskingDirective(Kind)) { 4489 // Visit subcaptures to generate implicit clauses for captured vars. 4490 auto *CS = cast<CapturedStmt>(AStmt); 4491 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4492 getOpenMPCaptureRegions(CaptureRegions, Kind); 4493 // Ignore outer tasking regions for target directives. 4494 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4495 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4496 DSAChecker.visitSubCaptures(CS); 4497 } 4498 if (DSAChecker.isErrorFound()) 4499 return StmtError(); 4500 // Generate list of implicitly defined firstprivate variables. 4501 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4502 4503 SmallVector<Expr *, 4> ImplicitFirstprivates( 4504 DSAChecker.getImplicitFirstprivate().begin(), 4505 DSAChecker.getImplicitFirstprivate().end()); 4506 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4507 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4508 ArrayRef<Expr *> ImplicitMap = 4509 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4510 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4511 } 4512 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4513 for (OMPClause *C : Clauses) { 4514 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4515 for (Expr *E : IRC->taskgroup_descriptors()) 4516 if (E) 4517 ImplicitFirstprivates.emplace_back(E); 4518 } 4519 } 4520 if (!ImplicitFirstprivates.empty()) { 4521 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4522 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4523 SourceLocation())) { 4524 ClausesWithImplicit.push_back(Implicit); 4525 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4526 ImplicitFirstprivates.size(); 4527 } else { 4528 ErrorFound = true; 4529 } 4530 } 4531 int ClauseKindCnt = -1; 4532 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4533 ++ClauseKindCnt; 4534 if (ImplicitMap.empty()) 4535 continue; 4536 CXXScopeSpec MapperIdScopeSpec; 4537 DeclarationNameInfo MapperId; 4538 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4539 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4540 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4541 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4542 ImplicitMap, OMPVarListLocTy())) { 4543 ClausesWithImplicit.emplace_back(Implicit); 4544 ErrorFound |= 4545 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4546 } else { 4547 ErrorFound = true; 4548 } 4549 } 4550 } 4551 4552 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4553 switch (Kind) { 4554 case OMPD_parallel: 4555 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4556 EndLoc); 4557 AllowedNameModifiers.push_back(OMPD_parallel); 4558 break; 4559 case OMPD_simd: 4560 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4561 VarsWithInheritedDSA); 4562 if (LangOpts.OpenMP >= 50) 4563 AllowedNameModifiers.push_back(OMPD_simd); 4564 break; 4565 case OMPD_for: 4566 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4567 VarsWithInheritedDSA); 4568 break; 4569 case OMPD_for_simd: 4570 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4571 EndLoc, VarsWithInheritedDSA); 4572 if (LangOpts.OpenMP >= 50) 4573 AllowedNameModifiers.push_back(OMPD_simd); 4574 break; 4575 case OMPD_sections: 4576 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4577 EndLoc); 4578 break; 4579 case OMPD_section: 4580 assert(ClausesWithImplicit.empty() && 4581 "No clauses are allowed for 'omp section' directive"); 4582 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4583 break; 4584 case OMPD_single: 4585 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4586 EndLoc); 4587 break; 4588 case OMPD_master: 4589 assert(ClausesWithImplicit.empty() && 4590 "No clauses are allowed for 'omp master' directive"); 4591 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4592 break; 4593 case OMPD_critical: 4594 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4595 StartLoc, EndLoc); 4596 break; 4597 case OMPD_parallel_for: 4598 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4599 EndLoc, VarsWithInheritedDSA); 4600 AllowedNameModifiers.push_back(OMPD_parallel); 4601 break; 4602 case OMPD_parallel_for_simd: 4603 Res = ActOnOpenMPParallelForSimdDirective( 4604 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4605 AllowedNameModifiers.push_back(OMPD_parallel); 4606 if (LangOpts.OpenMP >= 50) 4607 AllowedNameModifiers.push_back(OMPD_simd); 4608 break; 4609 case OMPD_parallel_master: 4610 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4611 StartLoc, EndLoc); 4612 AllowedNameModifiers.push_back(OMPD_parallel); 4613 break; 4614 case OMPD_parallel_sections: 4615 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4616 StartLoc, EndLoc); 4617 AllowedNameModifiers.push_back(OMPD_parallel); 4618 break; 4619 case OMPD_task: 4620 Res = 4621 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4622 AllowedNameModifiers.push_back(OMPD_task); 4623 break; 4624 case OMPD_taskyield: 4625 assert(ClausesWithImplicit.empty() && 4626 "No clauses are allowed for 'omp taskyield' directive"); 4627 assert(AStmt == nullptr && 4628 "No associated statement allowed for 'omp taskyield' directive"); 4629 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4630 break; 4631 case OMPD_barrier: 4632 assert(ClausesWithImplicit.empty() && 4633 "No clauses are allowed for 'omp barrier' directive"); 4634 assert(AStmt == nullptr && 4635 "No associated statement allowed for 'omp barrier' directive"); 4636 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4637 break; 4638 case OMPD_taskwait: 4639 assert(ClausesWithImplicit.empty() && 4640 "No clauses are allowed for 'omp taskwait' directive"); 4641 assert(AStmt == nullptr && 4642 "No associated statement allowed for 'omp taskwait' directive"); 4643 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4644 break; 4645 case OMPD_taskgroup: 4646 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4647 EndLoc); 4648 break; 4649 case OMPD_flush: 4650 assert(AStmt == nullptr && 4651 "No associated statement allowed for 'omp flush' directive"); 4652 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4653 break; 4654 case OMPD_ordered: 4655 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4656 EndLoc); 4657 break; 4658 case OMPD_atomic: 4659 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4660 EndLoc); 4661 break; 4662 case OMPD_teams: 4663 Res = 4664 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4665 break; 4666 case OMPD_target: 4667 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4668 EndLoc); 4669 AllowedNameModifiers.push_back(OMPD_target); 4670 break; 4671 case OMPD_target_parallel: 4672 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4673 StartLoc, EndLoc); 4674 AllowedNameModifiers.push_back(OMPD_target); 4675 AllowedNameModifiers.push_back(OMPD_parallel); 4676 break; 4677 case OMPD_target_parallel_for: 4678 Res = ActOnOpenMPTargetParallelForDirective( 4679 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4680 AllowedNameModifiers.push_back(OMPD_target); 4681 AllowedNameModifiers.push_back(OMPD_parallel); 4682 break; 4683 case OMPD_cancellation_point: 4684 assert(ClausesWithImplicit.empty() && 4685 "No clauses are allowed for 'omp cancellation point' directive"); 4686 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4687 "cancellation point' directive"); 4688 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4689 break; 4690 case OMPD_cancel: 4691 assert(AStmt == nullptr && 4692 "No associated statement allowed for 'omp cancel' directive"); 4693 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4694 CancelRegion); 4695 AllowedNameModifiers.push_back(OMPD_cancel); 4696 break; 4697 case OMPD_target_data: 4698 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4699 EndLoc); 4700 AllowedNameModifiers.push_back(OMPD_target_data); 4701 break; 4702 case OMPD_target_enter_data: 4703 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4704 EndLoc, AStmt); 4705 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4706 break; 4707 case OMPD_target_exit_data: 4708 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4709 EndLoc, AStmt); 4710 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4711 break; 4712 case OMPD_taskloop: 4713 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4714 EndLoc, VarsWithInheritedDSA); 4715 AllowedNameModifiers.push_back(OMPD_taskloop); 4716 break; 4717 case OMPD_taskloop_simd: 4718 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4719 EndLoc, VarsWithInheritedDSA); 4720 AllowedNameModifiers.push_back(OMPD_taskloop); 4721 if (LangOpts.OpenMP >= 50) 4722 AllowedNameModifiers.push_back(OMPD_simd); 4723 break; 4724 case OMPD_master_taskloop: 4725 Res = ActOnOpenMPMasterTaskLoopDirective( 4726 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4727 AllowedNameModifiers.push_back(OMPD_taskloop); 4728 break; 4729 case OMPD_master_taskloop_simd: 4730 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4731 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4732 AllowedNameModifiers.push_back(OMPD_taskloop); 4733 if (LangOpts.OpenMP >= 50) 4734 AllowedNameModifiers.push_back(OMPD_simd); 4735 break; 4736 case OMPD_parallel_master_taskloop: 4737 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4738 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4739 AllowedNameModifiers.push_back(OMPD_taskloop); 4740 AllowedNameModifiers.push_back(OMPD_parallel); 4741 break; 4742 case OMPD_parallel_master_taskloop_simd: 4743 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4744 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4745 AllowedNameModifiers.push_back(OMPD_taskloop); 4746 AllowedNameModifiers.push_back(OMPD_parallel); 4747 if (LangOpts.OpenMP >= 50) 4748 AllowedNameModifiers.push_back(OMPD_simd); 4749 break; 4750 case OMPD_distribute: 4751 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4752 EndLoc, VarsWithInheritedDSA); 4753 break; 4754 case OMPD_target_update: 4755 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4756 EndLoc, AStmt); 4757 AllowedNameModifiers.push_back(OMPD_target_update); 4758 break; 4759 case OMPD_distribute_parallel_for: 4760 Res = ActOnOpenMPDistributeParallelForDirective( 4761 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4762 AllowedNameModifiers.push_back(OMPD_parallel); 4763 break; 4764 case OMPD_distribute_parallel_for_simd: 4765 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4766 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4767 AllowedNameModifiers.push_back(OMPD_parallel); 4768 if (LangOpts.OpenMP >= 50) 4769 AllowedNameModifiers.push_back(OMPD_simd); 4770 break; 4771 case OMPD_distribute_simd: 4772 Res = ActOnOpenMPDistributeSimdDirective( 4773 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4774 if (LangOpts.OpenMP >= 50) 4775 AllowedNameModifiers.push_back(OMPD_simd); 4776 break; 4777 case OMPD_target_parallel_for_simd: 4778 Res = ActOnOpenMPTargetParallelForSimdDirective( 4779 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4780 AllowedNameModifiers.push_back(OMPD_target); 4781 AllowedNameModifiers.push_back(OMPD_parallel); 4782 if (LangOpts.OpenMP >= 50) 4783 AllowedNameModifiers.push_back(OMPD_simd); 4784 break; 4785 case OMPD_target_simd: 4786 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4787 EndLoc, VarsWithInheritedDSA); 4788 AllowedNameModifiers.push_back(OMPD_target); 4789 if (LangOpts.OpenMP >= 50) 4790 AllowedNameModifiers.push_back(OMPD_simd); 4791 break; 4792 case OMPD_teams_distribute: 4793 Res = ActOnOpenMPTeamsDistributeDirective( 4794 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4795 break; 4796 case OMPD_teams_distribute_simd: 4797 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4798 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4799 if (LangOpts.OpenMP >= 50) 4800 AllowedNameModifiers.push_back(OMPD_simd); 4801 break; 4802 case OMPD_teams_distribute_parallel_for_simd: 4803 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4804 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4805 AllowedNameModifiers.push_back(OMPD_parallel); 4806 if (LangOpts.OpenMP >= 50) 4807 AllowedNameModifiers.push_back(OMPD_simd); 4808 break; 4809 case OMPD_teams_distribute_parallel_for: 4810 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4811 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4812 AllowedNameModifiers.push_back(OMPD_parallel); 4813 break; 4814 case OMPD_target_teams: 4815 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4816 EndLoc); 4817 AllowedNameModifiers.push_back(OMPD_target); 4818 break; 4819 case OMPD_target_teams_distribute: 4820 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4821 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4822 AllowedNameModifiers.push_back(OMPD_target); 4823 break; 4824 case OMPD_target_teams_distribute_parallel_for: 4825 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4826 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4827 AllowedNameModifiers.push_back(OMPD_target); 4828 AllowedNameModifiers.push_back(OMPD_parallel); 4829 break; 4830 case OMPD_target_teams_distribute_parallel_for_simd: 4831 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4832 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4833 AllowedNameModifiers.push_back(OMPD_target); 4834 AllowedNameModifiers.push_back(OMPD_parallel); 4835 if (LangOpts.OpenMP >= 50) 4836 AllowedNameModifiers.push_back(OMPD_simd); 4837 break; 4838 case OMPD_target_teams_distribute_simd: 4839 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4840 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4841 AllowedNameModifiers.push_back(OMPD_target); 4842 if (LangOpts.OpenMP >= 50) 4843 AllowedNameModifiers.push_back(OMPD_simd); 4844 break; 4845 case OMPD_declare_target: 4846 case OMPD_end_declare_target: 4847 case OMPD_threadprivate: 4848 case OMPD_allocate: 4849 case OMPD_declare_reduction: 4850 case OMPD_declare_mapper: 4851 case OMPD_declare_simd: 4852 case OMPD_requires: 4853 case OMPD_declare_variant: 4854 llvm_unreachable("OpenMP Directive is not allowed"); 4855 case OMPD_unknown: 4856 llvm_unreachable("Unknown OpenMP directive"); 4857 } 4858 4859 ErrorFound = Res.isInvalid() || ErrorFound; 4860 4861 // Check variables in the clauses if default(none) was specified. 4862 if (DSAStack->getDefaultDSA() == DSA_none) { 4863 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4864 for (OMPClause *C : Clauses) { 4865 switch (C->getClauseKind()) { 4866 case OMPC_num_threads: 4867 case OMPC_dist_schedule: 4868 // Do not analyse if no parent teams directive. 4869 if (isOpenMPTeamsDirective(Kind)) 4870 break; 4871 continue; 4872 case OMPC_if: 4873 if (isOpenMPTeamsDirective(Kind) && 4874 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4875 break; 4876 if (isOpenMPParallelDirective(Kind) && 4877 isOpenMPTaskLoopDirective(Kind) && 4878 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 4879 break; 4880 continue; 4881 case OMPC_schedule: 4882 break; 4883 case OMPC_grainsize: 4884 case OMPC_num_tasks: 4885 case OMPC_final: 4886 case OMPC_priority: 4887 // Do not analyze if no parent parallel directive. 4888 if (isOpenMPParallelDirective(Kind)) 4889 break; 4890 continue; 4891 case OMPC_ordered: 4892 case OMPC_device: 4893 case OMPC_num_teams: 4894 case OMPC_thread_limit: 4895 case OMPC_hint: 4896 case OMPC_collapse: 4897 case OMPC_safelen: 4898 case OMPC_simdlen: 4899 case OMPC_default: 4900 case OMPC_proc_bind: 4901 case OMPC_private: 4902 case OMPC_firstprivate: 4903 case OMPC_lastprivate: 4904 case OMPC_shared: 4905 case OMPC_reduction: 4906 case OMPC_task_reduction: 4907 case OMPC_in_reduction: 4908 case OMPC_linear: 4909 case OMPC_aligned: 4910 case OMPC_copyin: 4911 case OMPC_copyprivate: 4912 case OMPC_nowait: 4913 case OMPC_untied: 4914 case OMPC_mergeable: 4915 case OMPC_allocate: 4916 case OMPC_read: 4917 case OMPC_write: 4918 case OMPC_update: 4919 case OMPC_capture: 4920 case OMPC_seq_cst: 4921 case OMPC_acq_rel: 4922 case OMPC_acquire: 4923 case OMPC_release: 4924 case OMPC_relaxed: 4925 case OMPC_depend: 4926 case OMPC_threads: 4927 case OMPC_simd: 4928 case OMPC_map: 4929 case OMPC_nogroup: 4930 case OMPC_defaultmap: 4931 case OMPC_to: 4932 case OMPC_from: 4933 case OMPC_use_device_ptr: 4934 case OMPC_is_device_ptr: 4935 case OMPC_nontemporal: 4936 case OMPC_order: 4937 continue; 4938 case OMPC_allocator: 4939 case OMPC_flush: 4940 case OMPC_threadprivate: 4941 case OMPC_uniform: 4942 case OMPC_unknown: 4943 case OMPC_unified_address: 4944 case OMPC_unified_shared_memory: 4945 case OMPC_reverse_offload: 4946 case OMPC_dynamic_allocators: 4947 case OMPC_atomic_default_mem_order: 4948 case OMPC_device_type: 4949 case OMPC_match: 4950 llvm_unreachable("Unexpected clause"); 4951 } 4952 for (Stmt *CC : C->children()) { 4953 if (CC) 4954 DSAChecker.Visit(CC); 4955 } 4956 } 4957 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 4958 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4959 } 4960 for (const auto &P : VarsWithInheritedDSA) { 4961 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4962 continue; 4963 ErrorFound = true; 4964 if (DSAStack->getDefaultDSA() == DSA_none) { 4965 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4966 << P.first << P.second->getSourceRange(); 4967 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4968 } else if (getLangOpts().OpenMP >= 50) { 4969 Diag(P.second->getExprLoc(), 4970 diag::err_omp_defaultmap_no_attr_for_variable) 4971 << P.first << P.second->getSourceRange(); 4972 Diag(DSAStack->getDefaultDSALocation(), 4973 diag::note_omp_defaultmap_attr_none); 4974 } 4975 } 4976 4977 if (!AllowedNameModifiers.empty()) 4978 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4979 ErrorFound; 4980 4981 if (ErrorFound) 4982 return StmtError(); 4983 4984 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4985 Res.getAs<OMPExecutableDirective>() 4986 ->getStructuredBlock() 4987 ->setIsOMPStructuredBlock(true); 4988 } 4989 4990 if (!CurContext->isDependentContext() && 4991 isOpenMPTargetExecutionDirective(Kind) && 4992 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4993 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4994 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4995 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4996 // Register target to DSA Stack. 4997 DSAStack->addTargetDirLocation(StartLoc); 4998 } 4999 5000 return Res; 5001 } 5002 5003 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5004 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5005 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5006 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5007 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5008 assert(Aligneds.size() == Alignments.size()); 5009 assert(Linears.size() == LinModifiers.size()); 5010 assert(Linears.size() == Steps.size()); 5011 if (!DG || DG.get().isNull()) 5012 return DeclGroupPtrTy(); 5013 5014 const int SimdId = 0; 5015 if (!DG.get().isSingleDecl()) { 5016 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5017 << SimdId; 5018 return DG; 5019 } 5020 Decl *ADecl = DG.get().getSingleDecl(); 5021 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5022 ADecl = FTD->getTemplatedDecl(); 5023 5024 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5025 if (!FD) { 5026 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5027 return DeclGroupPtrTy(); 5028 } 5029 5030 // OpenMP [2.8.2, declare simd construct, Description] 5031 // The parameter of the simdlen clause must be a constant positive integer 5032 // expression. 5033 ExprResult SL; 5034 if (Simdlen) 5035 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5036 // OpenMP [2.8.2, declare simd construct, Description] 5037 // The special this pointer can be used as if was one of the arguments to the 5038 // function in any of the linear, aligned, or uniform clauses. 5039 // The uniform clause declares one or more arguments to have an invariant 5040 // value for all concurrent invocations of the function in the execution of a 5041 // single SIMD loop. 5042 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5043 const Expr *UniformedLinearThis = nullptr; 5044 for (const Expr *E : Uniforms) { 5045 E = E->IgnoreParenImpCasts(); 5046 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5047 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5048 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5049 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5050 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5051 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5052 continue; 5053 } 5054 if (isa<CXXThisExpr>(E)) { 5055 UniformedLinearThis = E; 5056 continue; 5057 } 5058 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5059 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5060 } 5061 // OpenMP [2.8.2, declare simd construct, Description] 5062 // The aligned clause declares that the object to which each list item points 5063 // is aligned to the number of bytes expressed in the optional parameter of 5064 // the aligned clause. 5065 // The special this pointer can be used as if was one of the arguments to the 5066 // function in any of the linear, aligned, or uniform clauses. 5067 // The type of list items appearing in the aligned clause must be array, 5068 // pointer, reference to array, or reference to pointer. 5069 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5070 const Expr *AlignedThis = nullptr; 5071 for (const Expr *E : Aligneds) { 5072 E = E->IgnoreParenImpCasts(); 5073 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5074 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5075 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5076 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5077 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5078 ->getCanonicalDecl() == CanonPVD) { 5079 // OpenMP [2.8.1, simd construct, Restrictions] 5080 // A list-item cannot appear in more than one aligned clause. 5081 if (AlignedArgs.count(CanonPVD) > 0) { 5082 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5083 << 1 << getOpenMPClauseName(OMPC_aligned) 5084 << E->getSourceRange(); 5085 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5086 diag::note_omp_explicit_dsa) 5087 << getOpenMPClauseName(OMPC_aligned); 5088 continue; 5089 } 5090 AlignedArgs[CanonPVD] = E; 5091 QualType QTy = PVD->getType() 5092 .getNonReferenceType() 5093 .getUnqualifiedType() 5094 .getCanonicalType(); 5095 const Type *Ty = QTy.getTypePtrOrNull(); 5096 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5097 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5098 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5099 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5100 } 5101 continue; 5102 } 5103 } 5104 if (isa<CXXThisExpr>(E)) { 5105 if (AlignedThis) { 5106 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5107 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5108 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5109 << getOpenMPClauseName(OMPC_aligned); 5110 } 5111 AlignedThis = E; 5112 continue; 5113 } 5114 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5115 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5116 } 5117 // The optional parameter of the aligned clause, alignment, must be a constant 5118 // positive integer expression. If no optional parameter is specified, 5119 // implementation-defined default alignments for SIMD instructions on the 5120 // target platforms are assumed. 5121 SmallVector<const Expr *, 4> NewAligns; 5122 for (Expr *E : Alignments) { 5123 ExprResult Align; 5124 if (E) 5125 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5126 NewAligns.push_back(Align.get()); 5127 } 5128 // OpenMP [2.8.2, declare simd construct, Description] 5129 // The linear clause declares one or more list items to be private to a SIMD 5130 // lane and to have a linear relationship with respect to the iteration space 5131 // of a loop. 5132 // The special this pointer can be used as if was one of the arguments to the 5133 // function in any of the linear, aligned, or uniform clauses. 5134 // When a linear-step expression is specified in a linear clause it must be 5135 // either a constant integer expression or an integer-typed parameter that is 5136 // specified in a uniform clause on the directive. 5137 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5138 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5139 auto MI = LinModifiers.begin(); 5140 for (const Expr *E : Linears) { 5141 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5142 ++MI; 5143 E = E->IgnoreParenImpCasts(); 5144 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5145 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5146 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5147 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5148 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5149 ->getCanonicalDecl() == CanonPVD) { 5150 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5151 // A list-item cannot appear in more than one linear clause. 5152 if (LinearArgs.count(CanonPVD) > 0) { 5153 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5154 << getOpenMPClauseName(OMPC_linear) 5155 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5156 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5157 diag::note_omp_explicit_dsa) 5158 << getOpenMPClauseName(OMPC_linear); 5159 continue; 5160 } 5161 // Each argument can appear in at most one uniform or linear clause. 5162 if (UniformedArgs.count(CanonPVD) > 0) { 5163 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5164 << getOpenMPClauseName(OMPC_linear) 5165 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5166 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5167 diag::note_omp_explicit_dsa) 5168 << getOpenMPClauseName(OMPC_uniform); 5169 continue; 5170 } 5171 LinearArgs[CanonPVD] = E; 5172 if (E->isValueDependent() || E->isTypeDependent() || 5173 E->isInstantiationDependent() || 5174 E->containsUnexpandedParameterPack()) 5175 continue; 5176 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5177 PVD->getOriginalType()); 5178 continue; 5179 } 5180 } 5181 if (isa<CXXThisExpr>(E)) { 5182 if (UniformedLinearThis) { 5183 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5184 << getOpenMPClauseName(OMPC_linear) 5185 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5186 << E->getSourceRange(); 5187 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5188 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5189 : OMPC_linear); 5190 continue; 5191 } 5192 UniformedLinearThis = E; 5193 if (E->isValueDependent() || E->isTypeDependent() || 5194 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5195 continue; 5196 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5197 E->getType()); 5198 continue; 5199 } 5200 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5201 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5202 } 5203 Expr *Step = nullptr; 5204 Expr *NewStep = nullptr; 5205 SmallVector<Expr *, 4> NewSteps; 5206 for (Expr *E : Steps) { 5207 // Skip the same step expression, it was checked already. 5208 if (Step == E || !E) { 5209 NewSteps.push_back(E ? NewStep : nullptr); 5210 continue; 5211 } 5212 Step = E; 5213 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5214 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5215 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5216 if (UniformedArgs.count(CanonPVD) == 0) { 5217 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5218 << Step->getSourceRange(); 5219 } else if (E->isValueDependent() || E->isTypeDependent() || 5220 E->isInstantiationDependent() || 5221 E->containsUnexpandedParameterPack() || 5222 CanonPVD->getType()->hasIntegerRepresentation()) { 5223 NewSteps.push_back(Step); 5224 } else { 5225 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5226 << Step->getSourceRange(); 5227 } 5228 continue; 5229 } 5230 NewStep = Step; 5231 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5232 !Step->isInstantiationDependent() && 5233 !Step->containsUnexpandedParameterPack()) { 5234 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5235 .get(); 5236 if (NewStep) 5237 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5238 } 5239 NewSteps.push_back(NewStep); 5240 } 5241 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5242 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5243 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5244 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5245 const_cast<Expr **>(Linears.data()), Linears.size(), 5246 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5247 NewSteps.data(), NewSteps.size(), SR); 5248 ADecl->addAttr(NewAttr); 5249 return DG; 5250 } 5251 5252 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5253 QualType NewType) { 5254 assert(NewType->isFunctionProtoType() && 5255 "Expected function type with prototype."); 5256 assert(FD->getType()->isFunctionNoProtoType() && 5257 "Expected function with type with no prototype."); 5258 assert(FDWithProto->getType()->isFunctionProtoType() && 5259 "Expected function with prototype."); 5260 // Synthesize parameters with the same types. 5261 FD->setType(NewType); 5262 SmallVector<ParmVarDecl *, 16> Params; 5263 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5264 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5265 SourceLocation(), nullptr, P->getType(), 5266 /*TInfo=*/nullptr, SC_None, nullptr); 5267 Param->setScopeInfo(0, Params.size()); 5268 Param->setImplicit(); 5269 Params.push_back(Param); 5270 } 5271 5272 FD->setParams(Params); 5273 } 5274 5275 Optional<std::pair<FunctionDecl *, Expr *>> 5276 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5277 Expr *VariantRef, OMPTraitInfo &TI, 5278 SourceRange SR) { 5279 if (!DG || DG.get().isNull()) 5280 return None; 5281 5282 const int VariantId = 1; 5283 // Must be applied only to single decl. 5284 if (!DG.get().isSingleDecl()) { 5285 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5286 << VariantId << SR; 5287 return None; 5288 } 5289 Decl *ADecl = DG.get().getSingleDecl(); 5290 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5291 ADecl = FTD->getTemplatedDecl(); 5292 5293 // Decl must be a function. 5294 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5295 if (!FD) { 5296 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5297 << VariantId << SR; 5298 return None; 5299 } 5300 5301 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5302 return FD->hasAttrs() && 5303 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5304 FD->hasAttr<TargetAttr>()); 5305 }; 5306 // OpenMP is not compatible with CPU-specific attributes. 5307 if (HasMultiVersionAttributes(FD)) { 5308 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5309 << SR; 5310 return None; 5311 } 5312 5313 // Allow #pragma omp declare variant only if the function is not used. 5314 if (FD->isUsed(false)) 5315 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5316 << FD->getLocation(); 5317 5318 // Check if the function was emitted already. 5319 const FunctionDecl *Definition; 5320 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5321 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5322 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5323 << FD->getLocation(); 5324 5325 // The VariantRef must point to function. 5326 if (!VariantRef) { 5327 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5328 return None; 5329 } 5330 5331 auto ShouldDelayChecks = [](Expr *&E, bool) { 5332 return E && (E->isTypeDependent() || E->isValueDependent() || 5333 E->containsUnexpandedParameterPack() || 5334 E->isInstantiationDependent()); 5335 }; 5336 // Do not check templates, wait until instantiation. 5337 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5338 TI.anyScoreOrCondition(ShouldDelayChecks)) 5339 return std::make_pair(FD, VariantRef); 5340 5341 // Deal with non-constant score and user condition expressions. 5342 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5343 bool IsScore) -> bool { 5344 llvm::APSInt Result; 5345 if (!E || E->isIntegerConstantExpr(Result, Context)) 5346 return false; 5347 5348 if (IsScore) { 5349 // We warn on non-constant scores and pretend they were not present. 5350 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5351 << E; 5352 E = nullptr; 5353 } else { 5354 // We could replace a non-constant user condition with "false" but we 5355 // will soon need to handle these anyway for the dynamic version of 5356 // OpenMP context selectors. 5357 Diag(E->getExprLoc(), 5358 diag::err_omp_declare_variant_user_condition_not_constant) 5359 << E; 5360 } 5361 return true; 5362 }; 5363 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5364 return None; 5365 5366 // Convert VariantRef expression to the type of the original function to 5367 // resolve possible conflicts. 5368 ExprResult VariantRefCast; 5369 if (LangOpts.CPlusPlus) { 5370 QualType FnPtrType; 5371 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5372 if (Method && !Method->isStatic()) { 5373 const Type *ClassType = 5374 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5375 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5376 ExprResult ER; 5377 { 5378 // Build adrr_of unary op to correctly handle type checks for member 5379 // functions. 5380 Sema::TentativeAnalysisScope Trap(*this); 5381 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5382 VariantRef); 5383 } 5384 if (!ER.isUsable()) { 5385 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5386 << VariantId << VariantRef->getSourceRange(); 5387 return None; 5388 } 5389 VariantRef = ER.get(); 5390 } else { 5391 FnPtrType = Context.getPointerType(FD->getType()); 5392 } 5393 ImplicitConversionSequence ICS = 5394 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5395 /*SuppressUserConversions=*/false, 5396 AllowedExplicit::None, 5397 /*InOverloadResolution=*/false, 5398 /*CStyle=*/false, 5399 /*AllowObjCWritebackConversion=*/false); 5400 if (ICS.isFailure()) { 5401 Diag(VariantRef->getExprLoc(), 5402 diag::err_omp_declare_variant_incompat_types) 5403 << VariantRef->getType() 5404 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5405 << VariantRef->getSourceRange(); 5406 return None; 5407 } 5408 VariantRefCast = PerformImplicitConversion( 5409 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5410 if (!VariantRefCast.isUsable()) 5411 return None; 5412 // Drop previously built artificial addr_of unary op for member functions. 5413 if (Method && !Method->isStatic()) { 5414 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5415 if (auto *UO = dyn_cast<UnaryOperator>( 5416 PossibleAddrOfVariantRef->IgnoreImplicit())) 5417 VariantRefCast = UO->getSubExpr(); 5418 } 5419 } else { 5420 VariantRefCast = VariantRef; 5421 } 5422 5423 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5424 if (!ER.isUsable() || 5425 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5426 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5427 << VariantId << VariantRef->getSourceRange(); 5428 return None; 5429 } 5430 5431 // The VariantRef must point to function. 5432 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5433 if (!DRE) { 5434 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5435 << VariantId << VariantRef->getSourceRange(); 5436 return None; 5437 } 5438 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5439 if (!NewFD) { 5440 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5441 << VariantId << VariantRef->getSourceRange(); 5442 return None; 5443 } 5444 5445 // Check if function types are compatible in C. 5446 if (!LangOpts.CPlusPlus) { 5447 QualType NewType = 5448 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5449 if (NewType.isNull()) { 5450 Diag(VariantRef->getExprLoc(), 5451 diag::err_omp_declare_variant_incompat_types) 5452 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5453 return None; 5454 } 5455 if (NewType->isFunctionProtoType()) { 5456 if (FD->getType()->isFunctionNoProtoType()) 5457 setPrototype(*this, FD, NewFD, NewType); 5458 else if (NewFD->getType()->isFunctionNoProtoType()) 5459 setPrototype(*this, NewFD, FD, NewType); 5460 } 5461 } 5462 5463 // Check if variant function is not marked with declare variant directive. 5464 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5465 Diag(VariantRef->getExprLoc(), 5466 diag::warn_omp_declare_variant_marked_as_declare_variant) 5467 << VariantRef->getSourceRange(); 5468 SourceRange SR = 5469 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5470 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5471 return None; 5472 } 5473 5474 enum DoesntSupport { 5475 VirtFuncs = 1, 5476 Constructors = 3, 5477 Destructors = 4, 5478 DeletedFuncs = 5, 5479 DefaultedFuncs = 6, 5480 ConstexprFuncs = 7, 5481 ConstevalFuncs = 8, 5482 }; 5483 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5484 if (CXXFD->isVirtual()) { 5485 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5486 << VirtFuncs; 5487 return None; 5488 } 5489 5490 if (isa<CXXConstructorDecl>(FD)) { 5491 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5492 << Constructors; 5493 return None; 5494 } 5495 5496 if (isa<CXXDestructorDecl>(FD)) { 5497 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5498 << Destructors; 5499 return None; 5500 } 5501 } 5502 5503 if (FD->isDeleted()) { 5504 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5505 << DeletedFuncs; 5506 return None; 5507 } 5508 5509 if (FD->isDefaulted()) { 5510 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5511 << DefaultedFuncs; 5512 return None; 5513 } 5514 5515 if (FD->isConstexpr()) { 5516 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5517 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5518 return None; 5519 } 5520 5521 // Check general compatibility. 5522 if (areMultiversionVariantFunctionsCompatible( 5523 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5524 PartialDiagnosticAt(SourceLocation(), 5525 PartialDiagnostic::NullDiagnostic()), 5526 PartialDiagnosticAt( 5527 VariantRef->getExprLoc(), 5528 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5529 PartialDiagnosticAt(VariantRef->getExprLoc(), 5530 PDiag(diag::err_omp_declare_variant_diff) 5531 << FD->getLocation()), 5532 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5533 /*CLinkageMayDiffer=*/true)) 5534 return None; 5535 return std::make_pair(FD, cast<Expr>(DRE)); 5536 } 5537 5538 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 5539 Expr *VariantRef, 5540 OMPTraitInfo &TI, 5541 SourceRange SR) { 5542 auto *NewAttr = 5543 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, TI, SR); 5544 FD->addAttr(NewAttr); 5545 } 5546 5547 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5548 FunctionDecl *Func, 5549 bool MightBeOdrUse) { 5550 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5551 5552 if (!Func->isDependentContext() && Func->hasAttrs()) { 5553 for (OMPDeclareVariantAttr *A : 5554 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5555 // TODO: add checks for active OpenMP context where possible. 5556 Expr *VariantRef = A->getVariantFuncRef(); 5557 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5558 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5559 if (!F->isDefined() && F->isTemplateInstantiation()) 5560 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5561 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5562 } 5563 } 5564 } 5565 5566 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5567 Stmt *AStmt, 5568 SourceLocation StartLoc, 5569 SourceLocation EndLoc) { 5570 if (!AStmt) 5571 return StmtError(); 5572 5573 auto *CS = cast<CapturedStmt>(AStmt); 5574 // 1.2.2 OpenMP Language Terminology 5575 // Structured block - An executable statement with a single entry at the 5576 // top and a single exit at the bottom. 5577 // The point of exit cannot be a branch out of the structured block. 5578 // longjmp() and throw() must not violate the entry/exit criteria. 5579 CS->getCapturedDecl()->setNothrow(); 5580 5581 setFunctionHasBranchProtectedScope(); 5582 5583 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5584 DSAStack->isCancelRegion()); 5585 } 5586 5587 namespace { 5588 /// Iteration space of a single for loop. 5589 struct LoopIterationSpace final { 5590 /// True if the condition operator is the strict compare operator (<, > or 5591 /// !=). 5592 bool IsStrictCompare = false; 5593 /// Condition of the loop. 5594 Expr *PreCond = nullptr; 5595 /// This expression calculates the number of iterations in the loop. 5596 /// It is always possible to calculate it before starting the loop. 5597 Expr *NumIterations = nullptr; 5598 /// The loop counter variable. 5599 Expr *CounterVar = nullptr; 5600 /// Private loop counter variable. 5601 Expr *PrivateCounterVar = nullptr; 5602 /// This is initializer for the initial value of #CounterVar. 5603 Expr *CounterInit = nullptr; 5604 /// This is step for the #CounterVar used to generate its update: 5605 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5606 Expr *CounterStep = nullptr; 5607 /// Should step be subtracted? 5608 bool Subtract = false; 5609 /// Source range of the loop init. 5610 SourceRange InitSrcRange; 5611 /// Source range of the loop condition. 5612 SourceRange CondSrcRange; 5613 /// Source range of the loop increment. 5614 SourceRange IncSrcRange; 5615 /// Minimum value that can have the loop control variable. Used to support 5616 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5617 /// since only such variables can be used in non-loop invariant expressions. 5618 Expr *MinValue = nullptr; 5619 /// Maximum value that can have the loop control variable. Used to support 5620 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5621 /// since only such variables can be used in non-loop invariant expressions. 5622 Expr *MaxValue = nullptr; 5623 /// true, if the lower bound depends on the outer loop control var. 5624 bool IsNonRectangularLB = false; 5625 /// true, if the upper bound depends on the outer loop control var. 5626 bool IsNonRectangularUB = false; 5627 /// Index of the loop this loop depends on and forms non-rectangular loop 5628 /// nest. 5629 unsigned LoopDependentIdx = 0; 5630 /// Final condition for the non-rectangular loop nest support. It is used to 5631 /// check that the number of iterations for this particular counter must be 5632 /// finished. 5633 Expr *FinalCondition = nullptr; 5634 }; 5635 5636 /// Helper class for checking canonical form of the OpenMP loops and 5637 /// extracting iteration space of each loop in the loop nest, that will be used 5638 /// for IR generation. 5639 class OpenMPIterationSpaceChecker { 5640 /// Reference to Sema. 5641 Sema &SemaRef; 5642 /// Data-sharing stack. 5643 DSAStackTy &Stack; 5644 /// A location for diagnostics (when there is no some better location). 5645 SourceLocation DefaultLoc; 5646 /// A location for diagnostics (when increment is not compatible). 5647 SourceLocation ConditionLoc; 5648 /// A source location for referring to loop init later. 5649 SourceRange InitSrcRange; 5650 /// A source location for referring to condition later. 5651 SourceRange ConditionSrcRange; 5652 /// A source location for referring to increment later. 5653 SourceRange IncrementSrcRange; 5654 /// Loop variable. 5655 ValueDecl *LCDecl = nullptr; 5656 /// Reference to loop variable. 5657 Expr *LCRef = nullptr; 5658 /// Lower bound (initializer for the var). 5659 Expr *LB = nullptr; 5660 /// Upper bound. 5661 Expr *UB = nullptr; 5662 /// Loop step (increment). 5663 Expr *Step = nullptr; 5664 /// This flag is true when condition is one of: 5665 /// Var < UB 5666 /// Var <= UB 5667 /// UB > Var 5668 /// UB >= Var 5669 /// This will have no value when the condition is != 5670 llvm::Optional<bool> TestIsLessOp; 5671 /// This flag is true when condition is strict ( < or > ). 5672 bool TestIsStrictOp = false; 5673 /// This flag is true when step is subtracted on each iteration. 5674 bool SubtractStep = false; 5675 /// The outer loop counter this loop depends on (if any). 5676 const ValueDecl *DepDecl = nullptr; 5677 /// Contains number of loop (starts from 1) on which loop counter init 5678 /// expression of this loop depends on. 5679 Optional<unsigned> InitDependOnLC; 5680 /// Contains number of loop (starts from 1) on which loop counter condition 5681 /// expression of this loop depends on. 5682 Optional<unsigned> CondDependOnLC; 5683 /// Checks if the provide statement depends on the loop counter. 5684 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5685 /// Original condition required for checking of the exit condition for 5686 /// non-rectangular loop. 5687 Expr *Condition = nullptr; 5688 5689 public: 5690 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5691 SourceLocation DefaultLoc) 5692 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5693 ConditionLoc(DefaultLoc) {} 5694 /// Check init-expr for canonical loop form and save loop counter 5695 /// variable - #Var and its initialization value - #LB. 5696 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5697 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5698 /// for less/greater and for strict/non-strict comparison. 5699 bool checkAndSetCond(Expr *S); 5700 /// Check incr-expr for canonical loop form and return true if it 5701 /// does not conform, otherwise save loop step (#Step). 5702 bool checkAndSetInc(Expr *S); 5703 /// Return the loop counter variable. 5704 ValueDecl *getLoopDecl() const { return LCDecl; } 5705 /// Return the reference expression to loop counter variable. 5706 Expr *getLoopDeclRefExpr() const { return LCRef; } 5707 /// Source range of the loop init. 5708 SourceRange getInitSrcRange() const { return InitSrcRange; } 5709 /// Source range of the loop condition. 5710 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5711 /// Source range of the loop increment. 5712 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5713 /// True if the step should be subtracted. 5714 bool shouldSubtractStep() const { return SubtractStep; } 5715 /// True, if the compare operator is strict (<, > or !=). 5716 bool isStrictTestOp() const { return TestIsStrictOp; } 5717 /// Build the expression to calculate the number of iterations. 5718 Expr *buildNumIterations( 5719 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5720 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5721 /// Build the precondition expression for the loops. 5722 Expr * 5723 buildPreCond(Scope *S, Expr *Cond, 5724 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5725 /// Build reference expression to the counter be used for codegen. 5726 DeclRefExpr * 5727 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5728 DSAStackTy &DSA) const; 5729 /// Build reference expression to the private counter be used for 5730 /// codegen. 5731 Expr *buildPrivateCounterVar() const; 5732 /// Build initialization of the counter be used for codegen. 5733 Expr *buildCounterInit() const; 5734 /// Build step of the counter be used for codegen. 5735 Expr *buildCounterStep() const; 5736 /// Build loop data with counter value for depend clauses in ordered 5737 /// directives. 5738 Expr * 5739 buildOrderedLoopData(Scope *S, Expr *Counter, 5740 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5741 SourceLocation Loc, Expr *Inc = nullptr, 5742 OverloadedOperatorKind OOK = OO_Amp); 5743 /// Builds the minimum value for the loop counter. 5744 std::pair<Expr *, Expr *> buildMinMaxValues( 5745 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5746 /// Builds final condition for the non-rectangular loops. 5747 Expr *buildFinalCondition(Scope *S) const; 5748 /// Return true if any expression is dependent. 5749 bool dependent() const; 5750 /// Returns true if the initializer forms non-rectangular loop. 5751 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5752 /// Returns true if the condition forms non-rectangular loop. 5753 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5754 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5755 unsigned getLoopDependentIdx() const { 5756 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5757 } 5758 5759 private: 5760 /// Check the right-hand side of an assignment in the increment 5761 /// expression. 5762 bool checkAndSetIncRHS(Expr *RHS); 5763 /// Helper to set loop counter variable and its initializer. 5764 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5765 bool EmitDiags); 5766 /// Helper to set upper bound. 5767 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5768 SourceRange SR, SourceLocation SL); 5769 /// Helper to set loop increment. 5770 bool setStep(Expr *NewStep, bool Subtract); 5771 }; 5772 5773 bool OpenMPIterationSpaceChecker::dependent() const { 5774 if (!LCDecl) { 5775 assert(!LB && !UB && !Step); 5776 return false; 5777 } 5778 return LCDecl->getType()->isDependentType() || 5779 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5780 (Step && Step->isValueDependent()); 5781 } 5782 5783 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5784 Expr *NewLCRefExpr, 5785 Expr *NewLB, bool EmitDiags) { 5786 // State consistency checking to ensure correct usage. 5787 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5788 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5789 if (!NewLCDecl || !NewLB) 5790 return true; 5791 LCDecl = getCanonicalDecl(NewLCDecl); 5792 LCRef = NewLCRefExpr; 5793 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5794 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5795 if ((Ctor->isCopyOrMoveConstructor() || 5796 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5797 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5798 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5799 LB = NewLB; 5800 if (EmitDiags) 5801 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5802 return false; 5803 } 5804 5805 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5806 llvm::Optional<bool> LessOp, 5807 bool StrictOp, SourceRange SR, 5808 SourceLocation SL) { 5809 // State consistency checking to ensure correct usage. 5810 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5811 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5812 if (!NewUB) 5813 return true; 5814 UB = NewUB; 5815 if (LessOp) 5816 TestIsLessOp = LessOp; 5817 TestIsStrictOp = StrictOp; 5818 ConditionSrcRange = SR; 5819 ConditionLoc = SL; 5820 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5821 return false; 5822 } 5823 5824 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5825 // State consistency checking to ensure correct usage. 5826 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5827 if (!NewStep) 5828 return true; 5829 if (!NewStep->isValueDependent()) { 5830 // Check that the step is integer expression. 5831 SourceLocation StepLoc = NewStep->getBeginLoc(); 5832 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5833 StepLoc, getExprAsWritten(NewStep)); 5834 if (Val.isInvalid()) 5835 return true; 5836 NewStep = Val.get(); 5837 5838 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5839 // If test-expr is of form var relational-op b and relational-op is < or 5840 // <= then incr-expr must cause var to increase on each iteration of the 5841 // loop. If test-expr is of form var relational-op b and relational-op is 5842 // > or >= then incr-expr must cause var to decrease on each iteration of 5843 // the loop. 5844 // If test-expr is of form b relational-op var and relational-op is < or 5845 // <= then incr-expr must cause var to decrease on each iteration of the 5846 // loop. If test-expr is of form b relational-op var and relational-op is 5847 // > or >= then incr-expr must cause var to increase on each iteration of 5848 // the loop. 5849 llvm::APSInt Result; 5850 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5851 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5852 bool IsConstNeg = 5853 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5854 bool IsConstPos = 5855 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5856 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5857 5858 // != with increment is treated as <; != with decrement is treated as > 5859 if (!TestIsLessOp.hasValue()) 5860 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5861 if (UB && (IsConstZero || 5862 (TestIsLessOp.getValue() ? 5863 (IsConstNeg || (IsUnsigned && Subtract)) : 5864 (IsConstPos || (IsUnsigned && !Subtract))))) { 5865 SemaRef.Diag(NewStep->getExprLoc(), 5866 diag::err_omp_loop_incr_not_compatible) 5867 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5868 SemaRef.Diag(ConditionLoc, 5869 diag::note_omp_loop_cond_requres_compatible_incr) 5870 << TestIsLessOp.getValue() << ConditionSrcRange; 5871 return true; 5872 } 5873 if (TestIsLessOp.getValue() == Subtract) { 5874 NewStep = 5875 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5876 .get(); 5877 Subtract = !Subtract; 5878 } 5879 } 5880 5881 Step = NewStep; 5882 SubtractStep = Subtract; 5883 return false; 5884 } 5885 5886 namespace { 5887 /// Checker for the non-rectangular loops. Checks if the initializer or 5888 /// condition expression references loop counter variable. 5889 class LoopCounterRefChecker final 5890 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5891 Sema &SemaRef; 5892 DSAStackTy &Stack; 5893 const ValueDecl *CurLCDecl = nullptr; 5894 const ValueDecl *DepDecl = nullptr; 5895 const ValueDecl *PrevDepDecl = nullptr; 5896 bool IsInitializer = true; 5897 unsigned BaseLoopId = 0; 5898 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5899 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5900 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5901 << (IsInitializer ? 0 : 1); 5902 return false; 5903 } 5904 const auto &&Data = Stack.isLoopControlVariable(VD); 5905 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5906 // The type of the loop iterator on which we depend may not have a random 5907 // access iterator type. 5908 if (Data.first && VD->getType()->isRecordType()) { 5909 SmallString<128> Name; 5910 llvm::raw_svector_ostream OS(Name); 5911 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5912 /*Qualified=*/true); 5913 SemaRef.Diag(E->getExprLoc(), 5914 diag::err_omp_wrong_dependency_iterator_type) 5915 << OS.str(); 5916 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5917 return false; 5918 } 5919 if (Data.first && 5920 (DepDecl || (PrevDepDecl && 5921 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5922 if (!DepDecl && PrevDepDecl) 5923 DepDecl = PrevDepDecl; 5924 SmallString<128> Name; 5925 llvm::raw_svector_ostream OS(Name); 5926 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5927 /*Qualified=*/true); 5928 SemaRef.Diag(E->getExprLoc(), 5929 diag::err_omp_invariant_or_linear_dependency) 5930 << OS.str(); 5931 return false; 5932 } 5933 if (Data.first) { 5934 DepDecl = VD; 5935 BaseLoopId = Data.first; 5936 } 5937 return Data.first; 5938 } 5939 5940 public: 5941 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5942 const ValueDecl *VD = E->getDecl(); 5943 if (isa<VarDecl>(VD)) 5944 return checkDecl(E, VD); 5945 return false; 5946 } 5947 bool VisitMemberExpr(const MemberExpr *E) { 5948 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5949 const ValueDecl *VD = E->getMemberDecl(); 5950 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5951 return checkDecl(E, VD); 5952 } 5953 return false; 5954 } 5955 bool VisitStmt(const Stmt *S) { 5956 bool Res = false; 5957 for (const Stmt *Child : S->children()) 5958 Res = (Child && Visit(Child)) || Res; 5959 return Res; 5960 } 5961 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5962 const ValueDecl *CurLCDecl, bool IsInitializer, 5963 const ValueDecl *PrevDepDecl = nullptr) 5964 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5965 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5966 unsigned getBaseLoopId() const { 5967 assert(CurLCDecl && "Expected loop dependency."); 5968 return BaseLoopId; 5969 } 5970 const ValueDecl *getDepDecl() const { 5971 assert(CurLCDecl && "Expected loop dependency."); 5972 return DepDecl; 5973 } 5974 }; 5975 } // namespace 5976 5977 Optional<unsigned> 5978 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5979 bool IsInitializer) { 5980 // Check for the non-rectangular loops. 5981 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5982 DepDecl); 5983 if (LoopStmtChecker.Visit(S)) { 5984 DepDecl = LoopStmtChecker.getDepDecl(); 5985 return LoopStmtChecker.getBaseLoopId(); 5986 } 5987 return llvm::None; 5988 } 5989 5990 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5991 // Check init-expr for canonical loop form and save loop counter 5992 // variable - #Var and its initialization value - #LB. 5993 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5994 // var = lb 5995 // integer-type var = lb 5996 // random-access-iterator-type var = lb 5997 // pointer-type var = lb 5998 // 5999 if (!S) { 6000 if (EmitDiags) { 6001 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6002 } 6003 return true; 6004 } 6005 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6006 if (!ExprTemp->cleanupsHaveSideEffects()) 6007 S = ExprTemp->getSubExpr(); 6008 6009 InitSrcRange = S->getSourceRange(); 6010 if (Expr *E = dyn_cast<Expr>(S)) 6011 S = E->IgnoreParens(); 6012 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6013 if (BO->getOpcode() == BO_Assign) { 6014 Expr *LHS = BO->getLHS()->IgnoreParens(); 6015 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6016 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6017 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6018 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6019 EmitDiags); 6020 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6021 } 6022 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6023 if (ME->isArrow() && 6024 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6025 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6026 EmitDiags); 6027 } 6028 } 6029 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6030 if (DS->isSingleDecl()) { 6031 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6032 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6033 // Accept non-canonical init form here but emit ext. warning. 6034 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6035 SemaRef.Diag(S->getBeginLoc(), 6036 diag::ext_omp_loop_not_canonical_init) 6037 << S->getSourceRange(); 6038 return setLCDeclAndLB( 6039 Var, 6040 buildDeclRefExpr(SemaRef, Var, 6041 Var->getType().getNonReferenceType(), 6042 DS->getBeginLoc()), 6043 Var->getInit(), EmitDiags); 6044 } 6045 } 6046 } 6047 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6048 if (CE->getOperator() == OO_Equal) { 6049 Expr *LHS = CE->getArg(0); 6050 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6051 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6052 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6053 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6054 EmitDiags); 6055 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6056 } 6057 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6058 if (ME->isArrow() && 6059 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6060 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6061 EmitDiags); 6062 } 6063 } 6064 } 6065 6066 if (dependent() || SemaRef.CurContext->isDependentContext()) 6067 return false; 6068 if (EmitDiags) { 6069 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6070 << S->getSourceRange(); 6071 } 6072 return true; 6073 } 6074 6075 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6076 /// variable (which may be the loop variable) if possible. 6077 static const ValueDecl *getInitLCDecl(const Expr *E) { 6078 if (!E) 6079 return nullptr; 6080 E = getExprAsWritten(E); 6081 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6082 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6083 if ((Ctor->isCopyOrMoveConstructor() || 6084 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6085 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6086 E = CE->getArg(0)->IgnoreParenImpCasts(); 6087 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6088 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6089 return getCanonicalDecl(VD); 6090 } 6091 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6092 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6093 return getCanonicalDecl(ME->getMemberDecl()); 6094 return nullptr; 6095 } 6096 6097 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6098 // Check test-expr for canonical form, save upper-bound UB, flags for 6099 // less/greater and for strict/non-strict comparison. 6100 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6101 // var relational-op b 6102 // b relational-op var 6103 // 6104 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6105 if (!S) { 6106 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6107 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6108 return true; 6109 } 6110 Condition = S; 6111 S = getExprAsWritten(S); 6112 SourceLocation CondLoc = S->getBeginLoc(); 6113 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6114 if (BO->isRelationalOp()) { 6115 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6116 return setUB(BO->getRHS(), 6117 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6118 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6119 BO->getSourceRange(), BO->getOperatorLoc()); 6120 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6121 return setUB(BO->getLHS(), 6122 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6123 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6124 BO->getSourceRange(), BO->getOperatorLoc()); 6125 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6126 return setUB( 6127 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6128 /*LessOp=*/llvm::None, 6129 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6130 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6131 if (CE->getNumArgs() == 2) { 6132 auto Op = CE->getOperator(); 6133 switch (Op) { 6134 case OO_Greater: 6135 case OO_GreaterEqual: 6136 case OO_Less: 6137 case OO_LessEqual: 6138 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6139 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6140 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6141 CE->getOperatorLoc()); 6142 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6143 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6144 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6145 CE->getOperatorLoc()); 6146 break; 6147 case OO_ExclaimEqual: 6148 if (IneqCondIsCanonical) 6149 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6150 : CE->getArg(0), 6151 /*LessOp=*/llvm::None, 6152 /*StrictOp=*/true, CE->getSourceRange(), 6153 CE->getOperatorLoc()); 6154 break; 6155 default: 6156 break; 6157 } 6158 } 6159 } 6160 if (dependent() || SemaRef.CurContext->isDependentContext()) 6161 return false; 6162 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6163 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6164 return true; 6165 } 6166 6167 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6168 // RHS of canonical loop form increment can be: 6169 // var + incr 6170 // incr + var 6171 // var - incr 6172 // 6173 RHS = RHS->IgnoreParenImpCasts(); 6174 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6175 if (BO->isAdditiveOp()) { 6176 bool IsAdd = BO->getOpcode() == BO_Add; 6177 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6178 return setStep(BO->getRHS(), !IsAdd); 6179 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6180 return setStep(BO->getLHS(), /*Subtract=*/false); 6181 } 6182 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6183 bool IsAdd = CE->getOperator() == OO_Plus; 6184 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6185 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6186 return setStep(CE->getArg(1), !IsAdd); 6187 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6188 return setStep(CE->getArg(0), /*Subtract=*/false); 6189 } 6190 } 6191 if (dependent() || SemaRef.CurContext->isDependentContext()) 6192 return false; 6193 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6194 << RHS->getSourceRange() << LCDecl; 6195 return true; 6196 } 6197 6198 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6199 // Check incr-expr for canonical loop form and return true if it 6200 // does not conform. 6201 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6202 // ++var 6203 // var++ 6204 // --var 6205 // var-- 6206 // var += incr 6207 // var -= incr 6208 // var = var + incr 6209 // var = incr + var 6210 // var = var - incr 6211 // 6212 if (!S) { 6213 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6214 return true; 6215 } 6216 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6217 if (!ExprTemp->cleanupsHaveSideEffects()) 6218 S = ExprTemp->getSubExpr(); 6219 6220 IncrementSrcRange = S->getSourceRange(); 6221 S = S->IgnoreParens(); 6222 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6223 if (UO->isIncrementDecrementOp() && 6224 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6225 return setStep(SemaRef 6226 .ActOnIntegerConstant(UO->getBeginLoc(), 6227 (UO->isDecrementOp() ? -1 : 1)) 6228 .get(), 6229 /*Subtract=*/false); 6230 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6231 switch (BO->getOpcode()) { 6232 case BO_AddAssign: 6233 case BO_SubAssign: 6234 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6235 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6236 break; 6237 case BO_Assign: 6238 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6239 return checkAndSetIncRHS(BO->getRHS()); 6240 break; 6241 default: 6242 break; 6243 } 6244 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6245 switch (CE->getOperator()) { 6246 case OO_PlusPlus: 6247 case OO_MinusMinus: 6248 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6249 return setStep(SemaRef 6250 .ActOnIntegerConstant( 6251 CE->getBeginLoc(), 6252 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6253 .get(), 6254 /*Subtract=*/false); 6255 break; 6256 case OO_PlusEqual: 6257 case OO_MinusEqual: 6258 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6259 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6260 break; 6261 case OO_Equal: 6262 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6263 return checkAndSetIncRHS(CE->getArg(1)); 6264 break; 6265 default: 6266 break; 6267 } 6268 } 6269 if (dependent() || SemaRef.CurContext->isDependentContext()) 6270 return false; 6271 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6272 << S->getSourceRange() << LCDecl; 6273 return true; 6274 } 6275 6276 static ExprResult 6277 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6278 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6279 if (SemaRef.CurContext->isDependentContext()) 6280 return ExprResult(Capture); 6281 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6282 return SemaRef.PerformImplicitConversion( 6283 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6284 /*AllowExplicit=*/true); 6285 auto I = Captures.find(Capture); 6286 if (I != Captures.end()) 6287 return buildCapture(SemaRef, Capture, I->second); 6288 DeclRefExpr *Ref = nullptr; 6289 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6290 Captures[Capture] = Ref; 6291 return Res; 6292 } 6293 6294 /// Build the expression to calculate the number of iterations. 6295 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6296 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6297 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6298 ExprResult Diff; 6299 QualType VarType = LCDecl->getType().getNonReferenceType(); 6300 if (VarType->isIntegerType() || VarType->isPointerType() || 6301 SemaRef.getLangOpts().CPlusPlus) { 6302 Expr *LBVal = LB; 6303 Expr *UBVal = UB; 6304 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6305 // max(LB(MinVal), LB(MaxVal)) 6306 if (InitDependOnLC) { 6307 const LoopIterationSpace &IS = 6308 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6309 InitDependOnLC.getValueOr( 6310 CondDependOnLC.getValueOr(0))]; 6311 if (!IS.MinValue || !IS.MaxValue) 6312 return nullptr; 6313 // OuterVar = Min 6314 ExprResult MinValue = 6315 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6316 if (!MinValue.isUsable()) 6317 return nullptr; 6318 6319 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6320 IS.CounterVar, MinValue.get()); 6321 if (!LBMinVal.isUsable()) 6322 return nullptr; 6323 // OuterVar = Min, LBVal 6324 LBMinVal = 6325 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6326 if (!LBMinVal.isUsable()) 6327 return nullptr; 6328 // (OuterVar = Min, LBVal) 6329 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6330 if (!LBMinVal.isUsable()) 6331 return nullptr; 6332 6333 // OuterVar = Max 6334 ExprResult MaxValue = 6335 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6336 if (!MaxValue.isUsable()) 6337 return nullptr; 6338 6339 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6340 IS.CounterVar, MaxValue.get()); 6341 if (!LBMaxVal.isUsable()) 6342 return nullptr; 6343 // OuterVar = Max, LBVal 6344 LBMaxVal = 6345 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6346 if (!LBMaxVal.isUsable()) 6347 return nullptr; 6348 // (OuterVar = Max, LBVal) 6349 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6350 if (!LBMaxVal.isUsable()) 6351 return nullptr; 6352 6353 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6354 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6355 if (!LBMin || !LBMax) 6356 return nullptr; 6357 // LB(MinVal) < LB(MaxVal) 6358 ExprResult MinLessMaxRes = 6359 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6360 if (!MinLessMaxRes.isUsable()) 6361 return nullptr; 6362 Expr *MinLessMax = 6363 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6364 if (!MinLessMax) 6365 return nullptr; 6366 if (TestIsLessOp.getValue()) { 6367 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6368 // LB(MaxVal)) 6369 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6370 MinLessMax, LBMin, LBMax); 6371 if (!MinLB.isUsable()) 6372 return nullptr; 6373 LBVal = MinLB.get(); 6374 } else { 6375 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6376 // LB(MaxVal)) 6377 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6378 MinLessMax, LBMax, LBMin); 6379 if (!MaxLB.isUsable()) 6380 return nullptr; 6381 LBVal = MaxLB.get(); 6382 } 6383 } 6384 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6385 // min(UB(MinVal), UB(MaxVal)) 6386 if (CondDependOnLC) { 6387 const LoopIterationSpace &IS = 6388 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6389 InitDependOnLC.getValueOr( 6390 CondDependOnLC.getValueOr(0))]; 6391 if (!IS.MinValue || !IS.MaxValue) 6392 return nullptr; 6393 // OuterVar = Min 6394 ExprResult MinValue = 6395 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6396 if (!MinValue.isUsable()) 6397 return nullptr; 6398 6399 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6400 IS.CounterVar, MinValue.get()); 6401 if (!UBMinVal.isUsable()) 6402 return nullptr; 6403 // OuterVar = Min, UBVal 6404 UBMinVal = 6405 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6406 if (!UBMinVal.isUsable()) 6407 return nullptr; 6408 // (OuterVar = Min, UBVal) 6409 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6410 if (!UBMinVal.isUsable()) 6411 return nullptr; 6412 6413 // OuterVar = Max 6414 ExprResult MaxValue = 6415 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6416 if (!MaxValue.isUsable()) 6417 return nullptr; 6418 6419 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6420 IS.CounterVar, MaxValue.get()); 6421 if (!UBMaxVal.isUsable()) 6422 return nullptr; 6423 // OuterVar = Max, UBVal 6424 UBMaxVal = 6425 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6426 if (!UBMaxVal.isUsable()) 6427 return nullptr; 6428 // (OuterVar = Max, UBVal) 6429 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6430 if (!UBMaxVal.isUsable()) 6431 return nullptr; 6432 6433 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6434 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6435 if (!UBMin || !UBMax) 6436 return nullptr; 6437 // UB(MinVal) > UB(MaxVal) 6438 ExprResult MinGreaterMaxRes = 6439 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6440 if (!MinGreaterMaxRes.isUsable()) 6441 return nullptr; 6442 Expr *MinGreaterMax = 6443 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6444 if (!MinGreaterMax) 6445 return nullptr; 6446 if (TestIsLessOp.getValue()) { 6447 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6448 // UB(MaxVal)) 6449 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6450 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6451 if (!MaxUB.isUsable()) 6452 return nullptr; 6453 UBVal = MaxUB.get(); 6454 } else { 6455 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6456 // UB(MaxVal)) 6457 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6458 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6459 if (!MinUB.isUsable()) 6460 return nullptr; 6461 UBVal = MinUB.get(); 6462 } 6463 } 6464 // Upper - Lower 6465 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6466 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6467 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6468 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6469 if (!Upper || !Lower) 6470 return nullptr; 6471 6472 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6473 6474 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6475 // BuildBinOp already emitted error, this one is to point user to upper 6476 // and lower bound, and to tell what is passed to 'operator-'. 6477 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6478 << Upper->getSourceRange() << Lower->getSourceRange(); 6479 return nullptr; 6480 } 6481 } 6482 6483 if (!Diff.isUsable()) 6484 return nullptr; 6485 6486 // Upper - Lower [- 1] 6487 if (TestIsStrictOp) 6488 Diff = SemaRef.BuildBinOp( 6489 S, DefaultLoc, BO_Sub, Diff.get(), 6490 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6491 if (!Diff.isUsable()) 6492 return nullptr; 6493 6494 // Upper - Lower [- 1] + Step 6495 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6496 if (!NewStep.isUsable()) 6497 return nullptr; 6498 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6499 if (!Diff.isUsable()) 6500 return nullptr; 6501 6502 // Parentheses (for dumping/debugging purposes only). 6503 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6504 if (!Diff.isUsable()) 6505 return nullptr; 6506 6507 // (Upper - Lower [- 1] + Step) / Step 6508 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6509 if (!Diff.isUsable()) 6510 return nullptr; 6511 6512 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6513 QualType Type = Diff.get()->getType(); 6514 ASTContext &C = SemaRef.Context; 6515 bool UseVarType = VarType->hasIntegerRepresentation() && 6516 C.getTypeSize(Type) > C.getTypeSize(VarType); 6517 if (!Type->isIntegerType() || UseVarType) { 6518 unsigned NewSize = 6519 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6520 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6521 : Type->hasSignedIntegerRepresentation(); 6522 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6523 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6524 Diff = SemaRef.PerformImplicitConversion( 6525 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6526 if (!Diff.isUsable()) 6527 return nullptr; 6528 } 6529 } 6530 if (LimitedType) { 6531 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6532 if (NewSize != C.getTypeSize(Type)) { 6533 if (NewSize < C.getTypeSize(Type)) { 6534 assert(NewSize == 64 && "incorrect loop var size"); 6535 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6536 << InitSrcRange << ConditionSrcRange; 6537 } 6538 QualType NewType = C.getIntTypeForBitwidth( 6539 NewSize, Type->hasSignedIntegerRepresentation() || 6540 C.getTypeSize(Type) < NewSize); 6541 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6542 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6543 Sema::AA_Converting, true); 6544 if (!Diff.isUsable()) 6545 return nullptr; 6546 } 6547 } 6548 } 6549 6550 return Diff.get(); 6551 } 6552 6553 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6554 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6555 // Do not build for iterators, they cannot be used in non-rectangular loop 6556 // nests. 6557 if (LCDecl->getType()->isRecordType()) 6558 return std::make_pair(nullptr, nullptr); 6559 // If we subtract, the min is in the condition, otherwise the min is in the 6560 // init value. 6561 Expr *MinExpr = nullptr; 6562 Expr *MaxExpr = nullptr; 6563 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6564 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6565 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6566 : CondDependOnLC.hasValue(); 6567 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6568 : InitDependOnLC.hasValue(); 6569 Expr *Lower = 6570 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6571 Expr *Upper = 6572 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6573 if (!Upper || !Lower) 6574 return std::make_pair(nullptr, nullptr); 6575 6576 if (TestIsLessOp.getValue()) 6577 MinExpr = Lower; 6578 else 6579 MaxExpr = Upper; 6580 6581 // Build minimum/maximum value based on number of iterations. 6582 ExprResult Diff; 6583 QualType VarType = LCDecl->getType().getNonReferenceType(); 6584 6585 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6586 if (!Diff.isUsable()) 6587 return std::make_pair(nullptr, nullptr); 6588 6589 // Upper - Lower [- 1] 6590 if (TestIsStrictOp) 6591 Diff = SemaRef.BuildBinOp( 6592 S, DefaultLoc, BO_Sub, Diff.get(), 6593 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6594 if (!Diff.isUsable()) 6595 return std::make_pair(nullptr, nullptr); 6596 6597 // Upper - Lower [- 1] + Step 6598 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6599 if (!NewStep.isUsable()) 6600 return std::make_pair(nullptr, nullptr); 6601 6602 // Parentheses (for dumping/debugging purposes only). 6603 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6604 if (!Diff.isUsable()) 6605 return std::make_pair(nullptr, nullptr); 6606 6607 // (Upper - Lower [- 1]) / Step 6608 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6609 if (!Diff.isUsable()) 6610 return std::make_pair(nullptr, nullptr); 6611 6612 // ((Upper - Lower [- 1]) / Step) * Step 6613 // Parentheses (for dumping/debugging purposes only). 6614 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6615 if (!Diff.isUsable()) 6616 return std::make_pair(nullptr, nullptr); 6617 6618 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6619 if (!Diff.isUsable()) 6620 return std::make_pair(nullptr, nullptr); 6621 6622 // Convert to the original type or ptrdiff_t, if original type is pointer. 6623 if (!VarType->isAnyPointerType() && 6624 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6625 Diff = SemaRef.PerformImplicitConversion( 6626 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6627 } else if (VarType->isAnyPointerType() && 6628 !SemaRef.Context.hasSameType( 6629 Diff.get()->getType(), 6630 SemaRef.Context.getUnsignedPointerDiffType())) { 6631 Diff = SemaRef.PerformImplicitConversion( 6632 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6633 Sema::AA_Converting, /*AllowExplicit=*/true); 6634 } 6635 if (!Diff.isUsable()) 6636 return std::make_pair(nullptr, nullptr); 6637 6638 // Parentheses (for dumping/debugging purposes only). 6639 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6640 if (!Diff.isUsable()) 6641 return std::make_pair(nullptr, nullptr); 6642 6643 if (TestIsLessOp.getValue()) { 6644 // MinExpr = Lower; 6645 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6646 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6647 if (!Diff.isUsable()) 6648 return std::make_pair(nullptr, nullptr); 6649 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6650 if (!Diff.isUsable()) 6651 return std::make_pair(nullptr, nullptr); 6652 MaxExpr = Diff.get(); 6653 } else { 6654 // MaxExpr = Upper; 6655 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6656 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6657 if (!Diff.isUsable()) 6658 return std::make_pair(nullptr, nullptr); 6659 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6660 if (!Diff.isUsable()) 6661 return std::make_pair(nullptr, nullptr); 6662 MinExpr = Diff.get(); 6663 } 6664 6665 return std::make_pair(MinExpr, MaxExpr); 6666 } 6667 6668 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6669 if (InitDependOnLC || CondDependOnLC) 6670 return Condition; 6671 return nullptr; 6672 } 6673 6674 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6675 Scope *S, Expr *Cond, 6676 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6677 // Do not build a precondition when the condition/initialization is dependent 6678 // to prevent pessimistic early loop exit. 6679 // TODO: this can be improved by calculating min/max values but not sure that 6680 // it will be very effective. 6681 if (CondDependOnLC || InitDependOnLC) 6682 return SemaRef.PerformImplicitConversion( 6683 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6684 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6685 /*AllowExplicit=*/true).get(); 6686 6687 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6688 Sema::TentativeAnalysisScope Trap(SemaRef); 6689 6690 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6691 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6692 if (!NewLB.isUsable() || !NewUB.isUsable()) 6693 return nullptr; 6694 6695 ExprResult CondExpr = 6696 SemaRef.BuildBinOp(S, DefaultLoc, 6697 TestIsLessOp.getValue() ? 6698 (TestIsStrictOp ? BO_LT : BO_LE) : 6699 (TestIsStrictOp ? BO_GT : BO_GE), 6700 NewLB.get(), NewUB.get()); 6701 if (CondExpr.isUsable()) { 6702 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6703 SemaRef.Context.BoolTy)) 6704 CondExpr = SemaRef.PerformImplicitConversion( 6705 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6706 /*AllowExplicit=*/true); 6707 } 6708 6709 // Otherwise use original loop condition and evaluate it in runtime. 6710 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6711 } 6712 6713 /// Build reference expression to the counter be used for codegen. 6714 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6715 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6716 DSAStackTy &DSA) const { 6717 auto *VD = dyn_cast<VarDecl>(LCDecl); 6718 if (!VD) { 6719 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6720 DeclRefExpr *Ref = buildDeclRefExpr( 6721 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6722 const DSAStackTy::DSAVarData Data = 6723 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6724 // If the loop control decl is explicitly marked as private, do not mark it 6725 // as captured again. 6726 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6727 Captures.insert(std::make_pair(LCRef, Ref)); 6728 return Ref; 6729 } 6730 return cast<DeclRefExpr>(LCRef); 6731 } 6732 6733 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6734 if (LCDecl && !LCDecl->isInvalidDecl()) { 6735 QualType Type = LCDecl->getType().getNonReferenceType(); 6736 VarDecl *PrivateVar = buildVarDecl( 6737 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6738 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6739 isa<VarDecl>(LCDecl) 6740 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6741 : nullptr); 6742 if (PrivateVar->isInvalidDecl()) 6743 return nullptr; 6744 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6745 } 6746 return nullptr; 6747 } 6748 6749 /// Build initialization of the counter to be used for codegen. 6750 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6751 6752 /// Build step of the counter be used for codegen. 6753 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6754 6755 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6756 Scope *S, Expr *Counter, 6757 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6758 Expr *Inc, OverloadedOperatorKind OOK) { 6759 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6760 if (!Cnt) 6761 return nullptr; 6762 if (Inc) { 6763 assert((OOK == OO_Plus || OOK == OO_Minus) && 6764 "Expected only + or - operations for depend clauses."); 6765 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6766 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6767 if (!Cnt) 6768 return nullptr; 6769 } 6770 ExprResult Diff; 6771 QualType VarType = LCDecl->getType().getNonReferenceType(); 6772 if (VarType->isIntegerType() || VarType->isPointerType() || 6773 SemaRef.getLangOpts().CPlusPlus) { 6774 // Upper - Lower 6775 Expr *Upper = TestIsLessOp.getValue() 6776 ? Cnt 6777 : tryBuildCapture(SemaRef, UB, Captures).get(); 6778 Expr *Lower = TestIsLessOp.getValue() 6779 ? tryBuildCapture(SemaRef, LB, Captures).get() 6780 : Cnt; 6781 if (!Upper || !Lower) 6782 return nullptr; 6783 6784 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6785 6786 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6787 // BuildBinOp already emitted error, this one is to point user to upper 6788 // and lower bound, and to tell what is passed to 'operator-'. 6789 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6790 << Upper->getSourceRange() << Lower->getSourceRange(); 6791 return nullptr; 6792 } 6793 } 6794 6795 if (!Diff.isUsable()) 6796 return nullptr; 6797 6798 // Parentheses (for dumping/debugging purposes only). 6799 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6800 if (!Diff.isUsable()) 6801 return nullptr; 6802 6803 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6804 if (!NewStep.isUsable()) 6805 return nullptr; 6806 // (Upper - Lower) / Step 6807 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6808 if (!Diff.isUsable()) 6809 return nullptr; 6810 6811 return Diff.get(); 6812 } 6813 } // namespace 6814 6815 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6816 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6817 assert(Init && "Expected loop in canonical form."); 6818 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6819 if (AssociatedLoops > 0 && 6820 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6821 DSAStack->loopStart(); 6822 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6823 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6824 if (ValueDecl *D = ISC.getLoopDecl()) { 6825 auto *VD = dyn_cast<VarDecl>(D); 6826 DeclRefExpr *PrivateRef = nullptr; 6827 if (!VD) { 6828 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6829 VD = Private; 6830 } else { 6831 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6832 /*WithInit=*/false); 6833 VD = cast<VarDecl>(PrivateRef->getDecl()); 6834 } 6835 } 6836 DSAStack->addLoopControlVariable(D, VD); 6837 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6838 if (LD != D->getCanonicalDecl()) { 6839 DSAStack->resetPossibleLoopCounter(); 6840 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6841 MarkDeclarationsReferencedInExpr( 6842 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6843 Var->getType().getNonLValueExprType(Context), 6844 ForLoc, /*RefersToCapture=*/true)); 6845 } 6846 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6847 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6848 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6849 // associated for-loop of a simd construct with just one associated 6850 // for-loop may be listed in a linear clause with a constant-linear-step 6851 // that is the increment of the associated for-loop. The loop iteration 6852 // variable(s) in the associated for-loop(s) of a for or parallel for 6853 // construct may be listed in a private or lastprivate clause. 6854 DSAStackTy::DSAVarData DVar = 6855 DSAStack->getTopDSA(D, /*FromParent=*/false); 6856 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6857 // is declared in the loop and it is predetermined as a private. 6858 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6859 OpenMPClauseKind PredeterminedCKind = 6860 isOpenMPSimdDirective(DKind) 6861 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6862 : OMPC_private; 6863 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6864 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6865 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6866 DVar.CKind != OMPC_private))) || 6867 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6868 DKind == OMPD_master_taskloop || 6869 DKind == OMPD_parallel_master_taskloop || 6870 isOpenMPDistributeDirective(DKind)) && 6871 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6872 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6873 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6874 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6875 << getOpenMPClauseName(DVar.CKind) 6876 << getOpenMPDirectiveName(DKind) 6877 << getOpenMPClauseName(PredeterminedCKind); 6878 if (DVar.RefExpr == nullptr) 6879 DVar.CKind = PredeterminedCKind; 6880 reportOriginalDsa(*this, DSAStack, D, DVar, 6881 /*IsLoopIterVar=*/true); 6882 } else if (LoopDeclRefExpr) { 6883 // Make the loop iteration variable private (for worksharing 6884 // constructs), linear (for simd directives with the only one 6885 // associated loop) or lastprivate (for simd directives with several 6886 // collapsed or ordered loops). 6887 if (DVar.CKind == OMPC_unknown) 6888 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6889 PrivateRef); 6890 } 6891 } 6892 } 6893 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6894 } 6895 } 6896 6897 /// Called on a for stmt to check and extract its iteration space 6898 /// for further processing (such as collapsing). 6899 static bool checkOpenMPIterationSpace( 6900 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6901 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6902 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6903 Expr *OrderedLoopCountExpr, 6904 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6905 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6906 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6907 // OpenMP [2.9.1, Canonical Loop Form] 6908 // for (init-expr; test-expr; incr-expr) structured-block 6909 // for (range-decl: range-expr) structured-block 6910 auto *For = dyn_cast_or_null<ForStmt>(S); 6911 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6912 // Ranged for is supported only in OpenMP 5.0. 6913 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6914 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6915 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6916 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6917 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6918 if (TotalNestedLoopCount > 1) { 6919 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6920 SemaRef.Diag(DSA.getConstructLoc(), 6921 diag::note_omp_collapse_ordered_expr) 6922 << 2 << CollapseLoopCountExpr->getSourceRange() 6923 << OrderedLoopCountExpr->getSourceRange(); 6924 else if (CollapseLoopCountExpr) 6925 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6926 diag::note_omp_collapse_ordered_expr) 6927 << 0 << CollapseLoopCountExpr->getSourceRange(); 6928 else 6929 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6930 diag::note_omp_collapse_ordered_expr) 6931 << 1 << OrderedLoopCountExpr->getSourceRange(); 6932 } 6933 return true; 6934 } 6935 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6936 "No loop body."); 6937 6938 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6939 For ? For->getForLoc() : CXXFor->getForLoc()); 6940 6941 // Check init. 6942 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6943 if (ISC.checkAndSetInit(Init)) 6944 return true; 6945 6946 bool HasErrors = false; 6947 6948 // Check loop variable's type. 6949 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6950 // OpenMP [2.6, Canonical Loop Form] 6951 // Var is one of the following: 6952 // A variable of signed or unsigned integer type. 6953 // For C++, a variable of a random access iterator type. 6954 // For C, a variable of a pointer type. 6955 QualType VarType = LCDecl->getType().getNonReferenceType(); 6956 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6957 !VarType->isPointerType() && 6958 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6959 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6960 << SemaRef.getLangOpts().CPlusPlus; 6961 HasErrors = true; 6962 } 6963 6964 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6965 // a Construct 6966 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6967 // parallel for construct is (are) private. 6968 // The loop iteration variable in the associated for-loop of a simd 6969 // construct with just one associated for-loop is linear with a 6970 // constant-linear-step that is the increment of the associated for-loop. 6971 // Exclude loop var from the list of variables with implicitly defined data 6972 // sharing attributes. 6973 VarsWithImplicitDSA.erase(LCDecl); 6974 6975 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6976 6977 // Check test-expr. 6978 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6979 6980 // Check incr-expr. 6981 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6982 } 6983 6984 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6985 return HasErrors; 6986 6987 // Build the loop's iteration space representation. 6988 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6989 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6990 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6991 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6992 (isOpenMPWorksharingDirective(DKind) || 6993 isOpenMPTaskLoopDirective(DKind) || 6994 isOpenMPDistributeDirective(DKind)), 6995 Captures); 6996 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6997 ISC.buildCounterVar(Captures, DSA); 6998 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6999 ISC.buildPrivateCounterVar(); 7000 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7001 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7002 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7003 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7004 ISC.getConditionSrcRange(); 7005 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7006 ISC.getIncrementSrcRange(); 7007 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7008 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7009 ISC.isStrictTestOp(); 7010 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7011 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7012 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7013 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7014 ISC.buildFinalCondition(DSA.getCurScope()); 7015 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7016 ISC.doesInitDependOnLC(); 7017 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7018 ISC.doesCondDependOnLC(); 7019 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7020 ISC.getLoopDependentIdx(); 7021 7022 HasErrors |= 7023 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7024 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7025 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7026 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7027 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7028 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7029 if (!HasErrors && DSA.isOrderedRegion()) { 7030 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7031 if (CurrentNestedLoopCount < 7032 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7033 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7034 CurrentNestedLoopCount, 7035 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7036 DSA.getOrderedRegionParam().second->setLoopCounter( 7037 CurrentNestedLoopCount, 7038 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7039 } 7040 } 7041 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7042 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7043 // Erroneous case - clause has some problems. 7044 continue; 7045 } 7046 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7047 Pair.second.size() <= CurrentNestedLoopCount) { 7048 // Erroneous case - clause has some problems. 7049 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7050 continue; 7051 } 7052 Expr *CntValue; 7053 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7054 CntValue = ISC.buildOrderedLoopData( 7055 DSA.getCurScope(), 7056 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7057 Pair.first->getDependencyLoc()); 7058 else 7059 CntValue = ISC.buildOrderedLoopData( 7060 DSA.getCurScope(), 7061 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7062 Pair.first->getDependencyLoc(), 7063 Pair.second[CurrentNestedLoopCount].first, 7064 Pair.second[CurrentNestedLoopCount].second); 7065 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7066 } 7067 } 7068 7069 return HasErrors; 7070 } 7071 7072 /// Build 'VarRef = Start. 7073 static ExprResult 7074 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7075 ExprResult Start, bool IsNonRectangularLB, 7076 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7077 // Build 'VarRef = Start. 7078 ExprResult NewStart = IsNonRectangularLB 7079 ? Start.get() 7080 : tryBuildCapture(SemaRef, Start.get(), Captures); 7081 if (!NewStart.isUsable()) 7082 return ExprError(); 7083 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7084 VarRef.get()->getType())) { 7085 NewStart = SemaRef.PerformImplicitConversion( 7086 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7087 /*AllowExplicit=*/true); 7088 if (!NewStart.isUsable()) 7089 return ExprError(); 7090 } 7091 7092 ExprResult Init = 7093 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7094 return Init; 7095 } 7096 7097 /// Build 'VarRef = Start + Iter * Step'. 7098 static ExprResult buildCounterUpdate( 7099 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7100 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7101 bool IsNonRectangularLB, 7102 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7103 // Add parentheses (for debugging purposes only). 7104 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7105 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7106 !Step.isUsable()) 7107 return ExprError(); 7108 7109 ExprResult NewStep = Step; 7110 if (Captures) 7111 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7112 if (NewStep.isInvalid()) 7113 return ExprError(); 7114 ExprResult Update = 7115 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7116 if (!Update.isUsable()) 7117 return ExprError(); 7118 7119 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7120 // 'VarRef = Start (+|-) Iter * Step'. 7121 if (!Start.isUsable()) 7122 return ExprError(); 7123 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7124 if (!NewStart.isUsable()) 7125 return ExprError(); 7126 if (Captures && !IsNonRectangularLB) 7127 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7128 if (NewStart.isInvalid()) 7129 return ExprError(); 7130 7131 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7132 ExprResult SavedUpdate = Update; 7133 ExprResult UpdateVal; 7134 if (VarRef.get()->getType()->isOverloadableType() || 7135 NewStart.get()->getType()->isOverloadableType() || 7136 Update.get()->getType()->isOverloadableType()) { 7137 Sema::TentativeAnalysisScope Trap(SemaRef); 7138 7139 Update = 7140 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7141 if (Update.isUsable()) { 7142 UpdateVal = 7143 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7144 VarRef.get(), SavedUpdate.get()); 7145 if (UpdateVal.isUsable()) { 7146 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7147 UpdateVal.get()); 7148 } 7149 } 7150 } 7151 7152 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7153 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7154 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7155 NewStart.get(), SavedUpdate.get()); 7156 if (!Update.isUsable()) 7157 return ExprError(); 7158 7159 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7160 VarRef.get()->getType())) { 7161 Update = SemaRef.PerformImplicitConversion( 7162 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7163 if (!Update.isUsable()) 7164 return ExprError(); 7165 } 7166 7167 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7168 } 7169 return Update; 7170 } 7171 7172 /// Convert integer expression \a E to make it have at least \a Bits 7173 /// bits. 7174 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7175 if (E == nullptr) 7176 return ExprError(); 7177 ASTContext &C = SemaRef.Context; 7178 QualType OldType = E->getType(); 7179 unsigned HasBits = C.getTypeSize(OldType); 7180 if (HasBits >= Bits) 7181 return ExprResult(E); 7182 // OK to convert to signed, because new type has more bits than old. 7183 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7184 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7185 true); 7186 } 7187 7188 /// Check if the given expression \a E is a constant integer that fits 7189 /// into \a Bits bits. 7190 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7191 if (E == nullptr) 7192 return false; 7193 llvm::APSInt Result; 7194 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7195 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7196 return false; 7197 } 7198 7199 /// Build preinits statement for the given declarations. 7200 static Stmt *buildPreInits(ASTContext &Context, 7201 MutableArrayRef<Decl *> PreInits) { 7202 if (!PreInits.empty()) { 7203 return new (Context) DeclStmt( 7204 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7205 SourceLocation(), SourceLocation()); 7206 } 7207 return nullptr; 7208 } 7209 7210 /// Build preinits statement for the given declarations. 7211 static Stmt * 7212 buildPreInits(ASTContext &Context, 7213 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7214 if (!Captures.empty()) { 7215 SmallVector<Decl *, 16> PreInits; 7216 for (const auto &Pair : Captures) 7217 PreInits.push_back(Pair.second->getDecl()); 7218 return buildPreInits(Context, PreInits); 7219 } 7220 return nullptr; 7221 } 7222 7223 /// Build postupdate expression for the given list of postupdates expressions. 7224 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7225 Expr *PostUpdate = nullptr; 7226 if (!PostUpdates.empty()) { 7227 for (Expr *E : PostUpdates) { 7228 Expr *ConvE = S.BuildCStyleCastExpr( 7229 E->getExprLoc(), 7230 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7231 E->getExprLoc(), E) 7232 .get(); 7233 PostUpdate = PostUpdate 7234 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7235 PostUpdate, ConvE) 7236 .get() 7237 : ConvE; 7238 } 7239 } 7240 return PostUpdate; 7241 } 7242 7243 /// Called on a for stmt to check itself and nested loops (if any). 7244 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7245 /// number of collapsed loops otherwise. 7246 static unsigned 7247 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7248 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7249 DSAStackTy &DSA, 7250 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7251 OMPLoopDirective::HelperExprs &Built) { 7252 unsigned NestedLoopCount = 1; 7253 if (CollapseLoopCountExpr) { 7254 // Found 'collapse' clause - calculate collapse number. 7255 Expr::EvalResult Result; 7256 if (!CollapseLoopCountExpr->isValueDependent() && 7257 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7258 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7259 } else { 7260 Built.clear(/*Size=*/1); 7261 return 1; 7262 } 7263 } 7264 unsigned OrderedLoopCount = 1; 7265 if (OrderedLoopCountExpr) { 7266 // Found 'ordered' clause - calculate collapse number. 7267 Expr::EvalResult EVResult; 7268 if (!OrderedLoopCountExpr->isValueDependent() && 7269 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7270 SemaRef.getASTContext())) { 7271 llvm::APSInt Result = EVResult.Val.getInt(); 7272 if (Result.getLimitedValue() < NestedLoopCount) { 7273 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7274 diag::err_omp_wrong_ordered_loop_count) 7275 << OrderedLoopCountExpr->getSourceRange(); 7276 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7277 diag::note_collapse_loop_count) 7278 << CollapseLoopCountExpr->getSourceRange(); 7279 } 7280 OrderedLoopCount = Result.getLimitedValue(); 7281 } else { 7282 Built.clear(/*Size=*/1); 7283 return 1; 7284 } 7285 } 7286 // This is helper routine for loop directives (e.g., 'for', 'simd', 7287 // 'for simd', etc.). 7288 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7289 SmallVector<LoopIterationSpace, 4> IterSpaces( 7290 std::max(OrderedLoopCount, NestedLoopCount)); 7291 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7292 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7293 if (checkOpenMPIterationSpace( 7294 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7295 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7296 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7297 return 0; 7298 // Move on to the next nested for loop, or to the loop body. 7299 // OpenMP [2.8.1, simd construct, Restrictions] 7300 // All loops associated with the construct must be perfectly nested; that 7301 // is, there must be no intervening code nor any OpenMP directive between 7302 // any two loops. 7303 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7304 CurStmt = For->getBody(); 7305 } else { 7306 assert(isa<CXXForRangeStmt>(CurStmt) && 7307 "Expected canonical for or range-based for loops."); 7308 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7309 } 7310 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7311 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7312 } 7313 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7314 if (checkOpenMPIterationSpace( 7315 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7316 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7317 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7318 return 0; 7319 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7320 // Handle initialization of captured loop iterator variables. 7321 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7322 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7323 Captures[DRE] = DRE; 7324 } 7325 } 7326 // Move on to the next nested for loop, or to the loop body. 7327 // OpenMP [2.8.1, simd construct, Restrictions] 7328 // All loops associated with the construct must be perfectly nested; that 7329 // is, there must be no intervening code nor any OpenMP directive between 7330 // any two loops. 7331 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7332 CurStmt = For->getBody(); 7333 } else { 7334 assert(isa<CXXForRangeStmt>(CurStmt) && 7335 "Expected canonical for or range-based for loops."); 7336 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7337 } 7338 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7339 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7340 } 7341 7342 Built.clear(/* size */ NestedLoopCount); 7343 7344 if (SemaRef.CurContext->isDependentContext()) 7345 return NestedLoopCount; 7346 7347 // An example of what is generated for the following code: 7348 // 7349 // #pragma omp simd collapse(2) ordered(2) 7350 // for (i = 0; i < NI; ++i) 7351 // for (k = 0; k < NK; ++k) 7352 // for (j = J0; j < NJ; j+=2) { 7353 // <loop body> 7354 // } 7355 // 7356 // We generate the code below. 7357 // Note: the loop body may be outlined in CodeGen. 7358 // Note: some counters may be C++ classes, operator- is used to find number of 7359 // iterations and operator+= to calculate counter value. 7360 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7361 // or i64 is currently supported). 7362 // 7363 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7364 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7365 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7366 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7367 // // similar updates for vars in clauses (e.g. 'linear') 7368 // <loop body (using local i and j)> 7369 // } 7370 // i = NI; // assign final values of counters 7371 // j = NJ; 7372 // 7373 7374 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7375 // the iteration counts of the collapsed for loops. 7376 // Precondition tests if there is at least one iteration (all conditions are 7377 // true). 7378 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7379 Expr *N0 = IterSpaces[0].NumIterations; 7380 ExprResult LastIteration32 = 7381 widenIterationCount(/*Bits=*/32, 7382 SemaRef 7383 .PerformImplicitConversion( 7384 N0->IgnoreImpCasts(), N0->getType(), 7385 Sema::AA_Converting, /*AllowExplicit=*/true) 7386 .get(), 7387 SemaRef); 7388 ExprResult LastIteration64 = widenIterationCount( 7389 /*Bits=*/64, 7390 SemaRef 7391 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7392 Sema::AA_Converting, 7393 /*AllowExplicit=*/true) 7394 .get(), 7395 SemaRef); 7396 7397 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7398 return NestedLoopCount; 7399 7400 ASTContext &C = SemaRef.Context; 7401 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7402 7403 Scope *CurScope = DSA.getCurScope(); 7404 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7405 if (PreCond.isUsable()) { 7406 PreCond = 7407 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7408 PreCond.get(), IterSpaces[Cnt].PreCond); 7409 } 7410 Expr *N = IterSpaces[Cnt].NumIterations; 7411 SourceLocation Loc = N->getExprLoc(); 7412 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7413 if (LastIteration32.isUsable()) 7414 LastIteration32 = SemaRef.BuildBinOp( 7415 CurScope, Loc, BO_Mul, LastIteration32.get(), 7416 SemaRef 7417 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7418 Sema::AA_Converting, 7419 /*AllowExplicit=*/true) 7420 .get()); 7421 if (LastIteration64.isUsable()) 7422 LastIteration64 = SemaRef.BuildBinOp( 7423 CurScope, Loc, BO_Mul, LastIteration64.get(), 7424 SemaRef 7425 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7426 Sema::AA_Converting, 7427 /*AllowExplicit=*/true) 7428 .get()); 7429 } 7430 7431 // Choose either the 32-bit or 64-bit version. 7432 ExprResult LastIteration = LastIteration64; 7433 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7434 (LastIteration32.isUsable() && 7435 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7436 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7437 fitsInto( 7438 /*Bits=*/32, 7439 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7440 LastIteration64.get(), SemaRef)))) 7441 LastIteration = LastIteration32; 7442 QualType VType = LastIteration.get()->getType(); 7443 QualType RealVType = VType; 7444 QualType StrideVType = VType; 7445 if (isOpenMPTaskLoopDirective(DKind)) { 7446 VType = 7447 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7448 StrideVType = 7449 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7450 } 7451 7452 if (!LastIteration.isUsable()) 7453 return 0; 7454 7455 // Save the number of iterations. 7456 ExprResult NumIterations = LastIteration; 7457 { 7458 LastIteration = SemaRef.BuildBinOp( 7459 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7460 LastIteration.get(), 7461 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7462 if (!LastIteration.isUsable()) 7463 return 0; 7464 } 7465 7466 // Calculate the last iteration number beforehand instead of doing this on 7467 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7468 llvm::APSInt Result; 7469 bool IsConstant = 7470 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7471 ExprResult CalcLastIteration; 7472 if (!IsConstant) { 7473 ExprResult SaveRef = 7474 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7475 LastIteration = SaveRef; 7476 7477 // Prepare SaveRef + 1. 7478 NumIterations = SemaRef.BuildBinOp( 7479 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7480 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7481 if (!NumIterations.isUsable()) 7482 return 0; 7483 } 7484 7485 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7486 7487 // Build variables passed into runtime, necessary for worksharing directives. 7488 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7489 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7490 isOpenMPDistributeDirective(DKind)) { 7491 // Lower bound variable, initialized with zero. 7492 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7493 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7494 SemaRef.AddInitializerToDecl(LBDecl, 7495 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7496 /*DirectInit*/ false); 7497 7498 // Upper bound variable, initialized with last iteration number. 7499 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7500 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7501 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7502 /*DirectInit*/ false); 7503 7504 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7505 // This will be used to implement clause 'lastprivate'. 7506 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7507 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7508 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7509 SemaRef.AddInitializerToDecl(ILDecl, 7510 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7511 /*DirectInit*/ false); 7512 7513 // Stride variable returned by runtime (we initialize it to 1 by default). 7514 VarDecl *STDecl = 7515 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7516 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7517 SemaRef.AddInitializerToDecl(STDecl, 7518 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7519 /*DirectInit*/ false); 7520 7521 // Build expression: UB = min(UB, LastIteration) 7522 // It is necessary for CodeGen of directives with static scheduling. 7523 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7524 UB.get(), LastIteration.get()); 7525 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7526 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7527 LastIteration.get(), UB.get()); 7528 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7529 CondOp.get()); 7530 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7531 7532 // If we have a combined directive that combines 'distribute', 'for' or 7533 // 'simd' we need to be able to access the bounds of the schedule of the 7534 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7535 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7536 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7537 // Lower bound variable, initialized with zero. 7538 VarDecl *CombLBDecl = 7539 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7540 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7541 SemaRef.AddInitializerToDecl( 7542 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7543 /*DirectInit*/ false); 7544 7545 // Upper bound variable, initialized with last iteration number. 7546 VarDecl *CombUBDecl = 7547 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7548 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7549 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7550 /*DirectInit*/ false); 7551 7552 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7553 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7554 ExprResult CombCondOp = 7555 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7556 LastIteration.get(), CombUB.get()); 7557 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7558 CombCondOp.get()); 7559 CombEUB = 7560 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7561 7562 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7563 // We expect to have at least 2 more parameters than the 'parallel' 7564 // directive does - the lower and upper bounds of the previous schedule. 7565 assert(CD->getNumParams() >= 4 && 7566 "Unexpected number of parameters in loop combined directive"); 7567 7568 // Set the proper type for the bounds given what we learned from the 7569 // enclosed loops. 7570 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7571 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7572 7573 // Previous lower and upper bounds are obtained from the region 7574 // parameters. 7575 PrevLB = 7576 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7577 PrevUB = 7578 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7579 } 7580 } 7581 7582 // Build the iteration variable and its initialization before loop. 7583 ExprResult IV; 7584 ExprResult Init, CombInit; 7585 { 7586 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7587 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7588 Expr *RHS = 7589 (isOpenMPWorksharingDirective(DKind) || 7590 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7591 ? LB.get() 7592 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7593 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7594 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7595 7596 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7597 Expr *CombRHS = 7598 (isOpenMPWorksharingDirective(DKind) || 7599 isOpenMPTaskLoopDirective(DKind) || 7600 isOpenMPDistributeDirective(DKind)) 7601 ? CombLB.get() 7602 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7603 CombInit = 7604 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7605 CombInit = 7606 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7607 } 7608 } 7609 7610 bool UseStrictCompare = 7611 RealVType->hasUnsignedIntegerRepresentation() && 7612 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7613 return LIS.IsStrictCompare; 7614 }); 7615 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7616 // unsigned IV)) for worksharing loops. 7617 SourceLocation CondLoc = AStmt->getBeginLoc(); 7618 Expr *BoundUB = UB.get(); 7619 if (UseStrictCompare) { 7620 BoundUB = 7621 SemaRef 7622 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7623 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7624 .get(); 7625 BoundUB = 7626 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7627 } 7628 ExprResult Cond = 7629 (isOpenMPWorksharingDirective(DKind) || 7630 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7631 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7632 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7633 BoundUB) 7634 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7635 NumIterations.get()); 7636 ExprResult CombDistCond; 7637 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7638 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7639 NumIterations.get()); 7640 } 7641 7642 ExprResult CombCond; 7643 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7644 Expr *BoundCombUB = CombUB.get(); 7645 if (UseStrictCompare) { 7646 BoundCombUB = 7647 SemaRef 7648 .BuildBinOp( 7649 CurScope, CondLoc, BO_Add, BoundCombUB, 7650 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7651 .get(); 7652 BoundCombUB = 7653 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7654 .get(); 7655 } 7656 CombCond = 7657 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7658 IV.get(), BoundCombUB); 7659 } 7660 // Loop increment (IV = IV + 1) 7661 SourceLocation IncLoc = AStmt->getBeginLoc(); 7662 ExprResult Inc = 7663 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7664 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7665 if (!Inc.isUsable()) 7666 return 0; 7667 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7668 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7669 if (!Inc.isUsable()) 7670 return 0; 7671 7672 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7673 // Used for directives with static scheduling. 7674 // In combined construct, add combined version that use CombLB and CombUB 7675 // base variables for the update 7676 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7677 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7678 isOpenMPDistributeDirective(DKind)) { 7679 // LB + ST 7680 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7681 if (!NextLB.isUsable()) 7682 return 0; 7683 // LB = LB + ST 7684 NextLB = 7685 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7686 NextLB = 7687 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7688 if (!NextLB.isUsable()) 7689 return 0; 7690 // UB + ST 7691 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7692 if (!NextUB.isUsable()) 7693 return 0; 7694 // UB = UB + ST 7695 NextUB = 7696 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7697 NextUB = 7698 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7699 if (!NextUB.isUsable()) 7700 return 0; 7701 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7702 CombNextLB = 7703 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7704 if (!NextLB.isUsable()) 7705 return 0; 7706 // LB = LB + ST 7707 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7708 CombNextLB.get()); 7709 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7710 /*DiscardedValue*/ false); 7711 if (!CombNextLB.isUsable()) 7712 return 0; 7713 // UB + ST 7714 CombNextUB = 7715 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7716 if (!CombNextUB.isUsable()) 7717 return 0; 7718 // UB = UB + ST 7719 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7720 CombNextUB.get()); 7721 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7722 /*DiscardedValue*/ false); 7723 if (!CombNextUB.isUsable()) 7724 return 0; 7725 } 7726 } 7727 7728 // Create increment expression for distribute loop when combined in a same 7729 // directive with for as IV = IV + ST; ensure upper bound expression based 7730 // on PrevUB instead of NumIterations - used to implement 'for' when found 7731 // in combination with 'distribute', like in 'distribute parallel for' 7732 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7733 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7734 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7735 DistCond = SemaRef.BuildBinOp( 7736 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7737 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7738 7739 DistInc = 7740 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7741 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7742 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7743 DistInc.get()); 7744 DistInc = 7745 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7746 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7747 7748 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7749 // construct 7750 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7751 ExprResult IsUBGreater = 7752 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7753 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7754 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7755 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7756 CondOp.get()); 7757 PrevEUB = 7758 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7759 7760 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7761 // parallel for is in combination with a distribute directive with 7762 // schedule(static, 1) 7763 Expr *BoundPrevUB = PrevUB.get(); 7764 if (UseStrictCompare) { 7765 BoundPrevUB = 7766 SemaRef 7767 .BuildBinOp( 7768 CurScope, CondLoc, BO_Add, BoundPrevUB, 7769 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7770 .get(); 7771 BoundPrevUB = 7772 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7773 .get(); 7774 } 7775 ParForInDistCond = 7776 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7777 IV.get(), BoundPrevUB); 7778 } 7779 7780 // Build updates and final values of the loop counters. 7781 bool HasErrors = false; 7782 Built.Counters.resize(NestedLoopCount); 7783 Built.Inits.resize(NestedLoopCount); 7784 Built.Updates.resize(NestedLoopCount); 7785 Built.Finals.resize(NestedLoopCount); 7786 Built.DependentCounters.resize(NestedLoopCount); 7787 Built.DependentInits.resize(NestedLoopCount); 7788 Built.FinalsConditions.resize(NestedLoopCount); 7789 { 7790 // We implement the following algorithm for obtaining the 7791 // original loop iteration variable values based on the 7792 // value of the collapsed loop iteration variable IV. 7793 // 7794 // Let n+1 be the number of collapsed loops in the nest. 7795 // Iteration variables (I0, I1, .... In) 7796 // Iteration counts (N0, N1, ... Nn) 7797 // 7798 // Acc = IV; 7799 // 7800 // To compute Ik for loop k, 0 <= k <= n, generate: 7801 // Prod = N(k+1) * N(k+2) * ... * Nn; 7802 // Ik = Acc / Prod; 7803 // Acc -= Ik * Prod; 7804 // 7805 ExprResult Acc = IV; 7806 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7807 LoopIterationSpace &IS = IterSpaces[Cnt]; 7808 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7809 ExprResult Iter; 7810 7811 // Compute prod 7812 ExprResult Prod = 7813 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7814 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7815 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7816 IterSpaces[K].NumIterations); 7817 7818 // Iter = Acc / Prod 7819 // If there is at least one more inner loop to avoid 7820 // multiplication by 1. 7821 if (Cnt + 1 < NestedLoopCount) 7822 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7823 Acc.get(), Prod.get()); 7824 else 7825 Iter = Acc; 7826 if (!Iter.isUsable()) { 7827 HasErrors = true; 7828 break; 7829 } 7830 7831 // Update Acc: 7832 // Acc -= Iter * Prod 7833 // Check if there is at least one more inner loop to avoid 7834 // multiplication by 1. 7835 if (Cnt + 1 < NestedLoopCount) 7836 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7837 Iter.get(), Prod.get()); 7838 else 7839 Prod = Iter; 7840 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7841 Acc.get(), Prod.get()); 7842 7843 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7844 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7845 DeclRefExpr *CounterVar = buildDeclRefExpr( 7846 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7847 /*RefersToCapture=*/true); 7848 ExprResult Init = 7849 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7850 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7851 if (!Init.isUsable()) { 7852 HasErrors = true; 7853 break; 7854 } 7855 ExprResult Update = buildCounterUpdate( 7856 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7857 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7858 if (!Update.isUsable()) { 7859 HasErrors = true; 7860 break; 7861 } 7862 7863 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7864 ExprResult Final = 7865 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7866 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7867 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7868 if (!Final.isUsable()) { 7869 HasErrors = true; 7870 break; 7871 } 7872 7873 if (!Update.isUsable() || !Final.isUsable()) { 7874 HasErrors = true; 7875 break; 7876 } 7877 // Save results 7878 Built.Counters[Cnt] = IS.CounterVar; 7879 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7880 Built.Inits[Cnt] = Init.get(); 7881 Built.Updates[Cnt] = Update.get(); 7882 Built.Finals[Cnt] = Final.get(); 7883 Built.DependentCounters[Cnt] = nullptr; 7884 Built.DependentInits[Cnt] = nullptr; 7885 Built.FinalsConditions[Cnt] = nullptr; 7886 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7887 Built.DependentCounters[Cnt] = 7888 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7889 Built.DependentInits[Cnt] = 7890 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7891 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7892 } 7893 } 7894 } 7895 7896 if (HasErrors) 7897 return 0; 7898 7899 // Save results 7900 Built.IterationVarRef = IV.get(); 7901 Built.LastIteration = LastIteration.get(); 7902 Built.NumIterations = NumIterations.get(); 7903 Built.CalcLastIteration = SemaRef 7904 .ActOnFinishFullExpr(CalcLastIteration.get(), 7905 /*DiscardedValue=*/false) 7906 .get(); 7907 Built.PreCond = PreCond.get(); 7908 Built.PreInits = buildPreInits(C, Captures); 7909 Built.Cond = Cond.get(); 7910 Built.Init = Init.get(); 7911 Built.Inc = Inc.get(); 7912 Built.LB = LB.get(); 7913 Built.UB = UB.get(); 7914 Built.IL = IL.get(); 7915 Built.ST = ST.get(); 7916 Built.EUB = EUB.get(); 7917 Built.NLB = NextLB.get(); 7918 Built.NUB = NextUB.get(); 7919 Built.PrevLB = PrevLB.get(); 7920 Built.PrevUB = PrevUB.get(); 7921 Built.DistInc = DistInc.get(); 7922 Built.PrevEUB = PrevEUB.get(); 7923 Built.DistCombinedFields.LB = CombLB.get(); 7924 Built.DistCombinedFields.UB = CombUB.get(); 7925 Built.DistCombinedFields.EUB = CombEUB.get(); 7926 Built.DistCombinedFields.Init = CombInit.get(); 7927 Built.DistCombinedFields.Cond = CombCond.get(); 7928 Built.DistCombinedFields.NLB = CombNextLB.get(); 7929 Built.DistCombinedFields.NUB = CombNextUB.get(); 7930 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7931 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7932 7933 return NestedLoopCount; 7934 } 7935 7936 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7937 auto CollapseClauses = 7938 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7939 if (CollapseClauses.begin() != CollapseClauses.end()) 7940 return (*CollapseClauses.begin())->getNumForLoops(); 7941 return nullptr; 7942 } 7943 7944 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7945 auto OrderedClauses = 7946 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7947 if (OrderedClauses.begin() != OrderedClauses.end()) 7948 return (*OrderedClauses.begin())->getNumForLoops(); 7949 return nullptr; 7950 } 7951 7952 static bool checkSimdlenSafelenSpecified(Sema &S, 7953 const ArrayRef<OMPClause *> Clauses) { 7954 const OMPSafelenClause *Safelen = nullptr; 7955 const OMPSimdlenClause *Simdlen = nullptr; 7956 7957 for (const OMPClause *Clause : Clauses) { 7958 if (Clause->getClauseKind() == OMPC_safelen) 7959 Safelen = cast<OMPSafelenClause>(Clause); 7960 else if (Clause->getClauseKind() == OMPC_simdlen) 7961 Simdlen = cast<OMPSimdlenClause>(Clause); 7962 if (Safelen && Simdlen) 7963 break; 7964 } 7965 7966 if (Simdlen && Safelen) { 7967 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7968 const Expr *SafelenLength = Safelen->getSafelen(); 7969 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7970 SimdlenLength->isInstantiationDependent() || 7971 SimdlenLength->containsUnexpandedParameterPack()) 7972 return false; 7973 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7974 SafelenLength->isInstantiationDependent() || 7975 SafelenLength->containsUnexpandedParameterPack()) 7976 return false; 7977 Expr::EvalResult SimdlenResult, SafelenResult; 7978 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7979 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7980 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7981 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7982 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7983 // If both simdlen and safelen clauses are specified, the value of the 7984 // simdlen parameter must be less than or equal to the value of the safelen 7985 // parameter. 7986 if (SimdlenRes > SafelenRes) { 7987 S.Diag(SimdlenLength->getExprLoc(), 7988 diag::err_omp_wrong_simdlen_safelen_values) 7989 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7990 return true; 7991 } 7992 } 7993 return false; 7994 } 7995 7996 StmtResult 7997 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7998 SourceLocation StartLoc, SourceLocation EndLoc, 7999 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8000 if (!AStmt) 8001 return StmtError(); 8002 8003 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8004 OMPLoopDirective::HelperExprs B; 8005 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8006 // define the nested loops number. 8007 unsigned NestedLoopCount = checkOpenMPLoop( 8008 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8009 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8010 if (NestedLoopCount == 0) 8011 return StmtError(); 8012 8013 assert((CurContext->isDependentContext() || B.builtAll()) && 8014 "omp simd loop exprs were not built"); 8015 8016 if (!CurContext->isDependentContext()) { 8017 // Finalize the clauses that need pre-built expressions for CodeGen. 8018 for (OMPClause *C : Clauses) { 8019 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8020 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8021 B.NumIterations, *this, CurScope, 8022 DSAStack)) 8023 return StmtError(); 8024 } 8025 } 8026 8027 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8028 return StmtError(); 8029 8030 setFunctionHasBranchProtectedScope(); 8031 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8032 Clauses, AStmt, B); 8033 } 8034 8035 StmtResult 8036 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8037 SourceLocation StartLoc, SourceLocation EndLoc, 8038 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8039 if (!AStmt) 8040 return StmtError(); 8041 8042 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8043 OMPLoopDirective::HelperExprs B; 8044 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8045 // define the nested loops number. 8046 unsigned NestedLoopCount = checkOpenMPLoop( 8047 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8048 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8049 if (NestedLoopCount == 0) 8050 return StmtError(); 8051 8052 assert((CurContext->isDependentContext() || B.builtAll()) && 8053 "omp for loop exprs were not built"); 8054 8055 if (!CurContext->isDependentContext()) { 8056 // Finalize the clauses that need pre-built expressions for CodeGen. 8057 for (OMPClause *C : Clauses) { 8058 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8059 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8060 B.NumIterations, *this, CurScope, 8061 DSAStack)) 8062 return StmtError(); 8063 } 8064 } 8065 8066 setFunctionHasBranchProtectedScope(); 8067 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8068 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8069 } 8070 8071 StmtResult Sema::ActOnOpenMPForSimdDirective( 8072 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8073 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8074 if (!AStmt) 8075 return StmtError(); 8076 8077 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8078 OMPLoopDirective::HelperExprs B; 8079 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8080 // define the nested loops number. 8081 unsigned NestedLoopCount = 8082 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8083 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8084 VarsWithImplicitDSA, B); 8085 if (NestedLoopCount == 0) 8086 return StmtError(); 8087 8088 assert((CurContext->isDependentContext() || B.builtAll()) && 8089 "omp for simd loop exprs were not built"); 8090 8091 if (!CurContext->isDependentContext()) { 8092 // Finalize the clauses that need pre-built expressions for CodeGen. 8093 for (OMPClause *C : Clauses) { 8094 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8095 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8096 B.NumIterations, *this, CurScope, 8097 DSAStack)) 8098 return StmtError(); 8099 } 8100 } 8101 8102 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8103 return StmtError(); 8104 8105 setFunctionHasBranchProtectedScope(); 8106 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8107 Clauses, AStmt, B); 8108 } 8109 8110 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8111 Stmt *AStmt, 8112 SourceLocation StartLoc, 8113 SourceLocation EndLoc) { 8114 if (!AStmt) 8115 return StmtError(); 8116 8117 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8118 auto BaseStmt = AStmt; 8119 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8120 BaseStmt = CS->getCapturedStmt(); 8121 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8122 auto S = C->children(); 8123 if (S.begin() == S.end()) 8124 return StmtError(); 8125 // All associated statements must be '#pragma omp section' except for 8126 // the first one. 8127 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8128 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8129 if (SectionStmt) 8130 Diag(SectionStmt->getBeginLoc(), 8131 diag::err_omp_sections_substmt_not_section); 8132 return StmtError(); 8133 } 8134 cast<OMPSectionDirective>(SectionStmt) 8135 ->setHasCancel(DSAStack->isCancelRegion()); 8136 } 8137 } else { 8138 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8139 return StmtError(); 8140 } 8141 8142 setFunctionHasBranchProtectedScope(); 8143 8144 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8145 DSAStack->isCancelRegion()); 8146 } 8147 8148 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8149 SourceLocation StartLoc, 8150 SourceLocation EndLoc) { 8151 if (!AStmt) 8152 return StmtError(); 8153 8154 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8155 8156 setFunctionHasBranchProtectedScope(); 8157 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8158 8159 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8160 DSAStack->isCancelRegion()); 8161 } 8162 8163 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8164 Stmt *AStmt, 8165 SourceLocation StartLoc, 8166 SourceLocation EndLoc) { 8167 if (!AStmt) 8168 return StmtError(); 8169 8170 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8171 8172 setFunctionHasBranchProtectedScope(); 8173 8174 // OpenMP [2.7.3, single Construct, Restrictions] 8175 // The copyprivate clause must not be used with the nowait clause. 8176 const OMPClause *Nowait = nullptr; 8177 const OMPClause *Copyprivate = nullptr; 8178 for (const OMPClause *Clause : Clauses) { 8179 if (Clause->getClauseKind() == OMPC_nowait) 8180 Nowait = Clause; 8181 else if (Clause->getClauseKind() == OMPC_copyprivate) 8182 Copyprivate = Clause; 8183 if (Copyprivate && Nowait) { 8184 Diag(Copyprivate->getBeginLoc(), 8185 diag::err_omp_single_copyprivate_with_nowait); 8186 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8187 return StmtError(); 8188 } 8189 } 8190 8191 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8192 } 8193 8194 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8195 SourceLocation StartLoc, 8196 SourceLocation EndLoc) { 8197 if (!AStmt) 8198 return StmtError(); 8199 8200 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8201 8202 setFunctionHasBranchProtectedScope(); 8203 8204 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8205 } 8206 8207 StmtResult Sema::ActOnOpenMPCriticalDirective( 8208 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8209 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8210 if (!AStmt) 8211 return StmtError(); 8212 8213 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8214 8215 bool ErrorFound = false; 8216 llvm::APSInt Hint; 8217 SourceLocation HintLoc; 8218 bool DependentHint = false; 8219 for (const OMPClause *C : Clauses) { 8220 if (C->getClauseKind() == OMPC_hint) { 8221 if (!DirName.getName()) { 8222 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8223 ErrorFound = true; 8224 } 8225 Expr *E = cast<OMPHintClause>(C)->getHint(); 8226 if (E->isTypeDependent() || E->isValueDependent() || 8227 E->isInstantiationDependent()) { 8228 DependentHint = true; 8229 } else { 8230 Hint = E->EvaluateKnownConstInt(Context); 8231 HintLoc = C->getBeginLoc(); 8232 } 8233 } 8234 } 8235 if (ErrorFound) 8236 return StmtError(); 8237 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8238 if (Pair.first && DirName.getName() && !DependentHint) { 8239 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8240 Diag(StartLoc, diag::err_omp_critical_with_hint); 8241 if (HintLoc.isValid()) 8242 Diag(HintLoc, diag::note_omp_critical_hint_here) 8243 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8244 else 8245 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8246 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8247 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8248 << 1 8249 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8250 /*Radix=*/10, /*Signed=*/false); 8251 } else { 8252 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8253 } 8254 } 8255 } 8256 8257 setFunctionHasBranchProtectedScope(); 8258 8259 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8260 Clauses, AStmt); 8261 if (!Pair.first && DirName.getName() && !DependentHint) 8262 DSAStack->addCriticalWithHint(Dir, Hint); 8263 return Dir; 8264 } 8265 8266 StmtResult Sema::ActOnOpenMPParallelForDirective( 8267 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8268 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8269 if (!AStmt) 8270 return StmtError(); 8271 8272 auto *CS = cast<CapturedStmt>(AStmt); 8273 // 1.2.2 OpenMP Language Terminology 8274 // Structured block - An executable statement with a single entry at the 8275 // top and a single exit at the bottom. 8276 // The point of exit cannot be a branch out of the structured block. 8277 // longjmp() and throw() must not violate the entry/exit criteria. 8278 CS->getCapturedDecl()->setNothrow(); 8279 8280 OMPLoopDirective::HelperExprs B; 8281 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8282 // define the nested loops number. 8283 unsigned NestedLoopCount = 8284 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8285 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8286 VarsWithImplicitDSA, B); 8287 if (NestedLoopCount == 0) 8288 return StmtError(); 8289 8290 assert((CurContext->isDependentContext() || B.builtAll()) && 8291 "omp parallel for loop exprs were not built"); 8292 8293 if (!CurContext->isDependentContext()) { 8294 // Finalize the clauses that need pre-built expressions for CodeGen. 8295 for (OMPClause *C : Clauses) { 8296 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8297 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8298 B.NumIterations, *this, CurScope, 8299 DSAStack)) 8300 return StmtError(); 8301 } 8302 } 8303 8304 setFunctionHasBranchProtectedScope(); 8305 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8306 NestedLoopCount, Clauses, AStmt, B, 8307 DSAStack->isCancelRegion()); 8308 } 8309 8310 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8311 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8312 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8313 if (!AStmt) 8314 return StmtError(); 8315 8316 auto *CS = cast<CapturedStmt>(AStmt); 8317 // 1.2.2 OpenMP Language Terminology 8318 // Structured block - An executable statement with a single entry at the 8319 // top and a single exit at the bottom. 8320 // The point of exit cannot be a branch out of the structured block. 8321 // longjmp() and throw() must not violate the entry/exit criteria. 8322 CS->getCapturedDecl()->setNothrow(); 8323 8324 OMPLoopDirective::HelperExprs B; 8325 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8326 // define the nested loops number. 8327 unsigned NestedLoopCount = 8328 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8329 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8330 VarsWithImplicitDSA, B); 8331 if (NestedLoopCount == 0) 8332 return StmtError(); 8333 8334 if (!CurContext->isDependentContext()) { 8335 // Finalize the clauses that need pre-built expressions for CodeGen. 8336 for (OMPClause *C : Clauses) { 8337 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8338 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8339 B.NumIterations, *this, CurScope, 8340 DSAStack)) 8341 return StmtError(); 8342 } 8343 } 8344 8345 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8346 return StmtError(); 8347 8348 setFunctionHasBranchProtectedScope(); 8349 return OMPParallelForSimdDirective::Create( 8350 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8351 } 8352 8353 StmtResult 8354 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8355 Stmt *AStmt, SourceLocation StartLoc, 8356 SourceLocation EndLoc) { 8357 if (!AStmt) 8358 return StmtError(); 8359 8360 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8361 auto *CS = cast<CapturedStmt>(AStmt); 8362 // 1.2.2 OpenMP Language Terminology 8363 // Structured block - An executable statement with a single entry at the 8364 // top and a single exit at the bottom. 8365 // The point of exit cannot be a branch out of the structured block. 8366 // longjmp() and throw() must not violate the entry/exit criteria. 8367 CS->getCapturedDecl()->setNothrow(); 8368 8369 setFunctionHasBranchProtectedScope(); 8370 8371 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8372 AStmt); 8373 } 8374 8375 StmtResult 8376 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8377 Stmt *AStmt, SourceLocation StartLoc, 8378 SourceLocation EndLoc) { 8379 if (!AStmt) 8380 return StmtError(); 8381 8382 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8383 auto BaseStmt = AStmt; 8384 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8385 BaseStmt = CS->getCapturedStmt(); 8386 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8387 auto S = C->children(); 8388 if (S.begin() == S.end()) 8389 return StmtError(); 8390 // All associated statements must be '#pragma omp section' except for 8391 // the first one. 8392 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8393 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8394 if (SectionStmt) 8395 Diag(SectionStmt->getBeginLoc(), 8396 diag::err_omp_parallel_sections_substmt_not_section); 8397 return StmtError(); 8398 } 8399 cast<OMPSectionDirective>(SectionStmt) 8400 ->setHasCancel(DSAStack->isCancelRegion()); 8401 } 8402 } else { 8403 Diag(AStmt->getBeginLoc(), 8404 diag::err_omp_parallel_sections_not_compound_stmt); 8405 return StmtError(); 8406 } 8407 8408 setFunctionHasBranchProtectedScope(); 8409 8410 return OMPParallelSectionsDirective::Create( 8411 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8412 } 8413 8414 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8415 Stmt *AStmt, SourceLocation StartLoc, 8416 SourceLocation EndLoc) { 8417 if (!AStmt) 8418 return StmtError(); 8419 8420 auto *CS = cast<CapturedStmt>(AStmt); 8421 // 1.2.2 OpenMP Language Terminology 8422 // Structured block - An executable statement with a single entry at the 8423 // top and a single exit at the bottom. 8424 // The point of exit cannot be a branch out of the structured block. 8425 // longjmp() and throw() must not violate the entry/exit criteria. 8426 CS->getCapturedDecl()->setNothrow(); 8427 8428 setFunctionHasBranchProtectedScope(); 8429 8430 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8431 DSAStack->isCancelRegion()); 8432 } 8433 8434 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8435 SourceLocation EndLoc) { 8436 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8437 } 8438 8439 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8440 SourceLocation EndLoc) { 8441 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8442 } 8443 8444 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8445 SourceLocation EndLoc) { 8446 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8447 } 8448 8449 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8450 Stmt *AStmt, 8451 SourceLocation StartLoc, 8452 SourceLocation EndLoc) { 8453 if (!AStmt) 8454 return StmtError(); 8455 8456 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8457 8458 setFunctionHasBranchProtectedScope(); 8459 8460 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8461 AStmt, 8462 DSAStack->getTaskgroupReductionRef()); 8463 } 8464 8465 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8466 SourceLocation StartLoc, 8467 SourceLocation EndLoc) { 8468 OMPFlushClause *FC = nullptr; 8469 OMPClause *OrderClause = nullptr; 8470 for (OMPClause *C : Clauses) { 8471 if (C->getClauseKind() == OMPC_flush) 8472 FC = cast<OMPFlushClause>(C); 8473 else 8474 OrderClause = C; 8475 } 8476 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8477 SourceLocation MemOrderLoc; 8478 for (const OMPClause *C : Clauses) { 8479 if (C->getClauseKind() == OMPC_acq_rel || 8480 C->getClauseKind() == OMPC_acquire || 8481 C->getClauseKind() == OMPC_release) { 8482 if (MemOrderKind != OMPC_unknown) { 8483 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8484 << getOpenMPDirectiveName(OMPD_flush) << 1 8485 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8486 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8487 << getOpenMPClauseName(MemOrderKind); 8488 } else { 8489 MemOrderKind = C->getClauseKind(); 8490 MemOrderLoc = C->getBeginLoc(); 8491 } 8492 } 8493 } 8494 if (FC && OrderClause) { 8495 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 8496 << getOpenMPClauseName(OrderClause->getClauseKind()); 8497 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 8498 << getOpenMPClauseName(OrderClause->getClauseKind()); 8499 return StmtError(); 8500 } 8501 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8502 } 8503 8504 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8505 Stmt *AStmt, 8506 SourceLocation StartLoc, 8507 SourceLocation EndLoc) { 8508 const OMPClause *DependFound = nullptr; 8509 const OMPClause *DependSourceClause = nullptr; 8510 const OMPClause *DependSinkClause = nullptr; 8511 bool ErrorFound = false; 8512 const OMPThreadsClause *TC = nullptr; 8513 const OMPSIMDClause *SC = nullptr; 8514 for (const OMPClause *C : Clauses) { 8515 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8516 DependFound = C; 8517 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8518 if (DependSourceClause) { 8519 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8520 << getOpenMPDirectiveName(OMPD_ordered) 8521 << getOpenMPClauseName(OMPC_depend) << 2; 8522 ErrorFound = true; 8523 } else { 8524 DependSourceClause = C; 8525 } 8526 if (DependSinkClause) { 8527 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8528 << 0; 8529 ErrorFound = true; 8530 } 8531 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8532 if (DependSourceClause) { 8533 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8534 << 1; 8535 ErrorFound = true; 8536 } 8537 DependSinkClause = C; 8538 } 8539 } else if (C->getClauseKind() == OMPC_threads) { 8540 TC = cast<OMPThreadsClause>(C); 8541 } else if (C->getClauseKind() == OMPC_simd) { 8542 SC = cast<OMPSIMDClause>(C); 8543 } 8544 } 8545 if (!ErrorFound && !SC && 8546 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8547 // OpenMP [2.8.1,simd Construct, Restrictions] 8548 // An ordered construct with the simd clause is the only OpenMP construct 8549 // that can appear in the simd region. 8550 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8551 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8552 ErrorFound = true; 8553 } else if (DependFound && (TC || SC)) { 8554 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8555 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8556 ErrorFound = true; 8557 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8558 Diag(DependFound->getBeginLoc(), 8559 diag::err_omp_ordered_directive_without_param); 8560 ErrorFound = true; 8561 } else if (TC || Clauses.empty()) { 8562 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8563 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8564 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8565 << (TC != nullptr); 8566 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 8567 ErrorFound = true; 8568 } 8569 } 8570 if ((!AStmt && !DependFound) || ErrorFound) 8571 return StmtError(); 8572 8573 if (AStmt) { 8574 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8575 8576 setFunctionHasBranchProtectedScope(); 8577 } 8578 8579 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8580 } 8581 8582 namespace { 8583 /// Helper class for checking expression in 'omp atomic [update]' 8584 /// construct. 8585 class OpenMPAtomicUpdateChecker { 8586 /// Error results for atomic update expressions. 8587 enum ExprAnalysisErrorCode { 8588 /// A statement is not an expression statement. 8589 NotAnExpression, 8590 /// Expression is not builtin binary or unary operation. 8591 NotABinaryOrUnaryExpression, 8592 /// Unary operation is not post-/pre- increment/decrement operation. 8593 NotAnUnaryIncDecExpression, 8594 /// An expression is not of scalar type. 8595 NotAScalarType, 8596 /// A binary operation is not an assignment operation. 8597 NotAnAssignmentOp, 8598 /// RHS part of the binary operation is not a binary expression. 8599 NotABinaryExpression, 8600 /// RHS part is not additive/multiplicative/shift/biwise binary 8601 /// expression. 8602 NotABinaryOperator, 8603 /// RHS binary operation does not have reference to the updated LHS 8604 /// part. 8605 NotAnUpdateExpression, 8606 /// No errors is found. 8607 NoError 8608 }; 8609 /// Reference to Sema. 8610 Sema &SemaRef; 8611 /// A location for note diagnostics (when error is found). 8612 SourceLocation NoteLoc; 8613 /// 'x' lvalue part of the source atomic expression. 8614 Expr *X; 8615 /// 'expr' rvalue part of the source atomic expression. 8616 Expr *E; 8617 /// Helper expression of the form 8618 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8619 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8620 Expr *UpdateExpr; 8621 /// Is 'x' a LHS in a RHS part of full update expression. It is 8622 /// important for non-associative operations. 8623 bool IsXLHSInRHSPart; 8624 BinaryOperatorKind Op; 8625 SourceLocation OpLoc; 8626 /// true if the source expression is a postfix unary operation, false 8627 /// if it is a prefix unary operation. 8628 bool IsPostfixUpdate; 8629 8630 public: 8631 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8632 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8633 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8634 /// Check specified statement that it is suitable for 'atomic update' 8635 /// constructs and extract 'x', 'expr' and Operation from the original 8636 /// expression. If DiagId and NoteId == 0, then only check is performed 8637 /// without error notification. 8638 /// \param DiagId Diagnostic which should be emitted if error is found. 8639 /// \param NoteId Diagnostic note for the main error message. 8640 /// \return true if statement is not an update expression, false otherwise. 8641 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8642 /// Return the 'x' lvalue part of the source atomic expression. 8643 Expr *getX() const { return X; } 8644 /// Return the 'expr' rvalue part of the source atomic expression. 8645 Expr *getExpr() const { return E; } 8646 /// Return the update expression used in calculation of the updated 8647 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8648 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8649 Expr *getUpdateExpr() const { return UpdateExpr; } 8650 /// Return true if 'x' is LHS in RHS part of full update expression, 8651 /// false otherwise. 8652 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8653 8654 /// true if the source expression is a postfix unary operation, false 8655 /// if it is a prefix unary operation. 8656 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8657 8658 private: 8659 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8660 unsigned NoteId = 0); 8661 }; 8662 } // namespace 8663 8664 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8665 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8666 ExprAnalysisErrorCode ErrorFound = NoError; 8667 SourceLocation ErrorLoc, NoteLoc; 8668 SourceRange ErrorRange, NoteRange; 8669 // Allowed constructs are: 8670 // x = x binop expr; 8671 // x = expr binop x; 8672 if (AtomicBinOp->getOpcode() == BO_Assign) { 8673 X = AtomicBinOp->getLHS(); 8674 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8675 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8676 if (AtomicInnerBinOp->isMultiplicativeOp() || 8677 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8678 AtomicInnerBinOp->isBitwiseOp()) { 8679 Op = AtomicInnerBinOp->getOpcode(); 8680 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8681 Expr *LHS = AtomicInnerBinOp->getLHS(); 8682 Expr *RHS = AtomicInnerBinOp->getRHS(); 8683 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8684 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8685 /*Canonical=*/true); 8686 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8687 /*Canonical=*/true); 8688 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8689 /*Canonical=*/true); 8690 if (XId == LHSId) { 8691 E = RHS; 8692 IsXLHSInRHSPart = true; 8693 } else if (XId == RHSId) { 8694 E = LHS; 8695 IsXLHSInRHSPart = false; 8696 } else { 8697 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8698 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8699 NoteLoc = X->getExprLoc(); 8700 NoteRange = X->getSourceRange(); 8701 ErrorFound = NotAnUpdateExpression; 8702 } 8703 } else { 8704 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8705 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8706 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8707 NoteRange = SourceRange(NoteLoc, NoteLoc); 8708 ErrorFound = NotABinaryOperator; 8709 } 8710 } else { 8711 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8712 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8713 ErrorFound = NotABinaryExpression; 8714 } 8715 } else { 8716 ErrorLoc = AtomicBinOp->getExprLoc(); 8717 ErrorRange = AtomicBinOp->getSourceRange(); 8718 NoteLoc = AtomicBinOp->getOperatorLoc(); 8719 NoteRange = SourceRange(NoteLoc, NoteLoc); 8720 ErrorFound = NotAnAssignmentOp; 8721 } 8722 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8723 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8724 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8725 return true; 8726 } 8727 if (SemaRef.CurContext->isDependentContext()) 8728 E = X = UpdateExpr = nullptr; 8729 return ErrorFound != NoError; 8730 } 8731 8732 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8733 unsigned NoteId) { 8734 ExprAnalysisErrorCode ErrorFound = NoError; 8735 SourceLocation ErrorLoc, NoteLoc; 8736 SourceRange ErrorRange, NoteRange; 8737 // Allowed constructs are: 8738 // x++; 8739 // x--; 8740 // ++x; 8741 // --x; 8742 // x binop= expr; 8743 // x = x binop expr; 8744 // x = expr binop x; 8745 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8746 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8747 if (AtomicBody->getType()->isScalarType() || 8748 AtomicBody->isInstantiationDependent()) { 8749 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8750 AtomicBody->IgnoreParenImpCasts())) { 8751 // Check for Compound Assignment Operation 8752 Op = BinaryOperator::getOpForCompoundAssignment( 8753 AtomicCompAssignOp->getOpcode()); 8754 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8755 E = AtomicCompAssignOp->getRHS(); 8756 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8757 IsXLHSInRHSPart = true; 8758 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8759 AtomicBody->IgnoreParenImpCasts())) { 8760 // Check for Binary Operation 8761 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8762 return true; 8763 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8764 AtomicBody->IgnoreParenImpCasts())) { 8765 // Check for Unary Operation 8766 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8767 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8768 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8769 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8770 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8771 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8772 IsXLHSInRHSPart = true; 8773 } else { 8774 ErrorFound = NotAnUnaryIncDecExpression; 8775 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8776 ErrorRange = AtomicUnaryOp->getSourceRange(); 8777 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8778 NoteRange = SourceRange(NoteLoc, NoteLoc); 8779 } 8780 } else if (!AtomicBody->isInstantiationDependent()) { 8781 ErrorFound = NotABinaryOrUnaryExpression; 8782 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8783 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8784 } 8785 } else { 8786 ErrorFound = NotAScalarType; 8787 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8788 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8789 } 8790 } else { 8791 ErrorFound = NotAnExpression; 8792 NoteLoc = ErrorLoc = S->getBeginLoc(); 8793 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8794 } 8795 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8796 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8797 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8798 return true; 8799 } 8800 if (SemaRef.CurContext->isDependentContext()) 8801 E = X = UpdateExpr = nullptr; 8802 if (ErrorFound == NoError && E && X) { 8803 // Build an update expression of form 'OpaqueValueExpr(x) binop 8804 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8805 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8806 auto *OVEX = new (SemaRef.getASTContext()) 8807 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8808 auto *OVEExpr = new (SemaRef.getASTContext()) 8809 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8810 ExprResult Update = 8811 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8812 IsXLHSInRHSPart ? OVEExpr : OVEX); 8813 if (Update.isInvalid()) 8814 return true; 8815 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8816 Sema::AA_Casting); 8817 if (Update.isInvalid()) 8818 return true; 8819 UpdateExpr = Update.get(); 8820 } 8821 return ErrorFound != NoError; 8822 } 8823 8824 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8825 Stmt *AStmt, 8826 SourceLocation StartLoc, 8827 SourceLocation EndLoc) { 8828 // Register location of the first atomic directive. 8829 DSAStack->addAtomicDirectiveLoc(StartLoc); 8830 if (!AStmt) 8831 return StmtError(); 8832 8833 auto *CS = cast<CapturedStmt>(AStmt); 8834 // 1.2.2 OpenMP Language Terminology 8835 // Structured block - An executable statement with a single entry at the 8836 // top and a single exit at the bottom. 8837 // The point of exit cannot be a branch out of the structured block. 8838 // longjmp() and throw() must not violate the entry/exit criteria. 8839 OpenMPClauseKind AtomicKind = OMPC_unknown; 8840 SourceLocation AtomicKindLoc; 8841 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8842 SourceLocation MemOrderLoc; 8843 for (const OMPClause *C : Clauses) { 8844 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8845 C->getClauseKind() == OMPC_update || 8846 C->getClauseKind() == OMPC_capture) { 8847 if (AtomicKind != OMPC_unknown) { 8848 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8849 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8850 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 8851 << getOpenMPClauseName(AtomicKind); 8852 } else { 8853 AtomicKind = C->getClauseKind(); 8854 AtomicKindLoc = C->getBeginLoc(); 8855 } 8856 } 8857 if (C->getClauseKind() == OMPC_seq_cst || 8858 C->getClauseKind() == OMPC_acq_rel || 8859 C->getClauseKind() == OMPC_acquire || 8860 C->getClauseKind() == OMPC_release || 8861 C->getClauseKind() == OMPC_relaxed) { 8862 if (MemOrderKind != OMPC_unknown) { 8863 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8864 << getOpenMPDirectiveName(OMPD_atomic) << 0 8865 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8866 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8867 << getOpenMPClauseName(MemOrderKind); 8868 } else { 8869 MemOrderKind = C->getClauseKind(); 8870 MemOrderLoc = C->getBeginLoc(); 8871 } 8872 } 8873 } 8874 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 8875 // If atomic-clause is read then memory-order-clause must not be acq_rel or 8876 // release. 8877 // If atomic-clause is write then memory-order-clause must not be acq_rel or 8878 // acquire. 8879 // If atomic-clause is update or not present then memory-order-clause must not 8880 // be acq_rel or acquire. 8881 if ((AtomicKind == OMPC_read && 8882 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 8883 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 8884 AtomicKind == OMPC_unknown) && 8885 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 8886 SourceLocation Loc = AtomicKindLoc; 8887 if (AtomicKind == OMPC_unknown) 8888 Loc = StartLoc; 8889 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 8890 << getOpenMPClauseName(AtomicKind) 8891 << (AtomicKind == OMPC_unknown ? 1 : 0) 8892 << getOpenMPClauseName(MemOrderKind); 8893 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8894 << getOpenMPClauseName(MemOrderKind); 8895 } 8896 8897 Stmt *Body = CS->getCapturedStmt(); 8898 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8899 Body = EWC->getSubExpr(); 8900 8901 Expr *X = nullptr; 8902 Expr *V = nullptr; 8903 Expr *E = nullptr; 8904 Expr *UE = nullptr; 8905 bool IsXLHSInRHSPart = false; 8906 bool IsPostfixUpdate = false; 8907 // OpenMP [2.12.6, atomic Construct] 8908 // In the next expressions: 8909 // * x and v (as applicable) are both l-value expressions with scalar type. 8910 // * During the execution of an atomic region, multiple syntactic 8911 // occurrences of x must designate the same storage location. 8912 // * Neither of v and expr (as applicable) may access the storage location 8913 // designated by x. 8914 // * Neither of x and expr (as applicable) may access the storage location 8915 // designated by v. 8916 // * expr is an expression with scalar type. 8917 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8918 // * binop, binop=, ++, and -- are not overloaded operators. 8919 // * The expression x binop expr must be numerically equivalent to x binop 8920 // (expr). This requirement is satisfied if the operators in expr have 8921 // precedence greater than binop, or by using parentheses around expr or 8922 // subexpressions of expr. 8923 // * The expression expr binop x must be numerically equivalent to (expr) 8924 // binop x. This requirement is satisfied if the operators in expr have 8925 // precedence equal to or greater than binop, or by using parentheses around 8926 // expr or subexpressions of expr. 8927 // * For forms that allow multiple occurrences of x, the number of times 8928 // that x is evaluated is unspecified. 8929 if (AtomicKind == OMPC_read) { 8930 enum { 8931 NotAnExpression, 8932 NotAnAssignmentOp, 8933 NotAScalarType, 8934 NotAnLValue, 8935 NoError 8936 } ErrorFound = NoError; 8937 SourceLocation ErrorLoc, NoteLoc; 8938 SourceRange ErrorRange, NoteRange; 8939 // If clause is read: 8940 // v = x; 8941 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8942 const auto *AtomicBinOp = 8943 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8944 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8945 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8946 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8947 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8948 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8949 if (!X->isLValue() || !V->isLValue()) { 8950 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8951 ErrorFound = NotAnLValue; 8952 ErrorLoc = AtomicBinOp->getExprLoc(); 8953 ErrorRange = AtomicBinOp->getSourceRange(); 8954 NoteLoc = NotLValueExpr->getExprLoc(); 8955 NoteRange = NotLValueExpr->getSourceRange(); 8956 } 8957 } else if (!X->isInstantiationDependent() || 8958 !V->isInstantiationDependent()) { 8959 const Expr *NotScalarExpr = 8960 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8961 ? V 8962 : X; 8963 ErrorFound = NotAScalarType; 8964 ErrorLoc = AtomicBinOp->getExprLoc(); 8965 ErrorRange = AtomicBinOp->getSourceRange(); 8966 NoteLoc = NotScalarExpr->getExprLoc(); 8967 NoteRange = NotScalarExpr->getSourceRange(); 8968 } 8969 } else if (!AtomicBody->isInstantiationDependent()) { 8970 ErrorFound = NotAnAssignmentOp; 8971 ErrorLoc = AtomicBody->getExprLoc(); 8972 ErrorRange = AtomicBody->getSourceRange(); 8973 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8974 : AtomicBody->getExprLoc(); 8975 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8976 : AtomicBody->getSourceRange(); 8977 } 8978 } else { 8979 ErrorFound = NotAnExpression; 8980 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8981 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8982 } 8983 if (ErrorFound != NoError) { 8984 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8985 << ErrorRange; 8986 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8987 << NoteRange; 8988 return StmtError(); 8989 } 8990 if (CurContext->isDependentContext()) 8991 V = X = nullptr; 8992 } else if (AtomicKind == OMPC_write) { 8993 enum { 8994 NotAnExpression, 8995 NotAnAssignmentOp, 8996 NotAScalarType, 8997 NotAnLValue, 8998 NoError 8999 } ErrorFound = NoError; 9000 SourceLocation ErrorLoc, NoteLoc; 9001 SourceRange ErrorRange, NoteRange; 9002 // If clause is write: 9003 // x = expr; 9004 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9005 const auto *AtomicBinOp = 9006 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9007 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9008 X = AtomicBinOp->getLHS(); 9009 E = AtomicBinOp->getRHS(); 9010 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9011 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9012 if (!X->isLValue()) { 9013 ErrorFound = NotAnLValue; 9014 ErrorLoc = AtomicBinOp->getExprLoc(); 9015 ErrorRange = AtomicBinOp->getSourceRange(); 9016 NoteLoc = X->getExprLoc(); 9017 NoteRange = X->getSourceRange(); 9018 } 9019 } else if (!X->isInstantiationDependent() || 9020 !E->isInstantiationDependent()) { 9021 const Expr *NotScalarExpr = 9022 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9023 ? E 9024 : X; 9025 ErrorFound = NotAScalarType; 9026 ErrorLoc = AtomicBinOp->getExprLoc(); 9027 ErrorRange = AtomicBinOp->getSourceRange(); 9028 NoteLoc = NotScalarExpr->getExprLoc(); 9029 NoteRange = NotScalarExpr->getSourceRange(); 9030 } 9031 } else if (!AtomicBody->isInstantiationDependent()) { 9032 ErrorFound = NotAnAssignmentOp; 9033 ErrorLoc = AtomicBody->getExprLoc(); 9034 ErrorRange = AtomicBody->getSourceRange(); 9035 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9036 : AtomicBody->getExprLoc(); 9037 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9038 : AtomicBody->getSourceRange(); 9039 } 9040 } else { 9041 ErrorFound = NotAnExpression; 9042 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9043 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9044 } 9045 if (ErrorFound != NoError) { 9046 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9047 << ErrorRange; 9048 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9049 << NoteRange; 9050 return StmtError(); 9051 } 9052 if (CurContext->isDependentContext()) 9053 E = X = nullptr; 9054 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9055 // If clause is update: 9056 // x++; 9057 // x--; 9058 // ++x; 9059 // --x; 9060 // x binop= expr; 9061 // x = x binop expr; 9062 // x = expr binop x; 9063 OpenMPAtomicUpdateChecker Checker(*this); 9064 if (Checker.checkStatement( 9065 Body, (AtomicKind == OMPC_update) 9066 ? diag::err_omp_atomic_update_not_expression_statement 9067 : diag::err_omp_atomic_not_expression_statement, 9068 diag::note_omp_atomic_update)) 9069 return StmtError(); 9070 if (!CurContext->isDependentContext()) { 9071 E = Checker.getExpr(); 9072 X = Checker.getX(); 9073 UE = Checker.getUpdateExpr(); 9074 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9075 } 9076 } else if (AtomicKind == OMPC_capture) { 9077 enum { 9078 NotAnAssignmentOp, 9079 NotACompoundStatement, 9080 NotTwoSubstatements, 9081 NotASpecificExpression, 9082 NoError 9083 } ErrorFound = NoError; 9084 SourceLocation ErrorLoc, NoteLoc; 9085 SourceRange ErrorRange, NoteRange; 9086 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9087 // If clause is a capture: 9088 // v = x++; 9089 // v = x--; 9090 // v = ++x; 9091 // v = --x; 9092 // v = x binop= expr; 9093 // v = x = x binop expr; 9094 // v = x = expr binop x; 9095 const auto *AtomicBinOp = 9096 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9097 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9098 V = AtomicBinOp->getLHS(); 9099 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9100 OpenMPAtomicUpdateChecker Checker(*this); 9101 if (Checker.checkStatement( 9102 Body, diag::err_omp_atomic_capture_not_expression_statement, 9103 diag::note_omp_atomic_update)) 9104 return StmtError(); 9105 E = Checker.getExpr(); 9106 X = Checker.getX(); 9107 UE = Checker.getUpdateExpr(); 9108 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9109 IsPostfixUpdate = Checker.isPostfixUpdate(); 9110 } else if (!AtomicBody->isInstantiationDependent()) { 9111 ErrorLoc = AtomicBody->getExprLoc(); 9112 ErrorRange = AtomicBody->getSourceRange(); 9113 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9114 : AtomicBody->getExprLoc(); 9115 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9116 : AtomicBody->getSourceRange(); 9117 ErrorFound = NotAnAssignmentOp; 9118 } 9119 if (ErrorFound != NoError) { 9120 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9121 << ErrorRange; 9122 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9123 return StmtError(); 9124 } 9125 if (CurContext->isDependentContext()) 9126 UE = V = E = X = nullptr; 9127 } else { 9128 // If clause is a capture: 9129 // { v = x; x = expr; } 9130 // { v = x; x++; } 9131 // { v = x; x--; } 9132 // { v = x; ++x; } 9133 // { v = x; --x; } 9134 // { v = x; x binop= expr; } 9135 // { v = x; x = x binop expr; } 9136 // { v = x; x = expr binop x; } 9137 // { x++; v = x; } 9138 // { x--; v = x; } 9139 // { ++x; v = x; } 9140 // { --x; v = x; } 9141 // { x binop= expr; v = x; } 9142 // { x = x binop expr; v = x; } 9143 // { x = expr binop x; v = x; } 9144 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9145 // Check that this is { expr1; expr2; } 9146 if (CS->size() == 2) { 9147 Stmt *First = CS->body_front(); 9148 Stmt *Second = CS->body_back(); 9149 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9150 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9151 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9152 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9153 // Need to find what subexpression is 'v' and what is 'x'. 9154 OpenMPAtomicUpdateChecker Checker(*this); 9155 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9156 BinaryOperator *BinOp = nullptr; 9157 if (IsUpdateExprFound) { 9158 BinOp = dyn_cast<BinaryOperator>(First); 9159 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9160 } 9161 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9162 // { v = x; x++; } 9163 // { v = x; x--; } 9164 // { v = x; ++x; } 9165 // { v = x; --x; } 9166 // { v = x; x binop= expr; } 9167 // { v = x; x = x binop expr; } 9168 // { v = x; x = expr binop x; } 9169 // Check that the first expression has form v = x. 9170 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9171 llvm::FoldingSetNodeID XId, PossibleXId; 9172 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9173 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9174 IsUpdateExprFound = XId == PossibleXId; 9175 if (IsUpdateExprFound) { 9176 V = BinOp->getLHS(); 9177 X = Checker.getX(); 9178 E = Checker.getExpr(); 9179 UE = Checker.getUpdateExpr(); 9180 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9181 IsPostfixUpdate = true; 9182 } 9183 } 9184 if (!IsUpdateExprFound) { 9185 IsUpdateExprFound = !Checker.checkStatement(First); 9186 BinOp = nullptr; 9187 if (IsUpdateExprFound) { 9188 BinOp = dyn_cast<BinaryOperator>(Second); 9189 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9190 } 9191 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9192 // { x++; v = x; } 9193 // { x--; v = x; } 9194 // { ++x; v = x; } 9195 // { --x; v = x; } 9196 // { x binop= expr; v = x; } 9197 // { x = x binop expr; v = x; } 9198 // { x = expr binop x; v = x; } 9199 // Check that the second expression has form v = x. 9200 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9201 llvm::FoldingSetNodeID XId, PossibleXId; 9202 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9203 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9204 IsUpdateExprFound = XId == PossibleXId; 9205 if (IsUpdateExprFound) { 9206 V = BinOp->getLHS(); 9207 X = Checker.getX(); 9208 E = Checker.getExpr(); 9209 UE = Checker.getUpdateExpr(); 9210 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9211 IsPostfixUpdate = false; 9212 } 9213 } 9214 } 9215 if (!IsUpdateExprFound) { 9216 // { v = x; x = expr; } 9217 auto *FirstExpr = dyn_cast<Expr>(First); 9218 auto *SecondExpr = dyn_cast<Expr>(Second); 9219 if (!FirstExpr || !SecondExpr || 9220 !(FirstExpr->isInstantiationDependent() || 9221 SecondExpr->isInstantiationDependent())) { 9222 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9223 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9224 ErrorFound = NotAnAssignmentOp; 9225 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9226 : First->getBeginLoc(); 9227 NoteRange = ErrorRange = FirstBinOp 9228 ? FirstBinOp->getSourceRange() 9229 : SourceRange(ErrorLoc, ErrorLoc); 9230 } else { 9231 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9232 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9233 ErrorFound = NotAnAssignmentOp; 9234 NoteLoc = ErrorLoc = SecondBinOp 9235 ? SecondBinOp->getOperatorLoc() 9236 : Second->getBeginLoc(); 9237 NoteRange = ErrorRange = 9238 SecondBinOp ? SecondBinOp->getSourceRange() 9239 : SourceRange(ErrorLoc, ErrorLoc); 9240 } else { 9241 Expr *PossibleXRHSInFirst = 9242 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9243 Expr *PossibleXLHSInSecond = 9244 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9245 llvm::FoldingSetNodeID X1Id, X2Id; 9246 PossibleXRHSInFirst->Profile(X1Id, Context, 9247 /*Canonical=*/true); 9248 PossibleXLHSInSecond->Profile(X2Id, Context, 9249 /*Canonical=*/true); 9250 IsUpdateExprFound = X1Id == X2Id; 9251 if (IsUpdateExprFound) { 9252 V = FirstBinOp->getLHS(); 9253 X = SecondBinOp->getLHS(); 9254 E = SecondBinOp->getRHS(); 9255 UE = nullptr; 9256 IsXLHSInRHSPart = false; 9257 IsPostfixUpdate = true; 9258 } else { 9259 ErrorFound = NotASpecificExpression; 9260 ErrorLoc = FirstBinOp->getExprLoc(); 9261 ErrorRange = FirstBinOp->getSourceRange(); 9262 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9263 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9264 } 9265 } 9266 } 9267 } 9268 } 9269 } else { 9270 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9271 NoteRange = ErrorRange = 9272 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9273 ErrorFound = NotTwoSubstatements; 9274 } 9275 } else { 9276 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9277 NoteRange = ErrorRange = 9278 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9279 ErrorFound = NotACompoundStatement; 9280 } 9281 if (ErrorFound != NoError) { 9282 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9283 << ErrorRange; 9284 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9285 return StmtError(); 9286 } 9287 if (CurContext->isDependentContext()) 9288 UE = V = E = X = nullptr; 9289 } 9290 } 9291 9292 setFunctionHasBranchProtectedScope(); 9293 9294 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9295 X, V, E, UE, IsXLHSInRHSPart, 9296 IsPostfixUpdate); 9297 } 9298 9299 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9300 Stmt *AStmt, 9301 SourceLocation StartLoc, 9302 SourceLocation EndLoc) { 9303 if (!AStmt) 9304 return StmtError(); 9305 9306 auto *CS = cast<CapturedStmt>(AStmt); 9307 // 1.2.2 OpenMP Language Terminology 9308 // Structured block - An executable statement with a single entry at the 9309 // top and a single exit at the bottom. 9310 // The point of exit cannot be a branch out of the structured block. 9311 // longjmp() and throw() must not violate the entry/exit criteria. 9312 CS->getCapturedDecl()->setNothrow(); 9313 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9314 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9315 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9316 // 1.2.2 OpenMP Language Terminology 9317 // Structured block - An executable statement with a single entry at the 9318 // top and a single exit at the bottom. 9319 // The point of exit cannot be a branch out of the structured block. 9320 // longjmp() and throw() must not violate the entry/exit criteria. 9321 CS->getCapturedDecl()->setNothrow(); 9322 } 9323 9324 // OpenMP [2.16, Nesting of Regions] 9325 // If specified, a teams construct must be contained within a target 9326 // construct. That target construct must contain no statements or directives 9327 // outside of the teams construct. 9328 if (DSAStack->hasInnerTeamsRegion()) { 9329 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9330 bool OMPTeamsFound = true; 9331 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9332 auto I = CS->body_begin(); 9333 while (I != CS->body_end()) { 9334 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9335 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9336 OMPTeamsFound) { 9337 9338 OMPTeamsFound = false; 9339 break; 9340 } 9341 ++I; 9342 } 9343 assert(I != CS->body_end() && "Not found statement"); 9344 S = *I; 9345 } else { 9346 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9347 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9348 } 9349 if (!OMPTeamsFound) { 9350 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9351 Diag(DSAStack->getInnerTeamsRegionLoc(), 9352 diag::note_omp_nested_teams_construct_here); 9353 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9354 << isa<OMPExecutableDirective>(S); 9355 return StmtError(); 9356 } 9357 } 9358 9359 setFunctionHasBranchProtectedScope(); 9360 9361 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9362 } 9363 9364 StmtResult 9365 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9366 Stmt *AStmt, SourceLocation StartLoc, 9367 SourceLocation EndLoc) { 9368 if (!AStmt) 9369 return StmtError(); 9370 9371 auto *CS = cast<CapturedStmt>(AStmt); 9372 // 1.2.2 OpenMP Language Terminology 9373 // Structured block - An executable statement with a single entry at the 9374 // top and a single exit at the bottom. 9375 // The point of exit cannot be a branch out of the structured block. 9376 // longjmp() and throw() must not violate the entry/exit criteria. 9377 CS->getCapturedDecl()->setNothrow(); 9378 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9379 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9380 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9381 // 1.2.2 OpenMP Language Terminology 9382 // Structured block - An executable statement with a single entry at the 9383 // top and a single exit at the bottom. 9384 // The point of exit cannot be a branch out of the structured block. 9385 // longjmp() and throw() must not violate the entry/exit criteria. 9386 CS->getCapturedDecl()->setNothrow(); 9387 } 9388 9389 setFunctionHasBranchProtectedScope(); 9390 9391 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9392 AStmt); 9393 } 9394 9395 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9396 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9397 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9398 if (!AStmt) 9399 return StmtError(); 9400 9401 auto *CS = cast<CapturedStmt>(AStmt); 9402 // 1.2.2 OpenMP Language Terminology 9403 // Structured block - An executable statement with a single entry at the 9404 // top and a single exit at the bottom. 9405 // The point of exit cannot be a branch out of the structured block. 9406 // longjmp() and throw() must not violate the entry/exit criteria. 9407 CS->getCapturedDecl()->setNothrow(); 9408 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9409 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9410 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9411 // 1.2.2 OpenMP Language Terminology 9412 // Structured block - An executable statement with a single entry at the 9413 // top and a single exit at the bottom. 9414 // The point of exit cannot be a branch out of the structured block. 9415 // longjmp() and throw() must not violate the entry/exit criteria. 9416 CS->getCapturedDecl()->setNothrow(); 9417 } 9418 9419 OMPLoopDirective::HelperExprs B; 9420 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9421 // define the nested loops number. 9422 unsigned NestedLoopCount = 9423 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9424 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9425 VarsWithImplicitDSA, B); 9426 if (NestedLoopCount == 0) 9427 return StmtError(); 9428 9429 assert((CurContext->isDependentContext() || B.builtAll()) && 9430 "omp target parallel for loop exprs were not built"); 9431 9432 if (!CurContext->isDependentContext()) { 9433 // Finalize the clauses that need pre-built expressions for CodeGen. 9434 for (OMPClause *C : Clauses) { 9435 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9436 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9437 B.NumIterations, *this, CurScope, 9438 DSAStack)) 9439 return StmtError(); 9440 } 9441 } 9442 9443 setFunctionHasBranchProtectedScope(); 9444 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9445 NestedLoopCount, Clauses, AStmt, 9446 B, DSAStack->isCancelRegion()); 9447 } 9448 9449 /// Check for existence of a map clause in the list of clauses. 9450 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9451 const OpenMPClauseKind K) { 9452 return llvm::any_of( 9453 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9454 } 9455 9456 template <typename... Params> 9457 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9458 const Params... ClauseTypes) { 9459 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9460 } 9461 9462 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9463 Stmt *AStmt, 9464 SourceLocation StartLoc, 9465 SourceLocation EndLoc) { 9466 if (!AStmt) 9467 return StmtError(); 9468 9469 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9470 9471 // OpenMP [2.10.1, Restrictions, p. 97] 9472 // At least one map clause must appear on the directive. 9473 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9474 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9475 << "'map' or 'use_device_ptr'" 9476 << getOpenMPDirectiveName(OMPD_target_data); 9477 return StmtError(); 9478 } 9479 9480 setFunctionHasBranchProtectedScope(); 9481 9482 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9483 AStmt); 9484 } 9485 9486 StmtResult 9487 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9488 SourceLocation StartLoc, 9489 SourceLocation EndLoc, Stmt *AStmt) { 9490 if (!AStmt) 9491 return StmtError(); 9492 9493 auto *CS = cast<CapturedStmt>(AStmt); 9494 // 1.2.2 OpenMP Language Terminology 9495 // Structured block - An executable statement with a single entry at the 9496 // top and a single exit at the bottom. 9497 // The point of exit cannot be a branch out of the structured block. 9498 // longjmp() and throw() must not violate the entry/exit criteria. 9499 CS->getCapturedDecl()->setNothrow(); 9500 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9501 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9502 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9503 // 1.2.2 OpenMP Language Terminology 9504 // Structured block - An executable statement with a single entry at the 9505 // top and a single exit at the bottom. 9506 // The point of exit cannot be a branch out of the structured block. 9507 // longjmp() and throw() must not violate the entry/exit criteria. 9508 CS->getCapturedDecl()->setNothrow(); 9509 } 9510 9511 // OpenMP [2.10.2, Restrictions, p. 99] 9512 // At least one map clause must appear on the directive. 9513 if (!hasClauses(Clauses, OMPC_map)) { 9514 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9515 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9516 return StmtError(); 9517 } 9518 9519 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9520 AStmt); 9521 } 9522 9523 StmtResult 9524 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9525 SourceLocation StartLoc, 9526 SourceLocation EndLoc, Stmt *AStmt) { 9527 if (!AStmt) 9528 return StmtError(); 9529 9530 auto *CS = cast<CapturedStmt>(AStmt); 9531 // 1.2.2 OpenMP Language Terminology 9532 // Structured block - An executable statement with a single entry at the 9533 // top and a single exit at the bottom. 9534 // The point of exit cannot be a branch out of the structured block. 9535 // longjmp() and throw() must not violate the entry/exit criteria. 9536 CS->getCapturedDecl()->setNothrow(); 9537 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9538 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9539 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9540 // 1.2.2 OpenMP Language Terminology 9541 // Structured block - An executable statement with a single entry at the 9542 // top and a single exit at the bottom. 9543 // The point of exit cannot be a branch out of the structured block. 9544 // longjmp() and throw() must not violate the entry/exit criteria. 9545 CS->getCapturedDecl()->setNothrow(); 9546 } 9547 9548 // OpenMP [2.10.3, Restrictions, p. 102] 9549 // At least one map clause must appear on the directive. 9550 if (!hasClauses(Clauses, OMPC_map)) { 9551 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9552 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9553 return StmtError(); 9554 } 9555 9556 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9557 AStmt); 9558 } 9559 9560 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9561 SourceLocation StartLoc, 9562 SourceLocation EndLoc, 9563 Stmt *AStmt) { 9564 if (!AStmt) 9565 return StmtError(); 9566 9567 auto *CS = cast<CapturedStmt>(AStmt); 9568 // 1.2.2 OpenMP Language Terminology 9569 // Structured block - An executable statement with a single entry at the 9570 // top and a single exit at the bottom. 9571 // The point of exit cannot be a branch out of the structured block. 9572 // longjmp() and throw() must not violate the entry/exit criteria. 9573 CS->getCapturedDecl()->setNothrow(); 9574 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9575 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9576 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9577 // 1.2.2 OpenMP Language Terminology 9578 // Structured block - An executable statement with a single entry at the 9579 // top and a single exit at the bottom. 9580 // The point of exit cannot be a branch out of the structured block. 9581 // longjmp() and throw() must not violate the entry/exit criteria. 9582 CS->getCapturedDecl()->setNothrow(); 9583 } 9584 9585 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9586 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9587 return StmtError(); 9588 } 9589 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9590 AStmt); 9591 } 9592 9593 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9594 Stmt *AStmt, SourceLocation StartLoc, 9595 SourceLocation EndLoc) { 9596 if (!AStmt) 9597 return StmtError(); 9598 9599 auto *CS = cast<CapturedStmt>(AStmt); 9600 // 1.2.2 OpenMP Language Terminology 9601 // Structured block - An executable statement with a single entry at the 9602 // top and a single exit at the bottom. 9603 // The point of exit cannot be a branch out of the structured block. 9604 // longjmp() and throw() must not violate the entry/exit criteria. 9605 CS->getCapturedDecl()->setNothrow(); 9606 9607 setFunctionHasBranchProtectedScope(); 9608 9609 DSAStack->setParentTeamsRegionLoc(StartLoc); 9610 9611 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9612 } 9613 9614 StmtResult 9615 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9616 SourceLocation EndLoc, 9617 OpenMPDirectiveKind CancelRegion) { 9618 if (DSAStack->isParentNowaitRegion()) { 9619 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9620 return StmtError(); 9621 } 9622 if (DSAStack->isParentOrderedRegion()) { 9623 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9624 return StmtError(); 9625 } 9626 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9627 CancelRegion); 9628 } 9629 9630 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9631 SourceLocation StartLoc, 9632 SourceLocation EndLoc, 9633 OpenMPDirectiveKind CancelRegion) { 9634 if (DSAStack->isParentNowaitRegion()) { 9635 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9636 return StmtError(); 9637 } 9638 if (DSAStack->isParentOrderedRegion()) { 9639 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9640 return StmtError(); 9641 } 9642 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9643 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9644 CancelRegion); 9645 } 9646 9647 static bool checkGrainsizeNumTasksClauses(Sema &S, 9648 ArrayRef<OMPClause *> Clauses) { 9649 const OMPClause *PrevClause = nullptr; 9650 bool ErrorFound = false; 9651 for (const OMPClause *C : Clauses) { 9652 if (C->getClauseKind() == OMPC_grainsize || 9653 C->getClauseKind() == OMPC_num_tasks) { 9654 if (!PrevClause) 9655 PrevClause = C; 9656 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9657 S.Diag(C->getBeginLoc(), 9658 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9659 << getOpenMPClauseName(C->getClauseKind()) 9660 << getOpenMPClauseName(PrevClause->getClauseKind()); 9661 S.Diag(PrevClause->getBeginLoc(), 9662 diag::note_omp_previous_grainsize_num_tasks) 9663 << getOpenMPClauseName(PrevClause->getClauseKind()); 9664 ErrorFound = true; 9665 } 9666 } 9667 } 9668 return ErrorFound; 9669 } 9670 9671 static bool checkReductionClauseWithNogroup(Sema &S, 9672 ArrayRef<OMPClause *> Clauses) { 9673 const OMPClause *ReductionClause = nullptr; 9674 const OMPClause *NogroupClause = nullptr; 9675 for (const OMPClause *C : Clauses) { 9676 if (C->getClauseKind() == OMPC_reduction) { 9677 ReductionClause = C; 9678 if (NogroupClause) 9679 break; 9680 continue; 9681 } 9682 if (C->getClauseKind() == OMPC_nogroup) { 9683 NogroupClause = C; 9684 if (ReductionClause) 9685 break; 9686 continue; 9687 } 9688 } 9689 if (ReductionClause && NogroupClause) { 9690 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9691 << SourceRange(NogroupClause->getBeginLoc(), 9692 NogroupClause->getEndLoc()); 9693 return true; 9694 } 9695 return false; 9696 } 9697 9698 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9699 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9700 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9701 if (!AStmt) 9702 return StmtError(); 9703 9704 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9705 OMPLoopDirective::HelperExprs B; 9706 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9707 // define the nested loops number. 9708 unsigned NestedLoopCount = 9709 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9710 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9711 VarsWithImplicitDSA, B); 9712 if (NestedLoopCount == 0) 9713 return StmtError(); 9714 9715 assert((CurContext->isDependentContext() || B.builtAll()) && 9716 "omp for loop exprs were not built"); 9717 9718 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9719 // The grainsize clause and num_tasks clause are mutually exclusive and may 9720 // not appear on the same taskloop directive. 9721 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9722 return StmtError(); 9723 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9724 // If a reduction clause is present on the taskloop directive, the nogroup 9725 // clause must not be specified. 9726 if (checkReductionClauseWithNogroup(*this, Clauses)) 9727 return StmtError(); 9728 9729 setFunctionHasBranchProtectedScope(); 9730 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9731 NestedLoopCount, Clauses, AStmt, B, 9732 DSAStack->isCancelRegion()); 9733 } 9734 9735 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9736 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9737 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9738 if (!AStmt) 9739 return StmtError(); 9740 9741 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9742 OMPLoopDirective::HelperExprs B; 9743 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9744 // define the nested loops number. 9745 unsigned NestedLoopCount = 9746 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9747 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9748 VarsWithImplicitDSA, B); 9749 if (NestedLoopCount == 0) 9750 return StmtError(); 9751 9752 assert((CurContext->isDependentContext() || B.builtAll()) && 9753 "omp for loop exprs were not built"); 9754 9755 if (!CurContext->isDependentContext()) { 9756 // Finalize the clauses that need pre-built expressions for CodeGen. 9757 for (OMPClause *C : Clauses) { 9758 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9759 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9760 B.NumIterations, *this, CurScope, 9761 DSAStack)) 9762 return StmtError(); 9763 } 9764 } 9765 9766 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9767 // The grainsize clause and num_tasks clause are mutually exclusive and may 9768 // not appear on the same taskloop directive. 9769 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9770 return StmtError(); 9771 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9772 // If a reduction clause is present on the taskloop directive, the nogroup 9773 // clause must not be specified. 9774 if (checkReductionClauseWithNogroup(*this, Clauses)) 9775 return StmtError(); 9776 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9777 return StmtError(); 9778 9779 setFunctionHasBranchProtectedScope(); 9780 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9781 NestedLoopCount, Clauses, AStmt, B); 9782 } 9783 9784 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9785 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9786 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9787 if (!AStmt) 9788 return StmtError(); 9789 9790 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9791 OMPLoopDirective::HelperExprs B; 9792 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9793 // define the nested loops number. 9794 unsigned NestedLoopCount = 9795 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9796 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9797 VarsWithImplicitDSA, B); 9798 if (NestedLoopCount == 0) 9799 return StmtError(); 9800 9801 assert((CurContext->isDependentContext() || B.builtAll()) && 9802 "omp for loop exprs were not built"); 9803 9804 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9805 // The grainsize clause and num_tasks clause are mutually exclusive and may 9806 // not appear on the same taskloop directive. 9807 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9808 return StmtError(); 9809 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9810 // If a reduction clause is present on the taskloop directive, the nogroup 9811 // clause must not be specified. 9812 if (checkReductionClauseWithNogroup(*this, Clauses)) 9813 return StmtError(); 9814 9815 setFunctionHasBranchProtectedScope(); 9816 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9817 NestedLoopCount, Clauses, AStmt, B, 9818 DSAStack->isCancelRegion()); 9819 } 9820 9821 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9822 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9823 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9824 if (!AStmt) 9825 return StmtError(); 9826 9827 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9828 OMPLoopDirective::HelperExprs B; 9829 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9830 // define the nested loops number. 9831 unsigned NestedLoopCount = 9832 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9833 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9834 VarsWithImplicitDSA, B); 9835 if (NestedLoopCount == 0) 9836 return StmtError(); 9837 9838 assert((CurContext->isDependentContext() || B.builtAll()) && 9839 "omp for loop exprs were not built"); 9840 9841 if (!CurContext->isDependentContext()) { 9842 // Finalize the clauses that need pre-built expressions for CodeGen. 9843 for (OMPClause *C : Clauses) { 9844 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9845 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9846 B.NumIterations, *this, CurScope, 9847 DSAStack)) 9848 return StmtError(); 9849 } 9850 } 9851 9852 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9853 // The grainsize clause and num_tasks clause are mutually exclusive and may 9854 // not appear on the same taskloop directive. 9855 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9856 return StmtError(); 9857 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9858 // If a reduction clause is present on the taskloop directive, the nogroup 9859 // clause must not be specified. 9860 if (checkReductionClauseWithNogroup(*this, Clauses)) 9861 return StmtError(); 9862 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9863 return StmtError(); 9864 9865 setFunctionHasBranchProtectedScope(); 9866 return OMPMasterTaskLoopSimdDirective::Create( 9867 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9868 } 9869 9870 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9871 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9872 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9873 if (!AStmt) 9874 return StmtError(); 9875 9876 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9877 auto *CS = cast<CapturedStmt>(AStmt); 9878 // 1.2.2 OpenMP Language Terminology 9879 // Structured block - An executable statement with a single entry at the 9880 // top and a single exit at the bottom. 9881 // The point of exit cannot be a branch out of the structured block. 9882 // longjmp() and throw() must not violate the entry/exit criteria. 9883 CS->getCapturedDecl()->setNothrow(); 9884 for (int ThisCaptureLevel = 9885 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9886 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9887 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9888 // 1.2.2 OpenMP Language Terminology 9889 // Structured block - An executable statement with a single entry at the 9890 // top and a single exit at the bottom. 9891 // The point of exit cannot be a branch out of the structured block. 9892 // longjmp() and throw() must not violate the entry/exit criteria. 9893 CS->getCapturedDecl()->setNothrow(); 9894 } 9895 9896 OMPLoopDirective::HelperExprs B; 9897 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9898 // define the nested loops number. 9899 unsigned NestedLoopCount = checkOpenMPLoop( 9900 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9901 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9902 VarsWithImplicitDSA, B); 9903 if (NestedLoopCount == 0) 9904 return StmtError(); 9905 9906 assert((CurContext->isDependentContext() || B.builtAll()) && 9907 "omp for loop exprs were not built"); 9908 9909 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9910 // The grainsize clause and num_tasks clause are mutually exclusive and may 9911 // not appear on the same taskloop directive. 9912 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9913 return StmtError(); 9914 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9915 // If a reduction clause is present on the taskloop directive, the nogroup 9916 // clause must not be specified. 9917 if (checkReductionClauseWithNogroup(*this, Clauses)) 9918 return StmtError(); 9919 9920 setFunctionHasBranchProtectedScope(); 9921 return OMPParallelMasterTaskLoopDirective::Create( 9922 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9923 DSAStack->isCancelRegion()); 9924 } 9925 9926 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9927 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9928 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9929 if (!AStmt) 9930 return StmtError(); 9931 9932 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9933 auto *CS = cast<CapturedStmt>(AStmt); 9934 // 1.2.2 OpenMP Language Terminology 9935 // Structured block - An executable statement with a single entry at the 9936 // top and a single exit at the bottom. 9937 // The point of exit cannot be a branch out of the structured block. 9938 // longjmp() and throw() must not violate the entry/exit criteria. 9939 CS->getCapturedDecl()->setNothrow(); 9940 for (int ThisCaptureLevel = 9941 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9942 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9943 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9944 // 1.2.2 OpenMP Language Terminology 9945 // Structured block - An executable statement with a single entry at the 9946 // top and a single exit at the bottom. 9947 // The point of exit cannot be a branch out of the structured block. 9948 // longjmp() and throw() must not violate the entry/exit criteria. 9949 CS->getCapturedDecl()->setNothrow(); 9950 } 9951 9952 OMPLoopDirective::HelperExprs B; 9953 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9954 // define the nested loops number. 9955 unsigned NestedLoopCount = checkOpenMPLoop( 9956 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9957 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9958 VarsWithImplicitDSA, B); 9959 if (NestedLoopCount == 0) 9960 return StmtError(); 9961 9962 assert((CurContext->isDependentContext() || B.builtAll()) && 9963 "omp for loop exprs were not built"); 9964 9965 if (!CurContext->isDependentContext()) { 9966 // Finalize the clauses that need pre-built expressions for CodeGen. 9967 for (OMPClause *C : Clauses) { 9968 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9969 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9970 B.NumIterations, *this, CurScope, 9971 DSAStack)) 9972 return StmtError(); 9973 } 9974 } 9975 9976 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9977 // The grainsize clause and num_tasks clause are mutually exclusive and may 9978 // not appear on the same taskloop directive. 9979 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9980 return StmtError(); 9981 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9982 // If a reduction clause is present on the taskloop directive, the nogroup 9983 // clause must not be specified. 9984 if (checkReductionClauseWithNogroup(*this, Clauses)) 9985 return StmtError(); 9986 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9987 return StmtError(); 9988 9989 setFunctionHasBranchProtectedScope(); 9990 return OMPParallelMasterTaskLoopSimdDirective::Create( 9991 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9992 } 9993 9994 StmtResult Sema::ActOnOpenMPDistributeDirective( 9995 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9996 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9997 if (!AStmt) 9998 return StmtError(); 9999 10000 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10001 OMPLoopDirective::HelperExprs B; 10002 // In presence of clause 'collapse' with number of loops, it will 10003 // define the nested loops number. 10004 unsigned NestedLoopCount = 10005 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10006 nullptr /*ordered not a clause on distribute*/, AStmt, 10007 *this, *DSAStack, VarsWithImplicitDSA, B); 10008 if (NestedLoopCount == 0) 10009 return StmtError(); 10010 10011 assert((CurContext->isDependentContext() || B.builtAll()) && 10012 "omp for loop exprs were not built"); 10013 10014 setFunctionHasBranchProtectedScope(); 10015 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10016 NestedLoopCount, Clauses, AStmt, B); 10017 } 10018 10019 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10020 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10021 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10022 if (!AStmt) 10023 return StmtError(); 10024 10025 auto *CS = cast<CapturedStmt>(AStmt); 10026 // 1.2.2 OpenMP Language Terminology 10027 // Structured block - An executable statement with a single entry at the 10028 // top and a single exit at the bottom. 10029 // The point of exit cannot be a branch out of the structured block. 10030 // longjmp() and throw() must not violate the entry/exit criteria. 10031 CS->getCapturedDecl()->setNothrow(); 10032 for (int ThisCaptureLevel = 10033 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10034 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10035 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10036 // 1.2.2 OpenMP Language Terminology 10037 // Structured block - An executable statement with a single entry at the 10038 // top and a single exit at the bottom. 10039 // The point of exit cannot be a branch out of the structured block. 10040 // longjmp() and throw() must not violate the entry/exit criteria. 10041 CS->getCapturedDecl()->setNothrow(); 10042 } 10043 10044 OMPLoopDirective::HelperExprs B; 10045 // In presence of clause 'collapse' with number of loops, it will 10046 // define the nested loops number. 10047 unsigned NestedLoopCount = checkOpenMPLoop( 10048 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10049 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10050 VarsWithImplicitDSA, B); 10051 if (NestedLoopCount == 0) 10052 return StmtError(); 10053 10054 assert((CurContext->isDependentContext() || B.builtAll()) && 10055 "omp for loop exprs were not built"); 10056 10057 setFunctionHasBranchProtectedScope(); 10058 return OMPDistributeParallelForDirective::Create( 10059 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10060 DSAStack->isCancelRegion()); 10061 } 10062 10063 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10064 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10065 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10066 if (!AStmt) 10067 return StmtError(); 10068 10069 auto *CS = cast<CapturedStmt>(AStmt); 10070 // 1.2.2 OpenMP Language Terminology 10071 // Structured block - An executable statement with a single entry at the 10072 // top and a single exit at the bottom. 10073 // The point of exit cannot be a branch out of the structured block. 10074 // longjmp() and throw() must not violate the entry/exit criteria. 10075 CS->getCapturedDecl()->setNothrow(); 10076 for (int ThisCaptureLevel = 10077 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10078 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10079 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10080 // 1.2.2 OpenMP Language Terminology 10081 // Structured block - An executable statement with a single entry at the 10082 // top and a single exit at the bottom. 10083 // The point of exit cannot be a branch out of the structured block. 10084 // longjmp() and throw() must not violate the entry/exit criteria. 10085 CS->getCapturedDecl()->setNothrow(); 10086 } 10087 10088 OMPLoopDirective::HelperExprs B; 10089 // In presence of clause 'collapse' with number of loops, it will 10090 // define the nested loops number. 10091 unsigned NestedLoopCount = checkOpenMPLoop( 10092 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10093 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10094 VarsWithImplicitDSA, B); 10095 if (NestedLoopCount == 0) 10096 return StmtError(); 10097 10098 assert((CurContext->isDependentContext() || B.builtAll()) && 10099 "omp for loop exprs were not built"); 10100 10101 if (!CurContext->isDependentContext()) { 10102 // Finalize the clauses that need pre-built expressions for CodeGen. 10103 for (OMPClause *C : Clauses) { 10104 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10105 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10106 B.NumIterations, *this, CurScope, 10107 DSAStack)) 10108 return StmtError(); 10109 } 10110 } 10111 10112 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10113 return StmtError(); 10114 10115 setFunctionHasBranchProtectedScope(); 10116 return OMPDistributeParallelForSimdDirective::Create( 10117 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10118 } 10119 10120 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10121 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10122 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10123 if (!AStmt) 10124 return StmtError(); 10125 10126 auto *CS = cast<CapturedStmt>(AStmt); 10127 // 1.2.2 OpenMP Language Terminology 10128 // Structured block - An executable statement with a single entry at the 10129 // top and a single exit at the bottom. 10130 // The point of exit cannot be a branch out of the structured block. 10131 // longjmp() and throw() must not violate the entry/exit criteria. 10132 CS->getCapturedDecl()->setNothrow(); 10133 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10134 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10135 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10136 // 1.2.2 OpenMP Language Terminology 10137 // Structured block - An executable statement with a single entry at the 10138 // top and a single exit at the bottom. 10139 // The point of exit cannot be a branch out of the structured block. 10140 // longjmp() and throw() must not violate the entry/exit criteria. 10141 CS->getCapturedDecl()->setNothrow(); 10142 } 10143 10144 OMPLoopDirective::HelperExprs B; 10145 // In presence of clause 'collapse' with number of loops, it will 10146 // define the nested loops number. 10147 unsigned NestedLoopCount = 10148 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10149 nullptr /*ordered not a clause on distribute*/, CS, *this, 10150 *DSAStack, VarsWithImplicitDSA, B); 10151 if (NestedLoopCount == 0) 10152 return StmtError(); 10153 10154 assert((CurContext->isDependentContext() || B.builtAll()) && 10155 "omp for loop exprs were not built"); 10156 10157 if (!CurContext->isDependentContext()) { 10158 // Finalize the clauses that need pre-built expressions for CodeGen. 10159 for (OMPClause *C : Clauses) { 10160 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10161 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10162 B.NumIterations, *this, CurScope, 10163 DSAStack)) 10164 return StmtError(); 10165 } 10166 } 10167 10168 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10169 return StmtError(); 10170 10171 setFunctionHasBranchProtectedScope(); 10172 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10173 NestedLoopCount, Clauses, AStmt, B); 10174 } 10175 10176 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10177 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10178 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10179 if (!AStmt) 10180 return StmtError(); 10181 10182 auto *CS = cast<CapturedStmt>(AStmt); 10183 // 1.2.2 OpenMP Language Terminology 10184 // Structured block - An executable statement with a single entry at the 10185 // top and a single exit at the bottom. 10186 // The point of exit cannot be a branch out of the structured block. 10187 // longjmp() and throw() must not violate the entry/exit criteria. 10188 CS->getCapturedDecl()->setNothrow(); 10189 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10190 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10191 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10192 // 1.2.2 OpenMP Language Terminology 10193 // Structured block - An executable statement with a single entry at the 10194 // top and a single exit at the bottom. 10195 // The point of exit cannot be a branch out of the structured block. 10196 // longjmp() and throw() must not violate the entry/exit criteria. 10197 CS->getCapturedDecl()->setNothrow(); 10198 } 10199 10200 OMPLoopDirective::HelperExprs B; 10201 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10202 // define the nested loops number. 10203 unsigned NestedLoopCount = checkOpenMPLoop( 10204 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10205 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10206 VarsWithImplicitDSA, B); 10207 if (NestedLoopCount == 0) 10208 return StmtError(); 10209 10210 assert((CurContext->isDependentContext() || B.builtAll()) && 10211 "omp target parallel for simd loop exprs were not built"); 10212 10213 if (!CurContext->isDependentContext()) { 10214 // Finalize the clauses that need pre-built expressions for CodeGen. 10215 for (OMPClause *C : Clauses) { 10216 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10217 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10218 B.NumIterations, *this, CurScope, 10219 DSAStack)) 10220 return StmtError(); 10221 } 10222 } 10223 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10224 return StmtError(); 10225 10226 setFunctionHasBranchProtectedScope(); 10227 return OMPTargetParallelForSimdDirective::Create( 10228 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10229 } 10230 10231 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10232 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10233 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10234 if (!AStmt) 10235 return StmtError(); 10236 10237 auto *CS = cast<CapturedStmt>(AStmt); 10238 // 1.2.2 OpenMP Language Terminology 10239 // Structured block - An executable statement with a single entry at the 10240 // top and a single exit at the bottom. 10241 // The point of exit cannot be a branch out of the structured block. 10242 // longjmp() and throw() must not violate the entry/exit criteria. 10243 CS->getCapturedDecl()->setNothrow(); 10244 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10245 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10246 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10247 // 1.2.2 OpenMP Language Terminology 10248 // Structured block - An executable statement with a single entry at the 10249 // top and a single exit at the bottom. 10250 // The point of exit cannot be a branch out of the structured block. 10251 // longjmp() and throw() must not violate the entry/exit criteria. 10252 CS->getCapturedDecl()->setNothrow(); 10253 } 10254 10255 OMPLoopDirective::HelperExprs B; 10256 // In presence of clause 'collapse' with number of loops, it will define the 10257 // nested loops number. 10258 unsigned NestedLoopCount = 10259 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10260 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10261 VarsWithImplicitDSA, B); 10262 if (NestedLoopCount == 0) 10263 return StmtError(); 10264 10265 assert((CurContext->isDependentContext() || B.builtAll()) && 10266 "omp target simd loop exprs were not built"); 10267 10268 if (!CurContext->isDependentContext()) { 10269 // Finalize the clauses that need pre-built expressions for CodeGen. 10270 for (OMPClause *C : Clauses) { 10271 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10272 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10273 B.NumIterations, *this, CurScope, 10274 DSAStack)) 10275 return StmtError(); 10276 } 10277 } 10278 10279 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10280 return StmtError(); 10281 10282 setFunctionHasBranchProtectedScope(); 10283 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10284 NestedLoopCount, Clauses, AStmt, B); 10285 } 10286 10287 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10288 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10289 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10290 if (!AStmt) 10291 return StmtError(); 10292 10293 auto *CS = cast<CapturedStmt>(AStmt); 10294 // 1.2.2 OpenMP Language Terminology 10295 // Structured block - An executable statement with a single entry at the 10296 // top and a single exit at the bottom. 10297 // The point of exit cannot be a branch out of the structured block. 10298 // longjmp() and throw() must not violate the entry/exit criteria. 10299 CS->getCapturedDecl()->setNothrow(); 10300 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10301 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10302 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10303 // 1.2.2 OpenMP Language Terminology 10304 // Structured block - An executable statement with a single entry at the 10305 // top and a single exit at the bottom. 10306 // The point of exit cannot be a branch out of the structured block. 10307 // longjmp() and throw() must not violate the entry/exit criteria. 10308 CS->getCapturedDecl()->setNothrow(); 10309 } 10310 10311 OMPLoopDirective::HelperExprs B; 10312 // In presence of clause 'collapse' with number of loops, it will 10313 // define the nested loops number. 10314 unsigned NestedLoopCount = 10315 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10316 nullptr /*ordered not a clause on distribute*/, CS, *this, 10317 *DSAStack, VarsWithImplicitDSA, B); 10318 if (NestedLoopCount == 0) 10319 return StmtError(); 10320 10321 assert((CurContext->isDependentContext() || B.builtAll()) && 10322 "omp teams distribute loop exprs were not built"); 10323 10324 setFunctionHasBranchProtectedScope(); 10325 10326 DSAStack->setParentTeamsRegionLoc(StartLoc); 10327 10328 return OMPTeamsDistributeDirective::Create( 10329 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10330 } 10331 10332 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10333 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10334 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10335 if (!AStmt) 10336 return StmtError(); 10337 10338 auto *CS = cast<CapturedStmt>(AStmt); 10339 // 1.2.2 OpenMP Language Terminology 10340 // Structured block - An executable statement with a single entry at the 10341 // top and a single exit at the bottom. 10342 // The point of exit cannot be a branch out of the structured block. 10343 // longjmp() and throw() must not violate the entry/exit criteria. 10344 CS->getCapturedDecl()->setNothrow(); 10345 for (int ThisCaptureLevel = 10346 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10347 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10348 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10349 // 1.2.2 OpenMP Language Terminology 10350 // Structured block - An executable statement with a single entry at the 10351 // top and a single exit at the bottom. 10352 // The point of exit cannot be a branch out of the structured block. 10353 // longjmp() and throw() must not violate the entry/exit criteria. 10354 CS->getCapturedDecl()->setNothrow(); 10355 } 10356 10357 OMPLoopDirective::HelperExprs B; 10358 // In presence of clause 'collapse' with number of loops, it will 10359 // define the nested loops number. 10360 unsigned NestedLoopCount = checkOpenMPLoop( 10361 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10362 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10363 VarsWithImplicitDSA, B); 10364 10365 if (NestedLoopCount == 0) 10366 return StmtError(); 10367 10368 assert((CurContext->isDependentContext() || B.builtAll()) && 10369 "omp teams distribute simd loop exprs were not built"); 10370 10371 if (!CurContext->isDependentContext()) { 10372 // Finalize the clauses that need pre-built expressions for CodeGen. 10373 for (OMPClause *C : Clauses) { 10374 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10375 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10376 B.NumIterations, *this, CurScope, 10377 DSAStack)) 10378 return StmtError(); 10379 } 10380 } 10381 10382 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10383 return StmtError(); 10384 10385 setFunctionHasBranchProtectedScope(); 10386 10387 DSAStack->setParentTeamsRegionLoc(StartLoc); 10388 10389 return OMPTeamsDistributeSimdDirective::Create( 10390 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10391 } 10392 10393 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10394 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10395 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10396 if (!AStmt) 10397 return StmtError(); 10398 10399 auto *CS = cast<CapturedStmt>(AStmt); 10400 // 1.2.2 OpenMP Language Terminology 10401 // Structured block - An executable statement with a single entry at the 10402 // top and a single exit at the bottom. 10403 // The point of exit cannot be a branch out of the structured block. 10404 // longjmp() and throw() must not violate the entry/exit criteria. 10405 CS->getCapturedDecl()->setNothrow(); 10406 10407 for (int ThisCaptureLevel = 10408 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10409 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10410 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10411 // 1.2.2 OpenMP Language Terminology 10412 // Structured block - An executable statement with a single entry at the 10413 // top and a single exit at the bottom. 10414 // The point of exit cannot be a branch out of the structured block. 10415 // longjmp() and throw() must not violate the entry/exit criteria. 10416 CS->getCapturedDecl()->setNothrow(); 10417 } 10418 10419 OMPLoopDirective::HelperExprs B; 10420 // In presence of clause 'collapse' with number of loops, it will 10421 // define the nested loops number. 10422 unsigned NestedLoopCount = checkOpenMPLoop( 10423 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10424 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10425 VarsWithImplicitDSA, B); 10426 10427 if (NestedLoopCount == 0) 10428 return StmtError(); 10429 10430 assert((CurContext->isDependentContext() || B.builtAll()) && 10431 "omp for loop exprs were not built"); 10432 10433 if (!CurContext->isDependentContext()) { 10434 // Finalize the clauses that need pre-built expressions for CodeGen. 10435 for (OMPClause *C : Clauses) { 10436 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10437 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10438 B.NumIterations, *this, CurScope, 10439 DSAStack)) 10440 return StmtError(); 10441 } 10442 } 10443 10444 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10445 return StmtError(); 10446 10447 setFunctionHasBranchProtectedScope(); 10448 10449 DSAStack->setParentTeamsRegionLoc(StartLoc); 10450 10451 return OMPTeamsDistributeParallelForSimdDirective::Create( 10452 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10453 } 10454 10455 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10456 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10457 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10458 if (!AStmt) 10459 return StmtError(); 10460 10461 auto *CS = cast<CapturedStmt>(AStmt); 10462 // 1.2.2 OpenMP Language Terminology 10463 // Structured block - An executable statement with a single entry at the 10464 // top and a single exit at the bottom. 10465 // The point of exit cannot be a branch out of the structured block. 10466 // longjmp() and throw() must not violate the entry/exit criteria. 10467 CS->getCapturedDecl()->setNothrow(); 10468 10469 for (int ThisCaptureLevel = 10470 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10471 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10472 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10473 // 1.2.2 OpenMP Language Terminology 10474 // Structured block - An executable statement with a single entry at the 10475 // top and a single exit at the bottom. 10476 // The point of exit cannot be a branch out of the structured block. 10477 // longjmp() and throw() must not violate the entry/exit criteria. 10478 CS->getCapturedDecl()->setNothrow(); 10479 } 10480 10481 OMPLoopDirective::HelperExprs B; 10482 // In presence of clause 'collapse' with number of loops, it will 10483 // define the nested loops number. 10484 unsigned NestedLoopCount = checkOpenMPLoop( 10485 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10486 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10487 VarsWithImplicitDSA, B); 10488 10489 if (NestedLoopCount == 0) 10490 return StmtError(); 10491 10492 assert((CurContext->isDependentContext() || B.builtAll()) && 10493 "omp for loop exprs were not built"); 10494 10495 setFunctionHasBranchProtectedScope(); 10496 10497 DSAStack->setParentTeamsRegionLoc(StartLoc); 10498 10499 return OMPTeamsDistributeParallelForDirective::Create( 10500 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10501 DSAStack->isCancelRegion()); 10502 } 10503 10504 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10505 Stmt *AStmt, 10506 SourceLocation StartLoc, 10507 SourceLocation EndLoc) { 10508 if (!AStmt) 10509 return StmtError(); 10510 10511 auto *CS = cast<CapturedStmt>(AStmt); 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 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10520 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10521 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10522 // 1.2.2 OpenMP Language Terminology 10523 // Structured block - An executable statement with a single entry at the 10524 // top and a single exit at the bottom. 10525 // The point of exit cannot be a branch out of the structured block. 10526 // longjmp() and throw() must not violate the entry/exit criteria. 10527 CS->getCapturedDecl()->setNothrow(); 10528 } 10529 setFunctionHasBranchProtectedScope(); 10530 10531 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10532 AStmt); 10533 } 10534 10535 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10536 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10537 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10538 if (!AStmt) 10539 return StmtError(); 10540 10541 auto *CS = cast<CapturedStmt>(AStmt); 10542 // 1.2.2 OpenMP Language Terminology 10543 // Structured block - An executable statement with a single entry at the 10544 // top and a single exit at the bottom. 10545 // The point of exit cannot be a branch out of the structured block. 10546 // longjmp() and throw() must not violate the entry/exit criteria. 10547 CS->getCapturedDecl()->setNothrow(); 10548 for (int ThisCaptureLevel = 10549 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10550 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10551 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10552 // 1.2.2 OpenMP Language Terminology 10553 // Structured block - An executable statement with a single entry at the 10554 // top and a single exit at the bottom. 10555 // The point of exit cannot be a branch out of the structured block. 10556 // longjmp() and throw() must not violate the entry/exit criteria. 10557 CS->getCapturedDecl()->setNothrow(); 10558 } 10559 10560 OMPLoopDirective::HelperExprs B; 10561 // In presence of clause 'collapse' with number of loops, it will 10562 // define the nested loops number. 10563 unsigned NestedLoopCount = checkOpenMPLoop( 10564 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10565 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10566 VarsWithImplicitDSA, B); 10567 if (NestedLoopCount == 0) 10568 return StmtError(); 10569 10570 assert((CurContext->isDependentContext() || B.builtAll()) && 10571 "omp target teams distribute loop exprs were not built"); 10572 10573 setFunctionHasBranchProtectedScope(); 10574 return OMPTargetTeamsDistributeDirective::Create( 10575 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10576 } 10577 10578 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10579 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10580 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10581 if (!AStmt) 10582 return StmtError(); 10583 10584 auto *CS = cast<CapturedStmt>(AStmt); 10585 // 1.2.2 OpenMP Language Terminology 10586 // Structured block - An executable statement with a single entry at the 10587 // top and a single exit at the bottom. 10588 // The point of exit cannot be a branch out of the structured block. 10589 // longjmp() and throw() must not violate the entry/exit criteria. 10590 CS->getCapturedDecl()->setNothrow(); 10591 for (int ThisCaptureLevel = 10592 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10593 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10594 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10595 // 1.2.2 OpenMP Language Terminology 10596 // Structured block - An executable statement with a single entry at the 10597 // top and a single exit at the bottom. 10598 // The point of exit cannot be a branch out of the structured block. 10599 // longjmp() and throw() must not violate the entry/exit criteria. 10600 CS->getCapturedDecl()->setNothrow(); 10601 } 10602 10603 OMPLoopDirective::HelperExprs B; 10604 // In presence of clause 'collapse' with number of loops, it will 10605 // define the nested loops number. 10606 unsigned NestedLoopCount = checkOpenMPLoop( 10607 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10608 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10609 VarsWithImplicitDSA, B); 10610 if (NestedLoopCount == 0) 10611 return StmtError(); 10612 10613 assert((CurContext->isDependentContext() || B.builtAll()) && 10614 "omp target teams distribute parallel for loop exprs were not built"); 10615 10616 if (!CurContext->isDependentContext()) { 10617 // Finalize the clauses that need pre-built expressions for CodeGen. 10618 for (OMPClause *C : Clauses) { 10619 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10620 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10621 B.NumIterations, *this, CurScope, 10622 DSAStack)) 10623 return StmtError(); 10624 } 10625 } 10626 10627 setFunctionHasBranchProtectedScope(); 10628 return OMPTargetTeamsDistributeParallelForDirective::Create( 10629 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10630 DSAStack->isCancelRegion()); 10631 } 10632 10633 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10634 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10635 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10636 if (!AStmt) 10637 return StmtError(); 10638 10639 auto *CS = cast<CapturedStmt>(AStmt); 10640 // 1.2.2 OpenMP Language Terminology 10641 // Structured block - An executable statement with a single entry at the 10642 // top and a single exit at the bottom. 10643 // The point of exit cannot be a branch out of the structured block. 10644 // longjmp() and throw() must not violate the entry/exit criteria. 10645 CS->getCapturedDecl()->setNothrow(); 10646 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10647 OMPD_target_teams_distribute_parallel_for_simd); 10648 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10649 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10650 // 1.2.2 OpenMP Language Terminology 10651 // Structured block - An executable statement with a single entry at the 10652 // top and a single exit at the bottom. 10653 // The point of exit cannot be a branch out of the structured block. 10654 // longjmp() and throw() must not violate the entry/exit criteria. 10655 CS->getCapturedDecl()->setNothrow(); 10656 } 10657 10658 OMPLoopDirective::HelperExprs B; 10659 // In presence of clause 'collapse' with number of loops, it will 10660 // define the nested loops number. 10661 unsigned NestedLoopCount = 10662 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10663 getCollapseNumberExpr(Clauses), 10664 nullptr /*ordered not a clause on distribute*/, CS, *this, 10665 *DSAStack, VarsWithImplicitDSA, B); 10666 if (NestedLoopCount == 0) 10667 return StmtError(); 10668 10669 assert((CurContext->isDependentContext() || B.builtAll()) && 10670 "omp target teams distribute parallel for simd loop exprs were not " 10671 "built"); 10672 10673 if (!CurContext->isDependentContext()) { 10674 // Finalize the clauses that need pre-built expressions for CodeGen. 10675 for (OMPClause *C : Clauses) { 10676 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10677 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10678 B.NumIterations, *this, CurScope, 10679 DSAStack)) 10680 return StmtError(); 10681 } 10682 } 10683 10684 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10685 return StmtError(); 10686 10687 setFunctionHasBranchProtectedScope(); 10688 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10689 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10690 } 10691 10692 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10693 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10694 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10695 if (!AStmt) 10696 return StmtError(); 10697 10698 auto *CS = cast<CapturedStmt>(AStmt); 10699 // 1.2.2 OpenMP Language Terminology 10700 // Structured block - An executable statement with a single entry at the 10701 // top and a single exit at the bottom. 10702 // The point of exit cannot be a branch out of the structured block. 10703 // longjmp() and throw() must not violate the entry/exit criteria. 10704 CS->getCapturedDecl()->setNothrow(); 10705 for (int ThisCaptureLevel = 10706 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10707 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10708 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10709 // 1.2.2 OpenMP Language Terminology 10710 // Structured block - An executable statement with a single entry at the 10711 // top and a single exit at the bottom. 10712 // The point of exit cannot be a branch out of the structured block. 10713 // longjmp() and throw() must not violate the entry/exit criteria. 10714 CS->getCapturedDecl()->setNothrow(); 10715 } 10716 10717 OMPLoopDirective::HelperExprs B; 10718 // In presence of clause 'collapse' with number of loops, it will 10719 // define the nested loops number. 10720 unsigned NestedLoopCount = checkOpenMPLoop( 10721 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10722 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10723 VarsWithImplicitDSA, B); 10724 if (NestedLoopCount == 0) 10725 return StmtError(); 10726 10727 assert((CurContext->isDependentContext() || B.builtAll()) && 10728 "omp target teams distribute simd loop exprs were not built"); 10729 10730 if (!CurContext->isDependentContext()) { 10731 // Finalize the clauses that need pre-built expressions for CodeGen. 10732 for (OMPClause *C : Clauses) { 10733 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10734 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10735 B.NumIterations, *this, CurScope, 10736 DSAStack)) 10737 return StmtError(); 10738 } 10739 } 10740 10741 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10742 return StmtError(); 10743 10744 setFunctionHasBranchProtectedScope(); 10745 return OMPTargetTeamsDistributeSimdDirective::Create( 10746 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10747 } 10748 10749 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10750 SourceLocation StartLoc, 10751 SourceLocation LParenLoc, 10752 SourceLocation EndLoc) { 10753 OMPClause *Res = nullptr; 10754 switch (Kind) { 10755 case OMPC_final: 10756 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10757 break; 10758 case OMPC_num_threads: 10759 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10760 break; 10761 case OMPC_safelen: 10762 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10763 break; 10764 case OMPC_simdlen: 10765 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10766 break; 10767 case OMPC_allocator: 10768 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10769 break; 10770 case OMPC_collapse: 10771 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10772 break; 10773 case OMPC_ordered: 10774 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10775 break; 10776 case OMPC_device: 10777 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10778 break; 10779 case OMPC_num_teams: 10780 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10781 break; 10782 case OMPC_thread_limit: 10783 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10784 break; 10785 case OMPC_priority: 10786 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10787 break; 10788 case OMPC_grainsize: 10789 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10790 break; 10791 case OMPC_num_tasks: 10792 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10793 break; 10794 case OMPC_hint: 10795 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10796 break; 10797 case OMPC_if: 10798 case OMPC_default: 10799 case OMPC_proc_bind: 10800 case OMPC_schedule: 10801 case OMPC_private: 10802 case OMPC_firstprivate: 10803 case OMPC_lastprivate: 10804 case OMPC_shared: 10805 case OMPC_reduction: 10806 case OMPC_task_reduction: 10807 case OMPC_in_reduction: 10808 case OMPC_linear: 10809 case OMPC_aligned: 10810 case OMPC_copyin: 10811 case OMPC_copyprivate: 10812 case OMPC_nowait: 10813 case OMPC_untied: 10814 case OMPC_mergeable: 10815 case OMPC_threadprivate: 10816 case OMPC_allocate: 10817 case OMPC_flush: 10818 case OMPC_read: 10819 case OMPC_write: 10820 case OMPC_update: 10821 case OMPC_capture: 10822 case OMPC_seq_cst: 10823 case OMPC_acq_rel: 10824 case OMPC_acquire: 10825 case OMPC_release: 10826 case OMPC_relaxed: 10827 case OMPC_depend: 10828 case OMPC_threads: 10829 case OMPC_simd: 10830 case OMPC_map: 10831 case OMPC_nogroup: 10832 case OMPC_dist_schedule: 10833 case OMPC_defaultmap: 10834 case OMPC_unknown: 10835 case OMPC_uniform: 10836 case OMPC_to: 10837 case OMPC_from: 10838 case OMPC_use_device_ptr: 10839 case OMPC_is_device_ptr: 10840 case OMPC_unified_address: 10841 case OMPC_unified_shared_memory: 10842 case OMPC_reverse_offload: 10843 case OMPC_dynamic_allocators: 10844 case OMPC_atomic_default_mem_order: 10845 case OMPC_device_type: 10846 case OMPC_match: 10847 case OMPC_nontemporal: 10848 case OMPC_order: 10849 llvm_unreachable("Clause is not allowed."); 10850 } 10851 return Res; 10852 } 10853 10854 // An OpenMP directive such as 'target parallel' has two captured regions: 10855 // for the 'target' and 'parallel' respectively. This function returns 10856 // the region in which to capture expressions associated with a clause. 10857 // A return value of OMPD_unknown signifies that the expression should not 10858 // be captured. 10859 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10860 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 10861 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10862 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10863 switch (CKind) { 10864 case OMPC_if: 10865 switch (DKind) { 10866 case OMPD_target_parallel_for_simd: 10867 if (OpenMPVersion >= 50 && 10868 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10869 CaptureRegion = OMPD_parallel; 10870 break; 10871 } 10872 LLVM_FALLTHROUGH; 10873 case OMPD_target_parallel: 10874 case OMPD_target_parallel_for: 10875 // If this clause applies to the nested 'parallel' region, capture within 10876 // the 'target' region, otherwise do not capture. 10877 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10878 CaptureRegion = OMPD_target; 10879 break; 10880 case OMPD_target_teams_distribute_parallel_for_simd: 10881 if (OpenMPVersion >= 50 && 10882 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10883 CaptureRegion = OMPD_parallel; 10884 break; 10885 } 10886 LLVM_FALLTHROUGH; 10887 case OMPD_target_teams_distribute_parallel_for: 10888 // If this clause applies to the nested 'parallel' region, capture within 10889 // the 'teams' region, otherwise do not capture. 10890 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10891 CaptureRegion = OMPD_teams; 10892 break; 10893 case OMPD_teams_distribute_parallel_for_simd: 10894 if (OpenMPVersion >= 50 && 10895 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10896 CaptureRegion = OMPD_parallel; 10897 break; 10898 } 10899 LLVM_FALLTHROUGH; 10900 case OMPD_teams_distribute_parallel_for: 10901 CaptureRegion = OMPD_teams; 10902 break; 10903 case OMPD_target_update: 10904 case OMPD_target_enter_data: 10905 case OMPD_target_exit_data: 10906 CaptureRegion = OMPD_task; 10907 break; 10908 case OMPD_parallel_master_taskloop: 10909 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10910 CaptureRegion = OMPD_parallel; 10911 break; 10912 case OMPD_parallel_master_taskloop_simd: 10913 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 10914 NameModifier == OMPD_taskloop) { 10915 CaptureRegion = OMPD_parallel; 10916 break; 10917 } 10918 if (OpenMPVersion <= 45) 10919 break; 10920 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10921 CaptureRegion = OMPD_taskloop; 10922 break; 10923 case OMPD_parallel_for_simd: 10924 if (OpenMPVersion <= 45) 10925 break; 10926 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10927 CaptureRegion = OMPD_parallel; 10928 break; 10929 case OMPD_taskloop_simd: 10930 case OMPD_master_taskloop_simd: 10931 if (OpenMPVersion <= 45) 10932 break; 10933 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10934 CaptureRegion = OMPD_taskloop; 10935 break; 10936 case OMPD_distribute_parallel_for_simd: 10937 if (OpenMPVersion <= 45) 10938 break; 10939 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10940 CaptureRegion = OMPD_parallel; 10941 break; 10942 case OMPD_target_simd: 10943 if (OpenMPVersion >= 50 && 10944 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10945 CaptureRegion = OMPD_target; 10946 break; 10947 case OMPD_teams_distribute_simd: 10948 case OMPD_target_teams_distribute_simd: 10949 if (OpenMPVersion >= 50 && 10950 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10951 CaptureRegion = OMPD_teams; 10952 break; 10953 case OMPD_cancel: 10954 case OMPD_parallel: 10955 case OMPD_parallel_master: 10956 case OMPD_parallel_sections: 10957 case OMPD_parallel_for: 10958 case OMPD_target: 10959 case OMPD_target_teams: 10960 case OMPD_target_teams_distribute: 10961 case OMPD_distribute_parallel_for: 10962 case OMPD_task: 10963 case OMPD_taskloop: 10964 case OMPD_master_taskloop: 10965 case OMPD_target_data: 10966 case OMPD_simd: 10967 case OMPD_for_simd: 10968 case OMPD_distribute_simd: 10969 // Do not capture if-clause expressions. 10970 break; 10971 case OMPD_threadprivate: 10972 case OMPD_allocate: 10973 case OMPD_taskyield: 10974 case OMPD_barrier: 10975 case OMPD_taskwait: 10976 case OMPD_cancellation_point: 10977 case OMPD_flush: 10978 case OMPD_declare_reduction: 10979 case OMPD_declare_mapper: 10980 case OMPD_declare_simd: 10981 case OMPD_declare_variant: 10982 case OMPD_declare_target: 10983 case OMPD_end_declare_target: 10984 case OMPD_teams: 10985 case OMPD_for: 10986 case OMPD_sections: 10987 case OMPD_section: 10988 case OMPD_single: 10989 case OMPD_master: 10990 case OMPD_critical: 10991 case OMPD_taskgroup: 10992 case OMPD_distribute: 10993 case OMPD_ordered: 10994 case OMPD_atomic: 10995 case OMPD_teams_distribute: 10996 case OMPD_requires: 10997 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10998 case OMPD_unknown: 10999 llvm_unreachable("Unknown OpenMP directive"); 11000 } 11001 break; 11002 case OMPC_num_threads: 11003 switch (DKind) { 11004 case OMPD_target_parallel: 11005 case OMPD_target_parallel_for: 11006 case OMPD_target_parallel_for_simd: 11007 CaptureRegion = OMPD_target; 11008 break; 11009 case OMPD_teams_distribute_parallel_for: 11010 case OMPD_teams_distribute_parallel_for_simd: 11011 case OMPD_target_teams_distribute_parallel_for: 11012 case OMPD_target_teams_distribute_parallel_for_simd: 11013 CaptureRegion = OMPD_teams; 11014 break; 11015 case OMPD_parallel: 11016 case OMPD_parallel_master: 11017 case OMPD_parallel_sections: 11018 case OMPD_parallel_for: 11019 case OMPD_parallel_for_simd: 11020 case OMPD_distribute_parallel_for: 11021 case OMPD_distribute_parallel_for_simd: 11022 case OMPD_parallel_master_taskloop: 11023 case OMPD_parallel_master_taskloop_simd: 11024 // Do not capture num_threads-clause expressions. 11025 break; 11026 case OMPD_target_data: 11027 case OMPD_target_enter_data: 11028 case OMPD_target_exit_data: 11029 case OMPD_target_update: 11030 case OMPD_target: 11031 case OMPD_target_simd: 11032 case OMPD_target_teams: 11033 case OMPD_target_teams_distribute: 11034 case OMPD_target_teams_distribute_simd: 11035 case OMPD_cancel: 11036 case OMPD_task: 11037 case OMPD_taskloop: 11038 case OMPD_taskloop_simd: 11039 case OMPD_master_taskloop: 11040 case OMPD_master_taskloop_simd: 11041 case OMPD_threadprivate: 11042 case OMPD_allocate: 11043 case OMPD_taskyield: 11044 case OMPD_barrier: 11045 case OMPD_taskwait: 11046 case OMPD_cancellation_point: 11047 case OMPD_flush: 11048 case OMPD_declare_reduction: 11049 case OMPD_declare_mapper: 11050 case OMPD_declare_simd: 11051 case OMPD_declare_variant: 11052 case OMPD_declare_target: 11053 case OMPD_end_declare_target: 11054 case OMPD_teams: 11055 case OMPD_simd: 11056 case OMPD_for: 11057 case OMPD_for_simd: 11058 case OMPD_sections: 11059 case OMPD_section: 11060 case OMPD_single: 11061 case OMPD_master: 11062 case OMPD_critical: 11063 case OMPD_taskgroup: 11064 case OMPD_distribute: 11065 case OMPD_ordered: 11066 case OMPD_atomic: 11067 case OMPD_distribute_simd: 11068 case OMPD_teams_distribute: 11069 case OMPD_teams_distribute_simd: 11070 case OMPD_requires: 11071 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11072 case OMPD_unknown: 11073 llvm_unreachable("Unknown OpenMP directive"); 11074 } 11075 break; 11076 case OMPC_num_teams: 11077 switch (DKind) { 11078 case OMPD_target_teams: 11079 case OMPD_target_teams_distribute: 11080 case OMPD_target_teams_distribute_simd: 11081 case OMPD_target_teams_distribute_parallel_for: 11082 case OMPD_target_teams_distribute_parallel_for_simd: 11083 CaptureRegion = OMPD_target; 11084 break; 11085 case OMPD_teams_distribute_parallel_for: 11086 case OMPD_teams_distribute_parallel_for_simd: 11087 case OMPD_teams: 11088 case OMPD_teams_distribute: 11089 case OMPD_teams_distribute_simd: 11090 // Do not capture num_teams-clause expressions. 11091 break; 11092 case OMPD_distribute_parallel_for: 11093 case OMPD_distribute_parallel_for_simd: 11094 case OMPD_task: 11095 case OMPD_taskloop: 11096 case OMPD_taskloop_simd: 11097 case OMPD_master_taskloop: 11098 case OMPD_master_taskloop_simd: 11099 case OMPD_parallel_master_taskloop: 11100 case OMPD_parallel_master_taskloop_simd: 11101 case OMPD_target_data: 11102 case OMPD_target_enter_data: 11103 case OMPD_target_exit_data: 11104 case OMPD_target_update: 11105 case OMPD_cancel: 11106 case OMPD_parallel: 11107 case OMPD_parallel_master: 11108 case OMPD_parallel_sections: 11109 case OMPD_parallel_for: 11110 case OMPD_parallel_for_simd: 11111 case OMPD_target: 11112 case OMPD_target_simd: 11113 case OMPD_target_parallel: 11114 case OMPD_target_parallel_for: 11115 case OMPD_target_parallel_for_simd: 11116 case OMPD_threadprivate: 11117 case OMPD_allocate: 11118 case OMPD_taskyield: 11119 case OMPD_barrier: 11120 case OMPD_taskwait: 11121 case OMPD_cancellation_point: 11122 case OMPD_flush: 11123 case OMPD_declare_reduction: 11124 case OMPD_declare_mapper: 11125 case OMPD_declare_simd: 11126 case OMPD_declare_variant: 11127 case OMPD_declare_target: 11128 case OMPD_end_declare_target: 11129 case OMPD_simd: 11130 case OMPD_for: 11131 case OMPD_for_simd: 11132 case OMPD_sections: 11133 case OMPD_section: 11134 case OMPD_single: 11135 case OMPD_master: 11136 case OMPD_critical: 11137 case OMPD_taskgroup: 11138 case OMPD_distribute: 11139 case OMPD_ordered: 11140 case OMPD_atomic: 11141 case OMPD_distribute_simd: 11142 case OMPD_requires: 11143 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11144 case OMPD_unknown: 11145 llvm_unreachable("Unknown OpenMP directive"); 11146 } 11147 break; 11148 case OMPC_thread_limit: 11149 switch (DKind) { 11150 case OMPD_target_teams: 11151 case OMPD_target_teams_distribute: 11152 case OMPD_target_teams_distribute_simd: 11153 case OMPD_target_teams_distribute_parallel_for: 11154 case OMPD_target_teams_distribute_parallel_for_simd: 11155 CaptureRegion = OMPD_target; 11156 break; 11157 case OMPD_teams_distribute_parallel_for: 11158 case OMPD_teams_distribute_parallel_for_simd: 11159 case OMPD_teams: 11160 case OMPD_teams_distribute: 11161 case OMPD_teams_distribute_simd: 11162 // Do not capture thread_limit-clause expressions. 11163 break; 11164 case OMPD_distribute_parallel_for: 11165 case OMPD_distribute_parallel_for_simd: 11166 case OMPD_task: 11167 case OMPD_taskloop: 11168 case OMPD_taskloop_simd: 11169 case OMPD_master_taskloop: 11170 case OMPD_master_taskloop_simd: 11171 case OMPD_parallel_master_taskloop: 11172 case OMPD_parallel_master_taskloop_simd: 11173 case OMPD_target_data: 11174 case OMPD_target_enter_data: 11175 case OMPD_target_exit_data: 11176 case OMPD_target_update: 11177 case OMPD_cancel: 11178 case OMPD_parallel: 11179 case OMPD_parallel_master: 11180 case OMPD_parallel_sections: 11181 case OMPD_parallel_for: 11182 case OMPD_parallel_for_simd: 11183 case OMPD_target: 11184 case OMPD_target_simd: 11185 case OMPD_target_parallel: 11186 case OMPD_target_parallel_for: 11187 case OMPD_target_parallel_for_simd: 11188 case OMPD_threadprivate: 11189 case OMPD_allocate: 11190 case OMPD_taskyield: 11191 case OMPD_barrier: 11192 case OMPD_taskwait: 11193 case OMPD_cancellation_point: 11194 case OMPD_flush: 11195 case OMPD_declare_reduction: 11196 case OMPD_declare_mapper: 11197 case OMPD_declare_simd: 11198 case OMPD_declare_variant: 11199 case OMPD_declare_target: 11200 case OMPD_end_declare_target: 11201 case OMPD_simd: 11202 case OMPD_for: 11203 case OMPD_for_simd: 11204 case OMPD_sections: 11205 case OMPD_section: 11206 case OMPD_single: 11207 case OMPD_master: 11208 case OMPD_critical: 11209 case OMPD_taskgroup: 11210 case OMPD_distribute: 11211 case OMPD_ordered: 11212 case OMPD_atomic: 11213 case OMPD_distribute_simd: 11214 case OMPD_requires: 11215 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11216 case OMPD_unknown: 11217 llvm_unreachable("Unknown OpenMP directive"); 11218 } 11219 break; 11220 case OMPC_schedule: 11221 switch (DKind) { 11222 case OMPD_parallel_for: 11223 case OMPD_parallel_for_simd: 11224 case OMPD_distribute_parallel_for: 11225 case OMPD_distribute_parallel_for_simd: 11226 case OMPD_teams_distribute_parallel_for: 11227 case OMPD_teams_distribute_parallel_for_simd: 11228 case OMPD_target_parallel_for: 11229 case OMPD_target_parallel_for_simd: 11230 case OMPD_target_teams_distribute_parallel_for: 11231 case OMPD_target_teams_distribute_parallel_for_simd: 11232 CaptureRegion = OMPD_parallel; 11233 break; 11234 case OMPD_for: 11235 case OMPD_for_simd: 11236 // Do not capture schedule-clause expressions. 11237 break; 11238 case OMPD_task: 11239 case OMPD_taskloop: 11240 case OMPD_taskloop_simd: 11241 case OMPD_master_taskloop: 11242 case OMPD_master_taskloop_simd: 11243 case OMPD_parallel_master_taskloop: 11244 case OMPD_parallel_master_taskloop_simd: 11245 case OMPD_target_data: 11246 case OMPD_target_enter_data: 11247 case OMPD_target_exit_data: 11248 case OMPD_target_update: 11249 case OMPD_teams: 11250 case OMPD_teams_distribute: 11251 case OMPD_teams_distribute_simd: 11252 case OMPD_target_teams_distribute: 11253 case OMPD_target_teams_distribute_simd: 11254 case OMPD_target: 11255 case OMPD_target_simd: 11256 case OMPD_target_parallel: 11257 case OMPD_cancel: 11258 case OMPD_parallel: 11259 case OMPD_parallel_master: 11260 case OMPD_parallel_sections: 11261 case OMPD_threadprivate: 11262 case OMPD_allocate: 11263 case OMPD_taskyield: 11264 case OMPD_barrier: 11265 case OMPD_taskwait: 11266 case OMPD_cancellation_point: 11267 case OMPD_flush: 11268 case OMPD_declare_reduction: 11269 case OMPD_declare_mapper: 11270 case OMPD_declare_simd: 11271 case OMPD_declare_variant: 11272 case OMPD_declare_target: 11273 case OMPD_end_declare_target: 11274 case OMPD_simd: 11275 case OMPD_sections: 11276 case OMPD_section: 11277 case OMPD_single: 11278 case OMPD_master: 11279 case OMPD_critical: 11280 case OMPD_taskgroup: 11281 case OMPD_distribute: 11282 case OMPD_ordered: 11283 case OMPD_atomic: 11284 case OMPD_distribute_simd: 11285 case OMPD_target_teams: 11286 case OMPD_requires: 11287 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11288 case OMPD_unknown: 11289 llvm_unreachable("Unknown OpenMP directive"); 11290 } 11291 break; 11292 case OMPC_dist_schedule: 11293 switch (DKind) { 11294 case OMPD_teams_distribute_parallel_for: 11295 case OMPD_teams_distribute_parallel_for_simd: 11296 case OMPD_teams_distribute: 11297 case OMPD_teams_distribute_simd: 11298 case OMPD_target_teams_distribute_parallel_for: 11299 case OMPD_target_teams_distribute_parallel_for_simd: 11300 case OMPD_target_teams_distribute: 11301 case OMPD_target_teams_distribute_simd: 11302 CaptureRegion = OMPD_teams; 11303 break; 11304 case OMPD_distribute_parallel_for: 11305 case OMPD_distribute_parallel_for_simd: 11306 case OMPD_distribute: 11307 case OMPD_distribute_simd: 11308 // Do not capture thread_limit-clause expressions. 11309 break; 11310 case OMPD_parallel_for: 11311 case OMPD_parallel_for_simd: 11312 case OMPD_target_parallel_for_simd: 11313 case OMPD_target_parallel_for: 11314 case OMPD_task: 11315 case OMPD_taskloop: 11316 case OMPD_taskloop_simd: 11317 case OMPD_master_taskloop: 11318 case OMPD_master_taskloop_simd: 11319 case OMPD_parallel_master_taskloop: 11320 case OMPD_parallel_master_taskloop_simd: 11321 case OMPD_target_data: 11322 case OMPD_target_enter_data: 11323 case OMPD_target_exit_data: 11324 case OMPD_target_update: 11325 case OMPD_teams: 11326 case OMPD_target: 11327 case OMPD_target_simd: 11328 case OMPD_target_parallel: 11329 case OMPD_cancel: 11330 case OMPD_parallel: 11331 case OMPD_parallel_master: 11332 case OMPD_parallel_sections: 11333 case OMPD_threadprivate: 11334 case OMPD_allocate: 11335 case OMPD_taskyield: 11336 case OMPD_barrier: 11337 case OMPD_taskwait: 11338 case OMPD_cancellation_point: 11339 case OMPD_flush: 11340 case OMPD_declare_reduction: 11341 case OMPD_declare_mapper: 11342 case OMPD_declare_simd: 11343 case OMPD_declare_variant: 11344 case OMPD_declare_target: 11345 case OMPD_end_declare_target: 11346 case OMPD_simd: 11347 case OMPD_for: 11348 case OMPD_for_simd: 11349 case OMPD_sections: 11350 case OMPD_section: 11351 case OMPD_single: 11352 case OMPD_master: 11353 case OMPD_critical: 11354 case OMPD_taskgroup: 11355 case OMPD_ordered: 11356 case OMPD_atomic: 11357 case OMPD_target_teams: 11358 case OMPD_requires: 11359 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11360 case OMPD_unknown: 11361 llvm_unreachable("Unknown OpenMP directive"); 11362 } 11363 break; 11364 case OMPC_device: 11365 switch (DKind) { 11366 case OMPD_target_update: 11367 case OMPD_target_enter_data: 11368 case OMPD_target_exit_data: 11369 case OMPD_target: 11370 case OMPD_target_simd: 11371 case OMPD_target_teams: 11372 case OMPD_target_parallel: 11373 case OMPD_target_teams_distribute: 11374 case OMPD_target_teams_distribute_simd: 11375 case OMPD_target_parallel_for: 11376 case OMPD_target_parallel_for_simd: 11377 case OMPD_target_teams_distribute_parallel_for: 11378 case OMPD_target_teams_distribute_parallel_for_simd: 11379 CaptureRegion = OMPD_task; 11380 break; 11381 case OMPD_target_data: 11382 // Do not capture device-clause expressions. 11383 break; 11384 case OMPD_teams_distribute_parallel_for: 11385 case OMPD_teams_distribute_parallel_for_simd: 11386 case OMPD_teams: 11387 case OMPD_teams_distribute: 11388 case OMPD_teams_distribute_simd: 11389 case OMPD_distribute_parallel_for: 11390 case OMPD_distribute_parallel_for_simd: 11391 case OMPD_task: 11392 case OMPD_taskloop: 11393 case OMPD_taskloop_simd: 11394 case OMPD_master_taskloop: 11395 case OMPD_master_taskloop_simd: 11396 case OMPD_parallel_master_taskloop: 11397 case OMPD_parallel_master_taskloop_simd: 11398 case OMPD_cancel: 11399 case OMPD_parallel: 11400 case OMPD_parallel_master: 11401 case OMPD_parallel_sections: 11402 case OMPD_parallel_for: 11403 case OMPD_parallel_for_simd: 11404 case OMPD_threadprivate: 11405 case OMPD_allocate: 11406 case OMPD_taskyield: 11407 case OMPD_barrier: 11408 case OMPD_taskwait: 11409 case OMPD_cancellation_point: 11410 case OMPD_flush: 11411 case OMPD_declare_reduction: 11412 case OMPD_declare_mapper: 11413 case OMPD_declare_simd: 11414 case OMPD_declare_variant: 11415 case OMPD_declare_target: 11416 case OMPD_end_declare_target: 11417 case OMPD_simd: 11418 case OMPD_for: 11419 case OMPD_for_simd: 11420 case OMPD_sections: 11421 case OMPD_section: 11422 case OMPD_single: 11423 case OMPD_master: 11424 case OMPD_critical: 11425 case OMPD_taskgroup: 11426 case OMPD_distribute: 11427 case OMPD_ordered: 11428 case OMPD_atomic: 11429 case OMPD_distribute_simd: 11430 case OMPD_requires: 11431 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11432 case OMPD_unknown: 11433 llvm_unreachable("Unknown OpenMP directive"); 11434 } 11435 break; 11436 case OMPC_grainsize: 11437 case OMPC_num_tasks: 11438 case OMPC_final: 11439 case OMPC_priority: 11440 switch (DKind) { 11441 case OMPD_task: 11442 case OMPD_taskloop: 11443 case OMPD_taskloop_simd: 11444 case OMPD_master_taskloop: 11445 case OMPD_master_taskloop_simd: 11446 break; 11447 case OMPD_parallel_master_taskloop: 11448 case OMPD_parallel_master_taskloop_simd: 11449 CaptureRegion = OMPD_parallel; 11450 break; 11451 case OMPD_target_update: 11452 case OMPD_target_enter_data: 11453 case OMPD_target_exit_data: 11454 case OMPD_target: 11455 case OMPD_target_simd: 11456 case OMPD_target_teams: 11457 case OMPD_target_parallel: 11458 case OMPD_target_teams_distribute: 11459 case OMPD_target_teams_distribute_simd: 11460 case OMPD_target_parallel_for: 11461 case OMPD_target_parallel_for_simd: 11462 case OMPD_target_teams_distribute_parallel_for: 11463 case OMPD_target_teams_distribute_parallel_for_simd: 11464 case OMPD_target_data: 11465 case OMPD_teams_distribute_parallel_for: 11466 case OMPD_teams_distribute_parallel_for_simd: 11467 case OMPD_teams: 11468 case OMPD_teams_distribute: 11469 case OMPD_teams_distribute_simd: 11470 case OMPD_distribute_parallel_for: 11471 case OMPD_distribute_parallel_for_simd: 11472 case OMPD_cancel: 11473 case OMPD_parallel: 11474 case OMPD_parallel_master: 11475 case OMPD_parallel_sections: 11476 case OMPD_parallel_for: 11477 case OMPD_parallel_for_simd: 11478 case OMPD_threadprivate: 11479 case OMPD_allocate: 11480 case OMPD_taskyield: 11481 case OMPD_barrier: 11482 case OMPD_taskwait: 11483 case OMPD_cancellation_point: 11484 case OMPD_flush: 11485 case OMPD_declare_reduction: 11486 case OMPD_declare_mapper: 11487 case OMPD_declare_simd: 11488 case OMPD_declare_variant: 11489 case OMPD_declare_target: 11490 case OMPD_end_declare_target: 11491 case OMPD_simd: 11492 case OMPD_for: 11493 case OMPD_for_simd: 11494 case OMPD_sections: 11495 case OMPD_section: 11496 case OMPD_single: 11497 case OMPD_master: 11498 case OMPD_critical: 11499 case OMPD_taskgroup: 11500 case OMPD_distribute: 11501 case OMPD_ordered: 11502 case OMPD_atomic: 11503 case OMPD_distribute_simd: 11504 case OMPD_requires: 11505 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11506 case OMPD_unknown: 11507 llvm_unreachable("Unknown OpenMP directive"); 11508 } 11509 break; 11510 case OMPC_firstprivate: 11511 case OMPC_lastprivate: 11512 case OMPC_reduction: 11513 case OMPC_task_reduction: 11514 case OMPC_in_reduction: 11515 case OMPC_linear: 11516 case OMPC_default: 11517 case OMPC_proc_bind: 11518 case OMPC_safelen: 11519 case OMPC_simdlen: 11520 case OMPC_allocator: 11521 case OMPC_collapse: 11522 case OMPC_private: 11523 case OMPC_shared: 11524 case OMPC_aligned: 11525 case OMPC_copyin: 11526 case OMPC_copyprivate: 11527 case OMPC_ordered: 11528 case OMPC_nowait: 11529 case OMPC_untied: 11530 case OMPC_mergeable: 11531 case OMPC_threadprivate: 11532 case OMPC_allocate: 11533 case OMPC_flush: 11534 case OMPC_read: 11535 case OMPC_write: 11536 case OMPC_update: 11537 case OMPC_capture: 11538 case OMPC_seq_cst: 11539 case OMPC_acq_rel: 11540 case OMPC_acquire: 11541 case OMPC_release: 11542 case OMPC_relaxed: 11543 case OMPC_depend: 11544 case OMPC_threads: 11545 case OMPC_simd: 11546 case OMPC_map: 11547 case OMPC_nogroup: 11548 case OMPC_hint: 11549 case OMPC_defaultmap: 11550 case OMPC_unknown: 11551 case OMPC_uniform: 11552 case OMPC_to: 11553 case OMPC_from: 11554 case OMPC_use_device_ptr: 11555 case OMPC_is_device_ptr: 11556 case OMPC_unified_address: 11557 case OMPC_unified_shared_memory: 11558 case OMPC_reverse_offload: 11559 case OMPC_dynamic_allocators: 11560 case OMPC_atomic_default_mem_order: 11561 case OMPC_device_type: 11562 case OMPC_match: 11563 case OMPC_nontemporal: 11564 case OMPC_order: 11565 llvm_unreachable("Unexpected OpenMP clause."); 11566 } 11567 return CaptureRegion; 11568 } 11569 11570 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11571 Expr *Condition, SourceLocation StartLoc, 11572 SourceLocation LParenLoc, 11573 SourceLocation NameModifierLoc, 11574 SourceLocation ColonLoc, 11575 SourceLocation EndLoc) { 11576 Expr *ValExpr = Condition; 11577 Stmt *HelperValStmt = nullptr; 11578 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11579 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11580 !Condition->isInstantiationDependent() && 11581 !Condition->containsUnexpandedParameterPack()) { 11582 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11583 if (Val.isInvalid()) 11584 return nullptr; 11585 11586 ValExpr = Val.get(); 11587 11588 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11589 CaptureRegion = getOpenMPCaptureRegionForClause( 11590 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 11591 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11592 ValExpr = MakeFullExpr(ValExpr).get(); 11593 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11594 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11595 HelperValStmt = buildPreInits(Context, Captures); 11596 } 11597 } 11598 11599 return new (Context) 11600 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11601 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11602 } 11603 11604 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11605 SourceLocation StartLoc, 11606 SourceLocation LParenLoc, 11607 SourceLocation EndLoc) { 11608 Expr *ValExpr = Condition; 11609 Stmt *HelperValStmt = nullptr; 11610 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11611 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11612 !Condition->isInstantiationDependent() && 11613 !Condition->containsUnexpandedParameterPack()) { 11614 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11615 if (Val.isInvalid()) 11616 return nullptr; 11617 11618 ValExpr = MakeFullExpr(Val.get()).get(); 11619 11620 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11621 CaptureRegion = 11622 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 11623 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11624 ValExpr = MakeFullExpr(ValExpr).get(); 11625 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11626 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11627 HelperValStmt = buildPreInits(Context, Captures); 11628 } 11629 } 11630 11631 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11632 StartLoc, LParenLoc, EndLoc); 11633 } 11634 11635 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11636 Expr *Op) { 11637 if (!Op) 11638 return ExprError(); 11639 11640 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11641 public: 11642 IntConvertDiagnoser() 11643 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11644 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11645 QualType T) override { 11646 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11647 } 11648 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11649 QualType T) override { 11650 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11651 } 11652 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11653 QualType T, 11654 QualType ConvTy) override { 11655 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11656 } 11657 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11658 QualType ConvTy) override { 11659 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11660 << ConvTy->isEnumeralType() << ConvTy; 11661 } 11662 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11663 QualType T) override { 11664 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11665 } 11666 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11667 QualType ConvTy) override { 11668 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11669 << ConvTy->isEnumeralType() << ConvTy; 11670 } 11671 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11672 QualType) override { 11673 llvm_unreachable("conversion functions are permitted"); 11674 } 11675 } ConvertDiagnoser; 11676 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11677 } 11678 11679 static bool 11680 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11681 bool StrictlyPositive, bool BuildCapture = false, 11682 OpenMPDirectiveKind DKind = OMPD_unknown, 11683 OpenMPDirectiveKind *CaptureRegion = nullptr, 11684 Stmt **HelperValStmt = nullptr) { 11685 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11686 !ValExpr->isInstantiationDependent()) { 11687 SourceLocation Loc = ValExpr->getExprLoc(); 11688 ExprResult Value = 11689 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11690 if (Value.isInvalid()) 11691 return false; 11692 11693 ValExpr = Value.get(); 11694 // The expression must evaluate to a non-negative integer value. 11695 llvm::APSInt Result; 11696 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11697 Result.isSigned() && 11698 !((!StrictlyPositive && Result.isNonNegative()) || 11699 (StrictlyPositive && Result.isStrictlyPositive()))) { 11700 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11701 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11702 << ValExpr->getSourceRange(); 11703 return false; 11704 } 11705 if (!BuildCapture) 11706 return true; 11707 *CaptureRegion = 11708 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 11709 if (*CaptureRegion != OMPD_unknown && 11710 !SemaRef.CurContext->isDependentContext()) { 11711 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11712 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11713 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11714 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11715 } 11716 } 11717 return true; 11718 } 11719 11720 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11721 SourceLocation StartLoc, 11722 SourceLocation LParenLoc, 11723 SourceLocation EndLoc) { 11724 Expr *ValExpr = NumThreads; 11725 Stmt *HelperValStmt = nullptr; 11726 11727 // OpenMP [2.5, Restrictions] 11728 // The num_threads expression must evaluate to a positive integer value. 11729 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11730 /*StrictlyPositive=*/true)) 11731 return nullptr; 11732 11733 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11734 OpenMPDirectiveKind CaptureRegion = 11735 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 11736 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11737 ValExpr = MakeFullExpr(ValExpr).get(); 11738 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11739 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11740 HelperValStmt = buildPreInits(Context, Captures); 11741 } 11742 11743 return new (Context) OMPNumThreadsClause( 11744 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11745 } 11746 11747 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11748 OpenMPClauseKind CKind, 11749 bool StrictlyPositive) { 11750 if (!E) 11751 return ExprError(); 11752 if (E->isValueDependent() || E->isTypeDependent() || 11753 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11754 return E; 11755 llvm::APSInt Result; 11756 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11757 if (ICE.isInvalid()) 11758 return ExprError(); 11759 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11760 (!StrictlyPositive && !Result.isNonNegative())) { 11761 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11762 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11763 << E->getSourceRange(); 11764 return ExprError(); 11765 } 11766 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11767 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11768 << E->getSourceRange(); 11769 return ExprError(); 11770 } 11771 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11772 DSAStack->setAssociatedLoops(Result.getExtValue()); 11773 else if (CKind == OMPC_ordered) 11774 DSAStack->setAssociatedLoops(Result.getExtValue()); 11775 return ICE; 11776 } 11777 11778 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11779 SourceLocation LParenLoc, 11780 SourceLocation EndLoc) { 11781 // OpenMP [2.8.1, simd construct, Description] 11782 // The parameter of the safelen clause must be a constant 11783 // positive integer expression. 11784 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11785 if (Safelen.isInvalid()) 11786 return nullptr; 11787 return new (Context) 11788 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11789 } 11790 11791 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11792 SourceLocation LParenLoc, 11793 SourceLocation EndLoc) { 11794 // OpenMP [2.8.1, simd construct, Description] 11795 // The parameter of the simdlen clause must be a constant 11796 // positive integer expression. 11797 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11798 if (Simdlen.isInvalid()) 11799 return nullptr; 11800 return new (Context) 11801 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11802 } 11803 11804 /// Tries to find omp_allocator_handle_t type. 11805 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11806 DSAStackTy *Stack) { 11807 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11808 if (!OMPAllocatorHandleT.isNull()) 11809 return true; 11810 // Build the predefined allocator expressions. 11811 bool ErrorFound = false; 11812 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11813 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11814 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11815 StringRef Allocator = 11816 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11817 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11818 auto *VD = dyn_cast_or_null<ValueDecl>( 11819 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11820 if (!VD) { 11821 ErrorFound = true; 11822 break; 11823 } 11824 QualType AllocatorType = 11825 VD->getType().getNonLValueExprType(S.getASTContext()); 11826 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11827 if (!Res.isUsable()) { 11828 ErrorFound = true; 11829 break; 11830 } 11831 if (OMPAllocatorHandleT.isNull()) 11832 OMPAllocatorHandleT = AllocatorType; 11833 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11834 ErrorFound = true; 11835 break; 11836 } 11837 Stack->setAllocator(AllocatorKind, Res.get()); 11838 } 11839 if (ErrorFound) { 11840 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11841 return false; 11842 } 11843 OMPAllocatorHandleT.addConst(); 11844 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11845 return true; 11846 } 11847 11848 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11849 SourceLocation LParenLoc, 11850 SourceLocation EndLoc) { 11851 // OpenMP [2.11.3, allocate Directive, Description] 11852 // allocator is an expression of omp_allocator_handle_t type. 11853 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11854 return nullptr; 11855 11856 ExprResult Allocator = DefaultLvalueConversion(A); 11857 if (Allocator.isInvalid()) 11858 return nullptr; 11859 Allocator = PerformImplicitConversion(Allocator.get(), 11860 DSAStack->getOMPAllocatorHandleT(), 11861 Sema::AA_Initializing, 11862 /*AllowExplicit=*/true); 11863 if (Allocator.isInvalid()) 11864 return nullptr; 11865 return new (Context) 11866 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11867 } 11868 11869 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11870 SourceLocation StartLoc, 11871 SourceLocation LParenLoc, 11872 SourceLocation EndLoc) { 11873 // OpenMP [2.7.1, loop construct, Description] 11874 // OpenMP [2.8.1, simd construct, Description] 11875 // OpenMP [2.9.6, distribute construct, Description] 11876 // The parameter of the collapse clause must be a constant 11877 // positive integer expression. 11878 ExprResult NumForLoopsResult = 11879 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11880 if (NumForLoopsResult.isInvalid()) 11881 return nullptr; 11882 return new (Context) 11883 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11884 } 11885 11886 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11887 SourceLocation EndLoc, 11888 SourceLocation LParenLoc, 11889 Expr *NumForLoops) { 11890 // OpenMP [2.7.1, loop construct, Description] 11891 // OpenMP [2.8.1, simd construct, Description] 11892 // OpenMP [2.9.6, distribute construct, Description] 11893 // The parameter of the ordered clause must be a constant 11894 // positive integer expression if any. 11895 if (NumForLoops && LParenLoc.isValid()) { 11896 ExprResult NumForLoopsResult = 11897 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11898 if (NumForLoopsResult.isInvalid()) 11899 return nullptr; 11900 NumForLoops = NumForLoopsResult.get(); 11901 } else { 11902 NumForLoops = nullptr; 11903 } 11904 auto *Clause = OMPOrderedClause::Create( 11905 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11906 StartLoc, LParenLoc, EndLoc); 11907 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11908 return Clause; 11909 } 11910 11911 OMPClause *Sema::ActOnOpenMPSimpleClause( 11912 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11913 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11914 OMPClause *Res = nullptr; 11915 switch (Kind) { 11916 case OMPC_default: 11917 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 11918 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11919 break; 11920 case OMPC_proc_bind: 11921 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 11922 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11923 break; 11924 case OMPC_atomic_default_mem_order: 11925 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11926 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11927 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11928 break; 11929 case OMPC_order: 11930 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 11931 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11932 break; 11933 case OMPC_if: 11934 case OMPC_final: 11935 case OMPC_num_threads: 11936 case OMPC_safelen: 11937 case OMPC_simdlen: 11938 case OMPC_allocator: 11939 case OMPC_collapse: 11940 case OMPC_schedule: 11941 case OMPC_private: 11942 case OMPC_firstprivate: 11943 case OMPC_lastprivate: 11944 case OMPC_shared: 11945 case OMPC_reduction: 11946 case OMPC_task_reduction: 11947 case OMPC_in_reduction: 11948 case OMPC_linear: 11949 case OMPC_aligned: 11950 case OMPC_copyin: 11951 case OMPC_copyprivate: 11952 case OMPC_ordered: 11953 case OMPC_nowait: 11954 case OMPC_untied: 11955 case OMPC_mergeable: 11956 case OMPC_threadprivate: 11957 case OMPC_allocate: 11958 case OMPC_flush: 11959 case OMPC_read: 11960 case OMPC_write: 11961 case OMPC_update: 11962 case OMPC_capture: 11963 case OMPC_seq_cst: 11964 case OMPC_acq_rel: 11965 case OMPC_acquire: 11966 case OMPC_release: 11967 case OMPC_relaxed: 11968 case OMPC_depend: 11969 case OMPC_device: 11970 case OMPC_threads: 11971 case OMPC_simd: 11972 case OMPC_map: 11973 case OMPC_num_teams: 11974 case OMPC_thread_limit: 11975 case OMPC_priority: 11976 case OMPC_grainsize: 11977 case OMPC_nogroup: 11978 case OMPC_num_tasks: 11979 case OMPC_hint: 11980 case OMPC_dist_schedule: 11981 case OMPC_defaultmap: 11982 case OMPC_unknown: 11983 case OMPC_uniform: 11984 case OMPC_to: 11985 case OMPC_from: 11986 case OMPC_use_device_ptr: 11987 case OMPC_is_device_ptr: 11988 case OMPC_unified_address: 11989 case OMPC_unified_shared_memory: 11990 case OMPC_reverse_offload: 11991 case OMPC_dynamic_allocators: 11992 case OMPC_device_type: 11993 case OMPC_match: 11994 case OMPC_nontemporal: 11995 llvm_unreachable("Clause is not allowed."); 11996 } 11997 return Res; 11998 } 11999 12000 static std::string 12001 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12002 ArrayRef<unsigned> Exclude = llvm::None) { 12003 SmallString<256> Buffer; 12004 llvm::raw_svector_ostream Out(Buffer); 12005 unsigned Skipped = Exclude.size(); 12006 auto S = Exclude.begin(), E = Exclude.end(); 12007 for (unsigned I = First; I < Last; ++I) { 12008 if (std::find(S, E, I) != E) { 12009 --Skipped; 12010 continue; 12011 } 12012 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12013 if (I + Skipped + 2 == Last) 12014 Out << " or "; 12015 else if (I + Skipped + 1 != Last) 12016 Out << ", "; 12017 } 12018 return std::string(Out.str()); 12019 } 12020 12021 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12022 SourceLocation KindKwLoc, 12023 SourceLocation StartLoc, 12024 SourceLocation LParenLoc, 12025 SourceLocation EndLoc) { 12026 if (Kind == OMP_DEFAULT_unknown) { 12027 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12028 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12029 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12030 << getOpenMPClauseName(OMPC_default); 12031 return nullptr; 12032 } 12033 if (Kind == OMP_DEFAULT_none) 12034 DSAStack->setDefaultDSANone(KindKwLoc); 12035 else if (Kind == OMP_DEFAULT_shared) 12036 DSAStack->setDefaultDSAShared(KindKwLoc); 12037 12038 return new (Context) 12039 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12040 } 12041 12042 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12043 SourceLocation KindKwLoc, 12044 SourceLocation StartLoc, 12045 SourceLocation LParenLoc, 12046 SourceLocation EndLoc) { 12047 if (Kind == OMP_PROC_BIND_unknown) { 12048 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12049 << getListOfPossibleValues(OMPC_proc_bind, 12050 /*First=*/unsigned(OMP_PROC_BIND_master), 12051 /*Last=*/5) 12052 << getOpenMPClauseName(OMPC_proc_bind); 12053 return nullptr; 12054 } 12055 return new (Context) 12056 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12057 } 12058 12059 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12060 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12061 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12062 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12063 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12064 << getListOfPossibleValues( 12065 OMPC_atomic_default_mem_order, /*First=*/0, 12066 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12067 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12068 return nullptr; 12069 } 12070 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12071 LParenLoc, EndLoc); 12072 } 12073 12074 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12075 SourceLocation KindKwLoc, 12076 SourceLocation StartLoc, 12077 SourceLocation LParenLoc, 12078 SourceLocation EndLoc) { 12079 if (Kind == OMPC_ORDER_unknown) { 12080 static_assert(OMPC_ORDER_unknown > 0, 12081 "OMPC_ORDER_unknown not greater than 0"); 12082 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12083 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12084 /*Last=*/OMPC_ORDER_unknown) 12085 << getOpenMPClauseName(OMPC_order); 12086 return nullptr; 12087 } 12088 return new (Context) 12089 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12090 } 12091 12092 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12093 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12094 SourceLocation StartLoc, SourceLocation LParenLoc, 12095 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12096 SourceLocation EndLoc) { 12097 OMPClause *Res = nullptr; 12098 switch (Kind) { 12099 case OMPC_schedule: 12100 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12101 assert(Argument.size() == NumberOfElements && 12102 ArgumentLoc.size() == NumberOfElements); 12103 Res = ActOnOpenMPScheduleClause( 12104 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12105 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12106 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12107 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12108 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12109 break; 12110 case OMPC_if: 12111 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12112 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12113 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12114 DelimLoc, EndLoc); 12115 break; 12116 case OMPC_dist_schedule: 12117 Res = ActOnOpenMPDistScheduleClause( 12118 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12119 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12120 break; 12121 case OMPC_defaultmap: 12122 enum { Modifier, DefaultmapKind }; 12123 Res = ActOnOpenMPDefaultmapClause( 12124 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12125 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12126 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12127 EndLoc); 12128 break; 12129 case OMPC_final: 12130 case OMPC_num_threads: 12131 case OMPC_safelen: 12132 case OMPC_simdlen: 12133 case OMPC_allocator: 12134 case OMPC_collapse: 12135 case OMPC_default: 12136 case OMPC_proc_bind: 12137 case OMPC_private: 12138 case OMPC_firstprivate: 12139 case OMPC_lastprivate: 12140 case OMPC_shared: 12141 case OMPC_reduction: 12142 case OMPC_task_reduction: 12143 case OMPC_in_reduction: 12144 case OMPC_linear: 12145 case OMPC_aligned: 12146 case OMPC_copyin: 12147 case OMPC_copyprivate: 12148 case OMPC_ordered: 12149 case OMPC_nowait: 12150 case OMPC_untied: 12151 case OMPC_mergeable: 12152 case OMPC_threadprivate: 12153 case OMPC_allocate: 12154 case OMPC_flush: 12155 case OMPC_read: 12156 case OMPC_write: 12157 case OMPC_update: 12158 case OMPC_capture: 12159 case OMPC_seq_cst: 12160 case OMPC_acq_rel: 12161 case OMPC_acquire: 12162 case OMPC_release: 12163 case OMPC_relaxed: 12164 case OMPC_depend: 12165 case OMPC_device: 12166 case OMPC_threads: 12167 case OMPC_simd: 12168 case OMPC_map: 12169 case OMPC_num_teams: 12170 case OMPC_thread_limit: 12171 case OMPC_priority: 12172 case OMPC_grainsize: 12173 case OMPC_nogroup: 12174 case OMPC_num_tasks: 12175 case OMPC_hint: 12176 case OMPC_unknown: 12177 case OMPC_uniform: 12178 case OMPC_to: 12179 case OMPC_from: 12180 case OMPC_use_device_ptr: 12181 case OMPC_is_device_ptr: 12182 case OMPC_unified_address: 12183 case OMPC_unified_shared_memory: 12184 case OMPC_reverse_offload: 12185 case OMPC_dynamic_allocators: 12186 case OMPC_atomic_default_mem_order: 12187 case OMPC_device_type: 12188 case OMPC_match: 12189 case OMPC_nontemporal: 12190 case OMPC_order: 12191 llvm_unreachable("Clause is not allowed."); 12192 } 12193 return Res; 12194 } 12195 12196 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12197 OpenMPScheduleClauseModifier M2, 12198 SourceLocation M1Loc, SourceLocation M2Loc) { 12199 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12200 SmallVector<unsigned, 2> Excluded; 12201 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12202 Excluded.push_back(M2); 12203 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12204 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12205 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12206 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12207 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12208 << getListOfPossibleValues(OMPC_schedule, 12209 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12210 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12211 Excluded) 12212 << getOpenMPClauseName(OMPC_schedule); 12213 return true; 12214 } 12215 return false; 12216 } 12217 12218 OMPClause *Sema::ActOnOpenMPScheduleClause( 12219 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12220 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12221 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12222 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12223 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12224 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12225 return nullptr; 12226 // OpenMP, 2.7.1, Loop Construct, Restrictions 12227 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12228 // but not both. 12229 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12230 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12231 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12232 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12233 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12234 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12235 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12236 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12237 return nullptr; 12238 } 12239 if (Kind == OMPC_SCHEDULE_unknown) { 12240 std::string Values; 12241 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12242 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12243 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12244 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12245 Exclude); 12246 } else { 12247 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12248 /*Last=*/OMPC_SCHEDULE_unknown); 12249 } 12250 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12251 << Values << getOpenMPClauseName(OMPC_schedule); 12252 return nullptr; 12253 } 12254 // OpenMP, 2.7.1, Loop Construct, Restrictions 12255 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12256 // schedule(guided). 12257 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12258 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12259 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12260 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12261 diag::err_omp_schedule_nonmonotonic_static); 12262 return nullptr; 12263 } 12264 Expr *ValExpr = ChunkSize; 12265 Stmt *HelperValStmt = nullptr; 12266 if (ChunkSize) { 12267 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12268 !ChunkSize->isInstantiationDependent() && 12269 !ChunkSize->containsUnexpandedParameterPack()) { 12270 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12271 ExprResult Val = 12272 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12273 if (Val.isInvalid()) 12274 return nullptr; 12275 12276 ValExpr = Val.get(); 12277 12278 // OpenMP [2.7.1, Restrictions] 12279 // chunk_size must be a loop invariant integer expression with a positive 12280 // value. 12281 llvm::APSInt Result; 12282 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12283 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12284 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12285 << "schedule" << 1 << ChunkSize->getSourceRange(); 12286 return nullptr; 12287 } 12288 } else if (getOpenMPCaptureRegionForClause( 12289 DSAStack->getCurrentDirective(), OMPC_schedule, 12290 LangOpts.OpenMP) != OMPD_unknown && 12291 !CurContext->isDependentContext()) { 12292 ValExpr = MakeFullExpr(ValExpr).get(); 12293 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12294 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12295 HelperValStmt = buildPreInits(Context, Captures); 12296 } 12297 } 12298 } 12299 12300 return new (Context) 12301 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12302 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12303 } 12304 12305 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12306 SourceLocation StartLoc, 12307 SourceLocation EndLoc) { 12308 OMPClause *Res = nullptr; 12309 switch (Kind) { 12310 case OMPC_ordered: 12311 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12312 break; 12313 case OMPC_nowait: 12314 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12315 break; 12316 case OMPC_untied: 12317 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12318 break; 12319 case OMPC_mergeable: 12320 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12321 break; 12322 case OMPC_read: 12323 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12324 break; 12325 case OMPC_write: 12326 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12327 break; 12328 case OMPC_update: 12329 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12330 break; 12331 case OMPC_capture: 12332 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12333 break; 12334 case OMPC_seq_cst: 12335 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12336 break; 12337 case OMPC_acq_rel: 12338 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 12339 break; 12340 case OMPC_acquire: 12341 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 12342 break; 12343 case OMPC_release: 12344 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 12345 break; 12346 case OMPC_relaxed: 12347 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 12348 break; 12349 case OMPC_threads: 12350 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12351 break; 12352 case OMPC_simd: 12353 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12354 break; 12355 case OMPC_nogroup: 12356 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12357 break; 12358 case OMPC_unified_address: 12359 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12360 break; 12361 case OMPC_unified_shared_memory: 12362 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12363 break; 12364 case OMPC_reverse_offload: 12365 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12366 break; 12367 case OMPC_dynamic_allocators: 12368 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12369 break; 12370 case OMPC_if: 12371 case OMPC_final: 12372 case OMPC_num_threads: 12373 case OMPC_safelen: 12374 case OMPC_simdlen: 12375 case OMPC_allocator: 12376 case OMPC_collapse: 12377 case OMPC_schedule: 12378 case OMPC_private: 12379 case OMPC_firstprivate: 12380 case OMPC_lastprivate: 12381 case OMPC_shared: 12382 case OMPC_reduction: 12383 case OMPC_task_reduction: 12384 case OMPC_in_reduction: 12385 case OMPC_linear: 12386 case OMPC_aligned: 12387 case OMPC_copyin: 12388 case OMPC_copyprivate: 12389 case OMPC_default: 12390 case OMPC_proc_bind: 12391 case OMPC_threadprivate: 12392 case OMPC_allocate: 12393 case OMPC_flush: 12394 case OMPC_depend: 12395 case OMPC_device: 12396 case OMPC_map: 12397 case OMPC_num_teams: 12398 case OMPC_thread_limit: 12399 case OMPC_priority: 12400 case OMPC_grainsize: 12401 case OMPC_num_tasks: 12402 case OMPC_hint: 12403 case OMPC_dist_schedule: 12404 case OMPC_defaultmap: 12405 case OMPC_unknown: 12406 case OMPC_uniform: 12407 case OMPC_to: 12408 case OMPC_from: 12409 case OMPC_use_device_ptr: 12410 case OMPC_is_device_ptr: 12411 case OMPC_atomic_default_mem_order: 12412 case OMPC_device_type: 12413 case OMPC_match: 12414 case OMPC_nontemporal: 12415 case OMPC_order: 12416 llvm_unreachable("Clause is not allowed."); 12417 } 12418 return Res; 12419 } 12420 12421 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12422 SourceLocation EndLoc) { 12423 DSAStack->setNowaitRegion(); 12424 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12425 } 12426 12427 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12428 SourceLocation EndLoc) { 12429 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12430 } 12431 12432 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12433 SourceLocation EndLoc) { 12434 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12435 } 12436 12437 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12438 SourceLocation EndLoc) { 12439 return new (Context) OMPReadClause(StartLoc, EndLoc); 12440 } 12441 12442 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12443 SourceLocation EndLoc) { 12444 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12445 } 12446 12447 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12448 SourceLocation EndLoc) { 12449 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 12450 } 12451 12452 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12453 SourceLocation EndLoc) { 12454 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12455 } 12456 12457 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12458 SourceLocation EndLoc) { 12459 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12460 } 12461 12462 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 12463 SourceLocation EndLoc) { 12464 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 12465 } 12466 12467 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 12468 SourceLocation EndLoc) { 12469 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 12470 } 12471 12472 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 12473 SourceLocation EndLoc) { 12474 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 12475 } 12476 12477 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 12478 SourceLocation EndLoc) { 12479 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 12480 } 12481 12482 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12483 SourceLocation EndLoc) { 12484 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12485 } 12486 12487 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12488 SourceLocation EndLoc) { 12489 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12490 } 12491 12492 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12493 SourceLocation EndLoc) { 12494 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12495 } 12496 12497 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12498 SourceLocation EndLoc) { 12499 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12500 } 12501 12502 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12503 SourceLocation EndLoc) { 12504 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12505 } 12506 12507 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12508 SourceLocation EndLoc) { 12509 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12510 } 12511 12512 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12513 SourceLocation EndLoc) { 12514 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12515 } 12516 12517 OMPClause *Sema::ActOnOpenMPVarListClause( 12518 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12519 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12520 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12521 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 12522 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12523 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 12524 SourceLocation DepLinMapLastLoc) { 12525 SourceLocation StartLoc = Locs.StartLoc; 12526 SourceLocation LParenLoc = Locs.LParenLoc; 12527 SourceLocation EndLoc = Locs.EndLoc; 12528 OMPClause *Res = nullptr; 12529 switch (Kind) { 12530 case OMPC_private: 12531 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12532 break; 12533 case OMPC_firstprivate: 12534 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12535 break; 12536 case OMPC_lastprivate: 12537 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 12538 "Unexpected lastprivate modifier."); 12539 Res = ActOnOpenMPLastprivateClause( 12540 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 12541 DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 12542 break; 12543 case OMPC_shared: 12544 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12545 break; 12546 case OMPC_reduction: 12547 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12548 EndLoc, ReductionOrMapperIdScopeSpec, 12549 ReductionOrMapperId); 12550 break; 12551 case OMPC_task_reduction: 12552 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12553 EndLoc, ReductionOrMapperIdScopeSpec, 12554 ReductionOrMapperId); 12555 break; 12556 case OMPC_in_reduction: 12557 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12558 EndLoc, ReductionOrMapperIdScopeSpec, 12559 ReductionOrMapperId); 12560 break; 12561 case OMPC_linear: 12562 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 12563 "Unexpected linear modifier."); 12564 Res = ActOnOpenMPLinearClause( 12565 VarList, TailExpr, StartLoc, LParenLoc, 12566 static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc, 12567 ColonLoc, EndLoc); 12568 break; 12569 case OMPC_aligned: 12570 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12571 ColonLoc, EndLoc); 12572 break; 12573 case OMPC_copyin: 12574 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12575 break; 12576 case OMPC_copyprivate: 12577 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12578 break; 12579 case OMPC_flush: 12580 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12581 break; 12582 case OMPC_depend: 12583 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 12584 "Unexpected depend modifier."); 12585 Res = ActOnOpenMPDependClause( 12586 static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc, 12587 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 12588 break; 12589 case OMPC_map: 12590 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 12591 "Unexpected map modifier."); 12592 Res = ActOnOpenMPMapClause( 12593 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 12594 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 12595 IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs); 12596 break; 12597 case OMPC_to: 12598 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12599 ReductionOrMapperId, Locs); 12600 break; 12601 case OMPC_from: 12602 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12603 ReductionOrMapperId, Locs); 12604 break; 12605 case OMPC_use_device_ptr: 12606 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12607 break; 12608 case OMPC_is_device_ptr: 12609 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12610 break; 12611 case OMPC_allocate: 12612 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12613 ColonLoc, EndLoc); 12614 break; 12615 case OMPC_nontemporal: 12616 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 12617 break; 12618 case OMPC_if: 12619 case OMPC_final: 12620 case OMPC_num_threads: 12621 case OMPC_safelen: 12622 case OMPC_simdlen: 12623 case OMPC_allocator: 12624 case OMPC_collapse: 12625 case OMPC_default: 12626 case OMPC_proc_bind: 12627 case OMPC_schedule: 12628 case OMPC_ordered: 12629 case OMPC_nowait: 12630 case OMPC_untied: 12631 case OMPC_mergeable: 12632 case OMPC_threadprivate: 12633 case OMPC_read: 12634 case OMPC_write: 12635 case OMPC_update: 12636 case OMPC_capture: 12637 case OMPC_seq_cst: 12638 case OMPC_acq_rel: 12639 case OMPC_acquire: 12640 case OMPC_release: 12641 case OMPC_relaxed: 12642 case OMPC_device: 12643 case OMPC_threads: 12644 case OMPC_simd: 12645 case OMPC_num_teams: 12646 case OMPC_thread_limit: 12647 case OMPC_priority: 12648 case OMPC_grainsize: 12649 case OMPC_nogroup: 12650 case OMPC_num_tasks: 12651 case OMPC_hint: 12652 case OMPC_dist_schedule: 12653 case OMPC_defaultmap: 12654 case OMPC_unknown: 12655 case OMPC_uniform: 12656 case OMPC_unified_address: 12657 case OMPC_unified_shared_memory: 12658 case OMPC_reverse_offload: 12659 case OMPC_dynamic_allocators: 12660 case OMPC_atomic_default_mem_order: 12661 case OMPC_device_type: 12662 case OMPC_match: 12663 case OMPC_order: 12664 llvm_unreachable("Clause is not allowed."); 12665 } 12666 return Res; 12667 } 12668 12669 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12670 ExprObjectKind OK, SourceLocation Loc) { 12671 ExprResult Res = BuildDeclRefExpr( 12672 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12673 if (!Res.isUsable()) 12674 return ExprError(); 12675 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12676 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12677 if (!Res.isUsable()) 12678 return ExprError(); 12679 } 12680 if (VK != VK_LValue && Res.get()->isGLValue()) { 12681 Res = DefaultLvalueConversion(Res.get()); 12682 if (!Res.isUsable()) 12683 return ExprError(); 12684 } 12685 return Res; 12686 } 12687 12688 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12689 SourceLocation StartLoc, 12690 SourceLocation LParenLoc, 12691 SourceLocation EndLoc) { 12692 SmallVector<Expr *, 8> Vars; 12693 SmallVector<Expr *, 8> PrivateCopies; 12694 for (Expr *RefExpr : VarList) { 12695 assert(RefExpr && "NULL expr in OpenMP private clause."); 12696 SourceLocation ELoc; 12697 SourceRange ERange; 12698 Expr *SimpleRefExpr = RefExpr; 12699 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12700 if (Res.second) { 12701 // It will be analyzed later. 12702 Vars.push_back(RefExpr); 12703 PrivateCopies.push_back(nullptr); 12704 } 12705 ValueDecl *D = Res.first; 12706 if (!D) 12707 continue; 12708 12709 QualType Type = D->getType(); 12710 auto *VD = dyn_cast<VarDecl>(D); 12711 12712 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12713 // A variable that appears in a private clause must not have an incomplete 12714 // type or a reference type. 12715 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12716 continue; 12717 Type = Type.getNonReferenceType(); 12718 12719 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12720 // A variable that is privatized must not have a const-qualified type 12721 // unless it is of class type with a mutable member. This restriction does 12722 // not apply to the firstprivate clause. 12723 // 12724 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12725 // A variable that appears in a private clause must not have a 12726 // const-qualified type unless it is of class type with a mutable member. 12727 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12728 continue; 12729 12730 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12731 // in a Construct] 12732 // Variables with the predetermined data-sharing attributes may not be 12733 // listed in data-sharing attributes clauses, except for the cases 12734 // listed below. For these exceptions only, listing a predetermined 12735 // variable in a data-sharing attribute clause is allowed and overrides 12736 // the variable's predetermined data-sharing attributes. 12737 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12738 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12739 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12740 << getOpenMPClauseName(OMPC_private); 12741 reportOriginalDsa(*this, DSAStack, D, DVar); 12742 continue; 12743 } 12744 12745 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12746 // Variably modified types are not supported for tasks. 12747 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12748 isOpenMPTaskingDirective(CurrDir)) { 12749 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12750 << getOpenMPClauseName(OMPC_private) << Type 12751 << getOpenMPDirectiveName(CurrDir); 12752 bool IsDecl = 12753 !VD || 12754 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12755 Diag(D->getLocation(), 12756 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12757 << D; 12758 continue; 12759 } 12760 12761 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12762 // A list item cannot appear in both a map clause and a data-sharing 12763 // attribute clause on the same construct 12764 // 12765 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12766 // A list item cannot appear in both a map clause and a data-sharing 12767 // attribute clause on the same construct unless the construct is a 12768 // combined construct. 12769 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12770 CurrDir == OMPD_target) { 12771 OpenMPClauseKind ConflictKind; 12772 if (DSAStack->checkMappableExprComponentListsForDecl( 12773 VD, /*CurrentRegionOnly=*/true, 12774 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12775 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12776 ConflictKind = WhereFoundClauseKind; 12777 return true; 12778 })) { 12779 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12780 << getOpenMPClauseName(OMPC_private) 12781 << getOpenMPClauseName(ConflictKind) 12782 << getOpenMPDirectiveName(CurrDir); 12783 reportOriginalDsa(*this, DSAStack, D, DVar); 12784 continue; 12785 } 12786 } 12787 12788 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12789 // A variable of class type (or array thereof) that appears in a private 12790 // clause requires an accessible, unambiguous default constructor for the 12791 // class type. 12792 // Generate helper private variable and initialize it with the default 12793 // value. The address of the original variable is replaced by the address of 12794 // the new private variable in CodeGen. This new variable is not added to 12795 // IdResolver, so the code in the OpenMP region uses original variable for 12796 // proper diagnostics. 12797 Type = Type.getUnqualifiedType(); 12798 VarDecl *VDPrivate = 12799 buildVarDecl(*this, ELoc, Type, D->getName(), 12800 D->hasAttrs() ? &D->getAttrs() : nullptr, 12801 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12802 ActOnUninitializedDecl(VDPrivate); 12803 if (VDPrivate->isInvalidDecl()) 12804 continue; 12805 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12806 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12807 12808 DeclRefExpr *Ref = nullptr; 12809 if (!VD && !CurContext->isDependentContext()) 12810 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12811 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12812 Vars.push_back((VD || CurContext->isDependentContext()) 12813 ? RefExpr->IgnoreParens() 12814 : Ref); 12815 PrivateCopies.push_back(VDPrivateRefExpr); 12816 } 12817 12818 if (Vars.empty()) 12819 return nullptr; 12820 12821 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12822 PrivateCopies); 12823 } 12824 12825 namespace { 12826 class DiagsUninitializedSeveretyRAII { 12827 private: 12828 DiagnosticsEngine &Diags; 12829 SourceLocation SavedLoc; 12830 bool IsIgnored = false; 12831 12832 public: 12833 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12834 bool IsIgnored) 12835 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12836 if (!IsIgnored) { 12837 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12838 /*Map*/ diag::Severity::Ignored, Loc); 12839 } 12840 } 12841 ~DiagsUninitializedSeveretyRAII() { 12842 if (!IsIgnored) 12843 Diags.popMappings(SavedLoc); 12844 } 12845 }; 12846 } 12847 12848 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12849 SourceLocation StartLoc, 12850 SourceLocation LParenLoc, 12851 SourceLocation EndLoc) { 12852 SmallVector<Expr *, 8> Vars; 12853 SmallVector<Expr *, 8> PrivateCopies; 12854 SmallVector<Expr *, 8> Inits; 12855 SmallVector<Decl *, 4> ExprCaptures; 12856 bool IsImplicitClause = 12857 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12858 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12859 12860 for (Expr *RefExpr : VarList) { 12861 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12862 SourceLocation ELoc; 12863 SourceRange ERange; 12864 Expr *SimpleRefExpr = RefExpr; 12865 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12866 if (Res.second) { 12867 // It will be analyzed later. 12868 Vars.push_back(RefExpr); 12869 PrivateCopies.push_back(nullptr); 12870 Inits.push_back(nullptr); 12871 } 12872 ValueDecl *D = Res.first; 12873 if (!D) 12874 continue; 12875 12876 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12877 QualType Type = D->getType(); 12878 auto *VD = dyn_cast<VarDecl>(D); 12879 12880 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12881 // A variable that appears in a private clause must not have an incomplete 12882 // type or a reference type. 12883 if (RequireCompleteType(ELoc, Type, 12884 diag::err_omp_firstprivate_incomplete_type)) 12885 continue; 12886 Type = Type.getNonReferenceType(); 12887 12888 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12889 // A variable of class type (or array thereof) that appears in a private 12890 // clause requires an accessible, unambiguous copy constructor for the 12891 // class type. 12892 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12893 12894 // If an implicit firstprivate variable found it was checked already. 12895 DSAStackTy::DSAVarData TopDVar; 12896 if (!IsImplicitClause) { 12897 DSAStackTy::DSAVarData DVar = 12898 DSAStack->getTopDSA(D, /*FromParent=*/false); 12899 TopDVar = DVar; 12900 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12901 bool IsConstant = ElemType.isConstant(Context); 12902 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12903 // A list item that specifies a given variable may not appear in more 12904 // than one clause on the same directive, except that a variable may be 12905 // specified in both firstprivate and lastprivate clauses. 12906 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12907 // A list item may appear in a firstprivate or lastprivate clause but not 12908 // both. 12909 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12910 (isOpenMPDistributeDirective(CurrDir) || 12911 DVar.CKind != OMPC_lastprivate) && 12912 DVar.RefExpr) { 12913 Diag(ELoc, diag::err_omp_wrong_dsa) 12914 << getOpenMPClauseName(DVar.CKind) 12915 << getOpenMPClauseName(OMPC_firstprivate); 12916 reportOriginalDsa(*this, DSAStack, D, DVar); 12917 continue; 12918 } 12919 12920 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12921 // in a Construct] 12922 // Variables with the predetermined data-sharing attributes may not be 12923 // listed in data-sharing attributes clauses, except for the cases 12924 // listed below. For these exceptions only, listing a predetermined 12925 // variable in a data-sharing attribute clause is allowed and overrides 12926 // the variable's predetermined data-sharing attributes. 12927 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12928 // in a Construct, C/C++, p.2] 12929 // Variables with const-qualified type having no mutable member may be 12930 // listed in a firstprivate clause, even if they are static data members. 12931 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12932 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12933 Diag(ELoc, diag::err_omp_wrong_dsa) 12934 << getOpenMPClauseName(DVar.CKind) 12935 << getOpenMPClauseName(OMPC_firstprivate); 12936 reportOriginalDsa(*this, DSAStack, D, DVar); 12937 continue; 12938 } 12939 12940 // OpenMP [2.9.3.4, Restrictions, p.2] 12941 // A list item that is private within a parallel region must not appear 12942 // in a firstprivate clause on a worksharing construct if any of the 12943 // worksharing regions arising from the worksharing construct ever bind 12944 // to any of the parallel regions arising from the parallel construct. 12945 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12946 // A list item that is private within a teams region must not appear in a 12947 // firstprivate clause on a distribute construct if any of the distribute 12948 // regions arising from the distribute construct ever bind to any of the 12949 // teams regions arising from the teams construct. 12950 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12951 // A list item that appears in a reduction clause of a teams construct 12952 // must not appear in a firstprivate clause on a distribute construct if 12953 // any of the distribute regions arising from the distribute construct 12954 // ever bind to any of the teams regions arising from the teams construct. 12955 if ((isOpenMPWorksharingDirective(CurrDir) || 12956 isOpenMPDistributeDirective(CurrDir)) && 12957 !isOpenMPParallelDirective(CurrDir) && 12958 !isOpenMPTeamsDirective(CurrDir)) { 12959 DVar = DSAStack->getImplicitDSA(D, true); 12960 if (DVar.CKind != OMPC_shared && 12961 (isOpenMPParallelDirective(DVar.DKind) || 12962 isOpenMPTeamsDirective(DVar.DKind) || 12963 DVar.DKind == OMPD_unknown)) { 12964 Diag(ELoc, diag::err_omp_required_access) 12965 << getOpenMPClauseName(OMPC_firstprivate) 12966 << getOpenMPClauseName(OMPC_shared); 12967 reportOriginalDsa(*this, DSAStack, D, DVar); 12968 continue; 12969 } 12970 } 12971 // OpenMP [2.9.3.4, Restrictions, p.3] 12972 // A list item that appears in a reduction clause of a parallel construct 12973 // must not appear in a firstprivate clause on a worksharing or task 12974 // construct if any of the worksharing or task regions arising from the 12975 // worksharing or task construct ever bind to any of the parallel regions 12976 // arising from the parallel construct. 12977 // OpenMP [2.9.3.4, Restrictions, p.4] 12978 // A list item that appears in a reduction clause in worksharing 12979 // construct must not appear in a firstprivate clause in a task construct 12980 // encountered during execution of any of the worksharing regions arising 12981 // from the worksharing construct. 12982 if (isOpenMPTaskingDirective(CurrDir)) { 12983 DVar = DSAStack->hasInnermostDSA( 12984 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12985 [](OpenMPDirectiveKind K) { 12986 return isOpenMPParallelDirective(K) || 12987 isOpenMPWorksharingDirective(K) || 12988 isOpenMPTeamsDirective(K); 12989 }, 12990 /*FromParent=*/true); 12991 if (DVar.CKind == OMPC_reduction && 12992 (isOpenMPParallelDirective(DVar.DKind) || 12993 isOpenMPWorksharingDirective(DVar.DKind) || 12994 isOpenMPTeamsDirective(DVar.DKind))) { 12995 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12996 << getOpenMPDirectiveName(DVar.DKind); 12997 reportOriginalDsa(*this, DSAStack, D, DVar); 12998 continue; 12999 } 13000 } 13001 13002 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13003 // A list item cannot appear in both a map clause and a data-sharing 13004 // attribute clause on the same construct 13005 // 13006 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13007 // A list item cannot appear in both a map clause and a data-sharing 13008 // attribute clause on the same construct unless the construct is a 13009 // combined construct. 13010 if ((LangOpts.OpenMP <= 45 && 13011 isOpenMPTargetExecutionDirective(CurrDir)) || 13012 CurrDir == OMPD_target) { 13013 OpenMPClauseKind ConflictKind; 13014 if (DSAStack->checkMappableExprComponentListsForDecl( 13015 VD, /*CurrentRegionOnly=*/true, 13016 [&ConflictKind]( 13017 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13018 OpenMPClauseKind WhereFoundClauseKind) { 13019 ConflictKind = WhereFoundClauseKind; 13020 return true; 13021 })) { 13022 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13023 << getOpenMPClauseName(OMPC_firstprivate) 13024 << getOpenMPClauseName(ConflictKind) 13025 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13026 reportOriginalDsa(*this, DSAStack, D, DVar); 13027 continue; 13028 } 13029 } 13030 } 13031 13032 // Variably modified types are not supported for tasks. 13033 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13034 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13035 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13036 << getOpenMPClauseName(OMPC_firstprivate) << Type 13037 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13038 bool IsDecl = 13039 !VD || 13040 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13041 Diag(D->getLocation(), 13042 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13043 << D; 13044 continue; 13045 } 13046 13047 Type = Type.getUnqualifiedType(); 13048 VarDecl *VDPrivate = 13049 buildVarDecl(*this, ELoc, Type, D->getName(), 13050 D->hasAttrs() ? &D->getAttrs() : nullptr, 13051 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13052 // Generate helper private variable and initialize it with the value of the 13053 // original variable. The address of the original variable is replaced by 13054 // the address of the new private variable in the CodeGen. This new variable 13055 // is not added to IdResolver, so the code in the OpenMP region uses 13056 // original variable for proper diagnostics and variable capturing. 13057 Expr *VDInitRefExpr = nullptr; 13058 // For arrays generate initializer for single element and replace it by the 13059 // original array element in CodeGen. 13060 if (Type->isArrayType()) { 13061 VarDecl *VDInit = 13062 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13063 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13064 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13065 ElemType = ElemType.getUnqualifiedType(); 13066 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13067 ".firstprivate.temp"); 13068 InitializedEntity Entity = 13069 InitializedEntity::InitializeVariable(VDInitTemp); 13070 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13071 13072 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13073 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13074 if (Result.isInvalid()) 13075 VDPrivate->setInvalidDecl(); 13076 else 13077 VDPrivate->setInit(Result.getAs<Expr>()); 13078 // Remove temp variable declaration. 13079 Context.Deallocate(VDInitTemp); 13080 } else { 13081 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13082 ".firstprivate.temp"); 13083 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13084 RefExpr->getExprLoc()); 13085 AddInitializerToDecl(VDPrivate, 13086 DefaultLvalueConversion(VDInitRefExpr).get(), 13087 /*DirectInit=*/false); 13088 } 13089 if (VDPrivate->isInvalidDecl()) { 13090 if (IsImplicitClause) { 13091 Diag(RefExpr->getExprLoc(), 13092 diag::note_omp_task_predetermined_firstprivate_here); 13093 } 13094 continue; 13095 } 13096 CurContext->addDecl(VDPrivate); 13097 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13098 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13099 RefExpr->getExprLoc()); 13100 DeclRefExpr *Ref = nullptr; 13101 if (!VD && !CurContext->isDependentContext()) { 13102 if (TopDVar.CKind == OMPC_lastprivate) { 13103 Ref = TopDVar.PrivateCopy; 13104 } else { 13105 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13106 if (!isOpenMPCapturedDecl(D)) 13107 ExprCaptures.push_back(Ref->getDecl()); 13108 } 13109 } 13110 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13111 Vars.push_back((VD || CurContext->isDependentContext()) 13112 ? RefExpr->IgnoreParens() 13113 : Ref); 13114 PrivateCopies.push_back(VDPrivateRefExpr); 13115 Inits.push_back(VDInitRefExpr); 13116 } 13117 13118 if (Vars.empty()) 13119 return nullptr; 13120 13121 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13122 Vars, PrivateCopies, Inits, 13123 buildPreInits(Context, ExprCaptures)); 13124 } 13125 13126 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13127 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13128 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13129 SourceLocation LParenLoc, SourceLocation EndLoc) { 13130 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13131 assert(ColonLoc.isValid() && "Colon location must be valid."); 13132 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13133 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13134 /*Last=*/OMPC_LASTPRIVATE_unknown) 13135 << getOpenMPClauseName(OMPC_lastprivate); 13136 return nullptr; 13137 } 13138 13139 SmallVector<Expr *, 8> Vars; 13140 SmallVector<Expr *, 8> SrcExprs; 13141 SmallVector<Expr *, 8> DstExprs; 13142 SmallVector<Expr *, 8> AssignmentOps; 13143 SmallVector<Decl *, 4> ExprCaptures; 13144 SmallVector<Expr *, 4> ExprPostUpdates; 13145 for (Expr *RefExpr : VarList) { 13146 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13147 SourceLocation ELoc; 13148 SourceRange ERange; 13149 Expr *SimpleRefExpr = RefExpr; 13150 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13151 if (Res.second) { 13152 // It will be analyzed later. 13153 Vars.push_back(RefExpr); 13154 SrcExprs.push_back(nullptr); 13155 DstExprs.push_back(nullptr); 13156 AssignmentOps.push_back(nullptr); 13157 } 13158 ValueDecl *D = Res.first; 13159 if (!D) 13160 continue; 13161 13162 QualType Type = D->getType(); 13163 auto *VD = dyn_cast<VarDecl>(D); 13164 13165 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13166 // A variable that appears in a lastprivate clause must not have an 13167 // incomplete type or a reference type. 13168 if (RequireCompleteType(ELoc, Type, 13169 diag::err_omp_lastprivate_incomplete_type)) 13170 continue; 13171 Type = Type.getNonReferenceType(); 13172 13173 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13174 // A variable that is privatized must not have a const-qualified type 13175 // unless it is of class type with a mutable member. This restriction does 13176 // not apply to the firstprivate clause. 13177 // 13178 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13179 // A variable that appears in a lastprivate clause must not have a 13180 // const-qualified type unless it is of class type with a mutable member. 13181 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13182 continue; 13183 13184 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13185 // A list item that appears in a lastprivate clause with the conditional 13186 // modifier must be a scalar variable. 13187 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13188 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13189 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13190 VarDecl::DeclarationOnly; 13191 Diag(D->getLocation(), 13192 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13193 << D; 13194 continue; 13195 } 13196 13197 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13198 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13199 // in a Construct] 13200 // Variables with the predetermined data-sharing attributes may not be 13201 // listed in data-sharing attributes clauses, except for the cases 13202 // listed below. 13203 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13204 // A list item may appear in a firstprivate or lastprivate clause but not 13205 // both. 13206 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13207 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13208 (isOpenMPDistributeDirective(CurrDir) || 13209 DVar.CKind != OMPC_firstprivate) && 13210 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13211 Diag(ELoc, diag::err_omp_wrong_dsa) 13212 << getOpenMPClauseName(DVar.CKind) 13213 << getOpenMPClauseName(OMPC_lastprivate); 13214 reportOriginalDsa(*this, DSAStack, D, DVar); 13215 continue; 13216 } 13217 13218 // OpenMP [2.14.3.5, Restrictions, p.2] 13219 // A list item that is private within a parallel region, or that appears in 13220 // the reduction clause of a parallel construct, must not appear in a 13221 // lastprivate clause on a worksharing construct if any of the corresponding 13222 // worksharing regions ever binds to any of the corresponding parallel 13223 // regions. 13224 DSAStackTy::DSAVarData TopDVar = DVar; 13225 if (isOpenMPWorksharingDirective(CurrDir) && 13226 !isOpenMPParallelDirective(CurrDir) && 13227 !isOpenMPTeamsDirective(CurrDir)) { 13228 DVar = DSAStack->getImplicitDSA(D, true); 13229 if (DVar.CKind != OMPC_shared) { 13230 Diag(ELoc, diag::err_omp_required_access) 13231 << getOpenMPClauseName(OMPC_lastprivate) 13232 << getOpenMPClauseName(OMPC_shared); 13233 reportOriginalDsa(*this, DSAStack, D, DVar); 13234 continue; 13235 } 13236 } 13237 13238 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13239 // A variable of class type (or array thereof) that appears in a 13240 // lastprivate clause requires an accessible, unambiguous default 13241 // constructor for the class type, unless the list item is also specified 13242 // in a firstprivate clause. 13243 // A variable of class type (or array thereof) that appears in a 13244 // lastprivate clause requires an accessible, unambiguous copy assignment 13245 // operator for the class type. 13246 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13247 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13248 Type.getUnqualifiedType(), ".lastprivate.src", 13249 D->hasAttrs() ? &D->getAttrs() : nullptr); 13250 DeclRefExpr *PseudoSrcExpr = 13251 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13252 VarDecl *DstVD = 13253 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13254 D->hasAttrs() ? &D->getAttrs() : nullptr); 13255 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13256 // For arrays generate assignment operation for single element and replace 13257 // it by the original array element in CodeGen. 13258 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13259 PseudoDstExpr, PseudoSrcExpr); 13260 if (AssignmentOp.isInvalid()) 13261 continue; 13262 AssignmentOp = 13263 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13264 if (AssignmentOp.isInvalid()) 13265 continue; 13266 13267 DeclRefExpr *Ref = nullptr; 13268 if (!VD && !CurContext->isDependentContext()) { 13269 if (TopDVar.CKind == OMPC_firstprivate) { 13270 Ref = TopDVar.PrivateCopy; 13271 } else { 13272 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13273 if (!isOpenMPCapturedDecl(D)) 13274 ExprCaptures.push_back(Ref->getDecl()); 13275 } 13276 if (TopDVar.CKind == OMPC_firstprivate || 13277 (!isOpenMPCapturedDecl(D) && 13278 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13279 ExprResult RefRes = DefaultLvalueConversion(Ref); 13280 if (!RefRes.isUsable()) 13281 continue; 13282 ExprResult PostUpdateRes = 13283 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13284 RefRes.get()); 13285 if (!PostUpdateRes.isUsable()) 13286 continue; 13287 ExprPostUpdates.push_back( 13288 IgnoredValueConversions(PostUpdateRes.get()).get()); 13289 } 13290 } 13291 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13292 Vars.push_back((VD || CurContext->isDependentContext()) 13293 ? RefExpr->IgnoreParens() 13294 : Ref); 13295 SrcExprs.push_back(PseudoSrcExpr); 13296 DstExprs.push_back(PseudoDstExpr); 13297 AssignmentOps.push_back(AssignmentOp.get()); 13298 } 13299 13300 if (Vars.empty()) 13301 return nullptr; 13302 13303 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13304 Vars, SrcExprs, DstExprs, AssignmentOps, 13305 LPKind, LPKindLoc, ColonLoc, 13306 buildPreInits(Context, ExprCaptures), 13307 buildPostUpdate(*this, ExprPostUpdates)); 13308 } 13309 13310 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13311 SourceLocation StartLoc, 13312 SourceLocation LParenLoc, 13313 SourceLocation EndLoc) { 13314 SmallVector<Expr *, 8> Vars; 13315 for (Expr *RefExpr : VarList) { 13316 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13317 SourceLocation ELoc; 13318 SourceRange ERange; 13319 Expr *SimpleRefExpr = RefExpr; 13320 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13321 if (Res.second) { 13322 // It will be analyzed later. 13323 Vars.push_back(RefExpr); 13324 } 13325 ValueDecl *D = Res.first; 13326 if (!D) 13327 continue; 13328 13329 auto *VD = dyn_cast<VarDecl>(D); 13330 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13331 // in a Construct] 13332 // Variables with the predetermined data-sharing attributes may not be 13333 // listed in data-sharing attributes clauses, except for the cases 13334 // listed below. For these exceptions only, listing a predetermined 13335 // variable in a data-sharing attribute clause is allowed and overrides 13336 // the variable's predetermined data-sharing attributes. 13337 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13338 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13339 DVar.RefExpr) { 13340 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13341 << getOpenMPClauseName(OMPC_shared); 13342 reportOriginalDsa(*this, DSAStack, D, DVar); 13343 continue; 13344 } 13345 13346 DeclRefExpr *Ref = nullptr; 13347 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13348 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13349 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13350 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13351 ? RefExpr->IgnoreParens() 13352 : Ref); 13353 } 13354 13355 if (Vars.empty()) 13356 return nullptr; 13357 13358 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13359 } 13360 13361 namespace { 13362 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13363 DSAStackTy *Stack; 13364 13365 public: 13366 bool VisitDeclRefExpr(DeclRefExpr *E) { 13367 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13368 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13369 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13370 return false; 13371 if (DVar.CKind != OMPC_unknown) 13372 return true; 13373 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13374 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13375 /*FromParent=*/true); 13376 return DVarPrivate.CKind != OMPC_unknown; 13377 } 13378 return false; 13379 } 13380 bool VisitStmt(Stmt *S) { 13381 for (Stmt *Child : S->children()) { 13382 if (Child && Visit(Child)) 13383 return true; 13384 } 13385 return false; 13386 } 13387 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13388 }; 13389 } // namespace 13390 13391 namespace { 13392 // Transform MemberExpression for specified FieldDecl of current class to 13393 // DeclRefExpr to specified OMPCapturedExprDecl. 13394 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13395 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13396 ValueDecl *Field = nullptr; 13397 DeclRefExpr *CapturedExpr = nullptr; 13398 13399 public: 13400 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13401 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13402 13403 ExprResult TransformMemberExpr(MemberExpr *E) { 13404 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13405 E->getMemberDecl() == Field) { 13406 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13407 return CapturedExpr; 13408 } 13409 return BaseTransform::TransformMemberExpr(E); 13410 } 13411 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13412 }; 13413 } // namespace 13414 13415 template <typename T, typename U> 13416 static T filterLookupForUDReductionAndMapper( 13417 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13418 for (U &Set : Lookups) { 13419 for (auto *D : Set) { 13420 if (T Res = Gen(cast<ValueDecl>(D))) 13421 return Res; 13422 } 13423 } 13424 return T(); 13425 } 13426 13427 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13428 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13429 13430 for (auto RD : D->redecls()) { 13431 // Don't bother with extra checks if we already know this one isn't visible. 13432 if (RD == D) 13433 continue; 13434 13435 auto ND = cast<NamedDecl>(RD); 13436 if (LookupResult::isVisible(SemaRef, ND)) 13437 return ND; 13438 } 13439 13440 return nullptr; 13441 } 13442 13443 static void 13444 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13445 SourceLocation Loc, QualType Ty, 13446 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13447 // Find all of the associated namespaces and classes based on the 13448 // arguments we have. 13449 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13450 Sema::AssociatedClassSet AssociatedClasses; 13451 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13452 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13453 AssociatedClasses); 13454 13455 // C++ [basic.lookup.argdep]p3: 13456 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13457 // and let Y be the lookup set produced by argument dependent 13458 // lookup (defined as follows). If X contains [...] then Y is 13459 // empty. Otherwise Y is the set of declarations found in the 13460 // namespaces associated with the argument types as described 13461 // below. The set of declarations found by the lookup of the name 13462 // is the union of X and Y. 13463 // 13464 // Here, we compute Y and add its members to the overloaded 13465 // candidate set. 13466 for (auto *NS : AssociatedNamespaces) { 13467 // When considering an associated namespace, the lookup is the 13468 // same as the lookup performed when the associated namespace is 13469 // used as a qualifier (3.4.3.2) except that: 13470 // 13471 // -- Any using-directives in the associated namespace are 13472 // ignored. 13473 // 13474 // -- Any namespace-scope friend functions declared in 13475 // associated classes are visible within their respective 13476 // namespaces even if they are not visible during an ordinary 13477 // lookup (11.4). 13478 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13479 for (auto *D : R) { 13480 auto *Underlying = D; 13481 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13482 Underlying = USD->getTargetDecl(); 13483 13484 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13485 !isa<OMPDeclareMapperDecl>(Underlying)) 13486 continue; 13487 13488 if (!SemaRef.isVisible(D)) { 13489 D = findAcceptableDecl(SemaRef, D); 13490 if (!D) 13491 continue; 13492 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13493 Underlying = USD->getTargetDecl(); 13494 } 13495 Lookups.emplace_back(); 13496 Lookups.back().addDecl(Underlying); 13497 } 13498 } 13499 } 13500 13501 static ExprResult 13502 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13503 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13504 const DeclarationNameInfo &ReductionId, QualType Ty, 13505 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13506 if (ReductionIdScopeSpec.isInvalid()) 13507 return ExprError(); 13508 SmallVector<UnresolvedSet<8>, 4> Lookups; 13509 if (S) { 13510 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13511 Lookup.suppressDiagnostics(); 13512 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13513 NamedDecl *D = Lookup.getRepresentativeDecl(); 13514 do { 13515 S = S->getParent(); 13516 } while (S && !S->isDeclScope(D)); 13517 if (S) 13518 S = S->getParent(); 13519 Lookups.emplace_back(); 13520 Lookups.back().append(Lookup.begin(), Lookup.end()); 13521 Lookup.clear(); 13522 } 13523 } else if (auto *ULE = 13524 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13525 Lookups.push_back(UnresolvedSet<8>()); 13526 Decl *PrevD = nullptr; 13527 for (NamedDecl *D : ULE->decls()) { 13528 if (D == PrevD) 13529 Lookups.push_back(UnresolvedSet<8>()); 13530 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13531 Lookups.back().addDecl(DRD); 13532 PrevD = D; 13533 } 13534 } 13535 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13536 Ty->isInstantiationDependentType() || 13537 Ty->containsUnexpandedParameterPack() || 13538 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13539 return !D->isInvalidDecl() && 13540 (D->getType()->isDependentType() || 13541 D->getType()->isInstantiationDependentType() || 13542 D->getType()->containsUnexpandedParameterPack()); 13543 })) { 13544 UnresolvedSet<8> ResSet; 13545 for (const UnresolvedSet<8> &Set : Lookups) { 13546 if (Set.empty()) 13547 continue; 13548 ResSet.append(Set.begin(), Set.end()); 13549 // The last item marks the end of all declarations at the specified scope. 13550 ResSet.addDecl(Set[Set.size() - 1]); 13551 } 13552 return UnresolvedLookupExpr::Create( 13553 SemaRef.Context, /*NamingClass=*/nullptr, 13554 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13555 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13556 } 13557 // Lookup inside the classes. 13558 // C++ [over.match.oper]p3: 13559 // For a unary operator @ with an operand of a type whose 13560 // cv-unqualified version is T1, and for a binary operator @ with 13561 // a left operand of a type whose cv-unqualified version is T1 and 13562 // a right operand of a type whose cv-unqualified version is T2, 13563 // three sets of candidate functions, designated member 13564 // candidates, non-member candidates and built-in candidates, are 13565 // constructed as follows: 13566 // -- If T1 is a complete class type or a class currently being 13567 // defined, the set of member candidates is the result of the 13568 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13569 // the set of member candidates is empty. 13570 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13571 Lookup.suppressDiagnostics(); 13572 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13573 // Complete the type if it can be completed. 13574 // If the type is neither complete nor being defined, bail out now. 13575 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13576 TyRec->getDecl()->getDefinition()) { 13577 Lookup.clear(); 13578 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13579 if (Lookup.empty()) { 13580 Lookups.emplace_back(); 13581 Lookups.back().append(Lookup.begin(), Lookup.end()); 13582 } 13583 } 13584 } 13585 // Perform ADL. 13586 if (SemaRef.getLangOpts().CPlusPlus) 13587 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13588 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13589 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13590 if (!D->isInvalidDecl() && 13591 SemaRef.Context.hasSameType(D->getType(), Ty)) 13592 return D; 13593 return nullptr; 13594 })) 13595 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13596 VK_LValue, Loc); 13597 if (SemaRef.getLangOpts().CPlusPlus) { 13598 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13599 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13600 if (!D->isInvalidDecl() && 13601 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13602 !Ty.isMoreQualifiedThan(D->getType())) 13603 return D; 13604 return nullptr; 13605 })) { 13606 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13607 /*DetectVirtual=*/false); 13608 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13609 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13610 VD->getType().getUnqualifiedType()))) { 13611 if (SemaRef.CheckBaseClassAccess( 13612 Loc, VD->getType(), Ty, Paths.front(), 13613 /*DiagID=*/0) != Sema::AR_inaccessible) { 13614 SemaRef.BuildBasePathArray(Paths, BasePath); 13615 return SemaRef.BuildDeclRefExpr( 13616 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13617 } 13618 } 13619 } 13620 } 13621 } 13622 if (ReductionIdScopeSpec.isSet()) { 13623 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 13624 << Ty << Range; 13625 return ExprError(); 13626 } 13627 return ExprEmpty(); 13628 } 13629 13630 namespace { 13631 /// Data for the reduction-based clauses. 13632 struct ReductionData { 13633 /// List of original reduction items. 13634 SmallVector<Expr *, 8> Vars; 13635 /// List of private copies of the reduction items. 13636 SmallVector<Expr *, 8> Privates; 13637 /// LHS expressions for the reduction_op expressions. 13638 SmallVector<Expr *, 8> LHSs; 13639 /// RHS expressions for the reduction_op expressions. 13640 SmallVector<Expr *, 8> RHSs; 13641 /// Reduction operation expression. 13642 SmallVector<Expr *, 8> ReductionOps; 13643 /// Taskgroup descriptors for the corresponding reduction items in 13644 /// in_reduction clauses. 13645 SmallVector<Expr *, 8> TaskgroupDescriptors; 13646 /// List of captures for clause. 13647 SmallVector<Decl *, 4> ExprCaptures; 13648 /// List of postupdate expressions. 13649 SmallVector<Expr *, 4> ExprPostUpdates; 13650 ReductionData() = delete; 13651 /// Reserves required memory for the reduction data. 13652 ReductionData(unsigned Size) { 13653 Vars.reserve(Size); 13654 Privates.reserve(Size); 13655 LHSs.reserve(Size); 13656 RHSs.reserve(Size); 13657 ReductionOps.reserve(Size); 13658 TaskgroupDescriptors.reserve(Size); 13659 ExprCaptures.reserve(Size); 13660 ExprPostUpdates.reserve(Size); 13661 } 13662 /// Stores reduction item and reduction operation only (required for dependent 13663 /// reduction item). 13664 void push(Expr *Item, Expr *ReductionOp) { 13665 Vars.emplace_back(Item); 13666 Privates.emplace_back(nullptr); 13667 LHSs.emplace_back(nullptr); 13668 RHSs.emplace_back(nullptr); 13669 ReductionOps.emplace_back(ReductionOp); 13670 TaskgroupDescriptors.emplace_back(nullptr); 13671 } 13672 /// Stores reduction data. 13673 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13674 Expr *TaskgroupDescriptor) { 13675 Vars.emplace_back(Item); 13676 Privates.emplace_back(Private); 13677 LHSs.emplace_back(LHS); 13678 RHSs.emplace_back(RHS); 13679 ReductionOps.emplace_back(ReductionOp); 13680 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13681 } 13682 }; 13683 } // namespace 13684 13685 static bool checkOMPArraySectionConstantForReduction( 13686 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13687 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13688 const Expr *Length = OASE->getLength(); 13689 if (Length == nullptr) { 13690 // For array sections of the form [1:] or [:], we would need to analyze 13691 // the lower bound... 13692 if (OASE->getColonLoc().isValid()) 13693 return false; 13694 13695 // This is an array subscript which has implicit length 1! 13696 SingleElement = true; 13697 ArraySizes.push_back(llvm::APSInt::get(1)); 13698 } else { 13699 Expr::EvalResult Result; 13700 if (!Length->EvaluateAsInt(Result, Context)) 13701 return false; 13702 13703 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13704 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13705 ArraySizes.push_back(ConstantLengthValue); 13706 } 13707 13708 // Get the base of this array section and walk up from there. 13709 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13710 13711 // We require length = 1 for all array sections except the right-most to 13712 // guarantee that the memory region is contiguous and has no holes in it. 13713 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13714 Length = TempOASE->getLength(); 13715 if (Length == nullptr) { 13716 // For array sections of the form [1:] or [:], we would need to analyze 13717 // the lower bound... 13718 if (OASE->getColonLoc().isValid()) 13719 return false; 13720 13721 // This is an array subscript which has implicit length 1! 13722 ArraySizes.push_back(llvm::APSInt::get(1)); 13723 } else { 13724 Expr::EvalResult Result; 13725 if (!Length->EvaluateAsInt(Result, Context)) 13726 return false; 13727 13728 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13729 if (ConstantLengthValue.getSExtValue() != 1) 13730 return false; 13731 13732 ArraySizes.push_back(ConstantLengthValue); 13733 } 13734 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13735 } 13736 13737 // If we have a single element, we don't need to add the implicit lengths. 13738 if (!SingleElement) { 13739 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13740 // Has implicit length 1! 13741 ArraySizes.push_back(llvm::APSInt::get(1)); 13742 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13743 } 13744 } 13745 13746 // This array section can be privatized as a single value or as a constant 13747 // sized array. 13748 return true; 13749 } 13750 13751 static bool actOnOMPReductionKindClause( 13752 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13753 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13754 SourceLocation ColonLoc, SourceLocation EndLoc, 13755 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13756 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13757 DeclarationName DN = ReductionId.getName(); 13758 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13759 BinaryOperatorKind BOK = BO_Comma; 13760 13761 ASTContext &Context = S.Context; 13762 // OpenMP [2.14.3.6, reduction clause] 13763 // C 13764 // reduction-identifier is either an identifier or one of the following 13765 // operators: +, -, *, &, |, ^, && and || 13766 // C++ 13767 // reduction-identifier is either an id-expression or one of the following 13768 // operators: +, -, *, &, |, ^, && and || 13769 switch (OOK) { 13770 case OO_Plus: 13771 case OO_Minus: 13772 BOK = BO_Add; 13773 break; 13774 case OO_Star: 13775 BOK = BO_Mul; 13776 break; 13777 case OO_Amp: 13778 BOK = BO_And; 13779 break; 13780 case OO_Pipe: 13781 BOK = BO_Or; 13782 break; 13783 case OO_Caret: 13784 BOK = BO_Xor; 13785 break; 13786 case OO_AmpAmp: 13787 BOK = BO_LAnd; 13788 break; 13789 case OO_PipePipe: 13790 BOK = BO_LOr; 13791 break; 13792 case OO_New: 13793 case OO_Delete: 13794 case OO_Array_New: 13795 case OO_Array_Delete: 13796 case OO_Slash: 13797 case OO_Percent: 13798 case OO_Tilde: 13799 case OO_Exclaim: 13800 case OO_Equal: 13801 case OO_Less: 13802 case OO_Greater: 13803 case OO_LessEqual: 13804 case OO_GreaterEqual: 13805 case OO_PlusEqual: 13806 case OO_MinusEqual: 13807 case OO_StarEqual: 13808 case OO_SlashEqual: 13809 case OO_PercentEqual: 13810 case OO_CaretEqual: 13811 case OO_AmpEqual: 13812 case OO_PipeEqual: 13813 case OO_LessLess: 13814 case OO_GreaterGreater: 13815 case OO_LessLessEqual: 13816 case OO_GreaterGreaterEqual: 13817 case OO_EqualEqual: 13818 case OO_ExclaimEqual: 13819 case OO_Spaceship: 13820 case OO_PlusPlus: 13821 case OO_MinusMinus: 13822 case OO_Comma: 13823 case OO_ArrowStar: 13824 case OO_Arrow: 13825 case OO_Call: 13826 case OO_Subscript: 13827 case OO_Conditional: 13828 case OO_Coawait: 13829 case NUM_OVERLOADED_OPERATORS: 13830 llvm_unreachable("Unexpected reduction identifier"); 13831 case OO_None: 13832 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13833 if (II->isStr("max")) 13834 BOK = BO_GT; 13835 else if (II->isStr("min")) 13836 BOK = BO_LT; 13837 } 13838 break; 13839 } 13840 SourceRange ReductionIdRange; 13841 if (ReductionIdScopeSpec.isValid()) 13842 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13843 else 13844 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13845 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13846 13847 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13848 bool FirstIter = true; 13849 for (Expr *RefExpr : VarList) { 13850 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13851 // OpenMP [2.1, C/C++] 13852 // A list item is a variable or array section, subject to the restrictions 13853 // specified in Section 2.4 on page 42 and in each of the sections 13854 // describing clauses and directives for which a list appears. 13855 // OpenMP [2.14.3.3, Restrictions, p.1] 13856 // A variable that is part of another variable (as an array or 13857 // structure element) cannot appear in a private clause. 13858 if (!FirstIter && IR != ER) 13859 ++IR; 13860 FirstIter = false; 13861 SourceLocation ELoc; 13862 SourceRange ERange; 13863 Expr *SimpleRefExpr = RefExpr; 13864 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13865 /*AllowArraySection=*/true); 13866 if (Res.second) { 13867 // Try to find 'declare reduction' corresponding construct before using 13868 // builtin/overloaded operators. 13869 QualType Type = Context.DependentTy; 13870 CXXCastPath BasePath; 13871 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13872 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13873 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13874 Expr *ReductionOp = nullptr; 13875 if (S.CurContext->isDependentContext() && 13876 (DeclareReductionRef.isUnset() || 13877 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13878 ReductionOp = DeclareReductionRef.get(); 13879 // It will be analyzed later. 13880 RD.push(RefExpr, ReductionOp); 13881 } 13882 ValueDecl *D = Res.first; 13883 if (!D) 13884 continue; 13885 13886 Expr *TaskgroupDescriptor = nullptr; 13887 QualType Type; 13888 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13889 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13890 if (ASE) { 13891 Type = ASE->getType().getNonReferenceType(); 13892 } else if (OASE) { 13893 QualType BaseType = 13894 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13895 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13896 Type = ATy->getElementType(); 13897 else 13898 Type = BaseType->getPointeeType(); 13899 Type = Type.getNonReferenceType(); 13900 } else { 13901 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13902 } 13903 auto *VD = dyn_cast<VarDecl>(D); 13904 13905 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13906 // A variable that appears in a private clause must not have an incomplete 13907 // type or a reference type. 13908 if (S.RequireCompleteType(ELoc, D->getType(), 13909 diag::err_omp_reduction_incomplete_type)) 13910 continue; 13911 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13912 // A list item that appears in a reduction clause must not be 13913 // const-qualified. 13914 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13915 /*AcceptIfMutable*/ false, ASE || OASE)) 13916 continue; 13917 13918 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13919 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13920 // If a list-item is a reference type then it must bind to the same object 13921 // for all threads of the team. 13922 if (!ASE && !OASE) { 13923 if (VD) { 13924 VarDecl *VDDef = VD->getDefinition(); 13925 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13926 DSARefChecker Check(Stack); 13927 if (Check.Visit(VDDef->getInit())) { 13928 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13929 << getOpenMPClauseName(ClauseKind) << ERange; 13930 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13931 continue; 13932 } 13933 } 13934 } 13935 13936 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13937 // in a Construct] 13938 // Variables with the predetermined data-sharing attributes may not be 13939 // listed in data-sharing attributes clauses, except for the cases 13940 // listed below. For these exceptions only, listing a predetermined 13941 // variable in a data-sharing attribute clause is allowed and overrides 13942 // the variable's predetermined data-sharing attributes. 13943 // OpenMP [2.14.3.6, Restrictions, p.3] 13944 // Any number of reduction clauses can be specified on the directive, 13945 // but a list item can appear only once in the reduction clauses for that 13946 // directive. 13947 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13948 if (DVar.CKind == OMPC_reduction) { 13949 S.Diag(ELoc, diag::err_omp_once_referenced) 13950 << getOpenMPClauseName(ClauseKind); 13951 if (DVar.RefExpr) 13952 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13953 continue; 13954 } 13955 if (DVar.CKind != OMPC_unknown) { 13956 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13957 << getOpenMPClauseName(DVar.CKind) 13958 << getOpenMPClauseName(OMPC_reduction); 13959 reportOriginalDsa(S, Stack, D, DVar); 13960 continue; 13961 } 13962 13963 // OpenMP [2.14.3.6, Restrictions, p.1] 13964 // A list item that appears in a reduction clause of a worksharing 13965 // construct must be shared in the parallel regions to which any of the 13966 // worksharing regions arising from the worksharing construct bind. 13967 if (isOpenMPWorksharingDirective(CurrDir) && 13968 !isOpenMPParallelDirective(CurrDir) && 13969 !isOpenMPTeamsDirective(CurrDir)) { 13970 DVar = Stack->getImplicitDSA(D, true); 13971 if (DVar.CKind != OMPC_shared) { 13972 S.Diag(ELoc, diag::err_omp_required_access) 13973 << getOpenMPClauseName(OMPC_reduction) 13974 << getOpenMPClauseName(OMPC_shared); 13975 reportOriginalDsa(S, Stack, D, DVar); 13976 continue; 13977 } 13978 } 13979 } 13980 13981 // Try to find 'declare reduction' corresponding construct before using 13982 // builtin/overloaded operators. 13983 CXXCastPath BasePath; 13984 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13985 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13986 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13987 if (DeclareReductionRef.isInvalid()) 13988 continue; 13989 if (S.CurContext->isDependentContext() && 13990 (DeclareReductionRef.isUnset() || 13991 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13992 RD.push(RefExpr, DeclareReductionRef.get()); 13993 continue; 13994 } 13995 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13996 // Not allowed reduction identifier is found. 13997 S.Diag(ReductionId.getBeginLoc(), 13998 diag::err_omp_unknown_reduction_identifier) 13999 << Type << ReductionIdRange; 14000 continue; 14001 } 14002 14003 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14004 // The type of a list item that appears in a reduction clause must be valid 14005 // for the reduction-identifier. For a max or min reduction in C, the type 14006 // of the list item must be an allowed arithmetic data type: char, int, 14007 // float, double, or _Bool, possibly modified with long, short, signed, or 14008 // unsigned. For a max or min reduction in C++, the type of the list item 14009 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14010 // double, or bool, possibly modified with long, short, signed, or unsigned. 14011 if (DeclareReductionRef.isUnset()) { 14012 if ((BOK == BO_GT || BOK == BO_LT) && 14013 !(Type->isScalarType() || 14014 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14015 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14016 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14017 if (!ASE && !OASE) { 14018 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14019 VarDecl::DeclarationOnly; 14020 S.Diag(D->getLocation(), 14021 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14022 << D; 14023 } 14024 continue; 14025 } 14026 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14027 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14028 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14029 << getOpenMPClauseName(ClauseKind); 14030 if (!ASE && !OASE) { 14031 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14032 VarDecl::DeclarationOnly; 14033 S.Diag(D->getLocation(), 14034 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14035 << D; 14036 } 14037 continue; 14038 } 14039 } 14040 14041 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14042 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14043 D->hasAttrs() ? &D->getAttrs() : nullptr); 14044 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14045 D->hasAttrs() ? &D->getAttrs() : nullptr); 14046 QualType PrivateTy = Type; 14047 14048 // Try if we can determine constant lengths for all array sections and avoid 14049 // the VLA. 14050 bool ConstantLengthOASE = false; 14051 if (OASE) { 14052 bool SingleElement; 14053 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14054 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14055 Context, OASE, SingleElement, ArraySizes); 14056 14057 // If we don't have a single element, we must emit a constant array type. 14058 if (ConstantLengthOASE && !SingleElement) { 14059 for (llvm::APSInt &Size : ArraySizes) 14060 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14061 ArrayType::Normal, 14062 /*IndexTypeQuals=*/0); 14063 } 14064 } 14065 14066 if ((OASE && !ConstantLengthOASE) || 14067 (!OASE && !ASE && 14068 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14069 if (!Context.getTargetInfo().isVLASupported()) { 14070 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14071 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14072 S.Diag(ELoc, diag::note_vla_unsupported); 14073 } else { 14074 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14075 S.targetDiag(ELoc, diag::note_vla_unsupported); 14076 } 14077 continue; 14078 } 14079 // For arrays/array sections only: 14080 // Create pseudo array type for private copy. The size for this array will 14081 // be generated during codegen. 14082 // For array subscripts or single variables Private Ty is the same as Type 14083 // (type of the variable or single array element). 14084 PrivateTy = Context.getVariableArrayType( 14085 Type, 14086 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14087 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14088 } else if (!ASE && !OASE && 14089 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14090 PrivateTy = D->getType().getNonReferenceType(); 14091 } 14092 // Private copy. 14093 VarDecl *PrivateVD = 14094 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14095 D->hasAttrs() ? &D->getAttrs() : nullptr, 14096 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14097 // Add initializer for private variable. 14098 Expr *Init = nullptr; 14099 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14100 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14101 if (DeclareReductionRef.isUsable()) { 14102 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14103 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14104 if (DRD->getInitializer()) { 14105 Init = DRDRef; 14106 RHSVD->setInit(DRDRef); 14107 RHSVD->setInitStyle(VarDecl::CallInit); 14108 } 14109 } else { 14110 switch (BOK) { 14111 case BO_Add: 14112 case BO_Xor: 14113 case BO_Or: 14114 case BO_LOr: 14115 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14116 if (Type->isScalarType() || Type->isAnyComplexType()) 14117 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14118 break; 14119 case BO_Mul: 14120 case BO_LAnd: 14121 if (Type->isScalarType() || Type->isAnyComplexType()) { 14122 // '*' and '&&' reduction ops - initializer is '1'. 14123 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14124 } 14125 break; 14126 case BO_And: { 14127 // '&' reduction op - initializer is '~0'. 14128 QualType OrigType = Type; 14129 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14130 Type = ComplexTy->getElementType(); 14131 if (Type->isRealFloatingType()) { 14132 llvm::APFloat InitValue = 14133 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14134 /*isIEEE=*/true); 14135 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14136 Type, ELoc); 14137 } else if (Type->isScalarType()) { 14138 uint64_t Size = Context.getTypeSize(Type); 14139 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14140 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14141 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14142 } 14143 if (Init && OrigType->isAnyComplexType()) { 14144 // Init = 0xFFFF + 0xFFFFi; 14145 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14146 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14147 } 14148 Type = OrigType; 14149 break; 14150 } 14151 case BO_LT: 14152 case BO_GT: { 14153 // 'min' reduction op - initializer is 'Largest representable number in 14154 // the reduction list item type'. 14155 // 'max' reduction op - initializer is 'Least representable number in 14156 // the reduction list item type'. 14157 if (Type->isIntegerType() || Type->isPointerType()) { 14158 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14159 uint64_t Size = Context.getTypeSize(Type); 14160 QualType IntTy = 14161 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14162 llvm::APInt InitValue = 14163 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14164 : llvm::APInt::getMinValue(Size) 14165 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14166 : llvm::APInt::getMaxValue(Size); 14167 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14168 if (Type->isPointerType()) { 14169 // Cast to pointer type. 14170 ExprResult CastExpr = S.BuildCStyleCastExpr( 14171 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14172 if (CastExpr.isInvalid()) 14173 continue; 14174 Init = CastExpr.get(); 14175 } 14176 } else if (Type->isRealFloatingType()) { 14177 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14178 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14179 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14180 Type, ELoc); 14181 } 14182 break; 14183 } 14184 case BO_PtrMemD: 14185 case BO_PtrMemI: 14186 case BO_MulAssign: 14187 case BO_Div: 14188 case BO_Rem: 14189 case BO_Sub: 14190 case BO_Shl: 14191 case BO_Shr: 14192 case BO_LE: 14193 case BO_GE: 14194 case BO_EQ: 14195 case BO_NE: 14196 case BO_Cmp: 14197 case BO_AndAssign: 14198 case BO_XorAssign: 14199 case BO_OrAssign: 14200 case BO_Assign: 14201 case BO_AddAssign: 14202 case BO_SubAssign: 14203 case BO_DivAssign: 14204 case BO_RemAssign: 14205 case BO_ShlAssign: 14206 case BO_ShrAssign: 14207 case BO_Comma: 14208 llvm_unreachable("Unexpected reduction operation"); 14209 } 14210 } 14211 if (Init && DeclareReductionRef.isUnset()) 14212 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14213 else if (!Init) 14214 S.ActOnUninitializedDecl(RHSVD); 14215 if (RHSVD->isInvalidDecl()) 14216 continue; 14217 if (!RHSVD->hasInit() && 14218 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14219 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14220 << Type << ReductionIdRange; 14221 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14222 VarDecl::DeclarationOnly; 14223 S.Diag(D->getLocation(), 14224 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14225 << D; 14226 continue; 14227 } 14228 // Store initializer for single element in private copy. Will be used during 14229 // codegen. 14230 PrivateVD->setInit(RHSVD->getInit()); 14231 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14232 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14233 ExprResult ReductionOp; 14234 if (DeclareReductionRef.isUsable()) { 14235 QualType RedTy = DeclareReductionRef.get()->getType(); 14236 QualType PtrRedTy = Context.getPointerType(RedTy); 14237 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14238 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14239 if (!BasePath.empty()) { 14240 LHS = S.DefaultLvalueConversion(LHS.get()); 14241 RHS = S.DefaultLvalueConversion(RHS.get()); 14242 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14243 CK_UncheckedDerivedToBase, LHS.get(), 14244 &BasePath, LHS.get()->getValueKind()); 14245 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14246 CK_UncheckedDerivedToBase, RHS.get(), 14247 &BasePath, RHS.get()->getValueKind()); 14248 } 14249 FunctionProtoType::ExtProtoInfo EPI; 14250 QualType Params[] = {PtrRedTy, PtrRedTy}; 14251 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14252 auto *OVE = new (Context) OpaqueValueExpr( 14253 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14254 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14255 Expr *Args[] = {LHS.get(), RHS.get()}; 14256 ReductionOp = 14257 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14258 } else { 14259 ReductionOp = S.BuildBinOp( 14260 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14261 if (ReductionOp.isUsable()) { 14262 if (BOK != BO_LT && BOK != BO_GT) { 14263 ReductionOp = 14264 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14265 BO_Assign, LHSDRE, ReductionOp.get()); 14266 } else { 14267 auto *ConditionalOp = new (Context) 14268 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14269 Type, VK_LValue, OK_Ordinary); 14270 ReductionOp = 14271 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14272 BO_Assign, LHSDRE, ConditionalOp); 14273 } 14274 if (ReductionOp.isUsable()) 14275 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14276 /*DiscardedValue*/ false); 14277 } 14278 if (!ReductionOp.isUsable()) 14279 continue; 14280 } 14281 14282 // OpenMP [2.15.4.6, Restrictions, p.2] 14283 // A list item that appears in an in_reduction clause of a task construct 14284 // must appear in a task_reduction clause of a construct associated with a 14285 // taskgroup region that includes the participating task in its taskgroup 14286 // set. The construct associated with the innermost region that meets this 14287 // condition must specify the same reduction-identifier as the in_reduction 14288 // clause. 14289 if (ClauseKind == OMPC_in_reduction) { 14290 SourceRange ParentSR; 14291 BinaryOperatorKind ParentBOK; 14292 const Expr *ParentReductionOp; 14293 Expr *ParentBOKTD, *ParentReductionOpTD; 14294 DSAStackTy::DSAVarData ParentBOKDSA = 14295 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14296 ParentBOKTD); 14297 DSAStackTy::DSAVarData ParentReductionOpDSA = 14298 Stack->getTopMostTaskgroupReductionData( 14299 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14300 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14301 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14302 if (!IsParentBOK && !IsParentReductionOp) { 14303 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 14304 continue; 14305 } 14306 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14307 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 14308 IsParentReductionOp) { 14309 bool EmitError = true; 14310 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14311 llvm::FoldingSetNodeID RedId, ParentRedId; 14312 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14313 DeclareReductionRef.get()->Profile(RedId, Context, 14314 /*Canonical=*/true); 14315 EmitError = RedId != ParentRedId; 14316 } 14317 if (EmitError) { 14318 S.Diag(ReductionId.getBeginLoc(), 14319 diag::err_omp_reduction_identifier_mismatch) 14320 << ReductionIdRange << RefExpr->getSourceRange(); 14321 S.Diag(ParentSR.getBegin(), 14322 diag::note_omp_previous_reduction_identifier) 14323 << ParentSR 14324 << (IsParentBOK ? ParentBOKDSA.RefExpr 14325 : ParentReductionOpDSA.RefExpr) 14326 ->getSourceRange(); 14327 continue; 14328 } 14329 } 14330 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14331 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 14332 } 14333 14334 DeclRefExpr *Ref = nullptr; 14335 Expr *VarsExpr = RefExpr->IgnoreParens(); 14336 if (!VD && !S.CurContext->isDependentContext()) { 14337 if (ASE || OASE) { 14338 TransformExprToCaptures RebuildToCapture(S, D); 14339 VarsExpr = 14340 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14341 Ref = RebuildToCapture.getCapturedExpr(); 14342 } else { 14343 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14344 } 14345 if (!S.isOpenMPCapturedDecl(D)) { 14346 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14347 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14348 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14349 if (!RefRes.isUsable()) 14350 continue; 14351 ExprResult PostUpdateRes = 14352 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14353 RefRes.get()); 14354 if (!PostUpdateRes.isUsable()) 14355 continue; 14356 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14357 Stack->getCurrentDirective() == OMPD_taskgroup) { 14358 S.Diag(RefExpr->getExprLoc(), 14359 diag::err_omp_reduction_non_addressable_expression) 14360 << RefExpr->getSourceRange(); 14361 continue; 14362 } 14363 RD.ExprPostUpdates.emplace_back( 14364 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14365 } 14366 } 14367 } 14368 // All reduction items are still marked as reduction (to do not increase 14369 // code base size). 14370 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 14371 if (CurrDir == OMPD_taskgroup) { 14372 if (DeclareReductionRef.isUsable()) 14373 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14374 DeclareReductionRef.get()); 14375 else 14376 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14377 } 14378 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14379 TaskgroupDescriptor); 14380 } 14381 return RD.Vars.empty(); 14382 } 14383 14384 OMPClause *Sema::ActOnOpenMPReductionClause( 14385 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14386 SourceLocation ColonLoc, SourceLocation EndLoc, 14387 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14388 ArrayRef<Expr *> UnresolvedReductions) { 14389 ReductionData RD(VarList.size()); 14390 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14391 StartLoc, LParenLoc, ColonLoc, EndLoc, 14392 ReductionIdScopeSpec, ReductionId, 14393 UnresolvedReductions, RD)) 14394 return nullptr; 14395 14396 return OMPReductionClause::Create( 14397 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14398 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14399 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14400 buildPreInits(Context, RD.ExprCaptures), 14401 buildPostUpdate(*this, RD.ExprPostUpdates)); 14402 } 14403 14404 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14405 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14406 SourceLocation ColonLoc, SourceLocation EndLoc, 14407 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14408 ArrayRef<Expr *> UnresolvedReductions) { 14409 ReductionData RD(VarList.size()); 14410 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14411 StartLoc, LParenLoc, ColonLoc, EndLoc, 14412 ReductionIdScopeSpec, ReductionId, 14413 UnresolvedReductions, RD)) 14414 return nullptr; 14415 14416 return OMPTaskReductionClause::Create( 14417 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14418 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14419 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14420 buildPreInits(Context, RD.ExprCaptures), 14421 buildPostUpdate(*this, RD.ExprPostUpdates)); 14422 } 14423 14424 OMPClause *Sema::ActOnOpenMPInReductionClause( 14425 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14426 SourceLocation ColonLoc, SourceLocation EndLoc, 14427 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14428 ArrayRef<Expr *> UnresolvedReductions) { 14429 ReductionData RD(VarList.size()); 14430 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14431 StartLoc, LParenLoc, ColonLoc, EndLoc, 14432 ReductionIdScopeSpec, ReductionId, 14433 UnresolvedReductions, RD)) 14434 return nullptr; 14435 14436 return OMPInReductionClause::Create( 14437 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14438 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14439 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14440 buildPreInits(Context, RD.ExprCaptures), 14441 buildPostUpdate(*this, RD.ExprPostUpdates)); 14442 } 14443 14444 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14445 SourceLocation LinLoc) { 14446 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14447 LinKind == OMPC_LINEAR_unknown) { 14448 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14449 return true; 14450 } 14451 return false; 14452 } 14453 14454 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14455 OpenMPLinearClauseKind LinKind, 14456 QualType Type) { 14457 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14458 // A variable must not have an incomplete type or a reference type. 14459 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14460 return true; 14461 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14462 !Type->isReferenceType()) { 14463 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14464 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14465 return true; 14466 } 14467 Type = Type.getNonReferenceType(); 14468 14469 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14470 // A variable that is privatized must not have a const-qualified type 14471 // unless it is of class type with a mutable member. This restriction does 14472 // not apply to the firstprivate clause. 14473 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14474 return true; 14475 14476 // A list item must be of integral or pointer type. 14477 Type = Type.getUnqualifiedType().getCanonicalType(); 14478 const auto *Ty = Type.getTypePtrOrNull(); 14479 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 14480 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 14481 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14482 if (D) { 14483 bool IsDecl = 14484 !VD || 14485 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14486 Diag(D->getLocation(), 14487 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14488 << D; 14489 } 14490 return true; 14491 } 14492 return false; 14493 } 14494 14495 OMPClause *Sema::ActOnOpenMPLinearClause( 14496 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14497 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14498 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14499 SmallVector<Expr *, 8> Vars; 14500 SmallVector<Expr *, 8> Privates; 14501 SmallVector<Expr *, 8> Inits; 14502 SmallVector<Decl *, 4> ExprCaptures; 14503 SmallVector<Expr *, 4> ExprPostUpdates; 14504 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14505 LinKind = OMPC_LINEAR_val; 14506 for (Expr *RefExpr : VarList) { 14507 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14508 SourceLocation ELoc; 14509 SourceRange ERange; 14510 Expr *SimpleRefExpr = RefExpr; 14511 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14512 if (Res.second) { 14513 // It will be analyzed later. 14514 Vars.push_back(RefExpr); 14515 Privates.push_back(nullptr); 14516 Inits.push_back(nullptr); 14517 } 14518 ValueDecl *D = Res.first; 14519 if (!D) 14520 continue; 14521 14522 QualType Type = D->getType(); 14523 auto *VD = dyn_cast<VarDecl>(D); 14524 14525 // OpenMP [2.14.3.7, linear clause] 14526 // A list-item cannot appear in more than one linear clause. 14527 // A list-item that appears in a linear clause cannot appear in any 14528 // other data-sharing attribute clause. 14529 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14530 if (DVar.RefExpr) { 14531 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14532 << getOpenMPClauseName(OMPC_linear); 14533 reportOriginalDsa(*this, DSAStack, D, DVar); 14534 continue; 14535 } 14536 14537 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14538 continue; 14539 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14540 14541 // Build private copy of original var. 14542 VarDecl *Private = 14543 buildVarDecl(*this, ELoc, Type, D->getName(), 14544 D->hasAttrs() ? &D->getAttrs() : nullptr, 14545 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14546 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14547 // Build var to save initial value. 14548 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14549 Expr *InitExpr; 14550 DeclRefExpr *Ref = nullptr; 14551 if (!VD && !CurContext->isDependentContext()) { 14552 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14553 if (!isOpenMPCapturedDecl(D)) { 14554 ExprCaptures.push_back(Ref->getDecl()); 14555 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14556 ExprResult RefRes = DefaultLvalueConversion(Ref); 14557 if (!RefRes.isUsable()) 14558 continue; 14559 ExprResult PostUpdateRes = 14560 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14561 SimpleRefExpr, RefRes.get()); 14562 if (!PostUpdateRes.isUsable()) 14563 continue; 14564 ExprPostUpdates.push_back( 14565 IgnoredValueConversions(PostUpdateRes.get()).get()); 14566 } 14567 } 14568 } 14569 if (LinKind == OMPC_LINEAR_uval) 14570 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14571 else 14572 InitExpr = VD ? SimpleRefExpr : Ref; 14573 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14574 /*DirectInit=*/false); 14575 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14576 14577 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14578 Vars.push_back((VD || CurContext->isDependentContext()) 14579 ? RefExpr->IgnoreParens() 14580 : Ref); 14581 Privates.push_back(PrivateRef); 14582 Inits.push_back(InitRef); 14583 } 14584 14585 if (Vars.empty()) 14586 return nullptr; 14587 14588 Expr *StepExpr = Step; 14589 Expr *CalcStepExpr = nullptr; 14590 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14591 !Step->isInstantiationDependent() && 14592 !Step->containsUnexpandedParameterPack()) { 14593 SourceLocation StepLoc = Step->getBeginLoc(); 14594 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14595 if (Val.isInvalid()) 14596 return nullptr; 14597 StepExpr = Val.get(); 14598 14599 // Build var to save the step value. 14600 VarDecl *SaveVar = 14601 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14602 ExprResult SaveRef = 14603 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14604 ExprResult CalcStep = 14605 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14606 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14607 14608 // Warn about zero linear step (it would be probably better specified as 14609 // making corresponding variables 'const'). 14610 llvm::APSInt Result; 14611 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14612 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14613 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14614 << (Vars.size() > 1); 14615 if (!IsConstant && CalcStep.isUsable()) { 14616 // Calculate the step beforehand instead of doing this on each iteration. 14617 // (This is not used if the number of iterations may be kfold-ed). 14618 CalcStepExpr = CalcStep.get(); 14619 } 14620 } 14621 14622 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14623 ColonLoc, EndLoc, Vars, Privates, Inits, 14624 StepExpr, CalcStepExpr, 14625 buildPreInits(Context, ExprCaptures), 14626 buildPostUpdate(*this, ExprPostUpdates)); 14627 } 14628 14629 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14630 Expr *NumIterations, Sema &SemaRef, 14631 Scope *S, DSAStackTy *Stack) { 14632 // Walk the vars and build update/final expressions for the CodeGen. 14633 SmallVector<Expr *, 8> Updates; 14634 SmallVector<Expr *, 8> Finals; 14635 SmallVector<Expr *, 8> UsedExprs; 14636 Expr *Step = Clause.getStep(); 14637 Expr *CalcStep = Clause.getCalcStep(); 14638 // OpenMP [2.14.3.7, linear clause] 14639 // If linear-step is not specified it is assumed to be 1. 14640 if (!Step) 14641 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14642 else if (CalcStep) 14643 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14644 bool HasErrors = false; 14645 auto CurInit = Clause.inits().begin(); 14646 auto CurPrivate = Clause.privates().begin(); 14647 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14648 for (Expr *RefExpr : Clause.varlists()) { 14649 SourceLocation ELoc; 14650 SourceRange ERange; 14651 Expr *SimpleRefExpr = RefExpr; 14652 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14653 ValueDecl *D = Res.first; 14654 if (Res.second || !D) { 14655 Updates.push_back(nullptr); 14656 Finals.push_back(nullptr); 14657 HasErrors = true; 14658 continue; 14659 } 14660 auto &&Info = Stack->isLoopControlVariable(D); 14661 // OpenMP [2.15.11, distribute simd Construct] 14662 // A list item may not appear in a linear clause, unless it is the loop 14663 // iteration variable. 14664 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14665 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14666 SemaRef.Diag(ELoc, 14667 diag::err_omp_linear_distribute_var_non_loop_iteration); 14668 Updates.push_back(nullptr); 14669 Finals.push_back(nullptr); 14670 HasErrors = true; 14671 continue; 14672 } 14673 Expr *InitExpr = *CurInit; 14674 14675 // Build privatized reference to the current linear var. 14676 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14677 Expr *CapturedRef; 14678 if (LinKind == OMPC_LINEAR_uval) 14679 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14680 else 14681 CapturedRef = 14682 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14683 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14684 /*RefersToCapture=*/true); 14685 14686 // Build update: Var = InitExpr + IV * Step 14687 ExprResult Update; 14688 if (!Info.first) 14689 Update = buildCounterUpdate( 14690 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14691 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14692 else 14693 Update = *CurPrivate; 14694 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14695 /*DiscardedValue*/ false); 14696 14697 // Build final: Var = InitExpr + NumIterations * Step 14698 ExprResult Final; 14699 if (!Info.first) 14700 Final = 14701 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14702 InitExpr, NumIterations, Step, /*Subtract=*/false, 14703 /*IsNonRectangularLB=*/false); 14704 else 14705 Final = *CurPrivate; 14706 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14707 /*DiscardedValue*/ false); 14708 14709 if (!Update.isUsable() || !Final.isUsable()) { 14710 Updates.push_back(nullptr); 14711 Finals.push_back(nullptr); 14712 UsedExprs.push_back(nullptr); 14713 HasErrors = true; 14714 } else { 14715 Updates.push_back(Update.get()); 14716 Finals.push_back(Final.get()); 14717 if (!Info.first) 14718 UsedExprs.push_back(SimpleRefExpr); 14719 } 14720 ++CurInit; 14721 ++CurPrivate; 14722 } 14723 if (Expr *S = Clause.getStep()) 14724 UsedExprs.push_back(S); 14725 // Fill the remaining part with the nullptr. 14726 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14727 Clause.setUpdates(Updates); 14728 Clause.setFinals(Finals); 14729 Clause.setUsedExprs(UsedExprs); 14730 return HasErrors; 14731 } 14732 14733 OMPClause *Sema::ActOnOpenMPAlignedClause( 14734 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14735 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14736 SmallVector<Expr *, 8> Vars; 14737 for (Expr *RefExpr : VarList) { 14738 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14739 SourceLocation ELoc; 14740 SourceRange ERange; 14741 Expr *SimpleRefExpr = RefExpr; 14742 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14743 if (Res.second) { 14744 // It will be analyzed later. 14745 Vars.push_back(RefExpr); 14746 } 14747 ValueDecl *D = Res.first; 14748 if (!D) 14749 continue; 14750 14751 QualType QType = D->getType(); 14752 auto *VD = dyn_cast<VarDecl>(D); 14753 14754 // OpenMP [2.8.1, simd construct, Restrictions] 14755 // The type of list items appearing in the aligned clause must be 14756 // array, pointer, reference to array, or reference to pointer. 14757 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14758 const Type *Ty = QType.getTypePtrOrNull(); 14759 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14760 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14761 << QType << getLangOpts().CPlusPlus << ERange; 14762 bool IsDecl = 14763 !VD || 14764 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14765 Diag(D->getLocation(), 14766 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14767 << D; 14768 continue; 14769 } 14770 14771 // OpenMP [2.8.1, simd construct, Restrictions] 14772 // A list-item cannot appear in more than one aligned clause. 14773 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14774 Diag(ELoc, diag::err_omp_used_in_clause_twice) 14775 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 14776 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14777 << getOpenMPClauseName(OMPC_aligned); 14778 continue; 14779 } 14780 14781 DeclRefExpr *Ref = nullptr; 14782 if (!VD && isOpenMPCapturedDecl(D)) 14783 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14784 Vars.push_back(DefaultFunctionArrayConversion( 14785 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14786 .get()); 14787 } 14788 14789 // OpenMP [2.8.1, simd construct, Description] 14790 // The parameter of the aligned clause, alignment, must be a constant 14791 // positive integer expression. 14792 // If no optional parameter is specified, implementation-defined default 14793 // alignments for SIMD instructions on the target platforms are assumed. 14794 if (Alignment != nullptr) { 14795 ExprResult AlignResult = 14796 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14797 if (AlignResult.isInvalid()) 14798 return nullptr; 14799 Alignment = AlignResult.get(); 14800 } 14801 if (Vars.empty()) 14802 return nullptr; 14803 14804 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14805 EndLoc, Vars, Alignment); 14806 } 14807 14808 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14809 SourceLocation StartLoc, 14810 SourceLocation LParenLoc, 14811 SourceLocation EndLoc) { 14812 SmallVector<Expr *, 8> Vars; 14813 SmallVector<Expr *, 8> SrcExprs; 14814 SmallVector<Expr *, 8> DstExprs; 14815 SmallVector<Expr *, 8> AssignmentOps; 14816 for (Expr *RefExpr : VarList) { 14817 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14818 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14819 // It will be analyzed later. 14820 Vars.push_back(RefExpr); 14821 SrcExprs.push_back(nullptr); 14822 DstExprs.push_back(nullptr); 14823 AssignmentOps.push_back(nullptr); 14824 continue; 14825 } 14826 14827 SourceLocation ELoc = RefExpr->getExprLoc(); 14828 // OpenMP [2.1, C/C++] 14829 // A list item is a variable name. 14830 // OpenMP [2.14.4.1, Restrictions, p.1] 14831 // A list item that appears in a copyin clause must be threadprivate. 14832 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14833 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14834 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14835 << 0 << RefExpr->getSourceRange(); 14836 continue; 14837 } 14838 14839 Decl *D = DE->getDecl(); 14840 auto *VD = cast<VarDecl>(D); 14841 14842 QualType Type = VD->getType(); 14843 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14844 // It will be analyzed later. 14845 Vars.push_back(DE); 14846 SrcExprs.push_back(nullptr); 14847 DstExprs.push_back(nullptr); 14848 AssignmentOps.push_back(nullptr); 14849 continue; 14850 } 14851 14852 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14853 // A list item that appears in a copyin clause must be threadprivate. 14854 if (!DSAStack->isThreadPrivate(VD)) { 14855 Diag(ELoc, diag::err_omp_required_access) 14856 << getOpenMPClauseName(OMPC_copyin) 14857 << getOpenMPDirectiveName(OMPD_threadprivate); 14858 continue; 14859 } 14860 14861 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14862 // A variable of class type (or array thereof) that appears in a 14863 // copyin clause requires an accessible, unambiguous copy assignment 14864 // operator for the class type. 14865 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14866 VarDecl *SrcVD = 14867 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14868 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14869 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14870 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14871 VarDecl *DstVD = 14872 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14873 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14874 DeclRefExpr *PseudoDstExpr = 14875 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14876 // For arrays generate assignment operation for single element and replace 14877 // it by the original array element in CodeGen. 14878 ExprResult AssignmentOp = 14879 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14880 PseudoSrcExpr); 14881 if (AssignmentOp.isInvalid()) 14882 continue; 14883 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14884 /*DiscardedValue*/ false); 14885 if (AssignmentOp.isInvalid()) 14886 continue; 14887 14888 DSAStack->addDSA(VD, DE, OMPC_copyin); 14889 Vars.push_back(DE); 14890 SrcExprs.push_back(PseudoSrcExpr); 14891 DstExprs.push_back(PseudoDstExpr); 14892 AssignmentOps.push_back(AssignmentOp.get()); 14893 } 14894 14895 if (Vars.empty()) 14896 return nullptr; 14897 14898 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14899 SrcExprs, DstExprs, AssignmentOps); 14900 } 14901 14902 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14903 SourceLocation StartLoc, 14904 SourceLocation LParenLoc, 14905 SourceLocation EndLoc) { 14906 SmallVector<Expr *, 8> Vars; 14907 SmallVector<Expr *, 8> SrcExprs; 14908 SmallVector<Expr *, 8> DstExprs; 14909 SmallVector<Expr *, 8> AssignmentOps; 14910 for (Expr *RefExpr : VarList) { 14911 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14912 SourceLocation ELoc; 14913 SourceRange ERange; 14914 Expr *SimpleRefExpr = RefExpr; 14915 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14916 if (Res.second) { 14917 // It will be analyzed later. 14918 Vars.push_back(RefExpr); 14919 SrcExprs.push_back(nullptr); 14920 DstExprs.push_back(nullptr); 14921 AssignmentOps.push_back(nullptr); 14922 } 14923 ValueDecl *D = Res.first; 14924 if (!D) 14925 continue; 14926 14927 QualType Type = D->getType(); 14928 auto *VD = dyn_cast<VarDecl>(D); 14929 14930 // OpenMP [2.14.4.2, Restrictions, p.2] 14931 // A list item that appears in a copyprivate clause may not appear in a 14932 // private or firstprivate clause on the single construct. 14933 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14934 DSAStackTy::DSAVarData DVar = 14935 DSAStack->getTopDSA(D, /*FromParent=*/false); 14936 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14937 DVar.RefExpr) { 14938 Diag(ELoc, diag::err_omp_wrong_dsa) 14939 << getOpenMPClauseName(DVar.CKind) 14940 << getOpenMPClauseName(OMPC_copyprivate); 14941 reportOriginalDsa(*this, DSAStack, D, DVar); 14942 continue; 14943 } 14944 14945 // OpenMP [2.11.4.2, Restrictions, p.1] 14946 // All list items that appear in a copyprivate clause must be either 14947 // threadprivate or private in the enclosing context. 14948 if (DVar.CKind == OMPC_unknown) { 14949 DVar = DSAStack->getImplicitDSA(D, false); 14950 if (DVar.CKind == OMPC_shared) { 14951 Diag(ELoc, diag::err_omp_required_access) 14952 << getOpenMPClauseName(OMPC_copyprivate) 14953 << "threadprivate or private in the enclosing context"; 14954 reportOriginalDsa(*this, DSAStack, D, DVar); 14955 continue; 14956 } 14957 } 14958 } 14959 14960 // Variably modified types are not supported. 14961 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14962 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14963 << getOpenMPClauseName(OMPC_copyprivate) << Type 14964 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14965 bool IsDecl = 14966 !VD || 14967 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14968 Diag(D->getLocation(), 14969 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14970 << D; 14971 continue; 14972 } 14973 14974 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14975 // A variable of class type (or array thereof) that appears in a 14976 // copyin clause requires an accessible, unambiguous copy assignment 14977 // operator for the class type. 14978 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14979 .getUnqualifiedType(); 14980 VarDecl *SrcVD = 14981 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14982 D->hasAttrs() ? &D->getAttrs() : nullptr); 14983 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14984 VarDecl *DstVD = 14985 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14986 D->hasAttrs() ? &D->getAttrs() : nullptr); 14987 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14988 ExprResult AssignmentOp = BuildBinOp( 14989 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14990 if (AssignmentOp.isInvalid()) 14991 continue; 14992 AssignmentOp = 14993 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14994 if (AssignmentOp.isInvalid()) 14995 continue; 14996 14997 // No need to mark vars as copyprivate, they are already threadprivate or 14998 // implicitly private. 14999 assert(VD || isOpenMPCapturedDecl(D)); 15000 Vars.push_back( 15001 VD ? RefExpr->IgnoreParens() 15002 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15003 SrcExprs.push_back(PseudoSrcExpr); 15004 DstExprs.push_back(PseudoDstExpr); 15005 AssignmentOps.push_back(AssignmentOp.get()); 15006 } 15007 15008 if (Vars.empty()) 15009 return nullptr; 15010 15011 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15012 Vars, SrcExprs, DstExprs, AssignmentOps); 15013 } 15014 15015 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15016 SourceLocation StartLoc, 15017 SourceLocation LParenLoc, 15018 SourceLocation EndLoc) { 15019 if (VarList.empty()) 15020 return nullptr; 15021 15022 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15023 } 15024 15025 OMPClause * 15026 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 15027 SourceLocation DepLoc, SourceLocation ColonLoc, 15028 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15029 SourceLocation LParenLoc, SourceLocation EndLoc) { 15030 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15031 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15032 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15033 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15034 return nullptr; 15035 } 15036 if (DSAStack->getCurrentDirective() != OMPD_ordered && 15037 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15038 DepKind == OMPC_DEPEND_sink)) { 15039 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 15040 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15041 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 15042 /*Last=*/OMPC_DEPEND_unknown, Except) 15043 << getOpenMPClauseName(OMPC_depend); 15044 return nullptr; 15045 } 15046 SmallVector<Expr *, 8> Vars; 15047 DSAStackTy::OperatorOffsetTy OpsOffs; 15048 llvm::APSInt DepCounter(/*BitWidth=*/32); 15049 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15050 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15051 if (const Expr *OrderedCountExpr = 15052 DSAStack->getParentOrderedRegionParam().first) { 15053 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15054 TotalDepCount.setIsUnsigned(/*Val=*/true); 15055 } 15056 } 15057 for (Expr *RefExpr : VarList) { 15058 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15059 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15060 // It will be analyzed later. 15061 Vars.push_back(RefExpr); 15062 continue; 15063 } 15064 15065 SourceLocation ELoc = RefExpr->getExprLoc(); 15066 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15067 if (DepKind == OMPC_DEPEND_sink) { 15068 if (DSAStack->getParentOrderedRegionParam().first && 15069 DepCounter >= TotalDepCount) { 15070 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15071 continue; 15072 } 15073 ++DepCounter; 15074 // OpenMP [2.13.9, Summary] 15075 // depend(dependence-type : vec), where dependence-type is: 15076 // 'sink' and where vec is the iteration vector, which has the form: 15077 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15078 // where n is the value specified by the ordered clause in the loop 15079 // directive, xi denotes the loop iteration variable of the i-th nested 15080 // loop associated with the loop directive, and di is a constant 15081 // non-negative integer. 15082 if (CurContext->isDependentContext()) { 15083 // It will be analyzed later. 15084 Vars.push_back(RefExpr); 15085 continue; 15086 } 15087 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15088 OverloadedOperatorKind OOK = OO_None; 15089 SourceLocation OOLoc; 15090 Expr *LHS = SimpleExpr; 15091 Expr *RHS = nullptr; 15092 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15093 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15094 OOLoc = BO->getOperatorLoc(); 15095 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15096 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15097 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15098 OOK = OCE->getOperator(); 15099 OOLoc = OCE->getOperatorLoc(); 15100 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15101 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15102 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15103 OOK = MCE->getMethodDecl() 15104 ->getNameInfo() 15105 .getName() 15106 .getCXXOverloadedOperator(); 15107 OOLoc = MCE->getCallee()->getExprLoc(); 15108 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15109 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15110 } 15111 SourceLocation ELoc; 15112 SourceRange ERange; 15113 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15114 if (Res.second) { 15115 // It will be analyzed later. 15116 Vars.push_back(RefExpr); 15117 } 15118 ValueDecl *D = Res.first; 15119 if (!D) 15120 continue; 15121 15122 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15123 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15124 continue; 15125 } 15126 if (RHS) { 15127 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15128 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15129 if (RHSRes.isInvalid()) 15130 continue; 15131 } 15132 if (!CurContext->isDependentContext() && 15133 DSAStack->getParentOrderedRegionParam().first && 15134 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15135 const ValueDecl *VD = 15136 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15137 if (VD) 15138 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15139 << 1 << VD; 15140 else 15141 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15142 continue; 15143 } 15144 OpsOffs.emplace_back(RHS, OOK); 15145 } else { 15146 // OpenMP 5.0 [2.17.11, Restrictions] 15147 // List items used in depend clauses cannot be zero-length array sections. 15148 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15149 if (OASE) { 15150 const Expr *Length = OASE->getLength(); 15151 Expr::EvalResult Result; 15152 if (Length && !Length->isValueDependent() && 15153 Length->EvaluateAsInt(Result, Context) && 15154 Result.Val.getInt().isNullValue()) { 15155 Diag(ELoc, 15156 diag::err_omp_depend_zero_length_array_section_not_allowed) 15157 << SimpleExpr->getSourceRange(); 15158 continue; 15159 } 15160 } 15161 15162 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15163 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15164 (ASE && 15165 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 15166 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15167 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15168 << RefExpr->getSourceRange(); 15169 continue; 15170 } 15171 15172 ExprResult Res; 15173 { 15174 Sema::TentativeAnalysisScope Trap(*this); 15175 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15176 RefExpr->IgnoreParenImpCasts()); 15177 } 15178 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 15179 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15180 << RefExpr->getSourceRange(); 15181 continue; 15182 } 15183 } 15184 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15185 } 15186 15187 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15188 TotalDepCount > VarList.size() && 15189 DSAStack->getParentOrderedRegionParam().first && 15190 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15191 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15192 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15193 } 15194 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15195 Vars.empty()) 15196 return nullptr; 15197 15198 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15199 DepKind, DepLoc, ColonLoc, Vars, 15200 TotalDepCount.getZExtValue()); 15201 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15202 DSAStack->isParentOrderedRegion()) 15203 DSAStack->addDoacrossDependClause(C, OpsOffs); 15204 return C; 15205 } 15206 15207 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 15208 SourceLocation LParenLoc, 15209 SourceLocation EndLoc) { 15210 Expr *ValExpr = Device; 15211 Stmt *HelperValStmt = nullptr; 15212 15213 // OpenMP [2.9.1, Restrictions] 15214 // The device expression must evaluate to a non-negative integer value. 15215 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15216 /*StrictlyPositive=*/false)) 15217 return nullptr; 15218 15219 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15220 OpenMPDirectiveKind CaptureRegion = 15221 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15222 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15223 ValExpr = MakeFullExpr(ValExpr).get(); 15224 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15225 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15226 HelperValStmt = buildPreInits(Context, Captures); 15227 } 15228 15229 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 15230 StartLoc, LParenLoc, EndLoc); 15231 } 15232 15233 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15234 DSAStackTy *Stack, QualType QTy, 15235 bool FullCheck = true) { 15236 NamedDecl *ND; 15237 if (QTy->isIncompleteType(&ND)) { 15238 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15239 return false; 15240 } 15241 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15242 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15243 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15244 return true; 15245 } 15246 15247 /// Return true if it can be proven that the provided array expression 15248 /// (array section or array subscript) does NOT specify the whole size of the 15249 /// array whose base type is \a BaseQTy. 15250 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15251 const Expr *E, 15252 QualType BaseQTy) { 15253 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15254 15255 // If this is an array subscript, it refers to the whole size if the size of 15256 // the dimension is constant and equals 1. Also, an array section assumes the 15257 // format of an array subscript if no colon is used. 15258 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15259 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15260 return ATy->getSize().getSExtValue() != 1; 15261 // Size can't be evaluated statically. 15262 return false; 15263 } 15264 15265 assert(OASE && "Expecting array section if not an array subscript."); 15266 const Expr *LowerBound = OASE->getLowerBound(); 15267 const Expr *Length = OASE->getLength(); 15268 15269 // If there is a lower bound that does not evaluates to zero, we are not 15270 // covering the whole dimension. 15271 if (LowerBound) { 15272 Expr::EvalResult Result; 15273 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15274 return false; // Can't get the integer value as a constant. 15275 15276 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15277 if (ConstLowerBound.getSExtValue()) 15278 return true; 15279 } 15280 15281 // If we don't have a length we covering the whole dimension. 15282 if (!Length) 15283 return false; 15284 15285 // If the base is a pointer, we don't have a way to get the size of the 15286 // pointee. 15287 if (BaseQTy->isPointerType()) 15288 return false; 15289 15290 // We can only check if the length is the same as the size of the dimension 15291 // if we have a constant array. 15292 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15293 if (!CATy) 15294 return false; 15295 15296 Expr::EvalResult Result; 15297 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15298 return false; // Can't get the integer value as a constant. 15299 15300 llvm::APSInt ConstLength = Result.Val.getInt(); 15301 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15302 } 15303 15304 // Return true if it can be proven that the provided array expression (array 15305 // section or array subscript) does NOT specify a single element of the array 15306 // whose base type is \a BaseQTy. 15307 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15308 const Expr *E, 15309 QualType BaseQTy) { 15310 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15311 15312 // An array subscript always refer to a single element. Also, an array section 15313 // assumes the format of an array subscript if no colon is used. 15314 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 15315 return false; 15316 15317 assert(OASE && "Expecting array section if not an array subscript."); 15318 const Expr *Length = OASE->getLength(); 15319 15320 // If we don't have a length we have to check if the array has unitary size 15321 // for this dimension. Also, we should always expect a length if the base type 15322 // is pointer. 15323 if (!Length) { 15324 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15325 return ATy->getSize().getSExtValue() != 1; 15326 // We cannot assume anything. 15327 return false; 15328 } 15329 15330 // Check if the length evaluates to 1. 15331 Expr::EvalResult Result; 15332 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15333 return false; // Can't get the integer value as a constant. 15334 15335 llvm::APSInt ConstLength = Result.Val.getInt(); 15336 return ConstLength.getSExtValue() != 1; 15337 } 15338 15339 // Return the expression of the base of the mappable expression or null if it 15340 // cannot be determined and do all the necessary checks to see if the expression 15341 // is valid as a standalone mappable expression. In the process, record all the 15342 // components of the expression. 15343 static const Expr *checkMapClauseExpressionBase( 15344 Sema &SemaRef, Expr *E, 15345 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 15346 OpenMPClauseKind CKind, bool NoDiagnose) { 15347 SourceLocation ELoc = E->getExprLoc(); 15348 SourceRange ERange = E->getSourceRange(); 15349 15350 // The base of elements of list in a map clause have to be either: 15351 // - a reference to variable or field. 15352 // - a member expression. 15353 // - an array expression. 15354 // 15355 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 15356 // reference to 'r'. 15357 // 15358 // If we have: 15359 // 15360 // struct SS { 15361 // Bla S; 15362 // foo() { 15363 // #pragma omp target map (S.Arr[:12]); 15364 // } 15365 // } 15366 // 15367 // We want to retrieve the member expression 'this->S'; 15368 15369 const Expr *RelevantExpr = nullptr; 15370 15371 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 15372 // If a list item is an array section, it must specify contiguous storage. 15373 // 15374 // For this restriction it is sufficient that we make sure only references 15375 // to variables or fields and array expressions, and that no array sections 15376 // exist except in the rightmost expression (unless they cover the whole 15377 // dimension of the array). E.g. these would be invalid: 15378 // 15379 // r.ArrS[3:5].Arr[6:7] 15380 // 15381 // r.ArrS[3:5].x 15382 // 15383 // but these would be valid: 15384 // r.ArrS[3].Arr[6:7] 15385 // 15386 // r.ArrS[3].x 15387 15388 bool AllowUnitySizeArraySection = true; 15389 bool AllowWholeSizeArraySection = true; 15390 15391 while (!RelevantExpr) { 15392 E = E->IgnoreParenImpCasts(); 15393 15394 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 15395 if (!isa<VarDecl>(CurE->getDecl())) 15396 return nullptr; 15397 15398 RelevantExpr = CurE; 15399 15400 // If we got a reference to a declaration, we should not expect any array 15401 // section before that. 15402 AllowUnitySizeArraySection = false; 15403 AllowWholeSizeArraySection = false; 15404 15405 // Record the component. 15406 CurComponents.emplace_back(CurE, CurE->getDecl()); 15407 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 15408 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 15409 15410 if (isa<CXXThisExpr>(BaseE)) 15411 // We found a base expression: this->Val. 15412 RelevantExpr = CurE; 15413 else 15414 E = BaseE; 15415 15416 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 15417 if (!NoDiagnose) { 15418 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15419 << CurE->getSourceRange(); 15420 return nullptr; 15421 } 15422 if (RelevantExpr) 15423 return nullptr; 15424 continue; 15425 } 15426 15427 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 15428 15429 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15430 // A bit-field cannot appear in a map clause. 15431 // 15432 if (FD->isBitField()) { 15433 if (!NoDiagnose) { 15434 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15435 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 15436 return nullptr; 15437 } 15438 if (RelevantExpr) 15439 return nullptr; 15440 continue; 15441 } 15442 15443 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15444 // If the type of a list item is a reference to a type T then the type 15445 // will be considered to be T for all purposes of this clause. 15446 QualType CurType = BaseE->getType().getNonReferenceType(); 15447 15448 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15449 // A list item cannot be a variable that is a member of a structure with 15450 // a union type. 15451 // 15452 if (CurType->isUnionType()) { 15453 if (!NoDiagnose) { 15454 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15455 << CurE->getSourceRange(); 15456 return nullptr; 15457 } 15458 continue; 15459 } 15460 15461 // If we got a member expression, we should not expect any array section 15462 // before that: 15463 // 15464 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15465 // If a list item is an element of a structure, only the rightmost symbol 15466 // of the variable reference can be an array section. 15467 // 15468 AllowUnitySizeArraySection = false; 15469 AllowWholeSizeArraySection = false; 15470 15471 // Record the component. 15472 CurComponents.emplace_back(CurE, FD); 15473 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 15474 E = CurE->getBase()->IgnoreParenImpCasts(); 15475 15476 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15477 if (!NoDiagnose) { 15478 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15479 << 0 << CurE->getSourceRange(); 15480 return nullptr; 15481 } 15482 continue; 15483 } 15484 15485 // If we got an array subscript that express the whole dimension we 15486 // can have any array expressions before. If it only expressing part of 15487 // the dimension, we can only have unitary-size array expressions. 15488 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 15489 E->getType())) 15490 AllowWholeSizeArraySection = false; 15491 15492 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15493 Expr::EvalResult Result; 15494 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 15495 if (!Result.Val.getInt().isNullValue()) { 15496 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15497 diag::err_omp_invalid_map_this_expr); 15498 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15499 diag::note_omp_invalid_subscript_on_this_ptr_map); 15500 } 15501 } 15502 RelevantExpr = TE; 15503 } 15504 15505 // Record the component - we don't have any declaration associated. 15506 CurComponents.emplace_back(CurE, nullptr); 15507 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 15508 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15509 E = CurE->getBase()->IgnoreParenImpCasts(); 15510 15511 QualType CurType = 15512 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15513 15514 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15515 // If the type of a list item is a reference to a type T then the type 15516 // will be considered to be T for all purposes of this clause. 15517 if (CurType->isReferenceType()) 15518 CurType = CurType->getPointeeType(); 15519 15520 bool IsPointer = CurType->isAnyPointerType(); 15521 15522 if (!IsPointer && !CurType->isArrayType()) { 15523 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15524 << 0 << CurE->getSourceRange(); 15525 return nullptr; 15526 } 15527 15528 bool NotWhole = 15529 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 15530 bool NotUnity = 15531 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 15532 15533 if (AllowWholeSizeArraySection) { 15534 // Any array section is currently allowed. Allowing a whole size array 15535 // section implies allowing a unity array section as well. 15536 // 15537 // If this array section refers to the whole dimension we can still 15538 // accept other array sections before this one, except if the base is a 15539 // pointer. Otherwise, only unitary sections are accepted. 15540 if (NotWhole || IsPointer) 15541 AllowWholeSizeArraySection = false; 15542 } else if (AllowUnitySizeArraySection && NotUnity) { 15543 // A unity or whole array section is not allowed and that is not 15544 // compatible with the properties of the current array section. 15545 SemaRef.Diag( 15546 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15547 << CurE->getSourceRange(); 15548 return nullptr; 15549 } 15550 15551 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15552 Expr::EvalResult ResultR; 15553 Expr::EvalResult ResultL; 15554 if (CurE->getLength()->EvaluateAsInt(ResultR, 15555 SemaRef.getASTContext())) { 15556 if (!ResultR.Val.getInt().isOneValue()) { 15557 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15558 diag::err_omp_invalid_map_this_expr); 15559 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15560 diag::note_omp_invalid_length_on_this_ptr_mapping); 15561 } 15562 } 15563 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 15564 ResultL, SemaRef.getASTContext())) { 15565 if (!ResultL.Val.getInt().isNullValue()) { 15566 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15567 diag::err_omp_invalid_map_this_expr); 15568 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15569 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15570 } 15571 } 15572 RelevantExpr = TE; 15573 } 15574 15575 // Record the component - we don't have any declaration associated. 15576 CurComponents.emplace_back(CurE, nullptr); 15577 } else { 15578 if (!NoDiagnose) { 15579 // If nothing else worked, this is not a valid map clause expression. 15580 SemaRef.Diag( 15581 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15582 << ERange; 15583 } 15584 return nullptr; 15585 } 15586 } 15587 15588 return RelevantExpr; 15589 } 15590 15591 // Return true if expression E associated with value VD has conflicts with other 15592 // map information. 15593 static bool checkMapConflicts( 15594 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15595 bool CurrentRegionOnly, 15596 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15597 OpenMPClauseKind CKind) { 15598 assert(VD && E); 15599 SourceLocation ELoc = E->getExprLoc(); 15600 SourceRange ERange = E->getSourceRange(); 15601 15602 // In order to easily check the conflicts we need to match each component of 15603 // the expression under test with the components of the expressions that are 15604 // already in the stack. 15605 15606 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15607 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15608 "Map clause expression with unexpected base!"); 15609 15610 // Variables to help detecting enclosing problems in data environment nests. 15611 bool IsEnclosedByDataEnvironmentExpr = false; 15612 const Expr *EnclosingExpr = nullptr; 15613 15614 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15615 VD, CurrentRegionOnly, 15616 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15617 ERange, CKind, &EnclosingExpr, 15618 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15619 StackComponents, 15620 OpenMPClauseKind) { 15621 assert(!StackComponents.empty() && 15622 "Map clause expression with no components!"); 15623 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15624 "Map clause expression with unexpected base!"); 15625 (void)VD; 15626 15627 // The whole expression in the stack. 15628 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15629 15630 // Expressions must start from the same base. Here we detect at which 15631 // point both expressions diverge from each other and see if we can 15632 // detect if the memory referred to both expressions is contiguous and 15633 // do not overlap. 15634 auto CI = CurComponents.rbegin(); 15635 auto CE = CurComponents.rend(); 15636 auto SI = StackComponents.rbegin(); 15637 auto SE = StackComponents.rend(); 15638 for (; CI != CE && SI != SE; ++CI, ++SI) { 15639 15640 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15641 // At most one list item can be an array item derived from a given 15642 // variable in map clauses of the same construct. 15643 if (CurrentRegionOnly && 15644 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15645 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15646 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15647 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15648 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15649 diag::err_omp_multiple_array_items_in_map_clause) 15650 << CI->getAssociatedExpression()->getSourceRange(); 15651 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15652 diag::note_used_here) 15653 << SI->getAssociatedExpression()->getSourceRange(); 15654 return true; 15655 } 15656 15657 // Do both expressions have the same kind? 15658 if (CI->getAssociatedExpression()->getStmtClass() != 15659 SI->getAssociatedExpression()->getStmtClass()) 15660 break; 15661 15662 // Are we dealing with different variables/fields? 15663 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15664 break; 15665 } 15666 // Check if the extra components of the expressions in the enclosing 15667 // data environment are redundant for the current base declaration. 15668 // If they are, the maps completely overlap, which is legal. 15669 for (; SI != SE; ++SI) { 15670 QualType Type; 15671 if (const auto *ASE = 15672 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15673 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15674 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15675 SI->getAssociatedExpression())) { 15676 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15677 Type = 15678 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15679 } 15680 if (Type.isNull() || Type->isAnyPointerType() || 15681 checkArrayExpressionDoesNotReferToWholeSize( 15682 SemaRef, SI->getAssociatedExpression(), Type)) 15683 break; 15684 } 15685 15686 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15687 // List items of map clauses in the same construct must not share 15688 // original storage. 15689 // 15690 // If the expressions are exactly the same or one is a subset of the 15691 // other, it means they are sharing storage. 15692 if (CI == CE && SI == SE) { 15693 if (CurrentRegionOnly) { 15694 if (CKind == OMPC_map) { 15695 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15696 } else { 15697 assert(CKind == OMPC_to || CKind == OMPC_from); 15698 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15699 << ERange; 15700 } 15701 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15702 << RE->getSourceRange(); 15703 return true; 15704 } 15705 // If we find the same expression in the enclosing data environment, 15706 // that is legal. 15707 IsEnclosedByDataEnvironmentExpr = true; 15708 return false; 15709 } 15710 15711 QualType DerivedType = 15712 std::prev(CI)->getAssociatedDeclaration()->getType(); 15713 SourceLocation DerivedLoc = 15714 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15715 15716 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15717 // If the type of a list item is a reference to a type T then the type 15718 // will be considered to be T for all purposes of this clause. 15719 DerivedType = DerivedType.getNonReferenceType(); 15720 15721 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15722 // A variable for which the type is pointer and an array section 15723 // derived from that variable must not appear as list items of map 15724 // clauses of the same construct. 15725 // 15726 // Also, cover one of the cases in: 15727 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15728 // If any part of the original storage of a list item has corresponding 15729 // storage in the device data environment, all of the original storage 15730 // must have corresponding storage in the device data environment. 15731 // 15732 if (DerivedType->isAnyPointerType()) { 15733 if (CI == CE || SI == SE) { 15734 SemaRef.Diag( 15735 DerivedLoc, 15736 diag::err_omp_pointer_mapped_along_with_derived_section) 15737 << DerivedLoc; 15738 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15739 << RE->getSourceRange(); 15740 return true; 15741 } 15742 if (CI->getAssociatedExpression()->getStmtClass() != 15743 SI->getAssociatedExpression()->getStmtClass() || 15744 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15745 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15746 assert(CI != CE && SI != SE); 15747 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15748 << DerivedLoc; 15749 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15750 << RE->getSourceRange(); 15751 return true; 15752 } 15753 } 15754 15755 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15756 // List items of map clauses in the same construct must not share 15757 // original storage. 15758 // 15759 // An expression is a subset of the other. 15760 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15761 if (CKind == OMPC_map) { 15762 if (CI != CE || SI != SE) { 15763 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15764 // a pointer. 15765 auto Begin = 15766 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15767 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15768 auto It = Begin; 15769 while (It != End && !It->getAssociatedDeclaration()) 15770 std::advance(It, 1); 15771 assert(It != End && 15772 "Expected at least one component with the declaration."); 15773 if (It != Begin && It->getAssociatedDeclaration() 15774 ->getType() 15775 .getCanonicalType() 15776 ->isAnyPointerType()) { 15777 IsEnclosedByDataEnvironmentExpr = false; 15778 EnclosingExpr = nullptr; 15779 return false; 15780 } 15781 } 15782 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15783 } else { 15784 assert(CKind == OMPC_to || CKind == OMPC_from); 15785 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15786 << ERange; 15787 } 15788 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15789 << RE->getSourceRange(); 15790 return true; 15791 } 15792 15793 // The current expression uses the same base as other expression in the 15794 // data environment but does not contain it completely. 15795 if (!CurrentRegionOnly && SI != SE) 15796 EnclosingExpr = RE; 15797 15798 // The current expression is a subset of the expression in the data 15799 // environment. 15800 IsEnclosedByDataEnvironmentExpr |= 15801 (!CurrentRegionOnly && CI != CE && SI == SE); 15802 15803 return false; 15804 }); 15805 15806 if (CurrentRegionOnly) 15807 return FoundError; 15808 15809 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15810 // If any part of the original storage of a list item has corresponding 15811 // storage in the device data environment, all of the original storage must 15812 // have corresponding storage in the device data environment. 15813 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15814 // If a list item is an element of a structure, and a different element of 15815 // the structure has a corresponding list item in the device data environment 15816 // prior to a task encountering the construct associated with the map clause, 15817 // then the list item must also have a corresponding list item in the device 15818 // data environment prior to the task encountering the construct. 15819 // 15820 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15821 SemaRef.Diag(ELoc, 15822 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15823 << ERange; 15824 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15825 << EnclosingExpr->getSourceRange(); 15826 return true; 15827 } 15828 15829 return FoundError; 15830 } 15831 15832 // Look up the user-defined mapper given the mapper name and mapped type, and 15833 // build a reference to it. 15834 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15835 CXXScopeSpec &MapperIdScopeSpec, 15836 const DeclarationNameInfo &MapperId, 15837 QualType Type, 15838 Expr *UnresolvedMapper) { 15839 if (MapperIdScopeSpec.isInvalid()) 15840 return ExprError(); 15841 // Get the actual type for the array type. 15842 if (Type->isArrayType()) { 15843 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15844 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15845 } 15846 // Find all user-defined mappers with the given MapperId. 15847 SmallVector<UnresolvedSet<8>, 4> Lookups; 15848 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15849 Lookup.suppressDiagnostics(); 15850 if (S) { 15851 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15852 NamedDecl *D = Lookup.getRepresentativeDecl(); 15853 while (S && !S->isDeclScope(D)) 15854 S = S->getParent(); 15855 if (S) 15856 S = S->getParent(); 15857 Lookups.emplace_back(); 15858 Lookups.back().append(Lookup.begin(), Lookup.end()); 15859 Lookup.clear(); 15860 } 15861 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15862 // Extract the user-defined mappers with the given MapperId. 15863 Lookups.push_back(UnresolvedSet<8>()); 15864 for (NamedDecl *D : ULE->decls()) { 15865 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15866 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15867 Lookups.back().addDecl(DMD); 15868 } 15869 } 15870 // Defer the lookup for dependent types. The results will be passed through 15871 // UnresolvedMapper on instantiation. 15872 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15873 Type->isInstantiationDependentType() || 15874 Type->containsUnexpandedParameterPack() || 15875 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15876 return !D->isInvalidDecl() && 15877 (D->getType()->isDependentType() || 15878 D->getType()->isInstantiationDependentType() || 15879 D->getType()->containsUnexpandedParameterPack()); 15880 })) { 15881 UnresolvedSet<8> URS; 15882 for (const UnresolvedSet<8> &Set : Lookups) { 15883 if (Set.empty()) 15884 continue; 15885 URS.append(Set.begin(), Set.end()); 15886 } 15887 return UnresolvedLookupExpr::Create( 15888 SemaRef.Context, /*NamingClass=*/nullptr, 15889 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15890 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15891 } 15892 SourceLocation Loc = MapperId.getLoc(); 15893 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15894 // The type must be of struct, union or class type in C and C++ 15895 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15896 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15897 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15898 return ExprError(); 15899 } 15900 // Perform argument dependent lookup. 15901 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15902 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15903 // Return the first user-defined mapper with the desired type. 15904 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15905 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15906 if (!D->isInvalidDecl() && 15907 SemaRef.Context.hasSameType(D->getType(), Type)) 15908 return D; 15909 return nullptr; 15910 })) 15911 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15912 // Find the first user-defined mapper with a type derived from the desired 15913 // type. 15914 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15915 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15916 if (!D->isInvalidDecl() && 15917 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15918 !Type.isMoreQualifiedThan(D->getType())) 15919 return D; 15920 return nullptr; 15921 })) { 15922 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15923 /*DetectVirtual=*/false); 15924 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15925 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15926 VD->getType().getUnqualifiedType()))) { 15927 if (SemaRef.CheckBaseClassAccess( 15928 Loc, VD->getType(), Type, Paths.front(), 15929 /*DiagID=*/0) != Sema::AR_inaccessible) { 15930 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15931 } 15932 } 15933 } 15934 } 15935 // Report error if a mapper is specified, but cannot be found. 15936 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15937 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15938 << Type << MapperId.getName(); 15939 return ExprError(); 15940 } 15941 return ExprEmpty(); 15942 } 15943 15944 namespace { 15945 // Utility struct that gathers all the related lists associated with a mappable 15946 // expression. 15947 struct MappableVarListInfo { 15948 // The list of expressions. 15949 ArrayRef<Expr *> VarList; 15950 // The list of processed expressions. 15951 SmallVector<Expr *, 16> ProcessedVarList; 15952 // The mappble components for each expression. 15953 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15954 // The base declaration of the variable. 15955 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15956 // The reference to the user-defined mapper associated with every expression. 15957 SmallVector<Expr *, 16> UDMapperList; 15958 15959 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15960 // We have a list of components and base declarations for each entry in the 15961 // variable list. 15962 VarComponents.reserve(VarList.size()); 15963 VarBaseDeclarations.reserve(VarList.size()); 15964 } 15965 }; 15966 } 15967 15968 // Check the validity of the provided variable list for the provided clause kind 15969 // \a CKind. In the check process the valid expressions, mappable expression 15970 // components, variables, and user-defined mappers are extracted and used to 15971 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15972 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15973 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15974 static void checkMappableExpressionList( 15975 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15976 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15977 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15978 ArrayRef<Expr *> UnresolvedMappers, 15979 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15980 bool IsMapTypeImplicit = false) { 15981 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15982 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15983 "Unexpected clause kind with mappable expressions!"); 15984 15985 // If the identifier of user-defined mapper is not specified, it is "default". 15986 // We do not change the actual name in this clause to distinguish whether a 15987 // mapper is specified explicitly, i.e., it is not explicitly specified when 15988 // MapperId.getName() is empty. 15989 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15990 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15991 MapperId.setName(DeclNames.getIdentifier( 15992 &SemaRef.getASTContext().Idents.get("default"))); 15993 } 15994 15995 // Iterators to find the current unresolved mapper expression. 15996 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15997 bool UpdateUMIt = false; 15998 Expr *UnresolvedMapper = nullptr; 15999 16000 // Keep track of the mappable components and base declarations in this clause. 16001 // Each entry in the list is going to have a list of components associated. We 16002 // record each set of the components so that we can build the clause later on. 16003 // In the end we should have the same amount of declarations and component 16004 // lists. 16005 16006 for (Expr *RE : MVLI.VarList) { 16007 assert(RE && "Null expr in omp to/from/map clause"); 16008 SourceLocation ELoc = RE->getExprLoc(); 16009 16010 // Find the current unresolved mapper expression. 16011 if (UpdateUMIt && UMIt != UMEnd) { 16012 UMIt++; 16013 assert( 16014 UMIt != UMEnd && 16015 "Expect the size of UnresolvedMappers to match with that of VarList"); 16016 } 16017 UpdateUMIt = true; 16018 if (UMIt != UMEnd) 16019 UnresolvedMapper = *UMIt; 16020 16021 const Expr *VE = RE->IgnoreParenLValueCasts(); 16022 16023 if (VE->isValueDependent() || VE->isTypeDependent() || 16024 VE->isInstantiationDependent() || 16025 VE->containsUnexpandedParameterPack()) { 16026 // Try to find the associated user-defined mapper. 16027 ExprResult ER = buildUserDefinedMapperRef( 16028 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16029 VE->getType().getCanonicalType(), UnresolvedMapper); 16030 if (ER.isInvalid()) 16031 continue; 16032 MVLI.UDMapperList.push_back(ER.get()); 16033 // We can only analyze this information once the missing information is 16034 // resolved. 16035 MVLI.ProcessedVarList.push_back(RE); 16036 continue; 16037 } 16038 16039 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16040 16041 if (!RE->IgnoreParenImpCasts()->isLValue()) { 16042 SemaRef.Diag(ELoc, 16043 diag::err_omp_expected_named_var_member_or_array_expression) 16044 << RE->getSourceRange(); 16045 continue; 16046 } 16047 16048 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16049 ValueDecl *CurDeclaration = nullptr; 16050 16051 // Obtain the array or member expression bases if required. Also, fill the 16052 // components array with all the components identified in the process. 16053 const Expr *BE = checkMapClauseExpressionBase( 16054 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16055 if (!BE) 16056 continue; 16057 16058 assert(!CurComponents.empty() && 16059 "Invalid mappable expression information."); 16060 16061 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16062 // Add store "this" pointer to class in DSAStackTy for future checking 16063 DSAS->addMappedClassesQualTypes(TE->getType()); 16064 // Try to find the associated user-defined mapper. 16065 ExprResult ER = buildUserDefinedMapperRef( 16066 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16067 VE->getType().getCanonicalType(), UnresolvedMapper); 16068 if (ER.isInvalid()) 16069 continue; 16070 MVLI.UDMapperList.push_back(ER.get()); 16071 // Skip restriction checking for variable or field declarations 16072 MVLI.ProcessedVarList.push_back(RE); 16073 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16074 MVLI.VarComponents.back().append(CurComponents.begin(), 16075 CurComponents.end()); 16076 MVLI.VarBaseDeclarations.push_back(nullptr); 16077 continue; 16078 } 16079 16080 // For the following checks, we rely on the base declaration which is 16081 // expected to be associated with the last component. The declaration is 16082 // expected to be a variable or a field (if 'this' is being mapped). 16083 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16084 assert(CurDeclaration && "Null decl on map clause."); 16085 assert( 16086 CurDeclaration->isCanonicalDecl() && 16087 "Expecting components to have associated only canonical declarations."); 16088 16089 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16090 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16091 16092 assert((VD || FD) && "Only variables or fields are expected here!"); 16093 (void)FD; 16094 16095 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16096 // threadprivate variables cannot appear in a map clause. 16097 // OpenMP 4.5 [2.10.5, target update Construct] 16098 // threadprivate variables cannot appear in a from clause. 16099 if (VD && DSAS->isThreadPrivate(VD)) { 16100 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16101 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16102 << getOpenMPClauseName(CKind); 16103 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16104 continue; 16105 } 16106 16107 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16108 // A list item cannot appear in both a map clause and a data-sharing 16109 // attribute clause on the same construct. 16110 16111 // Check conflicts with other map clause expressions. We check the conflicts 16112 // with the current construct separately from the enclosing data 16113 // environment, because the restrictions are different. We only have to 16114 // check conflicts across regions for the map clauses. 16115 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16116 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16117 break; 16118 if (CKind == OMPC_map && 16119 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16120 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16121 break; 16122 16123 // OpenMP 4.5 [2.10.5, target update Construct] 16124 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16125 // If the type of a list item is a reference to a type T then the type will 16126 // be considered to be T for all purposes of this clause. 16127 auto I = llvm::find_if( 16128 CurComponents, 16129 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16130 return MC.getAssociatedDeclaration(); 16131 }); 16132 assert(I != CurComponents.end() && "Null decl on map clause."); 16133 QualType Type; 16134 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16135 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16136 if (ASE) { 16137 Type = ASE->getType().getNonReferenceType(); 16138 } else if (OASE) { 16139 QualType BaseType = 16140 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16141 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16142 Type = ATy->getElementType(); 16143 else 16144 Type = BaseType->getPointeeType(); 16145 Type = Type.getNonReferenceType(); 16146 } else { 16147 Type = VE->getType(); 16148 } 16149 16150 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16151 // A list item in a to or from clause must have a mappable type. 16152 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16153 // A list item must have a mappable type. 16154 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16155 DSAS, Type)) 16156 continue; 16157 16158 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16159 16160 if (CKind == OMPC_map) { 16161 // target enter data 16162 // OpenMP [2.10.2, Restrictions, p. 99] 16163 // A map-type must be specified in all map clauses and must be either 16164 // to or alloc. 16165 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16166 if (DKind == OMPD_target_enter_data && 16167 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16168 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16169 << (IsMapTypeImplicit ? 1 : 0) 16170 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16171 << getOpenMPDirectiveName(DKind); 16172 continue; 16173 } 16174 16175 // target exit_data 16176 // OpenMP [2.10.3, Restrictions, p. 102] 16177 // A map-type must be specified in all map clauses and must be either 16178 // from, release, or delete. 16179 if (DKind == OMPD_target_exit_data && 16180 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16181 MapType == OMPC_MAP_delete)) { 16182 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16183 << (IsMapTypeImplicit ? 1 : 0) 16184 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16185 << getOpenMPDirectiveName(DKind); 16186 continue; 16187 } 16188 16189 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 16190 // A list item cannot appear in both a map clause and a data-sharing 16191 // attribute clause on the same construct 16192 // 16193 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 16194 // A list item cannot appear in both a map clause and a data-sharing 16195 // attribute clause on the same construct unless the construct is a 16196 // combined construct. 16197 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 16198 isOpenMPTargetExecutionDirective(DKind)) || 16199 DKind == OMPD_target)) { 16200 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16201 if (isOpenMPPrivate(DVar.CKind)) { 16202 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16203 << getOpenMPClauseName(DVar.CKind) 16204 << getOpenMPClauseName(OMPC_map) 16205 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 16206 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 16207 continue; 16208 } 16209 } 16210 } 16211 16212 // Try to find the associated user-defined mapper. 16213 ExprResult ER = buildUserDefinedMapperRef( 16214 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16215 Type.getCanonicalType(), UnresolvedMapper); 16216 if (ER.isInvalid()) 16217 continue; 16218 MVLI.UDMapperList.push_back(ER.get()); 16219 16220 // Save the current expression. 16221 MVLI.ProcessedVarList.push_back(RE); 16222 16223 // Store the components in the stack so that they can be used to check 16224 // against other clauses later on. 16225 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 16226 /*WhereFoundClauseKind=*/OMPC_map); 16227 16228 // Save the components and declaration to create the clause. For purposes of 16229 // the clause creation, any component list that has has base 'this' uses 16230 // null as base declaration. 16231 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16232 MVLI.VarComponents.back().append(CurComponents.begin(), 16233 CurComponents.end()); 16234 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 16235 : CurDeclaration); 16236 } 16237 } 16238 16239 OMPClause *Sema::ActOnOpenMPMapClause( 16240 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 16241 ArrayRef<SourceLocation> MapTypeModifiersLoc, 16242 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 16243 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 16244 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 16245 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 16246 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 16247 OMPC_MAP_MODIFIER_unknown, 16248 OMPC_MAP_MODIFIER_unknown}; 16249 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 16250 16251 // Process map-type-modifiers, flag errors for duplicate modifiers. 16252 unsigned Count = 0; 16253 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 16254 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 16255 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 16256 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 16257 continue; 16258 } 16259 assert(Count < OMPMapClause::NumberOfModifiers && 16260 "Modifiers exceed the allowed number of map type modifiers"); 16261 Modifiers[Count] = MapTypeModifiers[I]; 16262 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 16263 ++Count; 16264 } 16265 16266 MappableVarListInfo MVLI(VarList); 16267 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 16268 MapperIdScopeSpec, MapperId, UnresolvedMappers, 16269 MapType, IsMapTypeImplicit); 16270 16271 // We need to produce a map clause even if we don't have variables so that 16272 // other diagnostics related with non-existing map clauses are accurate. 16273 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 16274 MVLI.VarBaseDeclarations, MVLI.VarComponents, 16275 MVLI.UDMapperList, Modifiers, ModifiersLoc, 16276 MapperIdScopeSpec.getWithLocInContext(Context), 16277 MapperId, MapType, IsMapTypeImplicit, MapLoc); 16278 } 16279 16280 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 16281 TypeResult ParsedType) { 16282 assert(ParsedType.isUsable()); 16283 16284 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 16285 if (ReductionType.isNull()) 16286 return QualType(); 16287 16288 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 16289 // A type name in a declare reduction directive cannot be a function type, an 16290 // array type, a reference type, or a type qualified with const, volatile or 16291 // restrict. 16292 if (ReductionType.hasQualifiers()) { 16293 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 16294 return QualType(); 16295 } 16296 16297 if (ReductionType->isFunctionType()) { 16298 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 16299 return QualType(); 16300 } 16301 if (ReductionType->isReferenceType()) { 16302 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 16303 return QualType(); 16304 } 16305 if (ReductionType->isArrayType()) { 16306 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 16307 return QualType(); 16308 } 16309 return ReductionType; 16310 } 16311 16312 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 16313 Scope *S, DeclContext *DC, DeclarationName Name, 16314 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 16315 AccessSpecifier AS, Decl *PrevDeclInScope) { 16316 SmallVector<Decl *, 8> Decls; 16317 Decls.reserve(ReductionTypes.size()); 16318 16319 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 16320 forRedeclarationInCurContext()); 16321 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 16322 // A reduction-identifier may not be re-declared in the current scope for the 16323 // same type or for a type that is compatible according to the base language 16324 // rules. 16325 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16326 OMPDeclareReductionDecl *PrevDRD = nullptr; 16327 bool InCompoundScope = true; 16328 if (S != nullptr) { 16329 // Find previous declaration with the same name not referenced in other 16330 // declarations. 16331 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16332 InCompoundScope = 16333 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16334 LookupName(Lookup, S); 16335 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16336 /*AllowInlineNamespace=*/false); 16337 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 16338 LookupResult::Filter Filter = Lookup.makeFilter(); 16339 while (Filter.hasNext()) { 16340 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 16341 if (InCompoundScope) { 16342 auto I = UsedAsPrevious.find(PrevDecl); 16343 if (I == UsedAsPrevious.end()) 16344 UsedAsPrevious[PrevDecl] = false; 16345 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 16346 UsedAsPrevious[D] = true; 16347 } 16348 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16349 PrevDecl->getLocation(); 16350 } 16351 Filter.done(); 16352 if (InCompoundScope) { 16353 for (const auto &PrevData : UsedAsPrevious) { 16354 if (!PrevData.second) { 16355 PrevDRD = PrevData.first; 16356 break; 16357 } 16358 } 16359 } 16360 } else if (PrevDeclInScope != nullptr) { 16361 auto *PrevDRDInScope = PrevDRD = 16362 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 16363 do { 16364 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 16365 PrevDRDInScope->getLocation(); 16366 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 16367 } while (PrevDRDInScope != nullptr); 16368 } 16369 for (const auto &TyData : ReductionTypes) { 16370 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 16371 bool Invalid = false; 16372 if (I != PreviousRedeclTypes.end()) { 16373 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 16374 << TyData.first; 16375 Diag(I->second, diag::note_previous_definition); 16376 Invalid = true; 16377 } 16378 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 16379 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 16380 Name, TyData.first, PrevDRD); 16381 DC->addDecl(DRD); 16382 DRD->setAccess(AS); 16383 Decls.push_back(DRD); 16384 if (Invalid) 16385 DRD->setInvalidDecl(); 16386 else 16387 PrevDRD = DRD; 16388 } 16389 16390 return DeclGroupPtrTy::make( 16391 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 16392 } 16393 16394 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 16395 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16396 16397 // Enter new function scope. 16398 PushFunctionScope(); 16399 setFunctionHasBranchProtectedScope(); 16400 getCurFunction()->setHasOMPDeclareReductionCombiner(); 16401 16402 if (S != nullptr) 16403 PushDeclContext(S, DRD); 16404 else 16405 CurContext = DRD; 16406 16407 PushExpressionEvaluationContext( 16408 ExpressionEvaluationContext::PotentiallyEvaluated); 16409 16410 QualType ReductionType = DRD->getType(); 16411 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 16412 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 16413 // uses semantics of argument handles by value, but it should be passed by 16414 // reference. C lang does not support references, so pass all parameters as 16415 // pointers. 16416 // Create 'T omp_in;' variable. 16417 VarDecl *OmpInParm = 16418 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16419 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16420 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16421 // uses semantics of argument handles by value, but it should be passed by 16422 // reference. C lang does not support references, so pass all parameters as 16423 // pointers. 16424 // Create 'T omp_out;' variable. 16425 VarDecl *OmpOutParm = 16426 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16427 if (S != nullptr) { 16428 PushOnScopeChains(OmpInParm, S); 16429 PushOnScopeChains(OmpOutParm, S); 16430 } else { 16431 DRD->addDecl(OmpInParm); 16432 DRD->addDecl(OmpOutParm); 16433 } 16434 Expr *InE = 16435 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16436 Expr *OutE = 16437 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16438 DRD->setCombinerData(InE, OutE); 16439 } 16440 16441 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16442 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16443 DiscardCleanupsInEvaluationContext(); 16444 PopExpressionEvaluationContext(); 16445 16446 PopDeclContext(); 16447 PopFunctionScopeInfo(); 16448 16449 if (Combiner != nullptr) 16450 DRD->setCombiner(Combiner); 16451 else 16452 DRD->setInvalidDecl(); 16453 } 16454 16455 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16456 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16457 16458 // Enter new function scope. 16459 PushFunctionScope(); 16460 setFunctionHasBranchProtectedScope(); 16461 16462 if (S != nullptr) 16463 PushDeclContext(S, DRD); 16464 else 16465 CurContext = DRD; 16466 16467 PushExpressionEvaluationContext( 16468 ExpressionEvaluationContext::PotentiallyEvaluated); 16469 16470 QualType ReductionType = DRD->getType(); 16471 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16472 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16473 // uses semantics of argument handles by value, but it should be passed by 16474 // reference. C lang does not support references, so pass all parameters as 16475 // pointers. 16476 // Create 'T omp_priv;' variable. 16477 VarDecl *OmpPrivParm = 16478 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16479 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16480 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16481 // uses semantics of argument handles by value, but it should be passed by 16482 // reference. C lang does not support references, so pass all parameters as 16483 // pointers. 16484 // Create 'T omp_orig;' variable. 16485 VarDecl *OmpOrigParm = 16486 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16487 if (S != nullptr) { 16488 PushOnScopeChains(OmpPrivParm, S); 16489 PushOnScopeChains(OmpOrigParm, S); 16490 } else { 16491 DRD->addDecl(OmpPrivParm); 16492 DRD->addDecl(OmpOrigParm); 16493 } 16494 Expr *OrigE = 16495 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16496 Expr *PrivE = 16497 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16498 DRD->setInitializerData(OrigE, PrivE); 16499 return OmpPrivParm; 16500 } 16501 16502 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16503 VarDecl *OmpPrivParm) { 16504 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16505 DiscardCleanupsInEvaluationContext(); 16506 PopExpressionEvaluationContext(); 16507 16508 PopDeclContext(); 16509 PopFunctionScopeInfo(); 16510 16511 if (Initializer != nullptr) { 16512 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16513 } else if (OmpPrivParm->hasInit()) { 16514 DRD->setInitializer(OmpPrivParm->getInit(), 16515 OmpPrivParm->isDirectInit() 16516 ? OMPDeclareReductionDecl::DirectInit 16517 : OMPDeclareReductionDecl::CopyInit); 16518 } else { 16519 DRD->setInvalidDecl(); 16520 } 16521 } 16522 16523 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16524 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16525 for (Decl *D : DeclReductions.get()) { 16526 if (IsValid) { 16527 if (S) 16528 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16529 /*AddToContext=*/false); 16530 } else { 16531 D->setInvalidDecl(); 16532 } 16533 } 16534 return DeclReductions; 16535 } 16536 16537 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16538 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16539 QualType T = TInfo->getType(); 16540 if (D.isInvalidType()) 16541 return true; 16542 16543 if (getLangOpts().CPlusPlus) { 16544 // Check that there are no default arguments (C++ only). 16545 CheckExtraCXXDefaultArguments(D); 16546 } 16547 16548 return CreateParsedType(T, TInfo); 16549 } 16550 16551 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16552 TypeResult ParsedType) { 16553 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16554 16555 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16556 assert(!MapperType.isNull() && "Expect valid mapper type"); 16557 16558 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16559 // The type must be of struct, union or class type in C and C++ 16560 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16561 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16562 return QualType(); 16563 } 16564 return MapperType; 16565 } 16566 16567 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16568 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16569 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16570 Decl *PrevDeclInScope) { 16571 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16572 forRedeclarationInCurContext()); 16573 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16574 // A mapper-identifier may not be redeclared in the current scope for the 16575 // same type or for a type that is compatible according to the base language 16576 // rules. 16577 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16578 OMPDeclareMapperDecl *PrevDMD = nullptr; 16579 bool InCompoundScope = true; 16580 if (S != nullptr) { 16581 // Find previous declaration with the same name not referenced in other 16582 // declarations. 16583 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16584 InCompoundScope = 16585 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16586 LookupName(Lookup, S); 16587 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16588 /*AllowInlineNamespace=*/false); 16589 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16590 LookupResult::Filter Filter = Lookup.makeFilter(); 16591 while (Filter.hasNext()) { 16592 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16593 if (InCompoundScope) { 16594 auto I = UsedAsPrevious.find(PrevDecl); 16595 if (I == UsedAsPrevious.end()) 16596 UsedAsPrevious[PrevDecl] = false; 16597 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16598 UsedAsPrevious[D] = true; 16599 } 16600 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16601 PrevDecl->getLocation(); 16602 } 16603 Filter.done(); 16604 if (InCompoundScope) { 16605 for (const auto &PrevData : UsedAsPrevious) { 16606 if (!PrevData.second) { 16607 PrevDMD = PrevData.first; 16608 break; 16609 } 16610 } 16611 } 16612 } else if (PrevDeclInScope) { 16613 auto *PrevDMDInScope = PrevDMD = 16614 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16615 do { 16616 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16617 PrevDMDInScope->getLocation(); 16618 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16619 } while (PrevDMDInScope != nullptr); 16620 } 16621 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16622 bool Invalid = false; 16623 if (I != PreviousRedeclTypes.end()) { 16624 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16625 << MapperType << Name; 16626 Diag(I->second, diag::note_previous_definition); 16627 Invalid = true; 16628 } 16629 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16630 MapperType, VN, PrevDMD); 16631 DC->addDecl(DMD); 16632 DMD->setAccess(AS); 16633 if (Invalid) 16634 DMD->setInvalidDecl(); 16635 16636 // Enter new function scope. 16637 PushFunctionScope(); 16638 setFunctionHasBranchProtectedScope(); 16639 16640 CurContext = DMD; 16641 16642 return DMD; 16643 } 16644 16645 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16646 Scope *S, 16647 QualType MapperType, 16648 SourceLocation StartLoc, 16649 DeclarationName VN) { 16650 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16651 if (S) 16652 PushOnScopeChains(VD, S); 16653 else 16654 DMD->addDecl(VD); 16655 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16656 DMD->setMapperVarRef(MapperVarRefExpr); 16657 } 16658 16659 Sema::DeclGroupPtrTy 16660 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16661 ArrayRef<OMPClause *> ClauseList) { 16662 PopDeclContext(); 16663 PopFunctionScopeInfo(); 16664 16665 if (D) { 16666 if (S) 16667 PushOnScopeChains(D, S, /*AddToContext=*/false); 16668 D->CreateClauses(Context, ClauseList); 16669 } 16670 16671 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16672 } 16673 16674 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16675 SourceLocation StartLoc, 16676 SourceLocation LParenLoc, 16677 SourceLocation EndLoc) { 16678 Expr *ValExpr = NumTeams; 16679 Stmt *HelperValStmt = nullptr; 16680 16681 // OpenMP [teams Constrcut, Restrictions] 16682 // The num_teams expression must evaluate to a positive integer value. 16683 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16684 /*StrictlyPositive=*/true)) 16685 return nullptr; 16686 16687 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16688 OpenMPDirectiveKind CaptureRegion = 16689 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 16690 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16691 ValExpr = MakeFullExpr(ValExpr).get(); 16692 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16693 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16694 HelperValStmt = buildPreInits(Context, Captures); 16695 } 16696 16697 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16698 StartLoc, LParenLoc, EndLoc); 16699 } 16700 16701 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16702 SourceLocation StartLoc, 16703 SourceLocation LParenLoc, 16704 SourceLocation EndLoc) { 16705 Expr *ValExpr = ThreadLimit; 16706 Stmt *HelperValStmt = nullptr; 16707 16708 // OpenMP [teams Constrcut, Restrictions] 16709 // The thread_limit expression must evaluate to a positive integer value. 16710 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16711 /*StrictlyPositive=*/true)) 16712 return nullptr; 16713 16714 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16715 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 16716 DKind, OMPC_thread_limit, LangOpts.OpenMP); 16717 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16718 ValExpr = MakeFullExpr(ValExpr).get(); 16719 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16720 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16721 HelperValStmt = buildPreInits(Context, Captures); 16722 } 16723 16724 return new (Context) OMPThreadLimitClause( 16725 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16726 } 16727 16728 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16729 SourceLocation StartLoc, 16730 SourceLocation LParenLoc, 16731 SourceLocation EndLoc) { 16732 Expr *ValExpr = Priority; 16733 Stmt *HelperValStmt = nullptr; 16734 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16735 16736 // OpenMP [2.9.1, task Constrcut] 16737 // The priority-value is a non-negative numerical scalar expression. 16738 if (!isNonNegativeIntegerValue( 16739 ValExpr, *this, OMPC_priority, 16740 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16741 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16742 return nullptr; 16743 16744 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16745 StartLoc, LParenLoc, EndLoc); 16746 } 16747 16748 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16749 SourceLocation StartLoc, 16750 SourceLocation LParenLoc, 16751 SourceLocation EndLoc) { 16752 Expr *ValExpr = Grainsize; 16753 Stmt *HelperValStmt = nullptr; 16754 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16755 16756 // OpenMP [2.9.2, taskloop Constrcut] 16757 // The parameter of the grainsize clause must be a positive integer 16758 // expression. 16759 if (!isNonNegativeIntegerValue( 16760 ValExpr, *this, OMPC_grainsize, 16761 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16762 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16763 return nullptr; 16764 16765 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16766 StartLoc, LParenLoc, EndLoc); 16767 } 16768 16769 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16770 SourceLocation StartLoc, 16771 SourceLocation LParenLoc, 16772 SourceLocation EndLoc) { 16773 Expr *ValExpr = NumTasks; 16774 Stmt *HelperValStmt = nullptr; 16775 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16776 16777 // OpenMP [2.9.2, taskloop Constrcut] 16778 // The parameter of the num_tasks clause must be a positive integer 16779 // expression. 16780 if (!isNonNegativeIntegerValue( 16781 ValExpr, *this, OMPC_num_tasks, 16782 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16783 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16784 return nullptr; 16785 16786 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16787 StartLoc, LParenLoc, EndLoc); 16788 } 16789 16790 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16791 SourceLocation LParenLoc, 16792 SourceLocation EndLoc) { 16793 // OpenMP [2.13.2, critical construct, Description] 16794 // ... where hint-expression is an integer constant expression that evaluates 16795 // to a valid lock hint. 16796 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16797 if (HintExpr.isInvalid()) 16798 return nullptr; 16799 return new (Context) 16800 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16801 } 16802 16803 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16804 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16805 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16806 SourceLocation EndLoc) { 16807 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16808 std::string Values; 16809 Values += "'"; 16810 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16811 Values += "'"; 16812 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16813 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16814 return nullptr; 16815 } 16816 Expr *ValExpr = ChunkSize; 16817 Stmt *HelperValStmt = nullptr; 16818 if (ChunkSize) { 16819 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16820 !ChunkSize->isInstantiationDependent() && 16821 !ChunkSize->containsUnexpandedParameterPack()) { 16822 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16823 ExprResult Val = 16824 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16825 if (Val.isInvalid()) 16826 return nullptr; 16827 16828 ValExpr = Val.get(); 16829 16830 // OpenMP [2.7.1, Restrictions] 16831 // chunk_size must be a loop invariant integer expression with a positive 16832 // value. 16833 llvm::APSInt Result; 16834 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16835 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16836 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16837 << "dist_schedule" << ChunkSize->getSourceRange(); 16838 return nullptr; 16839 } 16840 } else if (getOpenMPCaptureRegionForClause( 16841 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 16842 LangOpts.OpenMP) != OMPD_unknown && 16843 !CurContext->isDependentContext()) { 16844 ValExpr = MakeFullExpr(ValExpr).get(); 16845 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16846 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16847 HelperValStmt = buildPreInits(Context, Captures); 16848 } 16849 } 16850 } 16851 16852 return new (Context) 16853 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16854 Kind, ValExpr, HelperValStmt); 16855 } 16856 16857 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16858 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16859 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16860 SourceLocation KindLoc, SourceLocation EndLoc) { 16861 if (getLangOpts().OpenMP < 50) { 16862 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 16863 Kind != OMPC_DEFAULTMAP_scalar) { 16864 std::string Value; 16865 SourceLocation Loc; 16866 Value += "'"; 16867 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16868 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16869 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16870 Loc = MLoc; 16871 } else { 16872 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16873 OMPC_DEFAULTMAP_scalar); 16874 Loc = KindLoc; 16875 } 16876 Value += "'"; 16877 Diag(Loc, diag::err_omp_unexpected_clause_value) 16878 << Value << getOpenMPClauseName(OMPC_defaultmap); 16879 return nullptr; 16880 } 16881 } else { 16882 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 16883 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 16884 if (!isDefaultmapKind || !isDefaultmapModifier) { 16885 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 16886 "'firstprivate', 'none', 'default'"; 16887 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 16888 if (!isDefaultmapKind && isDefaultmapModifier) { 16889 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16890 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16891 } else if (isDefaultmapKind && !isDefaultmapModifier) { 16892 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16893 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16894 } else { 16895 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16896 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16897 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16898 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16899 } 16900 return nullptr; 16901 } 16902 16903 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 16904 // At most one defaultmap clause for each category can appear on the 16905 // directive. 16906 if (DSAStack->checkDefaultmapCategory(Kind)) { 16907 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 16908 return nullptr; 16909 } 16910 } 16911 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 16912 16913 return new (Context) 16914 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16915 } 16916 16917 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16918 DeclContext *CurLexicalContext = getCurLexicalContext(); 16919 if (!CurLexicalContext->isFileContext() && 16920 !CurLexicalContext->isExternCContext() && 16921 !CurLexicalContext->isExternCXXContext() && 16922 !isa<CXXRecordDecl>(CurLexicalContext) && 16923 !isa<ClassTemplateDecl>(CurLexicalContext) && 16924 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16925 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16926 Diag(Loc, diag::err_omp_region_not_file_context); 16927 return false; 16928 } 16929 ++DeclareTargetNestingLevel; 16930 return true; 16931 } 16932 16933 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16934 assert(DeclareTargetNestingLevel > 0 && 16935 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16936 --DeclareTargetNestingLevel; 16937 } 16938 16939 NamedDecl * 16940 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16941 const DeclarationNameInfo &Id, 16942 NamedDeclSetType &SameDirectiveDecls) { 16943 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16944 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16945 16946 if (Lookup.isAmbiguous()) 16947 return nullptr; 16948 Lookup.suppressDiagnostics(); 16949 16950 if (!Lookup.isSingleResult()) { 16951 VarOrFuncDeclFilterCCC CCC(*this); 16952 if (TypoCorrection Corrected = 16953 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16954 CTK_ErrorRecovery)) { 16955 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16956 << Id.getName()); 16957 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16958 return nullptr; 16959 } 16960 16961 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16962 return nullptr; 16963 } 16964 16965 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16966 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16967 !isa<FunctionTemplateDecl>(ND)) { 16968 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16969 return nullptr; 16970 } 16971 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16972 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16973 return ND; 16974 } 16975 16976 void Sema::ActOnOpenMPDeclareTargetName( 16977 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16978 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16979 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16980 isa<FunctionTemplateDecl>(ND)) && 16981 "Expected variable, function or function template."); 16982 16983 // Diagnose marking after use as it may lead to incorrect diagnosis and 16984 // codegen. 16985 if (LangOpts.OpenMP >= 50 && 16986 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16987 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16988 16989 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16990 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16991 if (DevTy.hasValue() && *DevTy != DT) { 16992 Diag(Loc, diag::err_omp_device_type_mismatch) 16993 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16994 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16995 return; 16996 } 16997 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16998 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16999 if (!Res) { 17000 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 17001 SourceRange(Loc, Loc)); 17002 ND->addAttr(A); 17003 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17004 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 17005 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 17006 } else if (*Res != MT) { 17007 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 17008 } 17009 } 17010 17011 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 17012 Sema &SemaRef, Decl *D) { 17013 if (!D || !isa<VarDecl>(D)) 17014 return; 17015 auto *VD = cast<VarDecl>(D); 17016 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17017 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17018 if (SemaRef.LangOpts.OpenMP >= 50 && 17019 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 17020 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 17021 VD->hasGlobalStorage()) { 17022 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17023 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17024 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17025 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17026 // If a lambda declaration and definition appears between a 17027 // declare target directive and the matching end declare target 17028 // directive, all variables that are captured by the lambda 17029 // expression must also appear in a to clause. 17030 SemaRef.Diag(VD->getLocation(), 17031 diag::err_omp_lambda_capture_in_declare_target_not_to); 17032 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17033 << VD << 0 << SR; 17034 return; 17035 } 17036 } 17037 if (MapTy.hasValue()) 17038 return; 17039 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17040 SemaRef.Diag(SL, diag::note_used_here) << SR; 17041 } 17042 17043 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17044 Sema &SemaRef, DSAStackTy *Stack, 17045 ValueDecl *VD) { 17046 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17047 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17048 /*FullCheck=*/false); 17049 } 17050 17051 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17052 SourceLocation IdLoc) { 17053 if (!D || D->isInvalidDecl()) 17054 return; 17055 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 17056 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 17057 if (auto *VD = dyn_cast<VarDecl>(D)) { 17058 // Only global variables can be marked as declare target. 17059 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 17060 !VD->isStaticDataMember()) 17061 return; 17062 // 2.10.6: threadprivate variable cannot appear in a declare target 17063 // directive. 17064 if (DSAStack->isThreadPrivate(VD)) { 17065 Diag(SL, diag::err_omp_threadprivate_in_target); 17066 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 17067 return; 17068 } 17069 } 17070 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 17071 D = FTD->getTemplatedDecl(); 17072 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 17073 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17074 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 17075 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 17076 Diag(IdLoc, diag::err_omp_function_in_link_clause); 17077 Diag(FD->getLocation(), diag::note_defined_here) << FD; 17078 return; 17079 } 17080 } 17081 if (auto *VD = dyn_cast<ValueDecl>(D)) { 17082 // Problem if any with var declared with incomplete type will be reported 17083 // as normal, so no need to check it here. 17084 if ((E || !VD->getType()->isIncompleteType()) && 17085 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 17086 return; 17087 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 17088 // Checking declaration inside declare target region. 17089 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 17090 isa<FunctionTemplateDecl>(D)) { 17091 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 17092 Context, OMPDeclareTargetDeclAttr::MT_To, 17093 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 17094 D->addAttr(A); 17095 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17096 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 17097 } 17098 return; 17099 } 17100 } 17101 if (!E) 17102 return; 17103 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 17104 } 17105 17106 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 17107 CXXScopeSpec &MapperIdScopeSpec, 17108 DeclarationNameInfo &MapperId, 17109 const OMPVarListLocTy &Locs, 17110 ArrayRef<Expr *> UnresolvedMappers) { 17111 MappableVarListInfo MVLI(VarList); 17112 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17113 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17114 if (MVLI.ProcessedVarList.empty()) 17115 return nullptr; 17116 17117 return OMPToClause::Create( 17118 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17119 MVLI.VarComponents, MVLI.UDMapperList, 17120 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17121 } 17122 17123 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17124 CXXScopeSpec &MapperIdScopeSpec, 17125 DeclarationNameInfo &MapperId, 17126 const OMPVarListLocTy &Locs, 17127 ArrayRef<Expr *> UnresolvedMappers) { 17128 MappableVarListInfo MVLI(VarList); 17129 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 17130 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17131 if (MVLI.ProcessedVarList.empty()) 17132 return nullptr; 17133 17134 return OMPFromClause::Create( 17135 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17136 MVLI.VarComponents, MVLI.UDMapperList, 17137 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17138 } 17139 17140 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 17141 const OMPVarListLocTy &Locs) { 17142 MappableVarListInfo MVLI(VarList); 17143 SmallVector<Expr *, 8> PrivateCopies; 17144 SmallVector<Expr *, 8> Inits; 17145 17146 for (Expr *RefExpr : VarList) { 17147 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 17148 SourceLocation ELoc; 17149 SourceRange ERange; 17150 Expr *SimpleRefExpr = RefExpr; 17151 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17152 if (Res.second) { 17153 // It will be analyzed later. 17154 MVLI.ProcessedVarList.push_back(RefExpr); 17155 PrivateCopies.push_back(nullptr); 17156 Inits.push_back(nullptr); 17157 } 17158 ValueDecl *D = Res.first; 17159 if (!D) 17160 continue; 17161 17162 QualType Type = D->getType(); 17163 Type = Type.getNonReferenceType().getUnqualifiedType(); 17164 17165 auto *VD = dyn_cast<VarDecl>(D); 17166 17167 // Item should be a pointer or reference to pointer. 17168 if (!Type->isPointerType()) { 17169 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 17170 << 0 << RefExpr->getSourceRange(); 17171 continue; 17172 } 17173 17174 // Build the private variable and the expression that refers to it. 17175 auto VDPrivate = 17176 buildVarDecl(*this, ELoc, Type, D->getName(), 17177 D->hasAttrs() ? &D->getAttrs() : nullptr, 17178 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17179 if (VDPrivate->isInvalidDecl()) 17180 continue; 17181 17182 CurContext->addDecl(VDPrivate); 17183 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17184 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17185 17186 // Add temporary variable to initialize the private copy of the pointer. 17187 VarDecl *VDInit = 17188 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 17189 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 17190 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 17191 AddInitializerToDecl(VDPrivate, 17192 DefaultLvalueConversion(VDInitRefExpr).get(), 17193 /*DirectInit=*/false); 17194 17195 // If required, build a capture to implement the privatization initialized 17196 // with the current list item value. 17197 DeclRefExpr *Ref = nullptr; 17198 if (!VD) 17199 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17200 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 17201 PrivateCopies.push_back(VDPrivateRefExpr); 17202 Inits.push_back(VDInitRefExpr); 17203 17204 // We need to add a data sharing attribute for this variable to make sure it 17205 // is correctly captured. A variable that shows up in a use_device_ptr has 17206 // similar properties of a first private variable. 17207 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17208 17209 // Create a mappable component for the list item. List items in this clause 17210 // only need a component. 17211 MVLI.VarBaseDeclarations.push_back(D); 17212 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17213 MVLI.VarComponents.back().push_back( 17214 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 17215 } 17216 17217 if (MVLI.ProcessedVarList.empty()) 17218 return nullptr; 17219 17220 return OMPUseDevicePtrClause::Create( 17221 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 17222 MVLI.VarBaseDeclarations, MVLI.VarComponents); 17223 } 17224 17225 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 17226 const OMPVarListLocTy &Locs) { 17227 MappableVarListInfo MVLI(VarList); 17228 for (Expr *RefExpr : VarList) { 17229 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 17230 SourceLocation ELoc; 17231 SourceRange ERange; 17232 Expr *SimpleRefExpr = RefExpr; 17233 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17234 if (Res.second) { 17235 // It will be analyzed later. 17236 MVLI.ProcessedVarList.push_back(RefExpr); 17237 } 17238 ValueDecl *D = Res.first; 17239 if (!D) 17240 continue; 17241 17242 QualType Type = D->getType(); 17243 // item should be a pointer or array or reference to pointer or array 17244 if (!Type.getNonReferenceType()->isPointerType() && 17245 !Type.getNonReferenceType()->isArrayType()) { 17246 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 17247 << 0 << RefExpr->getSourceRange(); 17248 continue; 17249 } 17250 17251 // Check if the declaration in the clause does not show up in any data 17252 // sharing attribute. 17253 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17254 if (isOpenMPPrivate(DVar.CKind)) { 17255 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17256 << getOpenMPClauseName(DVar.CKind) 17257 << getOpenMPClauseName(OMPC_is_device_ptr) 17258 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17259 reportOriginalDsa(*this, DSAStack, D, DVar); 17260 continue; 17261 } 17262 17263 const Expr *ConflictExpr; 17264 if (DSAStack->checkMappableExprComponentListsForDecl( 17265 D, /*CurrentRegionOnly=*/true, 17266 [&ConflictExpr]( 17267 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 17268 OpenMPClauseKind) -> bool { 17269 ConflictExpr = R.front().getAssociatedExpression(); 17270 return true; 17271 })) { 17272 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 17273 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 17274 << ConflictExpr->getSourceRange(); 17275 continue; 17276 } 17277 17278 // Store the components in the stack so that they can be used to check 17279 // against other clauses later on. 17280 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 17281 DSAStack->addMappableExpressionComponents( 17282 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 17283 17284 // Record the expression we've just processed. 17285 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 17286 17287 // Create a mappable component for the list item. List items in this clause 17288 // only need a component. We use a null declaration to signal fields in 17289 // 'this'. 17290 assert((isa<DeclRefExpr>(SimpleRefExpr) || 17291 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 17292 "Unexpected device pointer expression!"); 17293 MVLI.VarBaseDeclarations.push_back( 17294 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 17295 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17296 MVLI.VarComponents.back().push_back(MC); 17297 } 17298 17299 if (MVLI.ProcessedVarList.empty()) 17300 return nullptr; 17301 17302 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 17303 MVLI.VarBaseDeclarations, 17304 MVLI.VarComponents); 17305 } 17306 17307 OMPClause *Sema::ActOnOpenMPAllocateClause( 17308 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17309 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17310 if (Allocator) { 17311 // OpenMP [2.11.4 allocate Clause, Description] 17312 // allocator is an expression of omp_allocator_handle_t type. 17313 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 17314 return nullptr; 17315 17316 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 17317 if (AllocatorRes.isInvalid()) 17318 return nullptr; 17319 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 17320 DSAStack->getOMPAllocatorHandleT(), 17321 Sema::AA_Initializing, 17322 /*AllowExplicit=*/true); 17323 if (AllocatorRes.isInvalid()) 17324 return nullptr; 17325 Allocator = AllocatorRes.get(); 17326 } else { 17327 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 17328 // allocate clauses that appear on a target construct or on constructs in a 17329 // target region must specify an allocator expression unless a requires 17330 // directive with the dynamic_allocators clause is present in the same 17331 // compilation unit. 17332 if (LangOpts.OpenMPIsDevice && 17333 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 17334 targetDiag(StartLoc, diag::err_expected_allocator_expression); 17335 } 17336 // Analyze and build list of variables. 17337 SmallVector<Expr *, 8> Vars; 17338 for (Expr *RefExpr : VarList) { 17339 assert(RefExpr && "NULL expr in OpenMP private clause."); 17340 SourceLocation ELoc; 17341 SourceRange ERange; 17342 Expr *SimpleRefExpr = RefExpr; 17343 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17344 if (Res.second) { 17345 // It will be analyzed later. 17346 Vars.push_back(RefExpr); 17347 } 17348 ValueDecl *D = Res.first; 17349 if (!D) 17350 continue; 17351 17352 auto *VD = dyn_cast<VarDecl>(D); 17353 DeclRefExpr *Ref = nullptr; 17354 if (!VD && !CurContext->isDependentContext()) 17355 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17356 Vars.push_back((VD || CurContext->isDependentContext()) 17357 ? RefExpr->IgnoreParens() 17358 : Ref); 17359 } 17360 17361 if (Vars.empty()) 17362 return nullptr; 17363 17364 if (Allocator) 17365 DSAStack->addInnerAllocatorExpr(Allocator); 17366 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 17367 ColonLoc, EndLoc, Vars); 17368 } 17369 17370 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 17371 SourceLocation StartLoc, 17372 SourceLocation LParenLoc, 17373 SourceLocation EndLoc) { 17374 SmallVector<Expr *, 8> Vars; 17375 for (Expr *RefExpr : VarList) { 17376 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 17377 SourceLocation ELoc; 17378 SourceRange ERange; 17379 Expr *SimpleRefExpr = RefExpr; 17380 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17381 if (Res.second) 17382 // It will be analyzed later. 17383 Vars.push_back(RefExpr); 17384 ValueDecl *D = Res.first; 17385 if (!D) 17386 continue; 17387 17388 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 17389 // A list-item cannot appear in more than one nontemporal clause. 17390 if (const Expr *PrevRef = 17391 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 17392 Diag(ELoc, diag::err_omp_used_in_clause_twice) 17393 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 17394 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 17395 << getOpenMPClauseName(OMPC_nontemporal); 17396 continue; 17397 } 17398 17399 Vars.push_back(RefExpr); 17400 } 17401 17402 if (Vars.empty()) 17403 return nullptr; 17404 17405 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17406 Vars); 17407 } 17408