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::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1714 bool CheckForDelayedContext) { 1715 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1716 "Expected OpenMP device compilation."); 1717 assert(Callee && "Callee may not be null."); 1718 Callee = Callee->getMostRecentDecl(); 1719 FunctionDecl *Caller = getCurFunctionDecl(); 1720 1721 // host only function are not available on the device. 1722 if (Caller) { 1723 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1724 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1725 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1726 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1727 "CUDADiscarded unexpected in OpenMP device function check"); 1728 if ((CallerS == FunctionEmissionStatus::Emitted || 1729 (!isOpenMPDeviceDelayedContext(*this) && 1730 CallerS == FunctionEmissionStatus::Unknown)) && 1731 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1732 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1733 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1734 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1735 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1736 diag::note_omp_marked_device_type_here) 1737 << HostDevTy; 1738 return; 1739 } 1740 } 1741 // If the caller is known-emitted, mark the callee as known-emitted. 1742 // Otherwise, mark the call in our call graph so we can traverse it later. 1743 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1744 (!Caller && !CheckForDelayedContext) || 1745 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1746 markKnownEmitted(*this, Caller, Callee, Loc, 1747 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1748 return CheckForDelayedContext && 1749 S.getEmissionStatus(FD) == 1750 FunctionEmissionStatus::Emitted; 1751 }); 1752 else if (Caller) 1753 DeviceCallGraph[Caller].insert({Callee, Loc}); 1754 } 1755 1756 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1757 bool CheckCaller) { 1758 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1759 "Expected OpenMP host compilation."); 1760 assert(Callee && "Callee may not be null."); 1761 Callee = Callee->getMostRecentDecl(); 1762 FunctionDecl *Caller = getCurFunctionDecl(); 1763 1764 // device only function are not available on the host. 1765 if (Caller) { 1766 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1767 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1768 assert( 1769 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1770 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1771 "CUDADiscarded unexpected in OpenMP host function check"); 1772 if (CallerS == FunctionEmissionStatus::Emitted && 1773 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1774 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1775 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1776 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1777 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1778 diag::note_omp_marked_device_type_here) 1779 << NoHostDevTy; 1780 return; 1781 } 1782 } 1783 // If the caller is known-emitted, mark the callee as known-emitted. 1784 // Otherwise, mark the call in our call graph so we can traverse it later. 1785 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1786 if ((!CheckCaller && !Caller) || 1787 (Caller && 1788 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1789 markKnownEmitted( 1790 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1791 return CheckCaller && 1792 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1793 }); 1794 else if (Caller) 1795 DeviceCallGraph[Caller].insert({Callee, Loc}); 1796 } 1797 } 1798 1799 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1800 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1801 "OpenMP device compilation mode is expected."); 1802 QualType Ty = E->getType(); 1803 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1804 ((Ty->isFloat128Type() || 1805 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1806 !Context.getTargetInfo().hasFloat128Type()) || 1807 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1808 !Context.getTargetInfo().hasInt128Type())) 1809 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1810 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1811 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1812 } 1813 1814 static OpenMPDefaultmapClauseKind 1815 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1816 if (LO.OpenMP <= 45) { 1817 if (VD->getType().getNonReferenceType()->isScalarType()) 1818 return OMPC_DEFAULTMAP_scalar; 1819 return OMPC_DEFAULTMAP_aggregate; 1820 } 1821 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1822 return OMPC_DEFAULTMAP_pointer; 1823 if (VD->getType().getNonReferenceType()->isScalarType()) 1824 return OMPC_DEFAULTMAP_scalar; 1825 return OMPC_DEFAULTMAP_aggregate; 1826 } 1827 1828 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1829 unsigned OpenMPCaptureLevel) const { 1830 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1831 1832 ASTContext &Ctx = getASTContext(); 1833 bool IsByRef = true; 1834 1835 // Find the directive that is associated with the provided scope. 1836 D = cast<ValueDecl>(D->getCanonicalDecl()); 1837 QualType Ty = D->getType(); 1838 1839 bool IsVariableUsedInMapClause = false; 1840 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1841 // This table summarizes how a given variable should be passed to the device 1842 // given its type and the clauses where it appears. This table is based on 1843 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1844 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1845 // 1846 // ========================================================================= 1847 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1848 // | |(tofrom:scalar)| | pvt | | | | 1849 // ========================================================================= 1850 // | scl | | | | - | | bycopy| 1851 // | scl | | - | x | - | - | bycopy| 1852 // | scl | | x | - | - | - | null | 1853 // | scl | x | | | - | | byref | 1854 // | scl | x | - | x | - | - | bycopy| 1855 // | scl | x | x | - | - | - | null | 1856 // | scl | | - | - | - | x | byref | 1857 // | scl | x | - | - | - | x | byref | 1858 // 1859 // | agg | n.a. | | | - | | byref | 1860 // | agg | n.a. | - | x | - | - | byref | 1861 // | agg | n.a. | x | - | - | - | null | 1862 // | agg | n.a. | - | - | - | x | byref | 1863 // | agg | n.a. | - | - | - | x[] | byref | 1864 // 1865 // | ptr | n.a. | | | - | | bycopy| 1866 // | ptr | n.a. | - | x | - | - | bycopy| 1867 // | ptr | n.a. | x | - | - | - | null | 1868 // | ptr | n.a. | - | - | - | x | byref | 1869 // | ptr | n.a. | - | - | - | x[] | bycopy| 1870 // | ptr | n.a. | - | - | x | | bycopy| 1871 // | ptr | n.a. | - | - | x | x | bycopy| 1872 // | ptr | n.a. | - | - | x | x[] | bycopy| 1873 // ========================================================================= 1874 // Legend: 1875 // scl - scalar 1876 // ptr - pointer 1877 // agg - aggregate 1878 // x - applies 1879 // - - invalid in this combination 1880 // [] - mapped with an array section 1881 // byref - should be mapped by reference 1882 // byval - should be mapped by value 1883 // null - initialize a local variable to null on the device 1884 // 1885 // Observations: 1886 // - All scalar declarations that show up in a map clause have to be passed 1887 // by reference, because they may have been mapped in the enclosing data 1888 // environment. 1889 // - If the scalar value does not fit the size of uintptr, it has to be 1890 // passed by reference, regardless the result in the table above. 1891 // - For pointers mapped by value that have either an implicit map or an 1892 // array section, the runtime library may pass the NULL value to the 1893 // device instead of the value passed to it by the compiler. 1894 1895 if (Ty->isReferenceType()) 1896 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1897 1898 // Locate map clauses and see if the variable being captured is referred to 1899 // in any of those clauses. Here we only care about variables, not fields, 1900 // because fields are part of aggregates. 1901 bool IsVariableAssociatedWithSection = false; 1902 1903 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1904 D, Level, 1905 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1906 OMPClauseMappableExprCommon::MappableExprComponentListRef 1907 MapExprComponents, 1908 OpenMPClauseKind WhereFoundClauseKind) { 1909 // Only the map clause information influences how a variable is 1910 // captured. E.g. is_device_ptr does not require changing the default 1911 // behavior. 1912 if (WhereFoundClauseKind != OMPC_map) 1913 return false; 1914 1915 auto EI = MapExprComponents.rbegin(); 1916 auto EE = MapExprComponents.rend(); 1917 1918 assert(EI != EE && "Invalid map expression!"); 1919 1920 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1921 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1922 1923 ++EI; 1924 if (EI == EE) 1925 return false; 1926 1927 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1928 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1929 isa<MemberExpr>(EI->getAssociatedExpression())) { 1930 IsVariableAssociatedWithSection = true; 1931 // There is nothing more we need to know about this variable. 1932 return true; 1933 } 1934 1935 // Keep looking for more map info. 1936 return false; 1937 }); 1938 1939 if (IsVariableUsedInMapClause) { 1940 // If variable is identified in a map clause it is always captured by 1941 // reference except if it is a pointer that is dereferenced somehow. 1942 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1943 } else { 1944 // By default, all the data that has a scalar type is mapped by copy 1945 // (except for reduction variables). 1946 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1947 IsByRef = 1948 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1949 !Ty->isAnyPointerType()) || 1950 !Ty->isScalarType() || 1951 DSAStack->isDefaultmapCapturedByRef( 1952 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1953 DSAStack->hasExplicitDSA( 1954 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1955 } 1956 } 1957 1958 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1959 IsByRef = 1960 ((IsVariableUsedInMapClause && 1961 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1962 OMPD_target) || 1963 !DSAStack->hasExplicitDSA( 1964 D, 1965 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1966 Level, /*NotLastprivate=*/true)) && 1967 // If the variable is artificial and must be captured by value - try to 1968 // capture by value. 1969 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1970 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1971 } 1972 1973 // When passing data by copy, we need to make sure it fits the uintptr size 1974 // and alignment, because the runtime library only deals with uintptr types. 1975 // If it does not fit the uintptr size, we need to pass the data by reference 1976 // instead. 1977 if (!IsByRef && 1978 (Ctx.getTypeSizeInChars(Ty) > 1979 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1980 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1981 IsByRef = true; 1982 } 1983 1984 return IsByRef; 1985 } 1986 1987 unsigned Sema::getOpenMPNestingLevel() const { 1988 assert(getLangOpts().OpenMP); 1989 return DSAStack->getNestingLevel(); 1990 } 1991 1992 bool Sema::isInOpenMPTargetExecutionDirective() const { 1993 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1994 !DSAStack->isClauseParsingMode()) || 1995 DSAStack->hasDirective( 1996 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1997 SourceLocation) -> bool { 1998 return isOpenMPTargetExecutionDirective(K); 1999 }, 2000 false); 2001 } 2002 2003 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2004 unsigned StopAt) { 2005 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2006 D = getCanonicalDecl(D); 2007 2008 auto *VD = dyn_cast<VarDecl>(D); 2009 // Do not capture constexpr variables. 2010 if (VD && VD->isConstexpr()) 2011 return nullptr; 2012 2013 // If we want to determine whether the variable should be captured from the 2014 // perspective of the current capturing scope, and we've already left all the 2015 // capturing scopes of the top directive on the stack, check from the 2016 // perspective of its parent directive (if any) instead. 2017 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2018 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2019 2020 // If we are attempting to capture a global variable in a directive with 2021 // 'target' we return true so that this global is also mapped to the device. 2022 // 2023 if (VD && !VD->hasLocalStorage() && 2024 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2025 if (isInOpenMPDeclareTargetContext()) { 2026 // Try to mark variable as declare target if it is used in capturing 2027 // regions. 2028 if (LangOpts.OpenMP <= 45 && 2029 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2030 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2031 return nullptr; 2032 } else if (isInOpenMPTargetExecutionDirective()) { 2033 // If the declaration is enclosed in a 'declare target' directive, 2034 // then it should not be captured. 2035 // 2036 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2037 return nullptr; 2038 CapturedRegionScopeInfo *CSI = nullptr; 2039 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2040 llvm::reverse(FunctionScopes), 2041 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2042 if (!isa<CapturingScopeInfo>(FSI)) 2043 return nullptr; 2044 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2045 if (RSI->CapRegionKind == CR_OpenMP) { 2046 CSI = RSI; 2047 break; 2048 } 2049 } 2050 SmallVector<OpenMPDirectiveKind, 4> Regions; 2051 getOpenMPCaptureRegions(Regions, 2052 DSAStack->getDirective(CSI->OpenMPLevel)); 2053 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2054 return VD; 2055 } 2056 } 2057 2058 if (CheckScopeInfo) { 2059 bool OpenMPFound = false; 2060 for (unsigned I = StopAt + 1; I > 0; --I) { 2061 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2062 if(!isa<CapturingScopeInfo>(FSI)) 2063 return nullptr; 2064 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2065 if (RSI->CapRegionKind == CR_OpenMP) { 2066 OpenMPFound = true; 2067 break; 2068 } 2069 } 2070 if (!OpenMPFound) 2071 return nullptr; 2072 } 2073 2074 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2075 (!DSAStack->isClauseParsingMode() || 2076 DSAStack->getParentDirective() != OMPD_unknown)) { 2077 auto &&Info = DSAStack->isLoopControlVariable(D); 2078 if (Info.first || 2079 (VD && VD->hasLocalStorage() && 2080 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2081 (VD && DSAStack->isForceVarCapturing())) 2082 return VD ? VD : Info.second; 2083 DSAStackTy::DSAVarData DVarPrivate = 2084 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2085 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2086 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2087 // Threadprivate variables must not be captured. 2088 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2089 return nullptr; 2090 // The variable is not private or it is the variable in the directive with 2091 // default(none) clause and not used in any clause. 2092 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2093 [](OpenMPDirectiveKind) { return true; }, 2094 DSAStack->isClauseParsingMode()); 2095 if (DVarPrivate.CKind != OMPC_unknown || 2096 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2097 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2098 } 2099 return nullptr; 2100 } 2101 2102 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2103 unsigned Level) const { 2104 SmallVector<OpenMPDirectiveKind, 4> Regions; 2105 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2106 FunctionScopesIndex -= Regions.size(); 2107 } 2108 2109 void Sema::startOpenMPLoop() { 2110 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2111 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2112 DSAStack->loopInit(); 2113 } 2114 2115 void Sema::startOpenMPCXXRangeFor() { 2116 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2117 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2118 DSAStack->resetPossibleLoopCounter(); 2119 DSAStack->loopStart(); 2120 } 2121 } 2122 2123 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2124 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2125 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2126 if (DSAStack->getAssociatedLoops() > 0 && 2127 !DSAStack->isLoopStarted()) { 2128 DSAStack->resetPossibleLoopCounter(D); 2129 DSAStack->loopStart(); 2130 return true; 2131 } 2132 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2133 DSAStack->isLoopControlVariable(D).first) && 2134 !DSAStack->hasExplicitDSA( 2135 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2136 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2137 return true; 2138 } 2139 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2140 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2141 DSAStack->isForceVarCapturing() && 2142 !DSAStack->hasExplicitDSA( 2143 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2144 return true; 2145 } 2146 return DSAStack->hasExplicitDSA( 2147 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2148 (DSAStack->isClauseParsingMode() && 2149 DSAStack->getClauseParsingMode() == OMPC_private) || 2150 // Consider taskgroup reduction descriptor variable a private to avoid 2151 // possible capture in the region. 2152 (DSAStack->hasExplicitDirective( 2153 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2154 Level) && 2155 DSAStack->isTaskgroupReductionRef(D, Level)); 2156 } 2157 2158 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2159 unsigned Level) { 2160 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2161 D = getCanonicalDecl(D); 2162 OpenMPClauseKind OMPC = OMPC_unknown; 2163 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2164 const unsigned NewLevel = I - 1; 2165 if (DSAStack->hasExplicitDSA(D, 2166 [&OMPC](const OpenMPClauseKind K) { 2167 if (isOpenMPPrivate(K)) { 2168 OMPC = K; 2169 return true; 2170 } 2171 return false; 2172 }, 2173 NewLevel)) 2174 break; 2175 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2176 D, NewLevel, 2177 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2178 OpenMPClauseKind) { return true; })) { 2179 OMPC = OMPC_map; 2180 break; 2181 } 2182 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2183 NewLevel)) { 2184 OMPC = OMPC_map; 2185 if (DSAStack->mustBeFirstprivateAtLevel( 2186 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2187 OMPC = OMPC_firstprivate; 2188 break; 2189 } 2190 } 2191 if (OMPC != OMPC_unknown) 2192 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2193 } 2194 2195 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2196 unsigned CaptureLevel) const { 2197 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2198 // Return true if the current level is no longer enclosed in a target region. 2199 2200 SmallVector<OpenMPDirectiveKind, 4> Regions; 2201 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2202 const auto *VD = dyn_cast<VarDecl>(D); 2203 return VD && !VD->hasLocalStorage() && 2204 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2205 Level) && 2206 Regions[CaptureLevel] != OMPD_task; 2207 } 2208 2209 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2210 2211 void Sema::finalizeOpenMPDelayedAnalysis() { 2212 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2213 // Diagnose implicit declare target functions and their callees. 2214 for (const auto &CallerCallees : DeviceCallGraph) { 2215 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2216 OMPDeclareTargetDeclAttr::getDeviceType( 2217 CallerCallees.getFirst()->getMostRecentDecl()); 2218 // Ignore host functions during device analyzis. 2219 if (LangOpts.OpenMPIsDevice && DevTy && 2220 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2221 continue; 2222 // Ignore nohost functions during host analyzis. 2223 if (!LangOpts.OpenMPIsDevice && DevTy && 2224 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2225 continue; 2226 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2227 &Callee : CallerCallees.getSecond()) { 2228 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2229 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2230 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2231 if (LangOpts.OpenMPIsDevice && DevTy && 2232 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2233 // Diagnose host function called during device codegen. 2234 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2235 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2236 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2237 << HostDevTy << 0; 2238 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2239 diag::note_omp_marked_device_type_here) 2240 << HostDevTy; 2241 continue; 2242 } 2243 if (!LangOpts.OpenMPIsDevice && DevTy && 2244 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2245 // Diagnose nohost function called during host codegen. 2246 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2247 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2248 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2249 << NoHostDevTy << 1; 2250 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2251 diag::note_omp_marked_device_type_here) 2252 << NoHostDevTy; 2253 continue; 2254 } 2255 } 2256 } 2257 } 2258 2259 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2260 const DeclarationNameInfo &DirName, 2261 Scope *CurScope, SourceLocation Loc) { 2262 DSAStack->push(DKind, DirName, CurScope, Loc); 2263 PushExpressionEvaluationContext( 2264 ExpressionEvaluationContext::PotentiallyEvaluated); 2265 } 2266 2267 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2268 DSAStack->setClauseParsingMode(K); 2269 } 2270 2271 void Sema::EndOpenMPClause() { 2272 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2273 } 2274 2275 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2276 ArrayRef<OMPClause *> Clauses); 2277 static std::pair<ValueDecl *, bool> 2278 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2279 SourceRange &ERange, bool AllowArraySection = false); 2280 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2281 bool WithInit); 2282 2283 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2284 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2285 // A variable of class type (or array thereof) that appears in a lastprivate 2286 // clause requires an accessible, unambiguous default constructor for the 2287 // class type, unless the list item is also specified in a firstprivate 2288 // clause. 2289 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2290 for (OMPClause *C : D->clauses()) { 2291 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2292 SmallVector<Expr *, 8> PrivateCopies; 2293 for (Expr *DE : Clause->varlists()) { 2294 if (DE->isValueDependent() || DE->isTypeDependent()) { 2295 PrivateCopies.push_back(nullptr); 2296 continue; 2297 } 2298 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2299 auto *VD = cast<VarDecl>(DRE->getDecl()); 2300 QualType Type = VD->getType().getNonReferenceType(); 2301 const DSAStackTy::DSAVarData DVar = 2302 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2303 if (DVar.CKind == OMPC_lastprivate) { 2304 // Generate helper private variable and initialize it with the 2305 // default value. The address of the original variable is replaced 2306 // by the address of the new private variable in CodeGen. This new 2307 // variable is not added to IdResolver, so the code in the OpenMP 2308 // region uses original variable for proper diagnostics. 2309 VarDecl *VDPrivate = buildVarDecl( 2310 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2311 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2312 ActOnUninitializedDecl(VDPrivate); 2313 if (VDPrivate->isInvalidDecl()) { 2314 PrivateCopies.push_back(nullptr); 2315 continue; 2316 } 2317 PrivateCopies.push_back(buildDeclRefExpr( 2318 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2319 } else { 2320 // The variable is also a firstprivate, so initialization sequence 2321 // for private copy is generated already. 2322 PrivateCopies.push_back(nullptr); 2323 } 2324 } 2325 Clause->setPrivateCopies(PrivateCopies); 2326 continue; 2327 } 2328 // Finalize nontemporal clause by handling private copies, if any. 2329 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2330 SmallVector<Expr *, 8> PrivateRefs; 2331 for (Expr *RefExpr : Clause->varlists()) { 2332 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2333 SourceLocation ELoc; 2334 SourceRange ERange; 2335 Expr *SimpleRefExpr = RefExpr; 2336 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2337 if (Res.second) 2338 // It will be analyzed later. 2339 PrivateRefs.push_back(RefExpr); 2340 ValueDecl *D = Res.first; 2341 if (!D) 2342 continue; 2343 2344 const DSAStackTy::DSAVarData DVar = 2345 DSAStack->getTopDSA(D, /*FromParent=*/false); 2346 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2347 : SimpleRefExpr); 2348 } 2349 Clause->setPrivateRefs(PrivateRefs); 2350 continue; 2351 } 2352 } 2353 // Check allocate clauses. 2354 if (!CurContext->isDependentContext()) 2355 checkAllocateClauses(*this, DSAStack, D->clauses()); 2356 } 2357 2358 DSAStack->pop(); 2359 DiscardCleanupsInEvaluationContext(); 2360 PopExpressionEvaluationContext(); 2361 } 2362 2363 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2364 Expr *NumIterations, Sema &SemaRef, 2365 Scope *S, DSAStackTy *Stack); 2366 2367 namespace { 2368 2369 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2370 private: 2371 Sema &SemaRef; 2372 2373 public: 2374 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2375 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2376 NamedDecl *ND = Candidate.getCorrectionDecl(); 2377 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2378 return VD->hasGlobalStorage() && 2379 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2380 SemaRef.getCurScope()); 2381 } 2382 return false; 2383 } 2384 2385 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2386 return std::make_unique<VarDeclFilterCCC>(*this); 2387 } 2388 2389 }; 2390 2391 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2392 private: 2393 Sema &SemaRef; 2394 2395 public: 2396 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2397 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2398 NamedDecl *ND = Candidate.getCorrectionDecl(); 2399 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2400 isa<FunctionDecl>(ND))) { 2401 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2402 SemaRef.getCurScope()); 2403 } 2404 return false; 2405 } 2406 2407 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2408 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2409 } 2410 }; 2411 2412 } // namespace 2413 2414 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2415 CXXScopeSpec &ScopeSpec, 2416 const DeclarationNameInfo &Id, 2417 OpenMPDirectiveKind Kind) { 2418 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2419 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2420 2421 if (Lookup.isAmbiguous()) 2422 return ExprError(); 2423 2424 VarDecl *VD; 2425 if (!Lookup.isSingleResult()) { 2426 VarDeclFilterCCC CCC(*this); 2427 if (TypoCorrection Corrected = 2428 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2429 CTK_ErrorRecovery)) { 2430 diagnoseTypo(Corrected, 2431 PDiag(Lookup.empty() 2432 ? diag::err_undeclared_var_use_suggest 2433 : diag::err_omp_expected_var_arg_suggest) 2434 << Id.getName()); 2435 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2436 } else { 2437 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2438 : diag::err_omp_expected_var_arg) 2439 << Id.getName(); 2440 return ExprError(); 2441 } 2442 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2443 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2444 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2445 return ExprError(); 2446 } 2447 Lookup.suppressDiagnostics(); 2448 2449 // OpenMP [2.9.2, Syntax, C/C++] 2450 // Variables must be file-scope, namespace-scope, or static block-scope. 2451 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2452 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2453 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2454 bool IsDecl = 2455 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2456 Diag(VD->getLocation(), 2457 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2458 << VD; 2459 return ExprError(); 2460 } 2461 2462 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2463 NamedDecl *ND = CanonicalVD; 2464 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2465 // A threadprivate directive for file-scope variables must appear outside 2466 // any definition or declaration. 2467 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2468 !getCurLexicalContext()->isTranslationUnit()) { 2469 Diag(Id.getLoc(), diag::err_omp_var_scope) 2470 << getOpenMPDirectiveName(Kind) << VD; 2471 bool IsDecl = 2472 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2473 Diag(VD->getLocation(), 2474 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2475 << VD; 2476 return ExprError(); 2477 } 2478 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2479 // A threadprivate directive for static class member variables must appear 2480 // in the class definition, in the same scope in which the member 2481 // variables are declared. 2482 if (CanonicalVD->isStaticDataMember() && 2483 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2484 Diag(Id.getLoc(), diag::err_omp_var_scope) 2485 << getOpenMPDirectiveName(Kind) << VD; 2486 bool IsDecl = 2487 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2488 Diag(VD->getLocation(), 2489 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2490 << VD; 2491 return ExprError(); 2492 } 2493 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2494 // A threadprivate directive for namespace-scope variables must appear 2495 // outside any definition or declaration other than the namespace 2496 // definition itself. 2497 if (CanonicalVD->getDeclContext()->isNamespace() && 2498 (!getCurLexicalContext()->isFileContext() || 2499 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2500 Diag(Id.getLoc(), diag::err_omp_var_scope) 2501 << getOpenMPDirectiveName(Kind) << VD; 2502 bool IsDecl = 2503 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2504 Diag(VD->getLocation(), 2505 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2506 << VD; 2507 return ExprError(); 2508 } 2509 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2510 // A threadprivate directive for static block-scope variables must appear 2511 // in the scope of the variable and not in a nested scope. 2512 if (CanonicalVD->isLocalVarDecl() && CurScope && 2513 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2514 Diag(Id.getLoc(), diag::err_omp_var_scope) 2515 << getOpenMPDirectiveName(Kind) << VD; 2516 bool IsDecl = 2517 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2518 Diag(VD->getLocation(), 2519 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2520 << VD; 2521 return ExprError(); 2522 } 2523 2524 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2525 // A threadprivate directive must lexically precede all references to any 2526 // of the variables in its list. 2527 if (Kind == OMPD_threadprivate && VD->isUsed() && 2528 !DSAStack->isThreadPrivate(VD)) { 2529 Diag(Id.getLoc(), diag::err_omp_var_used) 2530 << getOpenMPDirectiveName(Kind) << VD; 2531 return ExprError(); 2532 } 2533 2534 QualType ExprType = VD->getType().getNonReferenceType(); 2535 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2536 SourceLocation(), VD, 2537 /*RefersToEnclosingVariableOrCapture=*/false, 2538 Id.getLoc(), ExprType, VK_LValue); 2539 } 2540 2541 Sema::DeclGroupPtrTy 2542 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2543 ArrayRef<Expr *> VarList) { 2544 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2545 CurContext->addDecl(D); 2546 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2547 } 2548 return nullptr; 2549 } 2550 2551 namespace { 2552 class LocalVarRefChecker final 2553 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2554 Sema &SemaRef; 2555 2556 public: 2557 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2558 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2559 if (VD->hasLocalStorage()) { 2560 SemaRef.Diag(E->getBeginLoc(), 2561 diag::err_omp_local_var_in_threadprivate_init) 2562 << E->getSourceRange(); 2563 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2564 << VD << VD->getSourceRange(); 2565 return true; 2566 } 2567 } 2568 return false; 2569 } 2570 bool VisitStmt(const Stmt *S) { 2571 for (const Stmt *Child : S->children()) { 2572 if (Child && Visit(Child)) 2573 return true; 2574 } 2575 return false; 2576 } 2577 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2578 }; 2579 } // namespace 2580 2581 OMPThreadPrivateDecl * 2582 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2583 SmallVector<Expr *, 8> Vars; 2584 for (Expr *RefExpr : VarList) { 2585 auto *DE = cast<DeclRefExpr>(RefExpr); 2586 auto *VD = cast<VarDecl>(DE->getDecl()); 2587 SourceLocation ILoc = DE->getExprLoc(); 2588 2589 // Mark variable as used. 2590 VD->setReferenced(); 2591 VD->markUsed(Context); 2592 2593 QualType QType = VD->getType(); 2594 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2595 // It will be analyzed later. 2596 Vars.push_back(DE); 2597 continue; 2598 } 2599 2600 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2601 // A threadprivate variable must not have an incomplete type. 2602 if (RequireCompleteType(ILoc, VD->getType(), 2603 diag::err_omp_threadprivate_incomplete_type)) { 2604 continue; 2605 } 2606 2607 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2608 // A threadprivate variable must not have a reference type. 2609 if (VD->getType()->isReferenceType()) { 2610 Diag(ILoc, diag::err_omp_ref_type_arg) 2611 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2612 bool IsDecl = 2613 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2614 Diag(VD->getLocation(), 2615 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2616 << VD; 2617 continue; 2618 } 2619 2620 // Check if this is a TLS variable. If TLS is not being supported, produce 2621 // the corresponding diagnostic. 2622 if ((VD->getTLSKind() != VarDecl::TLS_None && 2623 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2624 getLangOpts().OpenMPUseTLS && 2625 getASTContext().getTargetInfo().isTLSSupported())) || 2626 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2627 !VD->isLocalVarDecl())) { 2628 Diag(ILoc, diag::err_omp_var_thread_local) 2629 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2630 bool IsDecl = 2631 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2632 Diag(VD->getLocation(), 2633 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2634 << VD; 2635 continue; 2636 } 2637 2638 // Check if initial value of threadprivate variable reference variable with 2639 // local storage (it is not supported by runtime). 2640 if (const Expr *Init = VD->getAnyInitializer()) { 2641 LocalVarRefChecker Checker(*this); 2642 if (Checker.Visit(Init)) 2643 continue; 2644 } 2645 2646 Vars.push_back(RefExpr); 2647 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2648 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2649 Context, SourceRange(Loc, Loc))); 2650 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2651 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2652 } 2653 OMPThreadPrivateDecl *D = nullptr; 2654 if (!Vars.empty()) { 2655 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2656 Vars); 2657 D->setAccess(AS_public); 2658 } 2659 return D; 2660 } 2661 2662 static OMPAllocateDeclAttr::AllocatorTypeTy 2663 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2664 if (!Allocator) 2665 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2666 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2667 Allocator->isInstantiationDependent() || 2668 Allocator->containsUnexpandedParameterPack()) 2669 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2670 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2671 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2672 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2673 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2674 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2675 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2676 llvm::FoldingSetNodeID AEId, DAEId; 2677 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2678 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2679 if (AEId == DAEId) { 2680 AllocatorKindRes = AllocatorKind; 2681 break; 2682 } 2683 } 2684 return AllocatorKindRes; 2685 } 2686 2687 static bool checkPreviousOMPAllocateAttribute( 2688 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2689 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2690 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2691 return false; 2692 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2693 Expr *PrevAllocator = A->getAllocator(); 2694 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2695 getAllocatorKind(S, Stack, PrevAllocator); 2696 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2697 if (AllocatorsMatch && 2698 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2699 Allocator && PrevAllocator) { 2700 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2701 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2702 llvm::FoldingSetNodeID AEId, PAEId; 2703 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2704 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2705 AllocatorsMatch = AEId == PAEId; 2706 } 2707 if (!AllocatorsMatch) { 2708 SmallString<256> AllocatorBuffer; 2709 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2710 if (Allocator) 2711 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2712 SmallString<256> PrevAllocatorBuffer; 2713 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2714 if (PrevAllocator) 2715 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2716 S.getPrintingPolicy()); 2717 2718 SourceLocation AllocatorLoc = 2719 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2720 SourceRange AllocatorRange = 2721 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2722 SourceLocation PrevAllocatorLoc = 2723 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2724 SourceRange PrevAllocatorRange = 2725 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2726 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2727 << (Allocator ? 1 : 0) << AllocatorStream.str() 2728 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2729 << AllocatorRange; 2730 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2731 << PrevAllocatorRange; 2732 return true; 2733 } 2734 return false; 2735 } 2736 2737 static void 2738 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2739 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2740 Expr *Allocator, SourceRange SR) { 2741 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2742 return; 2743 if (Allocator && 2744 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2745 Allocator->isInstantiationDependent() || 2746 Allocator->containsUnexpandedParameterPack())) 2747 return; 2748 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2749 Allocator, SR); 2750 VD->addAttr(A); 2751 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2752 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2753 } 2754 2755 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2756 SourceLocation Loc, ArrayRef<Expr *> VarList, 2757 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2758 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2759 Expr *Allocator = nullptr; 2760 if (Clauses.empty()) { 2761 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2762 // allocate directives that appear in a target region must specify an 2763 // allocator clause unless a requires directive with the dynamic_allocators 2764 // clause is present in the same compilation unit. 2765 if (LangOpts.OpenMPIsDevice && 2766 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2767 targetDiag(Loc, diag::err_expected_allocator_clause); 2768 } else { 2769 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2770 } 2771 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2772 getAllocatorKind(*this, DSAStack, Allocator); 2773 SmallVector<Expr *, 8> Vars; 2774 for (Expr *RefExpr : VarList) { 2775 auto *DE = cast<DeclRefExpr>(RefExpr); 2776 auto *VD = cast<VarDecl>(DE->getDecl()); 2777 2778 // Check if this is a TLS variable or global register. 2779 if (VD->getTLSKind() != VarDecl::TLS_None || 2780 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2781 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2782 !VD->isLocalVarDecl())) 2783 continue; 2784 2785 // If the used several times in the allocate directive, the same allocator 2786 // must be used. 2787 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2788 AllocatorKind, Allocator)) 2789 continue; 2790 2791 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2792 // If a list item has a static storage type, the allocator expression in the 2793 // allocator clause must be a constant expression that evaluates to one of 2794 // the predefined memory allocator values. 2795 if (Allocator && VD->hasGlobalStorage()) { 2796 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2797 Diag(Allocator->getExprLoc(), 2798 diag::err_omp_expected_predefined_allocator) 2799 << Allocator->getSourceRange(); 2800 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2801 VarDecl::DeclarationOnly; 2802 Diag(VD->getLocation(), 2803 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2804 << VD; 2805 continue; 2806 } 2807 } 2808 2809 Vars.push_back(RefExpr); 2810 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2811 DE->getSourceRange()); 2812 } 2813 if (Vars.empty()) 2814 return nullptr; 2815 if (!Owner) 2816 Owner = getCurLexicalContext(); 2817 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2818 D->setAccess(AS_public); 2819 Owner->addDecl(D); 2820 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2821 } 2822 2823 Sema::DeclGroupPtrTy 2824 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2825 ArrayRef<OMPClause *> ClauseList) { 2826 OMPRequiresDecl *D = nullptr; 2827 if (!CurContext->isFileContext()) { 2828 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2829 } else { 2830 D = CheckOMPRequiresDecl(Loc, ClauseList); 2831 if (D) { 2832 CurContext->addDecl(D); 2833 DSAStack->addRequiresDecl(D); 2834 } 2835 } 2836 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2837 } 2838 2839 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2840 ArrayRef<OMPClause *> ClauseList) { 2841 /// For target specific clauses, the requires directive cannot be 2842 /// specified after the handling of any of the target regions in the 2843 /// current compilation unit. 2844 ArrayRef<SourceLocation> TargetLocations = 2845 DSAStack->getEncounteredTargetLocs(); 2846 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 2847 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 2848 for (const OMPClause *CNew : ClauseList) { 2849 // Check if any of the requires clauses affect target regions. 2850 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2851 isa<OMPUnifiedAddressClause>(CNew) || 2852 isa<OMPReverseOffloadClause>(CNew) || 2853 isa<OMPDynamicAllocatorsClause>(CNew)) { 2854 Diag(Loc, diag::err_omp_directive_before_requires) 2855 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 2856 for (SourceLocation TargetLoc : TargetLocations) { 2857 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 2858 << "target"; 2859 } 2860 } else if (!AtomicLoc.isInvalid() && 2861 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 2862 Diag(Loc, diag::err_omp_directive_before_requires) 2863 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 2864 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 2865 << "atomic"; 2866 } 2867 } 2868 } 2869 2870 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2871 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2872 ClauseList); 2873 return nullptr; 2874 } 2875 2876 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2877 const ValueDecl *D, 2878 const DSAStackTy::DSAVarData &DVar, 2879 bool IsLoopIterVar = false) { 2880 if (DVar.RefExpr) { 2881 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2882 << getOpenMPClauseName(DVar.CKind); 2883 return; 2884 } 2885 enum { 2886 PDSA_StaticMemberShared, 2887 PDSA_StaticLocalVarShared, 2888 PDSA_LoopIterVarPrivate, 2889 PDSA_LoopIterVarLinear, 2890 PDSA_LoopIterVarLastprivate, 2891 PDSA_ConstVarShared, 2892 PDSA_GlobalVarShared, 2893 PDSA_TaskVarFirstprivate, 2894 PDSA_LocalVarPrivate, 2895 PDSA_Implicit 2896 } Reason = PDSA_Implicit; 2897 bool ReportHint = false; 2898 auto ReportLoc = D->getLocation(); 2899 auto *VD = dyn_cast<VarDecl>(D); 2900 if (IsLoopIterVar) { 2901 if (DVar.CKind == OMPC_private) 2902 Reason = PDSA_LoopIterVarPrivate; 2903 else if (DVar.CKind == OMPC_lastprivate) 2904 Reason = PDSA_LoopIterVarLastprivate; 2905 else 2906 Reason = PDSA_LoopIterVarLinear; 2907 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2908 DVar.CKind == OMPC_firstprivate) { 2909 Reason = PDSA_TaskVarFirstprivate; 2910 ReportLoc = DVar.ImplicitDSALoc; 2911 } else if (VD && VD->isStaticLocal()) 2912 Reason = PDSA_StaticLocalVarShared; 2913 else if (VD && VD->isStaticDataMember()) 2914 Reason = PDSA_StaticMemberShared; 2915 else if (VD && VD->isFileVarDecl()) 2916 Reason = PDSA_GlobalVarShared; 2917 else if (D->getType().isConstant(SemaRef.getASTContext())) 2918 Reason = PDSA_ConstVarShared; 2919 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2920 ReportHint = true; 2921 Reason = PDSA_LocalVarPrivate; 2922 } 2923 if (Reason != PDSA_Implicit) { 2924 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2925 << Reason << ReportHint 2926 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2927 } else if (DVar.ImplicitDSALoc.isValid()) { 2928 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2929 << getOpenMPClauseName(DVar.CKind); 2930 } 2931 } 2932 2933 static OpenMPMapClauseKind 2934 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 2935 bool IsAggregateOrDeclareTarget) { 2936 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 2937 switch (M) { 2938 case OMPC_DEFAULTMAP_MODIFIER_alloc: 2939 Kind = OMPC_MAP_alloc; 2940 break; 2941 case OMPC_DEFAULTMAP_MODIFIER_to: 2942 Kind = OMPC_MAP_to; 2943 break; 2944 case OMPC_DEFAULTMAP_MODIFIER_from: 2945 Kind = OMPC_MAP_from; 2946 break; 2947 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 2948 Kind = OMPC_MAP_tofrom; 2949 break; 2950 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 2951 case OMPC_DEFAULTMAP_MODIFIER_last: 2952 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2953 case OMPC_DEFAULTMAP_MODIFIER_none: 2954 case OMPC_DEFAULTMAP_MODIFIER_default: 2955 case OMPC_DEFAULTMAP_MODIFIER_unknown: 2956 // IsAggregateOrDeclareTarget could be true if: 2957 // 1. the implicit behavior for aggregate is tofrom 2958 // 2. it's a declare target link 2959 if (IsAggregateOrDeclareTarget) { 2960 Kind = OMPC_MAP_tofrom; 2961 break; 2962 } 2963 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2964 } 2965 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 2966 return Kind; 2967 } 2968 2969 namespace { 2970 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2971 DSAStackTy *Stack; 2972 Sema &SemaRef; 2973 bool ErrorFound = false; 2974 bool TryCaptureCXXThisMembers = false; 2975 CapturedStmt *CS = nullptr; 2976 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2977 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 2978 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2979 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2980 2981 void VisitSubCaptures(OMPExecutableDirective *S) { 2982 // Check implicitly captured variables. 2983 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2984 return; 2985 visitSubCaptures(S->getInnermostCapturedStmt()); 2986 // Try to capture inner this->member references to generate correct mappings 2987 // and diagnostics. 2988 if (TryCaptureCXXThisMembers || 2989 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2990 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2991 [](const CapturedStmt::Capture &C) { 2992 return C.capturesThis(); 2993 }))) { 2994 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2995 TryCaptureCXXThisMembers = true; 2996 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2997 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2998 } 2999 } 3000 3001 public: 3002 void VisitDeclRefExpr(DeclRefExpr *E) { 3003 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3004 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3005 E->isInstantiationDependent()) 3006 return; 3007 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3008 // Check the datasharing rules for the expressions in the clauses. 3009 if (!CS) { 3010 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3011 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3012 Visit(CED->getInit()); 3013 return; 3014 } 3015 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3016 // Do not analyze internal variables and do not enclose them into 3017 // implicit clauses. 3018 return; 3019 VD = VD->getCanonicalDecl(); 3020 // Skip internally declared variables. 3021 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 3022 return; 3023 3024 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3025 // Check if the variable has explicit DSA set and stop analysis if it so. 3026 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3027 return; 3028 3029 // Skip internally declared static variables. 3030 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3031 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3032 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3033 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3034 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 3035 return; 3036 3037 SourceLocation ELoc = E->getExprLoc(); 3038 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3039 // The default(none) clause requires that each variable that is referenced 3040 // in the construct, and does not have a predetermined data-sharing 3041 // attribute, must have its data-sharing attribute explicitly determined 3042 // by being listed in a data-sharing attribute clause. 3043 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3044 isImplicitOrExplicitTaskingRegion(DKind) && 3045 VarsWithInheritedDSA.count(VD) == 0) { 3046 VarsWithInheritedDSA[VD] = E; 3047 return; 3048 } 3049 3050 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3051 // If implicit-behavior is none, each variable referenced in the 3052 // construct that does not have a predetermined data-sharing attribute 3053 // and does not appear in a to or link clause on a declare target 3054 // directive must be listed in a data-mapping attribute clause, a 3055 // data-haring attribute clause (including a data-sharing attribute 3056 // clause on a combined construct where target. is one of the 3057 // constituent constructs), or an is_device_ptr clause. 3058 OpenMPDefaultmapClauseKind ClauseKind = 3059 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3060 if (SemaRef.getLangOpts().OpenMP >= 50) { 3061 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3062 OMPC_DEFAULTMAP_MODIFIER_none; 3063 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3064 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3065 // Only check for data-mapping attribute and is_device_ptr here 3066 // since we have already make sure that the declaration does not 3067 // have a data-sharing attribute above 3068 if (!Stack->checkMappableExprComponentListsForDecl( 3069 VD, /*CurrentRegionOnly=*/true, 3070 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3071 MapExprComponents, 3072 OpenMPClauseKind) { 3073 auto MI = MapExprComponents.rbegin(); 3074 auto ME = MapExprComponents.rend(); 3075 return MI != ME && MI->getAssociatedDeclaration() == VD; 3076 })) { 3077 VarsWithInheritedDSA[VD] = E; 3078 return; 3079 } 3080 } 3081 } 3082 3083 if (isOpenMPTargetExecutionDirective(DKind) && 3084 !Stack->isLoopControlVariable(VD).first) { 3085 if (!Stack->checkMappableExprComponentListsForDecl( 3086 VD, /*CurrentRegionOnly=*/true, 3087 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3088 StackComponents, 3089 OpenMPClauseKind) { 3090 // Variable is used if it has been marked as an array, array 3091 // section or the variable iself. 3092 return StackComponents.size() == 1 || 3093 std::all_of( 3094 std::next(StackComponents.rbegin()), 3095 StackComponents.rend(), 3096 [](const OMPClauseMappableExprCommon:: 3097 MappableComponent &MC) { 3098 return MC.getAssociatedDeclaration() == 3099 nullptr && 3100 (isa<OMPArraySectionExpr>( 3101 MC.getAssociatedExpression()) || 3102 isa<ArraySubscriptExpr>( 3103 MC.getAssociatedExpression())); 3104 }); 3105 })) { 3106 bool IsFirstprivate = false; 3107 // By default lambdas are captured as firstprivates. 3108 if (const auto *RD = 3109 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3110 IsFirstprivate = RD->isLambda(); 3111 IsFirstprivate = 3112 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3113 if (IsFirstprivate) { 3114 ImplicitFirstprivate.emplace_back(E); 3115 } else { 3116 OpenMPDefaultmapClauseModifier M = 3117 Stack->getDefaultmapModifier(ClauseKind); 3118 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3119 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3120 ImplicitMap[Kind].emplace_back(E); 3121 } 3122 return; 3123 } 3124 } 3125 3126 // OpenMP [2.9.3.6, Restrictions, p.2] 3127 // A list item that appears in a reduction clause of the innermost 3128 // enclosing worksharing or parallel construct may not be accessed in an 3129 // explicit task. 3130 DVar = Stack->hasInnermostDSA( 3131 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3132 [](OpenMPDirectiveKind K) { 3133 return isOpenMPParallelDirective(K) || 3134 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3135 }, 3136 /*FromParent=*/true); 3137 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3138 ErrorFound = true; 3139 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3140 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3141 return; 3142 } 3143 3144 // Define implicit data-sharing attributes for task. 3145 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3146 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3147 !Stack->isLoopControlVariable(VD).first) { 3148 ImplicitFirstprivate.push_back(E); 3149 return; 3150 } 3151 3152 // Store implicitly used globals with declare target link for parent 3153 // target. 3154 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3155 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3156 Stack->addToParentTargetRegionLinkGlobals(E); 3157 return; 3158 } 3159 } 3160 } 3161 void VisitMemberExpr(MemberExpr *E) { 3162 if (E->isTypeDependent() || E->isValueDependent() || 3163 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3164 return; 3165 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3166 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3167 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 3168 if (!FD) 3169 return; 3170 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3171 // Check if the variable has explicit DSA set and stop analysis if it 3172 // so. 3173 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3174 return; 3175 3176 if (isOpenMPTargetExecutionDirective(DKind) && 3177 !Stack->isLoopControlVariable(FD).first && 3178 !Stack->checkMappableExprComponentListsForDecl( 3179 FD, /*CurrentRegionOnly=*/true, 3180 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3181 StackComponents, 3182 OpenMPClauseKind) { 3183 return isa<CXXThisExpr>( 3184 cast<MemberExpr>( 3185 StackComponents.back().getAssociatedExpression()) 3186 ->getBase() 3187 ->IgnoreParens()); 3188 })) { 3189 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3190 // A bit-field cannot appear in a map clause. 3191 // 3192 if (FD->isBitField()) 3193 return; 3194 3195 // Check to see if the member expression is referencing a class that 3196 // has already been explicitly mapped 3197 if (Stack->isClassPreviouslyMapped(TE->getType())) 3198 return; 3199 3200 OpenMPDefaultmapClauseModifier Modifier = 3201 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3202 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3203 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3204 ImplicitMap[Kind].emplace_back(E); 3205 return; 3206 } 3207 3208 SourceLocation ELoc = E->getExprLoc(); 3209 // OpenMP [2.9.3.6, Restrictions, p.2] 3210 // A list item that appears in a reduction clause of the innermost 3211 // enclosing worksharing or parallel construct may not be accessed in 3212 // an explicit task. 3213 DVar = Stack->hasInnermostDSA( 3214 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3215 [](OpenMPDirectiveKind K) { 3216 return isOpenMPParallelDirective(K) || 3217 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3218 }, 3219 /*FromParent=*/true); 3220 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3221 ErrorFound = true; 3222 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3223 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3224 return; 3225 } 3226 3227 // Define implicit data-sharing attributes for task. 3228 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3229 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3230 !Stack->isLoopControlVariable(FD).first) { 3231 // Check if there is a captured expression for the current field in the 3232 // region. Do not mark it as firstprivate unless there is no captured 3233 // expression. 3234 // TODO: try to make it firstprivate. 3235 if (DVar.CKind != OMPC_unknown) 3236 ImplicitFirstprivate.push_back(E); 3237 } 3238 return; 3239 } 3240 if (isOpenMPTargetExecutionDirective(DKind)) { 3241 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3242 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3243 /*NoDiagnose=*/true)) 3244 return; 3245 const auto *VD = cast<ValueDecl>( 3246 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3247 if (!Stack->checkMappableExprComponentListsForDecl( 3248 VD, /*CurrentRegionOnly=*/true, 3249 [&CurComponents]( 3250 OMPClauseMappableExprCommon::MappableExprComponentListRef 3251 StackComponents, 3252 OpenMPClauseKind) { 3253 auto CCI = CurComponents.rbegin(); 3254 auto CCE = CurComponents.rend(); 3255 for (const auto &SC : llvm::reverse(StackComponents)) { 3256 // Do both expressions have the same kind? 3257 if (CCI->getAssociatedExpression()->getStmtClass() != 3258 SC.getAssociatedExpression()->getStmtClass()) 3259 if (!(isa<OMPArraySectionExpr>( 3260 SC.getAssociatedExpression()) && 3261 isa<ArraySubscriptExpr>( 3262 CCI->getAssociatedExpression()))) 3263 return false; 3264 3265 const Decl *CCD = CCI->getAssociatedDeclaration(); 3266 const Decl *SCD = SC.getAssociatedDeclaration(); 3267 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3268 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3269 if (SCD != CCD) 3270 return false; 3271 std::advance(CCI, 1); 3272 if (CCI == CCE) 3273 break; 3274 } 3275 return true; 3276 })) { 3277 Visit(E->getBase()); 3278 } 3279 } else if (!TryCaptureCXXThisMembers) { 3280 Visit(E->getBase()); 3281 } 3282 } 3283 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3284 for (OMPClause *C : S->clauses()) { 3285 // Skip analysis of arguments of implicitly defined firstprivate clause 3286 // for task|target directives. 3287 // Skip analysis of arguments of implicitly defined map clause for target 3288 // directives. 3289 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3290 C->isImplicit())) { 3291 for (Stmt *CC : C->children()) { 3292 if (CC) 3293 Visit(CC); 3294 } 3295 } 3296 } 3297 // Check implicitly captured variables. 3298 VisitSubCaptures(S); 3299 } 3300 void VisitStmt(Stmt *S) { 3301 for (Stmt *C : S->children()) { 3302 if (C) { 3303 // Check implicitly captured variables in the task-based directives to 3304 // check if they must be firstprivatized. 3305 Visit(C); 3306 } 3307 } 3308 } 3309 3310 void visitSubCaptures(CapturedStmt *S) { 3311 for (const CapturedStmt::Capture &Cap : S->captures()) { 3312 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3313 continue; 3314 VarDecl *VD = Cap.getCapturedVar(); 3315 // Do not try to map the variable if it or its sub-component was mapped 3316 // already. 3317 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3318 Stack->checkMappableExprComponentListsForDecl( 3319 VD, /*CurrentRegionOnly=*/true, 3320 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3321 OpenMPClauseKind) { return true; })) 3322 continue; 3323 DeclRefExpr *DRE = buildDeclRefExpr( 3324 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3325 Cap.getLocation(), /*RefersToCapture=*/true); 3326 Visit(DRE); 3327 } 3328 } 3329 bool isErrorFound() const { return ErrorFound; } 3330 ArrayRef<Expr *> getImplicitFirstprivate() const { 3331 return ImplicitFirstprivate; 3332 } 3333 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3334 return ImplicitMap[Kind]; 3335 } 3336 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3337 return VarsWithInheritedDSA; 3338 } 3339 3340 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3341 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3342 // Process declare target link variables for the target directives. 3343 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3344 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3345 Visit(E); 3346 } 3347 } 3348 }; 3349 } // namespace 3350 3351 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3352 switch (DKind) { 3353 case OMPD_parallel: 3354 case OMPD_parallel_for: 3355 case OMPD_parallel_for_simd: 3356 case OMPD_parallel_sections: 3357 case OMPD_parallel_master: 3358 case OMPD_teams: 3359 case OMPD_teams_distribute: 3360 case OMPD_teams_distribute_simd: { 3361 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3362 QualType KmpInt32PtrTy = 3363 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3364 Sema::CapturedParamNameType Params[] = { 3365 std::make_pair(".global_tid.", KmpInt32PtrTy), 3366 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3367 std::make_pair(StringRef(), QualType()) // __context with shared vars 3368 }; 3369 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3370 Params); 3371 break; 3372 } 3373 case OMPD_target_teams: 3374 case OMPD_target_parallel: 3375 case OMPD_target_parallel_for: 3376 case OMPD_target_parallel_for_simd: 3377 case OMPD_target_teams_distribute: 3378 case OMPD_target_teams_distribute_simd: { 3379 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3380 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3381 QualType KmpInt32PtrTy = 3382 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3383 QualType Args[] = {VoidPtrTy}; 3384 FunctionProtoType::ExtProtoInfo EPI; 3385 EPI.Variadic = true; 3386 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3387 Sema::CapturedParamNameType Params[] = { 3388 std::make_pair(".global_tid.", KmpInt32Ty), 3389 std::make_pair(".part_id.", KmpInt32PtrTy), 3390 std::make_pair(".privates.", VoidPtrTy), 3391 std::make_pair( 3392 ".copy_fn.", 3393 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3394 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3395 std::make_pair(StringRef(), QualType()) // __context with shared vars 3396 }; 3397 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3398 Params, /*OpenMPCaptureLevel=*/0); 3399 // Mark this captured region as inlined, because we don't use outlined 3400 // function directly. 3401 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3402 AlwaysInlineAttr::CreateImplicit( 3403 Context, {}, AttributeCommonInfo::AS_Keyword, 3404 AlwaysInlineAttr::Keyword_forceinline)); 3405 Sema::CapturedParamNameType ParamsTarget[] = { 3406 std::make_pair(StringRef(), QualType()) // __context with shared vars 3407 }; 3408 // Start a captured region for 'target' with no implicit parameters. 3409 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3410 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3411 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3412 std::make_pair(".global_tid.", KmpInt32PtrTy), 3413 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3414 std::make_pair(StringRef(), QualType()) // __context with shared vars 3415 }; 3416 // Start a captured region for 'teams' or 'parallel'. Both regions have 3417 // the same implicit parameters. 3418 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3419 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3420 break; 3421 } 3422 case OMPD_target: 3423 case OMPD_target_simd: { 3424 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3425 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3426 QualType KmpInt32PtrTy = 3427 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3428 QualType Args[] = {VoidPtrTy}; 3429 FunctionProtoType::ExtProtoInfo EPI; 3430 EPI.Variadic = true; 3431 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3432 Sema::CapturedParamNameType Params[] = { 3433 std::make_pair(".global_tid.", KmpInt32Ty), 3434 std::make_pair(".part_id.", KmpInt32PtrTy), 3435 std::make_pair(".privates.", VoidPtrTy), 3436 std::make_pair( 3437 ".copy_fn.", 3438 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3439 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3440 std::make_pair(StringRef(), QualType()) // __context with shared vars 3441 }; 3442 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3443 Params, /*OpenMPCaptureLevel=*/0); 3444 // Mark this captured region as inlined, because we don't use outlined 3445 // function directly. 3446 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3447 AlwaysInlineAttr::CreateImplicit( 3448 Context, {}, AttributeCommonInfo::AS_Keyword, 3449 AlwaysInlineAttr::Keyword_forceinline)); 3450 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3451 std::make_pair(StringRef(), QualType()), 3452 /*OpenMPCaptureLevel=*/1); 3453 break; 3454 } 3455 case OMPD_simd: 3456 case OMPD_for: 3457 case OMPD_for_simd: 3458 case OMPD_sections: 3459 case OMPD_section: 3460 case OMPD_single: 3461 case OMPD_master: 3462 case OMPD_critical: 3463 case OMPD_taskgroup: 3464 case OMPD_distribute: 3465 case OMPD_distribute_simd: 3466 case OMPD_ordered: 3467 case OMPD_atomic: 3468 case OMPD_target_data: { 3469 Sema::CapturedParamNameType Params[] = { 3470 std::make_pair(StringRef(), QualType()) // __context with shared vars 3471 }; 3472 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3473 Params); 3474 break; 3475 } 3476 case OMPD_task: { 3477 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3478 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3479 QualType KmpInt32PtrTy = 3480 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3481 QualType Args[] = {VoidPtrTy}; 3482 FunctionProtoType::ExtProtoInfo EPI; 3483 EPI.Variadic = true; 3484 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3485 Sema::CapturedParamNameType Params[] = { 3486 std::make_pair(".global_tid.", KmpInt32Ty), 3487 std::make_pair(".part_id.", KmpInt32PtrTy), 3488 std::make_pair(".privates.", VoidPtrTy), 3489 std::make_pair( 3490 ".copy_fn.", 3491 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3492 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3493 std::make_pair(StringRef(), QualType()) // __context with shared vars 3494 }; 3495 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3496 Params); 3497 // Mark this captured region as inlined, because we don't use outlined 3498 // function directly. 3499 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3500 AlwaysInlineAttr::CreateImplicit( 3501 Context, {}, AttributeCommonInfo::AS_Keyword, 3502 AlwaysInlineAttr::Keyword_forceinline)); 3503 break; 3504 } 3505 case OMPD_taskloop: 3506 case OMPD_taskloop_simd: 3507 case OMPD_master_taskloop: 3508 case OMPD_master_taskloop_simd: { 3509 QualType KmpInt32Ty = 3510 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3511 .withConst(); 3512 QualType KmpUInt64Ty = 3513 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3514 .withConst(); 3515 QualType KmpInt64Ty = 3516 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3517 .withConst(); 3518 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3519 QualType KmpInt32PtrTy = 3520 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3521 QualType Args[] = {VoidPtrTy}; 3522 FunctionProtoType::ExtProtoInfo EPI; 3523 EPI.Variadic = true; 3524 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3525 Sema::CapturedParamNameType Params[] = { 3526 std::make_pair(".global_tid.", KmpInt32Ty), 3527 std::make_pair(".part_id.", KmpInt32PtrTy), 3528 std::make_pair(".privates.", VoidPtrTy), 3529 std::make_pair( 3530 ".copy_fn.", 3531 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3532 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3533 std::make_pair(".lb.", KmpUInt64Ty), 3534 std::make_pair(".ub.", KmpUInt64Ty), 3535 std::make_pair(".st.", KmpInt64Ty), 3536 std::make_pair(".liter.", KmpInt32Ty), 3537 std::make_pair(".reductions.", VoidPtrTy), 3538 std::make_pair(StringRef(), QualType()) // __context with shared vars 3539 }; 3540 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3541 Params); 3542 // Mark this captured region as inlined, because we don't use outlined 3543 // function directly. 3544 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3545 AlwaysInlineAttr::CreateImplicit( 3546 Context, {}, AttributeCommonInfo::AS_Keyword, 3547 AlwaysInlineAttr::Keyword_forceinline)); 3548 break; 3549 } 3550 case OMPD_parallel_master_taskloop: 3551 case OMPD_parallel_master_taskloop_simd: { 3552 QualType KmpInt32Ty = 3553 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3554 .withConst(); 3555 QualType KmpUInt64Ty = 3556 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3557 .withConst(); 3558 QualType KmpInt64Ty = 3559 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3560 .withConst(); 3561 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3562 QualType KmpInt32PtrTy = 3563 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3564 Sema::CapturedParamNameType ParamsParallel[] = { 3565 std::make_pair(".global_tid.", KmpInt32PtrTy), 3566 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3567 std::make_pair(StringRef(), QualType()) // __context with shared vars 3568 }; 3569 // Start a captured region for 'parallel'. 3570 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3571 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3572 QualType Args[] = {VoidPtrTy}; 3573 FunctionProtoType::ExtProtoInfo EPI; 3574 EPI.Variadic = true; 3575 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3576 Sema::CapturedParamNameType Params[] = { 3577 std::make_pair(".global_tid.", KmpInt32Ty), 3578 std::make_pair(".part_id.", KmpInt32PtrTy), 3579 std::make_pair(".privates.", VoidPtrTy), 3580 std::make_pair( 3581 ".copy_fn.", 3582 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3583 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3584 std::make_pair(".lb.", KmpUInt64Ty), 3585 std::make_pair(".ub.", KmpUInt64Ty), 3586 std::make_pair(".st.", KmpInt64Ty), 3587 std::make_pair(".liter.", KmpInt32Ty), 3588 std::make_pair(".reductions.", VoidPtrTy), 3589 std::make_pair(StringRef(), QualType()) // __context with shared vars 3590 }; 3591 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3592 Params, /*OpenMPCaptureLevel=*/2); 3593 // Mark this captured region as inlined, because we don't use outlined 3594 // function directly. 3595 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3596 AlwaysInlineAttr::CreateImplicit( 3597 Context, {}, AttributeCommonInfo::AS_Keyword, 3598 AlwaysInlineAttr::Keyword_forceinline)); 3599 break; 3600 } 3601 case OMPD_distribute_parallel_for_simd: 3602 case OMPD_distribute_parallel_for: { 3603 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3604 QualType KmpInt32PtrTy = 3605 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3606 Sema::CapturedParamNameType Params[] = { 3607 std::make_pair(".global_tid.", KmpInt32PtrTy), 3608 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3609 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3610 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3611 std::make_pair(StringRef(), QualType()) // __context with shared vars 3612 }; 3613 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3614 Params); 3615 break; 3616 } 3617 case OMPD_target_teams_distribute_parallel_for: 3618 case OMPD_target_teams_distribute_parallel_for_simd: { 3619 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3620 QualType KmpInt32PtrTy = 3621 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3622 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3623 3624 QualType Args[] = {VoidPtrTy}; 3625 FunctionProtoType::ExtProtoInfo EPI; 3626 EPI.Variadic = true; 3627 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3628 Sema::CapturedParamNameType Params[] = { 3629 std::make_pair(".global_tid.", KmpInt32Ty), 3630 std::make_pair(".part_id.", KmpInt32PtrTy), 3631 std::make_pair(".privates.", VoidPtrTy), 3632 std::make_pair( 3633 ".copy_fn.", 3634 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3635 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3636 std::make_pair(StringRef(), QualType()) // __context with shared vars 3637 }; 3638 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3639 Params, /*OpenMPCaptureLevel=*/0); 3640 // Mark this captured region as inlined, because we don't use outlined 3641 // function directly. 3642 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3643 AlwaysInlineAttr::CreateImplicit( 3644 Context, {}, AttributeCommonInfo::AS_Keyword, 3645 AlwaysInlineAttr::Keyword_forceinline)); 3646 Sema::CapturedParamNameType ParamsTarget[] = { 3647 std::make_pair(StringRef(), QualType()) // __context with shared vars 3648 }; 3649 // Start a captured region for 'target' with no implicit parameters. 3650 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3651 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3652 3653 Sema::CapturedParamNameType ParamsTeams[] = { 3654 std::make_pair(".global_tid.", KmpInt32PtrTy), 3655 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3656 std::make_pair(StringRef(), QualType()) // __context with shared vars 3657 }; 3658 // Start a captured region for 'target' with no implicit parameters. 3659 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3660 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3661 3662 Sema::CapturedParamNameType ParamsParallel[] = { 3663 std::make_pair(".global_tid.", KmpInt32PtrTy), 3664 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3665 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3666 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3667 std::make_pair(StringRef(), QualType()) // __context with shared vars 3668 }; 3669 // Start a captured region for 'teams' or 'parallel'. Both regions have 3670 // the same implicit parameters. 3671 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3672 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3673 break; 3674 } 3675 3676 case OMPD_teams_distribute_parallel_for: 3677 case OMPD_teams_distribute_parallel_for_simd: { 3678 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3679 QualType KmpInt32PtrTy = 3680 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3681 3682 Sema::CapturedParamNameType ParamsTeams[] = { 3683 std::make_pair(".global_tid.", KmpInt32PtrTy), 3684 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3685 std::make_pair(StringRef(), QualType()) // __context with shared vars 3686 }; 3687 // Start a captured region for 'target' with no implicit parameters. 3688 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3689 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3690 3691 Sema::CapturedParamNameType ParamsParallel[] = { 3692 std::make_pair(".global_tid.", KmpInt32PtrTy), 3693 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3694 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3695 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3696 std::make_pair(StringRef(), QualType()) // __context with shared vars 3697 }; 3698 // Start a captured region for 'teams' or 'parallel'. Both regions have 3699 // the same implicit parameters. 3700 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3701 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3702 break; 3703 } 3704 case OMPD_target_update: 3705 case OMPD_target_enter_data: 3706 case OMPD_target_exit_data: { 3707 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3708 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3709 QualType KmpInt32PtrTy = 3710 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3711 QualType Args[] = {VoidPtrTy}; 3712 FunctionProtoType::ExtProtoInfo EPI; 3713 EPI.Variadic = true; 3714 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3715 Sema::CapturedParamNameType Params[] = { 3716 std::make_pair(".global_tid.", KmpInt32Ty), 3717 std::make_pair(".part_id.", KmpInt32PtrTy), 3718 std::make_pair(".privates.", VoidPtrTy), 3719 std::make_pair( 3720 ".copy_fn.", 3721 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3722 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3723 std::make_pair(StringRef(), QualType()) // __context with shared vars 3724 }; 3725 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3726 Params); 3727 // Mark this captured region as inlined, because we don't use outlined 3728 // function directly. 3729 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3730 AlwaysInlineAttr::CreateImplicit( 3731 Context, {}, AttributeCommonInfo::AS_Keyword, 3732 AlwaysInlineAttr::Keyword_forceinline)); 3733 break; 3734 } 3735 case OMPD_threadprivate: 3736 case OMPD_allocate: 3737 case OMPD_taskyield: 3738 case OMPD_barrier: 3739 case OMPD_taskwait: 3740 case OMPD_cancellation_point: 3741 case OMPD_cancel: 3742 case OMPD_flush: 3743 case OMPD_declare_reduction: 3744 case OMPD_declare_mapper: 3745 case OMPD_declare_simd: 3746 case OMPD_declare_target: 3747 case OMPD_end_declare_target: 3748 case OMPD_requires: 3749 case OMPD_declare_variant: 3750 llvm_unreachable("OpenMP Directive is not allowed"); 3751 case OMPD_unknown: 3752 llvm_unreachable("Unknown OpenMP directive"); 3753 } 3754 } 3755 3756 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3757 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3758 } 3759 3760 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3761 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3762 getOpenMPCaptureRegions(CaptureRegions, DKind); 3763 return CaptureRegions.size(); 3764 } 3765 3766 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3767 Expr *CaptureExpr, bool WithInit, 3768 bool AsExpression) { 3769 assert(CaptureExpr); 3770 ASTContext &C = S.getASTContext(); 3771 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3772 QualType Ty = Init->getType(); 3773 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3774 if (S.getLangOpts().CPlusPlus) { 3775 Ty = C.getLValueReferenceType(Ty); 3776 } else { 3777 Ty = C.getPointerType(Ty); 3778 ExprResult Res = 3779 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3780 if (!Res.isUsable()) 3781 return nullptr; 3782 Init = Res.get(); 3783 } 3784 WithInit = true; 3785 } 3786 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3787 CaptureExpr->getBeginLoc()); 3788 if (!WithInit) 3789 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3790 S.CurContext->addHiddenDecl(CED); 3791 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3792 return CED; 3793 } 3794 3795 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3796 bool WithInit) { 3797 OMPCapturedExprDecl *CD; 3798 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3799 CD = cast<OMPCapturedExprDecl>(VD); 3800 else 3801 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3802 /*AsExpression=*/false); 3803 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3804 CaptureExpr->getExprLoc()); 3805 } 3806 3807 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3808 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3809 if (!Ref) { 3810 OMPCapturedExprDecl *CD = buildCaptureDecl( 3811 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3812 /*WithInit=*/true, /*AsExpression=*/true); 3813 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3814 CaptureExpr->getExprLoc()); 3815 } 3816 ExprResult Res = Ref; 3817 if (!S.getLangOpts().CPlusPlus && 3818 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3819 Ref->getType()->isPointerType()) { 3820 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3821 if (!Res.isUsable()) 3822 return ExprError(); 3823 } 3824 return S.DefaultLvalueConversion(Res.get()); 3825 } 3826 3827 namespace { 3828 // OpenMP directives parsed in this section are represented as a 3829 // CapturedStatement with an associated statement. If a syntax error 3830 // is detected during the parsing of the associated statement, the 3831 // compiler must abort processing and close the CapturedStatement. 3832 // 3833 // Combined directives such as 'target parallel' have more than one 3834 // nested CapturedStatements. This RAII ensures that we unwind out 3835 // of all the nested CapturedStatements when an error is found. 3836 class CaptureRegionUnwinderRAII { 3837 private: 3838 Sema &S; 3839 bool &ErrorFound; 3840 OpenMPDirectiveKind DKind = OMPD_unknown; 3841 3842 public: 3843 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3844 OpenMPDirectiveKind DKind) 3845 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3846 ~CaptureRegionUnwinderRAII() { 3847 if (ErrorFound) { 3848 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3849 while (--ThisCaptureLevel >= 0) 3850 S.ActOnCapturedRegionError(); 3851 } 3852 } 3853 }; 3854 } // namespace 3855 3856 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3857 // Capture variables captured by reference in lambdas for target-based 3858 // directives. 3859 if (!CurContext->isDependentContext() && 3860 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3861 isOpenMPTargetDataManagementDirective( 3862 DSAStack->getCurrentDirective()))) { 3863 QualType Type = V->getType(); 3864 if (const auto *RD = Type.getCanonicalType() 3865 .getNonReferenceType() 3866 ->getAsCXXRecordDecl()) { 3867 bool SavedForceCaptureByReferenceInTargetExecutable = 3868 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3869 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3870 /*V=*/true); 3871 if (RD->isLambda()) { 3872 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3873 FieldDecl *ThisCapture; 3874 RD->getCaptureFields(Captures, ThisCapture); 3875 for (const LambdaCapture &LC : RD->captures()) { 3876 if (LC.getCaptureKind() == LCK_ByRef) { 3877 VarDecl *VD = LC.getCapturedVar(); 3878 DeclContext *VDC = VD->getDeclContext(); 3879 if (!VDC->Encloses(CurContext)) 3880 continue; 3881 MarkVariableReferenced(LC.getLocation(), VD); 3882 } else if (LC.getCaptureKind() == LCK_This) { 3883 QualType ThisTy = getCurrentThisType(); 3884 if (!ThisTy.isNull() && 3885 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3886 CheckCXXThisCapture(LC.getLocation()); 3887 } 3888 } 3889 } 3890 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3891 SavedForceCaptureByReferenceInTargetExecutable); 3892 } 3893 } 3894 } 3895 3896 static bool checkOrderedOrderSpecified(Sema &S, 3897 const ArrayRef<OMPClause *> Clauses) { 3898 const OMPOrderedClause *Ordered = nullptr; 3899 const OMPOrderClause *Order = nullptr; 3900 3901 for (const OMPClause *Clause : Clauses) { 3902 if (Clause->getClauseKind() == OMPC_ordered) 3903 Ordered = cast<OMPOrderedClause>(Clause); 3904 else if (Clause->getClauseKind() == OMPC_order) { 3905 Order = cast<OMPOrderClause>(Clause); 3906 if (Order->getKind() != OMPC_ORDER_concurrent) 3907 Order = nullptr; 3908 } 3909 if (Ordered && Order) 3910 break; 3911 } 3912 3913 if (Ordered && Order) { 3914 S.Diag(Order->getKindKwLoc(), 3915 diag::err_omp_simple_clause_incompatible_with_ordered) 3916 << getOpenMPClauseName(OMPC_order) 3917 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 3918 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 3919 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 3920 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 3921 return true; 3922 } 3923 return false; 3924 } 3925 3926 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3927 ArrayRef<OMPClause *> Clauses) { 3928 bool ErrorFound = false; 3929 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3930 *this, ErrorFound, DSAStack->getCurrentDirective()); 3931 if (!S.isUsable()) { 3932 ErrorFound = true; 3933 return StmtError(); 3934 } 3935 3936 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3937 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3938 OMPOrderedClause *OC = nullptr; 3939 OMPScheduleClause *SC = nullptr; 3940 SmallVector<const OMPLinearClause *, 4> LCs; 3941 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3942 // This is required for proper codegen. 3943 for (OMPClause *Clause : Clauses) { 3944 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3945 Clause->getClauseKind() == OMPC_in_reduction) { 3946 // Capture taskgroup task_reduction descriptors inside the tasking regions 3947 // with the corresponding in_reduction items. 3948 auto *IRC = cast<OMPInReductionClause>(Clause); 3949 for (Expr *E : IRC->taskgroup_descriptors()) 3950 if (E) 3951 MarkDeclarationsReferencedInExpr(E); 3952 } 3953 if (isOpenMPPrivate(Clause->getClauseKind()) || 3954 Clause->getClauseKind() == OMPC_copyprivate || 3955 (getLangOpts().OpenMPUseTLS && 3956 getASTContext().getTargetInfo().isTLSSupported() && 3957 Clause->getClauseKind() == OMPC_copyin)) { 3958 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3959 // Mark all variables in private list clauses as used in inner region. 3960 for (Stmt *VarRef : Clause->children()) { 3961 if (auto *E = cast_or_null<Expr>(VarRef)) { 3962 MarkDeclarationsReferencedInExpr(E); 3963 } 3964 } 3965 DSAStack->setForceVarCapturing(/*V=*/false); 3966 } else if (CaptureRegions.size() > 1 || 3967 CaptureRegions.back() != OMPD_unknown) { 3968 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3969 PICs.push_back(C); 3970 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3971 if (Expr *E = C->getPostUpdateExpr()) 3972 MarkDeclarationsReferencedInExpr(E); 3973 } 3974 } 3975 if (Clause->getClauseKind() == OMPC_schedule) 3976 SC = cast<OMPScheduleClause>(Clause); 3977 else if (Clause->getClauseKind() == OMPC_ordered) 3978 OC = cast<OMPOrderedClause>(Clause); 3979 else if (Clause->getClauseKind() == OMPC_linear) 3980 LCs.push_back(cast<OMPLinearClause>(Clause)); 3981 } 3982 // Capture allocator expressions if used. 3983 for (Expr *E : DSAStack->getInnerAllocators()) 3984 MarkDeclarationsReferencedInExpr(E); 3985 // OpenMP, 2.7.1 Loop Construct, Restrictions 3986 // The nonmonotonic modifier cannot be specified if an ordered clause is 3987 // specified. 3988 if (SC && 3989 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3990 SC->getSecondScheduleModifier() == 3991 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3992 OC) { 3993 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3994 ? SC->getFirstScheduleModifierLoc() 3995 : SC->getSecondScheduleModifierLoc(), 3996 diag::err_omp_simple_clause_incompatible_with_ordered) 3997 << getOpenMPClauseName(OMPC_schedule) 3998 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 3999 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4000 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4001 ErrorFound = true; 4002 } 4003 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4004 // If an order(concurrent) clause is present, an ordered clause may not appear 4005 // on the same directive. 4006 if (checkOrderedOrderSpecified(*this, Clauses)) 4007 ErrorFound = true; 4008 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4009 for (const OMPLinearClause *C : LCs) { 4010 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4011 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4012 } 4013 ErrorFound = true; 4014 } 4015 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4016 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4017 OC->getNumForLoops()) { 4018 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4019 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4020 ErrorFound = true; 4021 } 4022 if (ErrorFound) { 4023 return StmtError(); 4024 } 4025 StmtResult SR = S; 4026 unsigned CompletedRegions = 0; 4027 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4028 // Mark all variables in private list clauses as used in inner region. 4029 // Required for proper codegen of combined directives. 4030 // TODO: add processing for other clauses. 4031 if (ThisCaptureRegion != OMPD_unknown) { 4032 for (const clang::OMPClauseWithPreInit *C : PICs) { 4033 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4034 // Find the particular capture region for the clause if the 4035 // directive is a combined one with multiple capture regions. 4036 // If the directive is not a combined one, the capture region 4037 // associated with the clause is OMPD_unknown and is generated 4038 // only once. 4039 if (CaptureRegion == ThisCaptureRegion || 4040 CaptureRegion == OMPD_unknown) { 4041 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4042 for (Decl *D : DS->decls()) 4043 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4044 } 4045 } 4046 } 4047 } 4048 if (++CompletedRegions == CaptureRegions.size()) 4049 DSAStack->setBodyComplete(); 4050 SR = ActOnCapturedRegionEnd(SR.get()); 4051 } 4052 return SR; 4053 } 4054 4055 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4056 OpenMPDirectiveKind CancelRegion, 4057 SourceLocation StartLoc) { 4058 // CancelRegion is only needed for cancel and cancellation_point. 4059 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4060 return false; 4061 4062 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4063 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4064 return false; 4065 4066 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4067 << getOpenMPDirectiveName(CancelRegion); 4068 return true; 4069 } 4070 4071 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4072 OpenMPDirectiveKind CurrentRegion, 4073 const DeclarationNameInfo &CurrentName, 4074 OpenMPDirectiveKind CancelRegion, 4075 SourceLocation StartLoc) { 4076 if (Stack->getCurScope()) { 4077 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4078 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4079 bool NestingProhibited = false; 4080 bool CloseNesting = true; 4081 bool OrphanSeen = false; 4082 enum { 4083 NoRecommend, 4084 ShouldBeInParallelRegion, 4085 ShouldBeInOrderedRegion, 4086 ShouldBeInTargetRegion, 4087 ShouldBeInTeamsRegion 4088 } Recommend = NoRecommend; 4089 if (isOpenMPSimdDirective(ParentRegion) && 4090 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4091 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4092 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 4093 // OpenMP [2.16, Nesting of Regions] 4094 // OpenMP constructs may not be nested inside a simd region. 4095 // OpenMP [2.8.1,simd Construct, Restrictions] 4096 // An ordered construct with the simd clause is the only OpenMP 4097 // construct that can appear in the simd region. 4098 // Allowing a SIMD construct nested in another SIMD construct is an 4099 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4100 // message. 4101 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4102 // The only OpenMP constructs that can be encountered during execution of 4103 // a simd region are the atomic construct, the loop construct, the simd 4104 // construct and the ordered construct with the simd clause. 4105 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4106 ? diag::err_omp_prohibited_region_simd 4107 : diag::warn_omp_nesting_simd) 4108 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4109 return CurrentRegion != OMPD_simd; 4110 } 4111 if (ParentRegion == OMPD_atomic) { 4112 // OpenMP [2.16, Nesting of Regions] 4113 // OpenMP constructs may not be nested inside an atomic region. 4114 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4115 return true; 4116 } 4117 if (CurrentRegion == OMPD_section) { 4118 // OpenMP [2.7.2, sections Construct, Restrictions] 4119 // Orphaned section directives are prohibited. That is, the section 4120 // directives must appear within the sections construct and must not be 4121 // encountered elsewhere in the sections region. 4122 if (ParentRegion != OMPD_sections && 4123 ParentRegion != OMPD_parallel_sections) { 4124 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4125 << (ParentRegion != OMPD_unknown) 4126 << getOpenMPDirectiveName(ParentRegion); 4127 return true; 4128 } 4129 return false; 4130 } 4131 // Allow some constructs (except teams and cancellation constructs) to be 4132 // orphaned (they could be used in functions, called from OpenMP regions 4133 // with the required preconditions). 4134 if (ParentRegion == OMPD_unknown && 4135 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4136 CurrentRegion != OMPD_cancellation_point && 4137 CurrentRegion != OMPD_cancel) 4138 return false; 4139 if (CurrentRegion == OMPD_cancellation_point || 4140 CurrentRegion == OMPD_cancel) { 4141 // OpenMP [2.16, Nesting of Regions] 4142 // A cancellation point construct for which construct-type-clause is 4143 // taskgroup must be nested inside a task construct. A cancellation 4144 // point construct for which construct-type-clause is not taskgroup must 4145 // be closely nested inside an OpenMP construct that matches the type 4146 // specified in construct-type-clause. 4147 // A cancel construct for which construct-type-clause is taskgroup must be 4148 // nested inside a task construct. A cancel construct for which 4149 // construct-type-clause is not taskgroup must be closely nested inside an 4150 // OpenMP construct that matches the type specified in 4151 // construct-type-clause. 4152 NestingProhibited = 4153 !((CancelRegion == OMPD_parallel && 4154 (ParentRegion == OMPD_parallel || 4155 ParentRegion == OMPD_target_parallel)) || 4156 (CancelRegion == OMPD_for && 4157 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4158 ParentRegion == OMPD_target_parallel_for || 4159 ParentRegion == OMPD_distribute_parallel_for || 4160 ParentRegion == OMPD_teams_distribute_parallel_for || 4161 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4162 (CancelRegion == OMPD_taskgroup && 4163 (ParentRegion == OMPD_task || 4164 (SemaRef.getLangOpts().OpenMP >= 50 && 4165 (ParentRegion == OMPD_taskloop || 4166 ParentRegion == OMPD_master_taskloop || 4167 ParentRegion == OMPD_parallel_master_taskloop)))) || 4168 (CancelRegion == OMPD_sections && 4169 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4170 ParentRegion == OMPD_parallel_sections))); 4171 OrphanSeen = ParentRegion == OMPD_unknown; 4172 } else if (CurrentRegion == OMPD_master) { 4173 // OpenMP [2.16, Nesting of Regions] 4174 // A master region may not be closely nested inside a worksharing, 4175 // atomic, or explicit task region. 4176 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4177 isOpenMPTaskingDirective(ParentRegion); 4178 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4179 // OpenMP [2.16, Nesting of Regions] 4180 // A critical region may not be nested (closely or otherwise) inside a 4181 // critical region with the same name. Note that this restriction is not 4182 // sufficient to prevent deadlock. 4183 SourceLocation PreviousCriticalLoc; 4184 bool DeadLock = Stack->hasDirective( 4185 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4186 const DeclarationNameInfo &DNI, 4187 SourceLocation Loc) { 4188 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4189 PreviousCriticalLoc = Loc; 4190 return true; 4191 } 4192 return false; 4193 }, 4194 false /* skip top directive */); 4195 if (DeadLock) { 4196 SemaRef.Diag(StartLoc, 4197 diag::err_omp_prohibited_region_critical_same_name) 4198 << CurrentName.getName(); 4199 if (PreviousCriticalLoc.isValid()) 4200 SemaRef.Diag(PreviousCriticalLoc, 4201 diag::note_omp_previous_critical_region); 4202 return true; 4203 } 4204 } else if (CurrentRegion == OMPD_barrier) { 4205 // OpenMP [2.16, Nesting of Regions] 4206 // A barrier region may not be closely nested inside a worksharing, 4207 // explicit task, critical, ordered, atomic, or master region. 4208 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4209 isOpenMPTaskingDirective(ParentRegion) || 4210 ParentRegion == OMPD_master || 4211 ParentRegion == OMPD_parallel_master || 4212 ParentRegion == OMPD_critical || 4213 ParentRegion == OMPD_ordered; 4214 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4215 !isOpenMPParallelDirective(CurrentRegion) && 4216 !isOpenMPTeamsDirective(CurrentRegion)) { 4217 // OpenMP [2.16, Nesting of Regions] 4218 // A worksharing region may not be closely nested inside a worksharing, 4219 // explicit task, critical, ordered, atomic, or master region. 4220 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4221 isOpenMPTaskingDirective(ParentRegion) || 4222 ParentRegion == OMPD_master || 4223 ParentRegion == OMPD_parallel_master || 4224 ParentRegion == OMPD_critical || 4225 ParentRegion == OMPD_ordered; 4226 Recommend = ShouldBeInParallelRegion; 4227 } else if (CurrentRegion == OMPD_ordered) { 4228 // OpenMP [2.16, Nesting of Regions] 4229 // An ordered region may not be closely nested inside a critical, 4230 // atomic, or explicit task region. 4231 // An ordered region must be closely nested inside a loop region (or 4232 // parallel loop region) with an ordered clause. 4233 // OpenMP [2.8.1,simd Construct, Restrictions] 4234 // An ordered construct with the simd clause is the only OpenMP construct 4235 // that can appear in the simd region. 4236 NestingProhibited = ParentRegion == OMPD_critical || 4237 isOpenMPTaskingDirective(ParentRegion) || 4238 !(isOpenMPSimdDirective(ParentRegion) || 4239 Stack->isParentOrderedRegion()); 4240 Recommend = ShouldBeInOrderedRegion; 4241 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4242 // OpenMP [2.16, Nesting of Regions] 4243 // If specified, a teams construct must be contained within a target 4244 // construct. 4245 NestingProhibited = 4246 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4247 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4248 ParentRegion != OMPD_target); 4249 OrphanSeen = ParentRegion == OMPD_unknown; 4250 Recommend = ShouldBeInTargetRegion; 4251 } 4252 if (!NestingProhibited && 4253 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4254 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4255 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4256 // OpenMP [2.16, Nesting of Regions] 4257 // distribute, parallel, parallel sections, parallel workshare, and the 4258 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4259 // constructs that can be closely nested in the teams region. 4260 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4261 !isOpenMPDistributeDirective(CurrentRegion); 4262 Recommend = ShouldBeInParallelRegion; 4263 } 4264 if (!NestingProhibited && 4265 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4266 // OpenMP 4.5 [2.17 Nesting of Regions] 4267 // The region associated with the distribute construct must be strictly 4268 // nested inside a teams region 4269 NestingProhibited = 4270 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4271 Recommend = ShouldBeInTeamsRegion; 4272 } 4273 if (!NestingProhibited && 4274 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4275 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4276 // OpenMP 4.5 [2.17 Nesting of Regions] 4277 // If a target, target update, target data, target enter data, or 4278 // target exit data construct is encountered during execution of a 4279 // target region, the behavior is unspecified. 4280 NestingProhibited = Stack->hasDirective( 4281 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4282 SourceLocation) { 4283 if (isOpenMPTargetExecutionDirective(K)) { 4284 OffendingRegion = K; 4285 return true; 4286 } 4287 return false; 4288 }, 4289 false /* don't skip top directive */); 4290 CloseNesting = false; 4291 } 4292 if (NestingProhibited) { 4293 if (OrphanSeen) { 4294 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4295 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4296 } else { 4297 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4298 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4299 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4300 } 4301 return true; 4302 } 4303 } 4304 return false; 4305 } 4306 4307 struct Kind2Unsigned { 4308 using argument_type = OpenMPDirectiveKind; 4309 unsigned operator()(argument_type DK) { return unsigned(DK); } 4310 }; 4311 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4312 ArrayRef<OMPClause *> Clauses, 4313 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4314 bool ErrorFound = false; 4315 unsigned NamedModifiersNumber = 0; 4316 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4317 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4318 SmallVector<SourceLocation, 4> NameModifierLoc; 4319 for (const OMPClause *C : Clauses) { 4320 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4321 // At most one if clause without a directive-name-modifier can appear on 4322 // the directive. 4323 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4324 if (FoundNameModifiers[CurNM]) { 4325 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4326 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4327 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4328 ErrorFound = true; 4329 } else if (CurNM != OMPD_unknown) { 4330 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4331 ++NamedModifiersNumber; 4332 } 4333 FoundNameModifiers[CurNM] = IC; 4334 if (CurNM == OMPD_unknown) 4335 continue; 4336 // Check if the specified name modifier is allowed for the current 4337 // directive. 4338 // At most one if clause with the particular directive-name-modifier can 4339 // appear on the directive. 4340 bool MatchFound = false; 4341 for (auto NM : AllowedNameModifiers) { 4342 if (CurNM == NM) { 4343 MatchFound = true; 4344 break; 4345 } 4346 } 4347 if (!MatchFound) { 4348 S.Diag(IC->getNameModifierLoc(), 4349 diag::err_omp_wrong_if_directive_name_modifier) 4350 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4351 ErrorFound = true; 4352 } 4353 } 4354 } 4355 // If any if clause on the directive includes a directive-name-modifier then 4356 // all if clauses on the directive must include a directive-name-modifier. 4357 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4358 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4359 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4360 diag::err_omp_no_more_if_clause); 4361 } else { 4362 std::string Values; 4363 std::string Sep(", "); 4364 unsigned AllowedCnt = 0; 4365 unsigned TotalAllowedNum = 4366 AllowedNameModifiers.size() - NamedModifiersNumber; 4367 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4368 ++Cnt) { 4369 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4370 if (!FoundNameModifiers[NM]) { 4371 Values += "'"; 4372 Values += getOpenMPDirectiveName(NM); 4373 Values += "'"; 4374 if (AllowedCnt + 2 == TotalAllowedNum) 4375 Values += " or "; 4376 else if (AllowedCnt + 1 != TotalAllowedNum) 4377 Values += Sep; 4378 ++AllowedCnt; 4379 } 4380 } 4381 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4382 diag::err_omp_unnamed_if_clause) 4383 << (TotalAllowedNum > 1) << Values; 4384 } 4385 for (SourceLocation Loc : NameModifierLoc) { 4386 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4387 } 4388 ErrorFound = true; 4389 } 4390 return ErrorFound; 4391 } 4392 4393 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4394 SourceLocation &ELoc, 4395 SourceRange &ERange, 4396 bool AllowArraySection) { 4397 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4398 RefExpr->containsUnexpandedParameterPack()) 4399 return std::make_pair(nullptr, true); 4400 4401 // OpenMP [3.1, C/C++] 4402 // A list item is a variable name. 4403 // OpenMP [2.9.3.3, Restrictions, p.1] 4404 // A variable that is part of another variable (as an array or 4405 // structure element) cannot appear in a private clause. 4406 RefExpr = RefExpr->IgnoreParens(); 4407 enum { 4408 NoArrayExpr = -1, 4409 ArraySubscript = 0, 4410 OMPArraySection = 1 4411 } IsArrayExpr = NoArrayExpr; 4412 if (AllowArraySection) { 4413 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4414 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4415 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4416 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4417 RefExpr = Base; 4418 IsArrayExpr = ArraySubscript; 4419 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4420 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4421 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4422 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4423 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4424 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4425 RefExpr = Base; 4426 IsArrayExpr = OMPArraySection; 4427 } 4428 } 4429 ELoc = RefExpr->getExprLoc(); 4430 ERange = RefExpr->getSourceRange(); 4431 RefExpr = RefExpr->IgnoreParenImpCasts(); 4432 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4433 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4434 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4435 (S.getCurrentThisType().isNull() || !ME || 4436 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4437 !isa<FieldDecl>(ME->getMemberDecl()))) { 4438 if (IsArrayExpr != NoArrayExpr) { 4439 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4440 << ERange; 4441 } else { 4442 S.Diag(ELoc, 4443 AllowArraySection 4444 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4445 : diag::err_omp_expected_var_name_member_expr) 4446 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4447 } 4448 return std::make_pair(nullptr, false); 4449 } 4450 return std::make_pair( 4451 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4452 } 4453 4454 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4455 ArrayRef<OMPClause *> Clauses) { 4456 assert(!S.CurContext->isDependentContext() && 4457 "Expected non-dependent context."); 4458 auto AllocateRange = 4459 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4460 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4461 DeclToCopy; 4462 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4463 return isOpenMPPrivate(C->getClauseKind()); 4464 }); 4465 for (OMPClause *Cl : PrivateRange) { 4466 MutableArrayRef<Expr *>::iterator I, It, Et; 4467 if (Cl->getClauseKind() == OMPC_private) { 4468 auto *PC = cast<OMPPrivateClause>(Cl); 4469 I = PC->private_copies().begin(); 4470 It = PC->varlist_begin(); 4471 Et = PC->varlist_end(); 4472 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4473 auto *PC = cast<OMPFirstprivateClause>(Cl); 4474 I = PC->private_copies().begin(); 4475 It = PC->varlist_begin(); 4476 Et = PC->varlist_end(); 4477 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4478 auto *PC = cast<OMPLastprivateClause>(Cl); 4479 I = PC->private_copies().begin(); 4480 It = PC->varlist_begin(); 4481 Et = PC->varlist_end(); 4482 } else if (Cl->getClauseKind() == OMPC_linear) { 4483 auto *PC = cast<OMPLinearClause>(Cl); 4484 I = PC->privates().begin(); 4485 It = PC->varlist_begin(); 4486 Et = PC->varlist_end(); 4487 } else if (Cl->getClauseKind() == OMPC_reduction) { 4488 auto *PC = cast<OMPReductionClause>(Cl); 4489 I = PC->privates().begin(); 4490 It = PC->varlist_begin(); 4491 Et = PC->varlist_end(); 4492 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4493 auto *PC = cast<OMPTaskReductionClause>(Cl); 4494 I = PC->privates().begin(); 4495 It = PC->varlist_begin(); 4496 Et = PC->varlist_end(); 4497 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4498 auto *PC = cast<OMPInReductionClause>(Cl); 4499 I = PC->privates().begin(); 4500 It = PC->varlist_begin(); 4501 Et = PC->varlist_end(); 4502 } else { 4503 llvm_unreachable("Expected private clause."); 4504 } 4505 for (Expr *E : llvm::make_range(It, Et)) { 4506 if (!*I) { 4507 ++I; 4508 continue; 4509 } 4510 SourceLocation ELoc; 4511 SourceRange ERange; 4512 Expr *SimpleRefExpr = E; 4513 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4514 /*AllowArraySection=*/true); 4515 DeclToCopy.try_emplace(Res.first, 4516 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4517 ++I; 4518 } 4519 } 4520 for (OMPClause *C : AllocateRange) { 4521 auto *AC = cast<OMPAllocateClause>(C); 4522 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4523 getAllocatorKind(S, Stack, AC->getAllocator()); 4524 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4525 // For task, taskloop or target directives, allocation requests to memory 4526 // allocators with the trait access set to thread result in unspecified 4527 // behavior. 4528 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4529 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4530 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4531 S.Diag(AC->getAllocator()->getExprLoc(), 4532 diag::warn_omp_allocate_thread_on_task_target_directive) 4533 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4534 } 4535 for (Expr *E : AC->varlists()) { 4536 SourceLocation ELoc; 4537 SourceRange ERange; 4538 Expr *SimpleRefExpr = E; 4539 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4540 ValueDecl *VD = Res.first; 4541 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4542 if (!isOpenMPPrivate(Data.CKind)) { 4543 S.Diag(E->getExprLoc(), 4544 diag::err_omp_expected_private_copy_for_allocate); 4545 continue; 4546 } 4547 VarDecl *PrivateVD = DeclToCopy[VD]; 4548 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4549 AllocatorKind, AC->getAllocator())) 4550 continue; 4551 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4552 E->getSourceRange()); 4553 } 4554 } 4555 } 4556 4557 StmtResult Sema::ActOnOpenMPExecutableDirective( 4558 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4559 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4560 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4561 StmtResult Res = StmtError(); 4562 // First check CancelRegion which is then used in checkNestingOfRegions. 4563 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4564 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4565 StartLoc)) 4566 return StmtError(); 4567 4568 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4569 VarsWithInheritedDSAType VarsWithInheritedDSA; 4570 bool ErrorFound = false; 4571 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4572 if (AStmt && !CurContext->isDependentContext()) { 4573 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4574 4575 // Check default data sharing attributes for referenced variables. 4576 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4577 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4578 Stmt *S = AStmt; 4579 while (--ThisCaptureLevel >= 0) 4580 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4581 DSAChecker.Visit(S); 4582 if (!isOpenMPTargetDataManagementDirective(Kind) && 4583 !isOpenMPTaskingDirective(Kind)) { 4584 // Visit subcaptures to generate implicit clauses for captured vars. 4585 auto *CS = cast<CapturedStmt>(AStmt); 4586 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4587 getOpenMPCaptureRegions(CaptureRegions, Kind); 4588 // Ignore outer tasking regions for target directives. 4589 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4590 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4591 DSAChecker.visitSubCaptures(CS); 4592 } 4593 if (DSAChecker.isErrorFound()) 4594 return StmtError(); 4595 // Generate list of implicitly defined firstprivate variables. 4596 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4597 4598 SmallVector<Expr *, 4> ImplicitFirstprivates( 4599 DSAChecker.getImplicitFirstprivate().begin(), 4600 DSAChecker.getImplicitFirstprivate().end()); 4601 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4602 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4603 ArrayRef<Expr *> ImplicitMap = 4604 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4605 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4606 } 4607 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4608 for (OMPClause *C : Clauses) { 4609 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4610 for (Expr *E : IRC->taskgroup_descriptors()) 4611 if (E) 4612 ImplicitFirstprivates.emplace_back(E); 4613 } 4614 } 4615 if (!ImplicitFirstprivates.empty()) { 4616 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4617 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4618 SourceLocation())) { 4619 ClausesWithImplicit.push_back(Implicit); 4620 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4621 ImplicitFirstprivates.size(); 4622 } else { 4623 ErrorFound = true; 4624 } 4625 } 4626 int ClauseKindCnt = -1; 4627 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4628 ++ClauseKindCnt; 4629 if (ImplicitMap.empty()) 4630 continue; 4631 CXXScopeSpec MapperIdScopeSpec; 4632 DeclarationNameInfo MapperId; 4633 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4634 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4635 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4636 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4637 ImplicitMap, OMPVarListLocTy())) { 4638 ClausesWithImplicit.emplace_back(Implicit); 4639 ErrorFound |= 4640 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4641 } else { 4642 ErrorFound = true; 4643 } 4644 } 4645 } 4646 4647 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4648 switch (Kind) { 4649 case OMPD_parallel: 4650 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4651 EndLoc); 4652 AllowedNameModifiers.push_back(OMPD_parallel); 4653 break; 4654 case OMPD_simd: 4655 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4656 VarsWithInheritedDSA); 4657 if (LangOpts.OpenMP >= 50) 4658 AllowedNameModifiers.push_back(OMPD_simd); 4659 break; 4660 case OMPD_for: 4661 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4662 VarsWithInheritedDSA); 4663 break; 4664 case OMPD_for_simd: 4665 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4666 EndLoc, VarsWithInheritedDSA); 4667 if (LangOpts.OpenMP >= 50) 4668 AllowedNameModifiers.push_back(OMPD_simd); 4669 break; 4670 case OMPD_sections: 4671 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4672 EndLoc); 4673 break; 4674 case OMPD_section: 4675 assert(ClausesWithImplicit.empty() && 4676 "No clauses are allowed for 'omp section' directive"); 4677 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4678 break; 4679 case OMPD_single: 4680 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4681 EndLoc); 4682 break; 4683 case OMPD_master: 4684 assert(ClausesWithImplicit.empty() && 4685 "No clauses are allowed for 'omp master' directive"); 4686 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4687 break; 4688 case OMPD_critical: 4689 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4690 StartLoc, EndLoc); 4691 break; 4692 case OMPD_parallel_for: 4693 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4694 EndLoc, VarsWithInheritedDSA); 4695 AllowedNameModifiers.push_back(OMPD_parallel); 4696 break; 4697 case OMPD_parallel_for_simd: 4698 Res = ActOnOpenMPParallelForSimdDirective( 4699 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4700 AllowedNameModifiers.push_back(OMPD_parallel); 4701 if (LangOpts.OpenMP >= 50) 4702 AllowedNameModifiers.push_back(OMPD_simd); 4703 break; 4704 case OMPD_parallel_master: 4705 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4706 StartLoc, EndLoc); 4707 AllowedNameModifiers.push_back(OMPD_parallel); 4708 break; 4709 case OMPD_parallel_sections: 4710 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4711 StartLoc, EndLoc); 4712 AllowedNameModifiers.push_back(OMPD_parallel); 4713 break; 4714 case OMPD_task: 4715 Res = 4716 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4717 AllowedNameModifiers.push_back(OMPD_task); 4718 break; 4719 case OMPD_taskyield: 4720 assert(ClausesWithImplicit.empty() && 4721 "No clauses are allowed for 'omp taskyield' directive"); 4722 assert(AStmt == nullptr && 4723 "No associated statement allowed for 'omp taskyield' directive"); 4724 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4725 break; 4726 case OMPD_barrier: 4727 assert(ClausesWithImplicit.empty() && 4728 "No clauses are allowed for 'omp barrier' directive"); 4729 assert(AStmt == nullptr && 4730 "No associated statement allowed for 'omp barrier' directive"); 4731 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4732 break; 4733 case OMPD_taskwait: 4734 assert(ClausesWithImplicit.empty() && 4735 "No clauses are allowed for 'omp taskwait' directive"); 4736 assert(AStmt == nullptr && 4737 "No associated statement allowed for 'omp taskwait' directive"); 4738 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4739 break; 4740 case OMPD_taskgroup: 4741 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4742 EndLoc); 4743 break; 4744 case OMPD_flush: 4745 assert(AStmt == nullptr && 4746 "No associated statement allowed for 'omp flush' directive"); 4747 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4748 break; 4749 case OMPD_ordered: 4750 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4751 EndLoc); 4752 break; 4753 case OMPD_atomic: 4754 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4755 EndLoc); 4756 break; 4757 case OMPD_teams: 4758 Res = 4759 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4760 break; 4761 case OMPD_target: 4762 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4763 EndLoc); 4764 AllowedNameModifiers.push_back(OMPD_target); 4765 break; 4766 case OMPD_target_parallel: 4767 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4768 StartLoc, EndLoc); 4769 AllowedNameModifiers.push_back(OMPD_target); 4770 AllowedNameModifiers.push_back(OMPD_parallel); 4771 break; 4772 case OMPD_target_parallel_for: 4773 Res = ActOnOpenMPTargetParallelForDirective( 4774 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4775 AllowedNameModifiers.push_back(OMPD_target); 4776 AllowedNameModifiers.push_back(OMPD_parallel); 4777 break; 4778 case OMPD_cancellation_point: 4779 assert(ClausesWithImplicit.empty() && 4780 "No clauses are allowed for 'omp cancellation point' directive"); 4781 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4782 "cancellation point' directive"); 4783 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4784 break; 4785 case OMPD_cancel: 4786 assert(AStmt == nullptr && 4787 "No associated statement allowed for 'omp cancel' directive"); 4788 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4789 CancelRegion); 4790 AllowedNameModifiers.push_back(OMPD_cancel); 4791 break; 4792 case OMPD_target_data: 4793 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4794 EndLoc); 4795 AllowedNameModifiers.push_back(OMPD_target_data); 4796 break; 4797 case OMPD_target_enter_data: 4798 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4799 EndLoc, AStmt); 4800 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4801 break; 4802 case OMPD_target_exit_data: 4803 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4804 EndLoc, AStmt); 4805 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4806 break; 4807 case OMPD_taskloop: 4808 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4809 EndLoc, VarsWithInheritedDSA); 4810 AllowedNameModifiers.push_back(OMPD_taskloop); 4811 break; 4812 case OMPD_taskloop_simd: 4813 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4814 EndLoc, VarsWithInheritedDSA); 4815 AllowedNameModifiers.push_back(OMPD_taskloop); 4816 if (LangOpts.OpenMP >= 50) 4817 AllowedNameModifiers.push_back(OMPD_simd); 4818 break; 4819 case OMPD_master_taskloop: 4820 Res = ActOnOpenMPMasterTaskLoopDirective( 4821 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4822 AllowedNameModifiers.push_back(OMPD_taskloop); 4823 break; 4824 case OMPD_master_taskloop_simd: 4825 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4826 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4827 AllowedNameModifiers.push_back(OMPD_taskloop); 4828 if (LangOpts.OpenMP >= 50) 4829 AllowedNameModifiers.push_back(OMPD_simd); 4830 break; 4831 case OMPD_parallel_master_taskloop: 4832 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4833 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4834 AllowedNameModifiers.push_back(OMPD_taskloop); 4835 AllowedNameModifiers.push_back(OMPD_parallel); 4836 break; 4837 case OMPD_parallel_master_taskloop_simd: 4838 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4839 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4840 AllowedNameModifiers.push_back(OMPD_taskloop); 4841 AllowedNameModifiers.push_back(OMPD_parallel); 4842 if (LangOpts.OpenMP >= 50) 4843 AllowedNameModifiers.push_back(OMPD_simd); 4844 break; 4845 case OMPD_distribute: 4846 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4847 EndLoc, VarsWithInheritedDSA); 4848 break; 4849 case OMPD_target_update: 4850 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4851 EndLoc, AStmt); 4852 AllowedNameModifiers.push_back(OMPD_target_update); 4853 break; 4854 case OMPD_distribute_parallel_for: 4855 Res = ActOnOpenMPDistributeParallelForDirective( 4856 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4857 AllowedNameModifiers.push_back(OMPD_parallel); 4858 break; 4859 case OMPD_distribute_parallel_for_simd: 4860 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4861 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4862 AllowedNameModifiers.push_back(OMPD_parallel); 4863 if (LangOpts.OpenMP >= 50) 4864 AllowedNameModifiers.push_back(OMPD_simd); 4865 break; 4866 case OMPD_distribute_simd: 4867 Res = ActOnOpenMPDistributeSimdDirective( 4868 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4869 if (LangOpts.OpenMP >= 50) 4870 AllowedNameModifiers.push_back(OMPD_simd); 4871 break; 4872 case OMPD_target_parallel_for_simd: 4873 Res = ActOnOpenMPTargetParallelForSimdDirective( 4874 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4875 AllowedNameModifiers.push_back(OMPD_target); 4876 AllowedNameModifiers.push_back(OMPD_parallel); 4877 if (LangOpts.OpenMP >= 50) 4878 AllowedNameModifiers.push_back(OMPD_simd); 4879 break; 4880 case OMPD_target_simd: 4881 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4882 EndLoc, VarsWithInheritedDSA); 4883 AllowedNameModifiers.push_back(OMPD_target); 4884 if (LangOpts.OpenMP >= 50) 4885 AllowedNameModifiers.push_back(OMPD_simd); 4886 break; 4887 case OMPD_teams_distribute: 4888 Res = ActOnOpenMPTeamsDistributeDirective( 4889 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4890 break; 4891 case OMPD_teams_distribute_simd: 4892 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4893 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4894 if (LangOpts.OpenMP >= 50) 4895 AllowedNameModifiers.push_back(OMPD_simd); 4896 break; 4897 case OMPD_teams_distribute_parallel_for_simd: 4898 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4899 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4900 AllowedNameModifiers.push_back(OMPD_parallel); 4901 if (LangOpts.OpenMP >= 50) 4902 AllowedNameModifiers.push_back(OMPD_simd); 4903 break; 4904 case OMPD_teams_distribute_parallel_for: 4905 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4906 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4907 AllowedNameModifiers.push_back(OMPD_parallel); 4908 break; 4909 case OMPD_target_teams: 4910 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4911 EndLoc); 4912 AllowedNameModifiers.push_back(OMPD_target); 4913 break; 4914 case OMPD_target_teams_distribute: 4915 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4916 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4917 AllowedNameModifiers.push_back(OMPD_target); 4918 break; 4919 case OMPD_target_teams_distribute_parallel_for: 4920 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4921 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4922 AllowedNameModifiers.push_back(OMPD_target); 4923 AllowedNameModifiers.push_back(OMPD_parallel); 4924 break; 4925 case OMPD_target_teams_distribute_parallel_for_simd: 4926 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4927 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4928 AllowedNameModifiers.push_back(OMPD_target); 4929 AllowedNameModifiers.push_back(OMPD_parallel); 4930 if (LangOpts.OpenMP >= 50) 4931 AllowedNameModifiers.push_back(OMPD_simd); 4932 break; 4933 case OMPD_target_teams_distribute_simd: 4934 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4935 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4936 AllowedNameModifiers.push_back(OMPD_target); 4937 if (LangOpts.OpenMP >= 50) 4938 AllowedNameModifiers.push_back(OMPD_simd); 4939 break; 4940 case OMPD_declare_target: 4941 case OMPD_end_declare_target: 4942 case OMPD_threadprivate: 4943 case OMPD_allocate: 4944 case OMPD_declare_reduction: 4945 case OMPD_declare_mapper: 4946 case OMPD_declare_simd: 4947 case OMPD_requires: 4948 case OMPD_declare_variant: 4949 llvm_unreachable("OpenMP Directive is not allowed"); 4950 case OMPD_unknown: 4951 llvm_unreachable("Unknown OpenMP directive"); 4952 } 4953 4954 ErrorFound = Res.isInvalid() || ErrorFound; 4955 4956 // Check variables in the clauses if default(none) was specified. 4957 if (DSAStack->getDefaultDSA() == DSA_none) { 4958 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4959 for (OMPClause *C : Clauses) { 4960 switch (C->getClauseKind()) { 4961 case OMPC_num_threads: 4962 case OMPC_dist_schedule: 4963 // Do not analyse if no parent teams directive. 4964 if (isOpenMPTeamsDirective(Kind)) 4965 break; 4966 continue; 4967 case OMPC_if: 4968 if (isOpenMPTeamsDirective(Kind) && 4969 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4970 break; 4971 if (isOpenMPParallelDirective(Kind) && 4972 isOpenMPTaskLoopDirective(Kind) && 4973 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 4974 break; 4975 continue; 4976 case OMPC_schedule: 4977 break; 4978 case OMPC_grainsize: 4979 case OMPC_num_tasks: 4980 case OMPC_final: 4981 case OMPC_priority: 4982 // Do not analyze if no parent parallel directive. 4983 if (isOpenMPParallelDirective(Kind)) 4984 break; 4985 continue; 4986 case OMPC_ordered: 4987 case OMPC_device: 4988 case OMPC_num_teams: 4989 case OMPC_thread_limit: 4990 case OMPC_hint: 4991 case OMPC_collapse: 4992 case OMPC_safelen: 4993 case OMPC_simdlen: 4994 case OMPC_default: 4995 case OMPC_proc_bind: 4996 case OMPC_private: 4997 case OMPC_firstprivate: 4998 case OMPC_lastprivate: 4999 case OMPC_shared: 5000 case OMPC_reduction: 5001 case OMPC_task_reduction: 5002 case OMPC_in_reduction: 5003 case OMPC_linear: 5004 case OMPC_aligned: 5005 case OMPC_copyin: 5006 case OMPC_copyprivate: 5007 case OMPC_nowait: 5008 case OMPC_untied: 5009 case OMPC_mergeable: 5010 case OMPC_allocate: 5011 case OMPC_read: 5012 case OMPC_write: 5013 case OMPC_update: 5014 case OMPC_capture: 5015 case OMPC_seq_cst: 5016 case OMPC_acq_rel: 5017 case OMPC_acquire: 5018 case OMPC_release: 5019 case OMPC_relaxed: 5020 case OMPC_depend: 5021 case OMPC_threads: 5022 case OMPC_simd: 5023 case OMPC_map: 5024 case OMPC_nogroup: 5025 case OMPC_defaultmap: 5026 case OMPC_to: 5027 case OMPC_from: 5028 case OMPC_use_device_ptr: 5029 case OMPC_is_device_ptr: 5030 case OMPC_nontemporal: 5031 case OMPC_order: 5032 continue; 5033 case OMPC_allocator: 5034 case OMPC_flush: 5035 case OMPC_threadprivate: 5036 case OMPC_uniform: 5037 case OMPC_unknown: 5038 case OMPC_unified_address: 5039 case OMPC_unified_shared_memory: 5040 case OMPC_reverse_offload: 5041 case OMPC_dynamic_allocators: 5042 case OMPC_atomic_default_mem_order: 5043 case OMPC_device_type: 5044 case OMPC_match: 5045 llvm_unreachable("Unexpected clause"); 5046 } 5047 for (Stmt *CC : C->children()) { 5048 if (CC) 5049 DSAChecker.Visit(CC); 5050 } 5051 } 5052 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5053 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5054 } 5055 for (const auto &P : VarsWithInheritedDSA) { 5056 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5057 continue; 5058 ErrorFound = true; 5059 if (DSAStack->getDefaultDSA() == DSA_none) { 5060 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5061 << P.first << P.second->getSourceRange(); 5062 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5063 } else if (getLangOpts().OpenMP >= 50) { 5064 Diag(P.second->getExprLoc(), 5065 diag::err_omp_defaultmap_no_attr_for_variable) 5066 << P.first << P.second->getSourceRange(); 5067 Diag(DSAStack->getDefaultDSALocation(), 5068 diag::note_omp_defaultmap_attr_none); 5069 } 5070 } 5071 5072 if (!AllowedNameModifiers.empty()) 5073 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5074 ErrorFound; 5075 5076 if (ErrorFound) 5077 return StmtError(); 5078 5079 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 5080 Res.getAs<OMPExecutableDirective>() 5081 ->getStructuredBlock() 5082 ->setIsOMPStructuredBlock(true); 5083 } 5084 5085 if (!CurContext->isDependentContext() && 5086 isOpenMPTargetExecutionDirective(Kind) && 5087 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5088 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5089 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5090 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5091 // Register target to DSA Stack. 5092 DSAStack->addTargetDirLocation(StartLoc); 5093 } 5094 5095 return Res; 5096 } 5097 5098 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5099 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5100 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5101 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5102 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5103 assert(Aligneds.size() == Alignments.size()); 5104 assert(Linears.size() == LinModifiers.size()); 5105 assert(Linears.size() == Steps.size()); 5106 if (!DG || DG.get().isNull()) 5107 return DeclGroupPtrTy(); 5108 5109 const int SimdId = 0; 5110 if (!DG.get().isSingleDecl()) { 5111 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5112 << SimdId; 5113 return DG; 5114 } 5115 Decl *ADecl = DG.get().getSingleDecl(); 5116 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5117 ADecl = FTD->getTemplatedDecl(); 5118 5119 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5120 if (!FD) { 5121 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5122 return DeclGroupPtrTy(); 5123 } 5124 5125 // OpenMP [2.8.2, declare simd construct, Description] 5126 // The parameter of the simdlen clause must be a constant positive integer 5127 // expression. 5128 ExprResult SL; 5129 if (Simdlen) 5130 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5131 // OpenMP [2.8.2, declare simd construct, Description] 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 // The uniform clause declares one or more arguments to have an invariant 5135 // value for all concurrent invocations of the function in the execution of a 5136 // single SIMD loop. 5137 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5138 const Expr *UniformedLinearThis = nullptr; 5139 for (const Expr *E : Uniforms) { 5140 E = E->IgnoreParenImpCasts(); 5141 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5142 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5143 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5144 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5145 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5146 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5147 continue; 5148 } 5149 if (isa<CXXThisExpr>(E)) { 5150 UniformedLinearThis = E; 5151 continue; 5152 } 5153 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5154 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5155 } 5156 // OpenMP [2.8.2, declare simd construct, Description] 5157 // The aligned clause declares that the object to which each list item points 5158 // is aligned to the number of bytes expressed in the optional parameter of 5159 // the aligned clause. 5160 // The special this pointer can be used as if was one of the arguments to the 5161 // function in any of the linear, aligned, or uniform clauses. 5162 // The type of list items appearing in the aligned clause must be array, 5163 // pointer, reference to array, or reference to pointer. 5164 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5165 const Expr *AlignedThis = nullptr; 5166 for (const Expr *E : Aligneds) { 5167 E = E->IgnoreParenImpCasts(); 5168 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5169 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5170 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5171 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5172 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5173 ->getCanonicalDecl() == CanonPVD) { 5174 // OpenMP [2.8.1, simd construct, Restrictions] 5175 // A list-item cannot appear in more than one aligned clause. 5176 if (AlignedArgs.count(CanonPVD) > 0) { 5177 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5178 << 1 << getOpenMPClauseName(OMPC_aligned) 5179 << E->getSourceRange(); 5180 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5181 diag::note_omp_explicit_dsa) 5182 << getOpenMPClauseName(OMPC_aligned); 5183 continue; 5184 } 5185 AlignedArgs[CanonPVD] = E; 5186 QualType QTy = PVD->getType() 5187 .getNonReferenceType() 5188 .getUnqualifiedType() 5189 .getCanonicalType(); 5190 const Type *Ty = QTy.getTypePtrOrNull(); 5191 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5192 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5193 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5194 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5195 } 5196 continue; 5197 } 5198 } 5199 if (isa<CXXThisExpr>(E)) { 5200 if (AlignedThis) { 5201 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5202 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5203 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5204 << getOpenMPClauseName(OMPC_aligned); 5205 } 5206 AlignedThis = E; 5207 continue; 5208 } 5209 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5210 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5211 } 5212 // The optional parameter of the aligned clause, alignment, must be a constant 5213 // positive integer expression. If no optional parameter is specified, 5214 // implementation-defined default alignments for SIMD instructions on the 5215 // target platforms are assumed. 5216 SmallVector<const Expr *, 4> NewAligns; 5217 for (Expr *E : Alignments) { 5218 ExprResult Align; 5219 if (E) 5220 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5221 NewAligns.push_back(Align.get()); 5222 } 5223 // OpenMP [2.8.2, declare simd construct, Description] 5224 // The linear clause declares one or more list items to be private to a SIMD 5225 // lane and to have a linear relationship with respect to the iteration space 5226 // of a loop. 5227 // The special this pointer can be used as if was one of the arguments to the 5228 // function in any of the linear, aligned, or uniform clauses. 5229 // When a linear-step expression is specified in a linear clause it must be 5230 // either a constant integer expression or an integer-typed parameter that is 5231 // specified in a uniform clause on the directive. 5232 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5233 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5234 auto MI = LinModifiers.begin(); 5235 for (const Expr *E : Linears) { 5236 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5237 ++MI; 5238 E = E->IgnoreParenImpCasts(); 5239 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5240 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5241 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5242 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5243 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5244 ->getCanonicalDecl() == CanonPVD) { 5245 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5246 // A list-item cannot appear in more than one linear clause. 5247 if (LinearArgs.count(CanonPVD) > 0) { 5248 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5249 << getOpenMPClauseName(OMPC_linear) 5250 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5251 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5252 diag::note_omp_explicit_dsa) 5253 << getOpenMPClauseName(OMPC_linear); 5254 continue; 5255 } 5256 // Each argument can appear in at most one uniform or linear clause. 5257 if (UniformedArgs.count(CanonPVD) > 0) { 5258 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5259 << getOpenMPClauseName(OMPC_linear) 5260 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5261 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5262 diag::note_omp_explicit_dsa) 5263 << getOpenMPClauseName(OMPC_uniform); 5264 continue; 5265 } 5266 LinearArgs[CanonPVD] = E; 5267 if (E->isValueDependent() || E->isTypeDependent() || 5268 E->isInstantiationDependent() || 5269 E->containsUnexpandedParameterPack()) 5270 continue; 5271 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5272 PVD->getOriginalType()); 5273 continue; 5274 } 5275 } 5276 if (isa<CXXThisExpr>(E)) { 5277 if (UniformedLinearThis) { 5278 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5279 << getOpenMPClauseName(OMPC_linear) 5280 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5281 << E->getSourceRange(); 5282 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5283 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5284 : OMPC_linear); 5285 continue; 5286 } 5287 UniformedLinearThis = E; 5288 if (E->isValueDependent() || E->isTypeDependent() || 5289 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5290 continue; 5291 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5292 E->getType()); 5293 continue; 5294 } 5295 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5296 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5297 } 5298 Expr *Step = nullptr; 5299 Expr *NewStep = nullptr; 5300 SmallVector<Expr *, 4> NewSteps; 5301 for (Expr *E : Steps) { 5302 // Skip the same step expression, it was checked already. 5303 if (Step == E || !E) { 5304 NewSteps.push_back(E ? NewStep : nullptr); 5305 continue; 5306 } 5307 Step = E; 5308 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5309 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5310 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5311 if (UniformedArgs.count(CanonPVD) == 0) { 5312 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5313 << Step->getSourceRange(); 5314 } else if (E->isValueDependent() || E->isTypeDependent() || 5315 E->isInstantiationDependent() || 5316 E->containsUnexpandedParameterPack() || 5317 CanonPVD->getType()->hasIntegerRepresentation()) { 5318 NewSteps.push_back(Step); 5319 } else { 5320 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5321 << Step->getSourceRange(); 5322 } 5323 continue; 5324 } 5325 NewStep = Step; 5326 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5327 !Step->isInstantiationDependent() && 5328 !Step->containsUnexpandedParameterPack()) { 5329 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5330 .get(); 5331 if (NewStep) 5332 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5333 } 5334 NewSteps.push_back(NewStep); 5335 } 5336 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5337 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5338 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5339 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5340 const_cast<Expr **>(Linears.data()), Linears.size(), 5341 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5342 NewSteps.data(), NewSteps.size(), SR); 5343 ADecl->addAttr(NewAttr); 5344 return DG; 5345 } 5346 5347 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5348 QualType NewType) { 5349 assert(NewType->isFunctionProtoType() && 5350 "Expected function type with prototype."); 5351 assert(FD->getType()->isFunctionNoProtoType() && 5352 "Expected function with type with no prototype."); 5353 assert(FDWithProto->getType()->isFunctionProtoType() && 5354 "Expected function with prototype."); 5355 // Synthesize parameters with the same types. 5356 FD->setType(NewType); 5357 SmallVector<ParmVarDecl *, 16> Params; 5358 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5359 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5360 SourceLocation(), nullptr, P->getType(), 5361 /*TInfo=*/nullptr, SC_None, nullptr); 5362 Param->setScopeInfo(0, Params.size()); 5363 Param->setImplicit(); 5364 Params.push_back(Param); 5365 } 5366 5367 FD->setParams(Params); 5368 } 5369 5370 Optional<std::pair<FunctionDecl *, Expr *>> 5371 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5372 Expr *VariantRef, OMPTraitInfo &TI, 5373 SourceRange SR) { 5374 if (!DG || DG.get().isNull()) 5375 return None; 5376 5377 const int VariantId = 1; 5378 // Must be applied only to single decl. 5379 if (!DG.get().isSingleDecl()) { 5380 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5381 << VariantId << SR; 5382 return None; 5383 } 5384 Decl *ADecl = DG.get().getSingleDecl(); 5385 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5386 ADecl = FTD->getTemplatedDecl(); 5387 5388 // Decl must be a function. 5389 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5390 if (!FD) { 5391 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5392 << VariantId << SR; 5393 return None; 5394 } 5395 5396 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5397 return FD->hasAttrs() && 5398 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5399 FD->hasAttr<TargetAttr>()); 5400 }; 5401 // OpenMP is not compatible with CPU-specific attributes. 5402 if (HasMultiVersionAttributes(FD)) { 5403 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5404 << SR; 5405 return None; 5406 } 5407 5408 // Allow #pragma omp declare variant only if the function is not used. 5409 if (FD->isUsed(false)) 5410 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5411 << FD->getLocation(); 5412 5413 // Check if the function was emitted already. 5414 const FunctionDecl *Definition; 5415 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5416 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5417 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5418 << FD->getLocation(); 5419 5420 // The VariantRef must point to function. 5421 if (!VariantRef) { 5422 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5423 return None; 5424 } 5425 5426 auto ShouldDelayChecks = [](Expr *&E, bool) { 5427 return E && (E->isTypeDependent() || E->isValueDependent() || 5428 E->containsUnexpandedParameterPack() || 5429 E->isInstantiationDependent()); 5430 }; 5431 // Do not check templates, wait until instantiation. 5432 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5433 TI.anyScoreOrCondition(ShouldDelayChecks)) 5434 return std::make_pair(FD, VariantRef); 5435 5436 // Deal with non-constant score and user condition expressions. 5437 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5438 bool IsScore) -> bool { 5439 llvm::APSInt Result; 5440 if (!E || E->isIntegerConstantExpr(Result, Context)) 5441 return false; 5442 5443 if (IsScore) { 5444 // We warn on non-constant scores and pretend they were not present. 5445 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5446 << E; 5447 E = nullptr; 5448 } else { 5449 // We could replace a non-constant user condition with "false" but we 5450 // will soon need to handle these anyway for the dynamic version of 5451 // OpenMP context selectors. 5452 Diag(E->getExprLoc(), 5453 diag::err_omp_declare_variant_user_condition_not_constant) 5454 << E; 5455 } 5456 return true; 5457 }; 5458 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5459 return None; 5460 5461 // Convert VariantRef expression to the type of the original function to 5462 // resolve possible conflicts. 5463 ExprResult VariantRefCast; 5464 if (LangOpts.CPlusPlus) { 5465 QualType FnPtrType; 5466 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5467 if (Method && !Method->isStatic()) { 5468 const Type *ClassType = 5469 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5470 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5471 ExprResult ER; 5472 { 5473 // Build adrr_of unary op to correctly handle type checks for member 5474 // functions. 5475 Sema::TentativeAnalysisScope Trap(*this); 5476 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5477 VariantRef); 5478 } 5479 if (!ER.isUsable()) { 5480 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5481 << VariantId << VariantRef->getSourceRange(); 5482 return None; 5483 } 5484 VariantRef = ER.get(); 5485 } else { 5486 FnPtrType = Context.getPointerType(FD->getType()); 5487 } 5488 ImplicitConversionSequence ICS = 5489 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5490 /*SuppressUserConversions=*/false, 5491 AllowedExplicit::None, 5492 /*InOverloadResolution=*/false, 5493 /*CStyle=*/false, 5494 /*AllowObjCWritebackConversion=*/false); 5495 if (ICS.isFailure()) { 5496 Diag(VariantRef->getExprLoc(), 5497 diag::err_omp_declare_variant_incompat_types) 5498 << VariantRef->getType() 5499 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5500 << VariantRef->getSourceRange(); 5501 return None; 5502 } 5503 VariantRefCast = PerformImplicitConversion( 5504 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5505 if (!VariantRefCast.isUsable()) 5506 return None; 5507 // Drop previously built artificial addr_of unary op for member functions. 5508 if (Method && !Method->isStatic()) { 5509 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5510 if (auto *UO = dyn_cast<UnaryOperator>( 5511 PossibleAddrOfVariantRef->IgnoreImplicit())) 5512 VariantRefCast = UO->getSubExpr(); 5513 } 5514 } else { 5515 VariantRefCast = VariantRef; 5516 } 5517 5518 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5519 if (!ER.isUsable() || 5520 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5521 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5522 << VariantId << VariantRef->getSourceRange(); 5523 return None; 5524 } 5525 5526 // The VariantRef must point to function. 5527 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5528 if (!DRE) { 5529 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5530 << VariantId << VariantRef->getSourceRange(); 5531 return None; 5532 } 5533 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5534 if (!NewFD) { 5535 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5536 << VariantId << VariantRef->getSourceRange(); 5537 return None; 5538 } 5539 5540 // Check if function types are compatible in C. 5541 if (!LangOpts.CPlusPlus) { 5542 QualType NewType = 5543 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5544 if (NewType.isNull()) { 5545 Diag(VariantRef->getExprLoc(), 5546 diag::err_omp_declare_variant_incompat_types) 5547 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5548 return None; 5549 } 5550 if (NewType->isFunctionProtoType()) { 5551 if (FD->getType()->isFunctionNoProtoType()) 5552 setPrototype(*this, FD, NewFD, NewType); 5553 else if (NewFD->getType()->isFunctionNoProtoType()) 5554 setPrototype(*this, NewFD, FD, NewType); 5555 } 5556 } 5557 5558 // Check if variant function is not marked with declare variant directive. 5559 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5560 Diag(VariantRef->getExprLoc(), 5561 diag::warn_omp_declare_variant_marked_as_declare_variant) 5562 << VariantRef->getSourceRange(); 5563 SourceRange SR = 5564 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5565 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5566 return None; 5567 } 5568 5569 enum DoesntSupport { 5570 VirtFuncs = 1, 5571 Constructors = 3, 5572 Destructors = 4, 5573 DeletedFuncs = 5, 5574 DefaultedFuncs = 6, 5575 ConstexprFuncs = 7, 5576 ConstevalFuncs = 8, 5577 }; 5578 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5579 if (CXXFD->isVirtual()) { 5580 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5581 << VirtFuncs; 5582 return None; 5583 } 5584 5585 if (isa<CXXConstructorDecl>(FD)) { 5586 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5587 << Constructors; 5588 return None; 5589 } 5590 5591 if (isa<CXXDestructorDecl>(FD)) { 5592 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5593 << Destructors; 5594 return None; 5595 } 5596 } 5597 5598 if (FD->isDeleted()) { 5599 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5600 << DeletedFuncs; 5601 return None; 5602 } 5603 5604 if (FD->isDefaulted()) { 5605 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5606 << DefaultedFuncs; 5607 return None; 5608 } 5609 5610 if (FD->isConstexpr()) { 5611 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5612 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5613 return None; 5614 } 5615 5616 // Check general compatibility. 5617 if (areMultiversionVariantFunctionsCompatible( 5618 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5619 PartialDiagnosticAt(SourceLocation(), 5620 PartialDiagnostic::NullDiagnostic()), 5621 PartialDiagnosticAt( 5622 VariantRef->getExprLoc(), 5623 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5624 PartialDiagnosticAt(VariantRef->getExprLoc(), 5625 PDiag(diag::err_omp_declare_variant_diff) 5626 << FD->getLocation()), 5627 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5628 /*CLinkageMayDiffer=*/true)) 5629 return None; 5630 return std::make_pair(FD, cast<Expr>(DRE)); 5631 } 5632 5633 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 5634 Expr *VariantRef, 5635 OMPTraitInfo &TI, 5636 SourceRange SR) { 5637 auto *NewAttr = 5638 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, TI, SR); 5639 FD->addAttr(NewAttr); 5640 } 5641 5642 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5643 FunctionDecl *Func, 5644 bool MightBeOdrUse) { 5645 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5646 5647 if (!Func->isDependentContext() && Func->hasAttrs()) { 5648 for (OMPDeclareVariantAttr *A : 5649 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5650 // TODO: add checks for active OpenMP context where possible. 5651 Expr *VariantRef = A->getVariantFuncRef(); 5652 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5653 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5654 if (!F->isDefined() && F->isTemplateInstantiation()) 5655 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5656 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5657 } 5658 } 5659 } 5660 5661 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5662 Stmt *AStmt, 5663 SourceLocation StartLoc, 5664 SourceLocation EndLoc) { 5665 if (!AStmt) 5666 return StmtError(); 5667 5668 auto *CS = cast<CapturedStmt>(AStmt); 5669 // 1.2.2 OpenMP Language Terminology 5670 // Structured block - An executable statement with a single entry at the 5671 // top and a single exit at the bottom. 5672 // The point of exit cannot be a branch out of the structured block. 5673 // longjmp() and throw() must not violate the entry/exit criteria. 5674 CS->getCapturedDecl()->setNothrow(); 5675 5676 setFunctionHasBranchProtectedScope(); 5677 5678 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5679 DSAStack->isCancelRegion()); 5680 } 5681 5682 namespace { 5683 /// Iteration space of a single for loop. 5684 struct LoopIterationSpace final { 5685 /// True if the condition operator is the strict compare operator (<, > or 5686 /// !=). 5687 bool IsStrictCompare = false; 5688 /// Condition of the loop. 5689 Expr *PreCond = nullptr; 5690 /// This expression calculates the number of iterations in the loop. 5691 /// It is always possible to calculate it before starting the loop. 5692 Expr *NumIterations = nullptr; 5693 /// The loop counter variable. 5694 Expr *CounterVar = nullptr; 5695 /// Private loop counter variable. 5696 Expr *PrivateCounterVar = nullptr; 5697 /// This is initializer for the initial value of #CounterVar. 5698 Expr *CounterInit = nullptr; 5699 /// This is step for the #CounterVar used to generate its update: 5700 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5701 Expr *CounterStep = nullptr; 5702 /// Should step be subtracted? 5703 bool Subtract = false; 5704 /// Source range of the loop init. 5705 SourceRange InitSrcRange; 5706 /// Source range of the loop condition. 5707 SourceRange CondSrcRange; 5708 /// Source range of the loop increment. 5709 SourceRange IncSrcRange; 5710 /// Minimum value that can have the loop control variable. Used to support 5711 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5712 /// since only such variables can be used in non-loop invariant expressions. 5713 Expr *MinValue = nullptr; 5714 /// Maximum value that can have the loop control variable. Used to support 5715 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5716 /// since only such variables can be used in non-loop invariant expressions. 5717 Expr *MaxValue = nullptr; 5718 /// true, if the lower bound depends on the outer loop control var. 5719 bool IsNonRectangularLB = false; 5720 /// true, if the upper bound depends on the outer loop control var. 5721 bool IsNonRectangularUB = false; 5722 /// Index of the loop this loop depends on and forms non-rectangular loop 5723 /// nest. 5724 unsigned LoopDependentIdx = 0; 5725 /// Final condition for the non-rectangular loop nest support. It is used to 5726 /// check that the number of iterations for this particular counter must be 5727 /// finished. 5728 Expr *FinalCondition = nullptr; 5729 }; 5730 5731 /// Helper class for checking canonical form of the OpenMP loops and 5732 /// extracting iteration space of each loop in the loop nest, that will be used 5733 /// for IR generation. 5734 class OpenMPIterationSpaceChecker { 5735 /// Reference to Sema. 5736 Sema &SemaRef; 5737 /// Data-sharing stack. 5738 DSAStackTy &Stack; 5739 /// A location for diagnostics (when there is no some better location). 5740 SourceLocation DefaultLoc; 5741 /// A location for diagnostics (when increment is not compatible). 5742 SourceLocation ConditionLoc; 5743 /// A source location for referring to loop init later. 5744 SourceRange InitSrcRange; 5745 /// A source location for referring to condition later. 5746 SourceRange ConditionSrcRange; 5747 /// A source location for referring to increment later. 5748 SourceRange IncrementSrcRange; 5749 /// Loop variable. 5750 ValueDecl *LCDecl = nullptr; 5751 /// Reference to loop variable. 5752 Expr *LCRef = nullptr; 5753 /// Lower bound (initializer for the var). 5754 Expr *LB = nullptr; 5755 /// Upper bound. 5756 Expr *UB = nullptr; 5757 /// Loop step (increment). 5758 Expr *Step = nullptr; 5759 /// This flag is true when condition is one of: 5760 /// Var < UB 5761 /// Var <= UB 5762 /// UB > Var 5763 /// UB >= Var 5764 /// This will have no value when the condition is != 5765 llvm::Optional<bool> TestIsLessOp; 5766 /// This flag is true when condition is strict ( < or > ). 5767 bool TestIsStrictOp = false; 5768 /// This flag is true when step is subtracted on each iteration. 5769 bool SubtractStep = false; 5770 /// The outer loop counter this loop depends on (if any). 5771 const ValueDecl *DepDecl = nullptr; 5772 /// Contains number of loop (starts from 1) on which loop counter init 5773 /// expression of this loop depends on. 5774 Optional<unsigned> InitDependOnLC; 5775 /// Contains number of loop (starts from 1) on which loop counter condition 5776 /// expression of this loop depends on. 5777 Optional<unsigned> CondDependOnLC; 5778 /// Checks if the provide statement depends on the loop counter. 5779 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5780 /// Original condition required for checking of the exit condition for 5781 /// non-rectangular loop. 5782 Expr *Condition = nullptr; 5783 5784 public: 5785 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5786 SourceLocation DefaultLoc) 5787 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5788 ConditionLoc(DefaultLoc) {} 5789 /// Check init-expr for canonical loop form and save loop counter 5790 /// variable - #Var and its initialization value - #LB. 5791 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5792 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5793 /// for less/greater and for strict/non-strict comparison. 5794 bool checkAndSetCond(Expr *S); 5795 /// Check incr-expr for canonical loop form and return true if it 5796 /// does not conform, otherwise save loop step (#Step). 5797 bool checkAndSetInc(Expr *S); 5798 /// Return the loop counter variable. 5799 ValueDecl *getLoopDecl() const { return LCDecl; } 5800 /// Return the reference expression to loop counter variable. 5801 Expr *getLoopDeclRefExpr() const { return LCRef; } 5802 /// Source range of the loop init. 5803 SourceRange getInitSrcRange() const { return InitSrcRange; } 5804 /// Source range of the loop condition. 5805 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5806 /// Source range of the loop increment. 5807 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5808 /// True if the step should be subtracted. 5809 bool shouldSubtractStep() const { return SubtractStep; } 5810 /// True, if the compare operator is strict (<, > or !=). 5811 bool isStrictTestOp() const { return TestIsStrictOp; } 5812 /// Build the expression to calculate the number of iterations. 5813 Expr *buildNumIterations( 5814 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5815 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5816 /// Build the precondition expression for the loops. 5817 Expr * 5818 buildPreCond(Scope *S, Expr *Cond, 5819 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5820 /// Build reference expression to the counter be used for codegen. 5821 DeclRefExpr * 5822 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5823 DSAStackTy &DSA) const; 5824 /// Build reference expression to the private counter be used for 5825 /// codegen. 5826 Expr *buildPrivateCounterVar() const; 5827 /// Build initialization of the counter be used for codegen. 5828 Expr *buildCounterInit() const; 5829 /// Build step of the counter be used for codegen. 5830 Expr *buildCounterStep() const; 5831 /// Build loop data with counter value for depend clauses in ordered 5832 /// directives. 5833 Expr * 5834 buildOrderedLoopData(Scope *S, Expr *Counter, 5835 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5836 SourceLocation Loc, Expr *Inc = nullptr, 5837 OverloadedOperatorKind OOK = OO_Amp); 5838 /// Builds the minimum value for the loop counter. 5839 std::pair<Expr *, Expr *> buildMinMaxValues( 5840 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5841 /// Builds final condition for the non-rectangular loops. 5842 Expr *buildFinalCondition(Scope *S) const; 5843 /// Return true if any expression is dependent. 5844 bool dependent() const; 5845 /// Returns true if the initializer forms non-rectangular loop. 5846 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5847 /// Returns true if the condition forms non-rectangular loop. 5848 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5849 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5850 unsigned getLoopDependentIdx() const { 5851 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5852 } 5853 5854 private: 5855 /// Check the right-hand side of an assignment in the increment 5856 /// expression. 5857 bool checkAndSetIncRHS(Expr *RHS); 5858 /// Helper to set loop counter variable and its initializer. 5859 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5860 bool EmitDiags); 5861 /// Helper to set upper bound. 5862 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5863 SourceRange SR, SourceLocation SL); 5864 /// Helper to set loop increment. 5865 bool setStep(Expr *NewStep, bool Subtract); 5866 }; 5867 5868 bool OpenMPIterationSpaceChecker::dependent() const { 5869 if (!LCDecl) { 5870 assert(!LB && !UB && !Step); 5871 return false; 5872 } 5873 return LCDecl->getType()->isDependentType() || 5874 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5875 (Step && Step->isValueDependent()); 5876 } 5877 5878 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5879 Expr *NewLCRefExpr, 5880 Expr *NewLB, bool EmitDiags) { 5881 // State consistency checking to ensure correct usage. 5882 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5883 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5884 if (!NewLCDecl || !NewLB) 5885 return true; 5886 LCDecl = getCanonicalDecl(NewLCDecl); 5887 LCRef = NewLCRefExpr; 5888 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5889 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5890 if ((Ctor->isCopyOrMoveConstructor() || 5891 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5892 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5893 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5894 LB = NewLB; 5895 if (EmitDiags) 5896 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5897 return false; 5898 } 5899 5900 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5901 llvm::Optional<bool> LessOp, 5902 bool StrictOp, SourceRange SR, 5903 SourceLocation SL) { 5904 // State consistency checking to ensure correct usage. 5905 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5906 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5907 if (!NewUB) 5908 return true; 5909 UB = NewUB; 5910 if (LessOp) 5911 TestIsLessOp = LessOp; 5912 TestIsStrictOp = StrictOp; 5913 ConditionSrcRange = SR; 5914 ConditionLoc = SL; 5915 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5916 return false; 5917 } 5918 5919 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5920 // State consistency checking to ensure correct usage. 5921 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5922 if (!NewStep) 5923 return true; 5924 if (!NewStep->isValueDependent()) { 5925 // Check that the step is integer expression. 5926 SourceLocation StepLoc = NewStep->getBeginLoc(); 5927 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5928 StepLoc, getExprAsWritten(NewStep)); 5929 if (Val.isInvalid()) 5930 return true; 5931 NewStep = Val.get(); 5932 5933 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5934 // If test-expr is of form var relational-op b and relational-op is < or 5935 // <= then incr-expr must cause var to increase on each iteration of the 5936 // loop. If test-expr is of form var relational-op b and relational-op is 5937 // > or >= then incr-expr must cause var to decrease on each iteration of 5938 // the loop. 5939 // If test-expr is of form b relational-op var and relational-op is < or 5940 // <= then incr-expr must cause var to decrease on each iteration of the 5941 // loop. If test-expr is of form b relational-op var and relational-op is 5942 // > or >= then incr-expr must cause var to increase on each iteration of 5943 // the loop. 5944 llvm::APSInt Result; 5945 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5946 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5947 bool IsConstNeg = 5948 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5949 bool IsConstPos = 5950 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5951 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5952 5953 // != with increment is treated as <; != with decrement is treated as > 5954 if (!TestIsLessOp.hasValue()) 5955 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5956 if (UB && (IsConstZero || 5957 (TestIsLessOp.getValue() ? 5958 (IsConstNeg || (IsUnsigned && Subtract)) : 5959 (IsConstPos || (IsUnsigned && !Subtract))))) { 5960 SemaRef.Diag(NewStep->getExprLoc(), 5961 diag::err_omp_loop_incr_not_compatible) 5962 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5963 SemaRef.Diag(ConditionLoc, 5964 diag::note_omp_loop_cond_requres_compatible_incr) 5965 << TestIsLessOp.getValue() << ConditionSrcRange; 5966 return true; 5967 } 5968 if (TestIsLessOp.getValue() == Subtract) { 5969 NewStep = 5970 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5971 .get(); 5972 Subtract = !Subtract; 5973 } 5974 } 5975 5976 Step = NewStep; 5977 SubtractStep = Subtract; 5978 return false; 5979 } 5980 5981 namespace { 5982 /// Checker for the non-rectangular loops. Checks if the initializer or 5983 /// condition expression references loop counter variable. 5984 class LoopCounterRefChecker final 5985 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5986 Sema &SemaRef; 5987 DSAStackTy &Stack; 5988 const ValueDecl *CurLCDecl = nullptr; 5989 const ValueDecl *DepDecl = nullptr; 5990 const ValueDecl *PrevDepDecl = nullptr; 5991 bool IsInitializer = true; 5992 unsigned BaseLoopId = 0; 5993 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5994 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5995 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5996 << (IsInitializer ? 0 : 1); 5997 return false; 5998 } 5999 const auto &&Data = Stack.isLoopControlVariable(VD); 6000 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6001 // The type of the loop iterator on which we depend may not have a random 6002 // access iterator type. 6003 if (Data.first && VD->getType()->isRecordType()) { 6004 SmallString<128> Name; 6005 llvm::raw_svector_ostream OS(Name); 6006 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6007 /*Qualified=*/true); 6008 SemaRef.Diag(E->getExprLoc(), 6009 diag::err_omp_wrong_dependency_iterator_type) 6010 << OS.str(); 6011 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6012 return false; 6013 } 6014 if (Data.first && 6015 (DepDecl || (PrevDepDecl && 6016 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6017 if (!DepDecl && PrevDepDecl) 6018 DepDecl = PrevDepDecl; 6019 SmallString<128> Name; 6020 llvm::raw_svector_ostream OS(Name); 6021 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6022 /*Qualified=*/true); 6023 SemaRef.Diag(E->getExprLoc(), 6024 diag::err_omp_invariant_or_linear_dependency) 6025 << OS.str(); 6026 return false; 6027 } 6028 if (Data.first) { 6029 DepDecl = VD; 6030 BaseLoopId = Data.first; 6031 } 6032 return Data.first; 6033 } 6034 6035 public: 6036 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6037 const ValueDecl *VD = E->getDecl(); 6038 if (isa<VarDecl>(VD)) 6039 return checkDecl(E, VD); 6040 return false; 6041 } 6042 bool VisitMemberExpr(const MemberExpr *E) { 6043 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6044 const ValueDecl *VD = E->getMemberDecl(); 6045 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6046 return checkDecl(E, VD); 6047 } 6048 return false; 6049 } 6050 bool VisitStmt(const Stmt *S) { 6051 bool Res = false; 6052 for (const Stmt *Child : S->children()) 6053 Res = (Child && Visit(Child)) || Res; 6054 return Res; 6055 } 6056 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6057 const ValueDecl *CurLCDecl, bool IsInitializer, 6058 const ValueDecl *PrevDepDecl = nullptr) 6059 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6060 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6061 unsigned getBaseLoopId() const { 6062 assert(CurLCDecl && "Expected loop dependency."); 6063 return BaseLoopId; 6064 } 6065 const ValueDecl *getDepDecl() const { 6066 assert(CurLCDecl && "Expected loop dependency."); 6067 return DepDecl; 6068 } 6069 }; 6070 } // namespace 6071 6072 Optional<unsigned> 6073 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6074 bool IsInitializer) { 6075 // Check for the non-rectangular loops. 6076 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6077 DepDecl); 6078 if (LoopStmtChecker.Visit(S)) { 6079 DepDecl = LoopStmtChecker.getDepDecl(); 6080 return LoopStmtChecker.getBaseLoopId(); 6081 } 6082 return llvm::None; 6083 } 6084 6085 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6086 // Check init-expr for canonical loop form and save loop counter 6087 // variable - #Var and its initialization value - #LB. 6088 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6089 // var = lb 6090 // integer-type var = lb 6091 // random-access-iterator-type var = lb 6092 // pointer-type var = lb 6093 // 6094 if (!S) { 6095 if (EmitDiags) { 6096 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6097 } 6098 return true; 6099 } 6100 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6101 if (!ExprTemp->cleanupsHaveSideEffects()) 6102 S = ExprTemp->getSubExpr(); 6103 6104 InitSrcRange = S->getSourceRange(); 6105 if (Expr *E = dyn_cast<Expr>(S)) 6106 S = E->IgnoreParens(); 6107 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6108 if (BO->getOpcode() == BO_Assign) { 6109 Expr *LHS = BO->getLHS()->IgnoreParens(); 6110 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6111 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6112 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6113 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6114 EmitDiags); 6115 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6116 } 6117 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6118 if (ME->isArrow() && 6119 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6120 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6121 EmitDiags); 6122 } 6123 } 6124 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6125 if (DS->isSingleDecl()) { 6126 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6127 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6128 // Accept non-canonical init form here but emit ext. warning. 6129 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6130 SemaRef.Diag(S->getBeginLoc(), 6131 diag::ext_omp_loop_not_canonical_init) 6132 << S->getSourceRange(); 6133 return setLCDeclAndLB( 6134 Var, 6135 buildDeclRefExpr(SemaRef, Var, 6136 Var->getType().getNonReferenceType(), 6137 DS->getBeginLoc()), 6138 Var->getInit(), EmitDiags); 6139 } 6140 } 6141 } 6142 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6143 if (CE->getOperator() == OO_Equal) { 6144 Expr *LHS = CE->getArg(0); 6145 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6146 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6147 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6148 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6149 EmitDiags); 6150 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6151 } 6152 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6153 if (ME->isArrow() && 6154 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6155 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6156 EmitDiags); 6157 } 6158 } 6159 } 6160 6161 if (dependent() || SemaRef.CurContext->isDependentContext()) 6162 return false; 6163 if (EmitDiags) { 6164 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6165 << S->getSourceRange(); 6166 } 6167 return true; 6168 } 6169 6170 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6171 /// variable (which may be the loop variable) if possible. 6172 static const ValueDecl *getInitLCDecl(const Expr *E) { 6173 if (!E) 6174 return nullptr; 6175 E = getExprAsWritten(E); 6176 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6177 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6178 if ((Ctor->isCopyOrMoveConstructor() || 6179 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6180 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6181 E = CE->getArg(0)->IgnoreParenImpCasts(); 6182 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6183 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6184 return getCanonicalDecl(VD); 6185 } 6186 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6187 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6188 return getCanonicalDecl(ME->getMemberDecl()); 6189 return nullptr; 6190 } 6191 6192 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6193 // Check test-expr for canonical form, save upper-bound UB, flags for 6194 // less/greater and for strict/non-strict comparison. 6195 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6196 // var relational-op b 6197 // b relational-op var 6198 // 6199 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6200 if (!S) { 6201 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6202 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6203 return true; 6204 } 6205 Condition = S; 6206 S = getExprAsWritten(S); 6207 SourceLocation CondLoc = S->getBeginLoc(); 6208 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6209 if (BO->isRelationalOp()) { 6210 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6211 return setUB(BO->getRHS(), 6212 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6213 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6214 BO->getSourceRange(), BO->getOperatorLoc()); 6215 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6216 return setUB(BO->getLHS(), 6217 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6218 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6219 BO->getSourceRange(), BO->getOperatorLoc()); 6220 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6221 return setUB( 6222 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6223 /*LessOp=*/llvm::None, 6224 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6225 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6226 if (CE->getNumArgs() == 2) { 6227 auto Op = CE->getOperator(); 6228 switch (Op) { 6229 case OO_Greater: 6230 case OO_GreaterEqual: 6231 case OO_Less: 6232 case OO_LessEqual: 6233 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6234 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6235 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6236 CE->getOperatorLoc()); 6237 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6238 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6239 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6240 CE->getOperatorLoc()); 6241 break; 6242 case OO_ExclaimEqual: 6243 if (IneqCondIsCanonical) 6244 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6245 : CE->getArg(0), 6246 /*LessOp=*/llvm::None, 6247 /*StrictOp=*/true, CE->getSourceRange(), 6248 CE->getOperatorLoc()); 6249 break; 6250 default: 6251 break; 6252 } 6253 } 6254 } 6255 if (dependent() || SemaRef.CurContext->isDependentContext()) 6256 return false; 6257 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6258 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6259 return true; 6260 } 6261 6262 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6263 // RHS of canonical loop form increment can be: 6264 // var + incr 6265 // incr + var 6266 // var - incr 6267 // 6268 RHS = RHS->IgnoreParenImpCasts(); 6269 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6270 if (BO->isAdditiveOp()) { 6271 bool IsAdd = BO->getOpcode() == BO_Add; 6272 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6273 return setStep(BO->getRHS(), !IsAdd); 6274 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6275 return setStep(BO->getLHS(), /*Subtract=*/false); 6276 } 6277 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6278 bool IsAdd = CE->getOperator() == OO_Plus; 6279 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6280 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6281 return setStep(CE->getArg(1), !IsAdd); 6282 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6283 return setStep(CE->getArg(0), /*Subtract=*/false); 6284 } 6285 } 6286 if (dependent() || SemaRef.CurContext->isDependentContext()) 6287 return false; 6288 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6289 << RHS->getSourceRange() << LCDecl; 6290 return true; 6291 } 6292 6293 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6294 // Check incr-expr for canonical loop form and return true if it 6295 // does not conform. 6296 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6297 // ++var 6298 // var++ 6299 // --var 6300 // var-- 6301 // var += incr 6302 // var -= incr 6303 // var = var + incr 6304 // var = incr + var 6305 // var = var - incr 6306 // 6307 if (!S) { 6308 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6309 return true; 6310 } 6311 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6312 if (!ExprTemp->cleanupsHaveSideEffects()) 6313 S = ExprTemp->getSubExpr(); 6314 6315 IncrementSrcRange = S->getSourceRange(); 6316 S = S->IgnoreParens(); 6317 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6318 if (UO->isIncrementDecrementOp() && 6319 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6320 return setStep(SemaRef 6321 .ActOnIntegerConstant(UO->getBeginLoc(), 6322 (UO->isDecrementOp() ? -1 : 1)) 6323 .get(), 6324 /*Subtract=*/false); 6325 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6326 switch (BO->getOpcode()) { 6327 case BO_AddAssign: 6328 case BO_SubAssign: 6329 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6330 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6331 break; 6332 case BO_Assign: 6333 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6334 return checkAndSetIncRHS(BO->getRHS()); 6335 break; 6336 default: 6337 break; 6338 } 6339 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6340 switch (CE->getOperator()) { 6341 case OO_PlusPlus: 6342 case OO_MinusMinus: 6343 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6344 return setStep(SemaRef 6345 .ActOnIntegerConstant( 6346 CE->getBeginLoc(), 6347 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6348 .get(), 6349 /*Subtract=*/false); 6350 break; 6351 case OO_PlusEqual: 6352 case OO_MinusEqual: 6353 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6354 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6355 break; 6356 case OO_Equal: 6357 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6358 return checkAndSetIncRHS(CE->getArg(1)); 6359 break; 6360 default: 6361 break; 6362 } 6363 } 6364 if (dependent() || SemaRef.CurContext->isDependentContext()) 6365 return false; 6366 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6367 << S->getSourceRange() << LCDecl; 6368 return true; 6369 } 6370 6371 static ExprResult 6372 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6373 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6374 if (SemaRef.CurContext->isDependentContext()) 6375 return ExprResult(Capture); 6376 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6377 return SemaRef.PerformImplicitConversion( 6378 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6379 /*AllowExplicit=*/true); 6380 auto I = Captures.find(Capture); 6381 if (I != Captures.end()) 6382 return buildCapture(SemaRef, Capture, I->second); 6383 DeclRefExpr *Ref = nullptr; 6384 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6385 Captures[Capture] = Ref; 6386 return Res; 6387 } 6388 6389 /// Build the expression to calculate the number of iterations. 6390 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6391 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6392 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6393 ExprResult Diff; 6394 QualType VarType = LCDecl->getType().getNonReferenceType(); 6395 if (VarType->isIntegerType() || VarType->isPointerType() || 6396 SemaRef.getLangOpts().CPlusPlus) { 6397 Expr *LBVal = LB; 6398 Expr *UBVal = UB; 6399 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6400 // max(LB(MinVal), LB(MaxVal)) 6401 if (InitDependOnLC) { 6402 const LoopIterationSpace &IS = 6403 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6404 InitDependOnLC.getValueOr( 6405 CondDependOnLC.getValueOr(0))]; 6406 if (!IS.MinValue || !IS.MaxValue) 6407 return nullptr; 6408 // OuterVar = Min 6409 ExprResult MinValue = 6410 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6411 if (!MinValue.isUsable()) 6412 return nullptr; 6413 6414 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6415 IS.CounterVar, MinValue.get()); 6416 if (!LBMinVal.isUsable()) 6417 return nullptr; 6418 // OuterVar = Min, LBVal 6419 LBMinVal = 6420 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6421 if (!LBMinVal.isUsable()) 6422 return nullptr; 6423 // (OuterVar = Min, LBVal) 6424 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6425 if (!LBMinVal.isUsable()) 6426 return nullptr; 6427 6428 // OuterVar = Max 6429 ExprResult MaxValue = 6430 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6431 if (!MaxValue.isUsable()) 6432 return nullptr; 6433 6434 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6435 IS.CounterVar, MaxValue.get()); 6436 if (!LBMaxVal.isUsable()) 6437 return nullptr; 6438 // OuterVar = Max, LBVal 6439 LBMaxVal = 6440 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6441 if (!LBMaxVal.isUsable()) 6442 return nullptr; 6443 // (OuterVar = Max, LBVal) 6444 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6445 if (!LBMaxVal.isUsable()) 6446 return nullptr; 6447 6448 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6449 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6450 if (!LBMin || !LBMax) 6451 return nullptr; 6452 // LB(MinVal) < LB(MaxVal) 6453 ExprResult MinLessMaxRes = 6454 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6455 if (!MinLessMaxRes.isUsable()) 6456 return nullptr; 6457 Expr *MinLessMax = 6458 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6459 if (!MinLessMax) 6460 return nullptr; 6461 if (TestIsLessOp.getValue()) { 6462 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6463 // LB(MaxVal)) 6464 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6465 MinLessMax, LBMin, LBMax); 6466 if (!MinLB.isUsable()) 6467 return nullptr; 6468 LBVal = MinLB.get(); 6469 } else { 6470 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6471 // LB(MaxVal)) 6472 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6473 MinLessMax, LBMax, LBMin); 6474 if (!MaxLB.isUsable()) 6475 return nullptr; 6476 LBVal = MaxLB.get(); 6477 } 6478 } 6479 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6480 // min(UB(MinVal), UB(MaxVal)) 6481 if (CondDependOnLC) { 6482 const LoopIterationSpace &IS = 6483 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6484 InitDependOnLC.getValueOr( 6485 CondDependOnLC.getValueOr(0))]; 6486 if (!IS.MinValue || !IS.MaxValue) 6487 return nullptr; 6488 // OuterVar = Min 6489 ExprResult MinValue = 6490 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6491 if (!MinValue.isUsable()) 6492 return nullptr; 6493 6494 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6495 IS.CounterVar, MinValue.get()); 6496 if (!UBMinVal.isUsable()) 6497 return nullptr; 6498 // OuterVar = Min, UBVal 6499 UBMinVal = 6500 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6501 if (!UBMinVal.isUsable()) 6502 return nullptr; 6503 // (OuterVar = Min, UBVal) 6504 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6505 if (!UBMinVal.isUsable()) 6506 return nullptr; 6507 6508 // OuterVar = Max 6509 ExprResult MaxValue = 6510 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6511 if (!MaxValue.isUsable()) 6512 return nullptr; 6513 6514 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6515 IS.CounterVar, MaxValue.get()); 6516 if (!UBMaxVal.isUsable()) 6517 return nullptr; 6518 // OuterVar = Max, UBVal 6519 UBMaxVal = 6520 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6521 if (!UBMaxVal.isUsable()) 6522 return nullptr; 6523 // (OuterVar = Max, UBVal) 6524 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6525 if (!UBMaxVal.isUsable()) 6526 return nullptr; 6527 6528 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6529 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6530 if (!UBMin || !UBMax) 6531 return nullptr; 6532 // UB(MinVal) > UB(MaxVal) 6533 ExprResult MinGreaterMaxRes = 6534 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6535 if (!MinGreaterMaxRes.isUsable()) 6536 return nullptr; 6537 Expr *MinGreaterMax = 6538 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6539 if (!MinGreaterMax) 6540 return nullptr; 6541 if (TestIsLessOp.getValue()) { 6542 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6543 // UB(MaxVal)) 6544 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6545 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6546 if (!MaxUB.isUsable()) 6547 return nullptr; 6548 UBVal = MaxUB.get(); 6549 } else { 6550 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6551 // UB(MaxVal)) 6552 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6553 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6554 if (!MinUB.isUsable()) 6555 return nullptr; 6556 UBVal = MinUB.get(); 6557 } 6558 } 6559 // Upper - Lower 6560 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6561 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6562 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6563 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6564 if (!Upper || !Lower) 6565 return nullptr; 6566 6567 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6568 6569 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6570 // BuildBinOp already emitted error, this one is to point user to upper 6571 // and lower bound, and to tell what is passed to 'operator-'. 6572 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6573 << Upper->getSourceRange() << Lower->getSourceRange(); 6574 return nullptr; 6575 } 6576 } 6577 6578 if (!Diff.isUsable()) 6579 return nullptr; 6580 6581 // Upper - Lower [- 1] 6582 if (TestIsStrictOp) 6583 Diff = SemaRef.BuildBinOp( 6584 S, DefaultLoc, BO_Sub, Diff.get(), 6585 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6586 if (!Diff.isUsable()) 6587 return nullptr; 6588 6589 // Upper - Lower [- 1] + Step 6590 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6591 if (!NewStep.isUsable()) 6592 return nullptr; 6593 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6594 if (!Diff.isUsable()) 6595 return nullptr; 6596 6597 // Parentheses (for dumping/debugging purposes only). 6598 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6599 if (!Diff.isUsable()) 6600 return nullptr; 6601 6602 // (Upper - Lower [- 1] + Step) / Step 6603 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6604 if (!Diff.isUsable()) 6605 return nullptr; 6606 6607 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6608 QualType Type = Diff.get()->getType(); 6609 ASTContext &C = SemaRef.Context; 6610 bool UseVarType = VarType->hasIntegerRepresentation() && 6611 C.getTypeSize(Type) > C.getTypeSize(VarType); 6612 if (!Type->isIntegerType() || UseVarType) { 6613 unsigned NewSize = 6614 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6615 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6616 : Type->hasSignedIntegerRepresentation(); 6617 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6618 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6619 Diff = SemaRef.PerformImplicitConversion( 6620 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6621 if (!Diff.isUsable()) 6622 return nullptr; 6623 } 6624 } 6625 if (LimitedType) { 6626 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6627 if (NewSize != C.getTypeSize(Type)) { 6628 if (NewSize < C.getTypeSize(Type)) { 6629 assert(NewSize == 64 && "incorrect loop var size"); 6630 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6631 << InitSrcRange << ConditionSrcRange; 6632 } 6633 QualType NewType = C.getIntTypeForBitwidth( 6634 NewSize, Type->hasSignedIntegerRepresentation() || 6635 C.getTypeSize(Type) < NewSize); 6636 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6637 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6638 Sema::AA_Converting, true); 6639 if (!Diff.isUsable()) 6640 return nullptr; 6641 } 6642 } 6643 } 6644 6645 return Diff.get(); 6646 } 6647 6648 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6649 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6650 // Do not build for iterators, they cannot be used in non-rectangular loop 6651 // nests. 6652 if (LCDecl->getType()->isRecordType()) 6653 return std::make_pair(nullptr, nullptr); 6654 // If we subtract, the min is in the condition, otherwise the min is in the 6655 // init value. 6656 Expr *MinExpr = nullptr; 6657 Expr *MaxExpr = nullptr; 6658 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6659 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6660 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6661 : CondDependOnLC.hasValue(); 6662 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6663 : InitDependOnLC.hasValue(); 6664 Expr *Lower = 6665 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6666 Expr *Upper = 6667 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6668 if (!Upper || !Lower) 6669 return std::make_pair(nullptr, nullptr); 6670 6671 if (TestIsLessOp.getValue()) 6672 MinExpr = Lower; 6673 else 6674 MaxExpr = Upper; 6675 6676 // Build minimum/maximum value based on number of iterations. 6677 ExprResult Diff; 6678 QualType VarType = LCDecl->getType().getNonReferenceType(); 6679 6680 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6681 if (!Diff.isUsable()) 6682 return std::make_pair(nullptr, nullptr); 6683 6684 // Upper - Lower [- 1] 6685 if (TestIsStrictOp) 6686 Diff = SemaRef.BuildBinOp( 6687 S, DefaultLoc, BO_Sub, Diff.get(), 6688 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6689 if (!Diff.isUsable()) 6690 return std::make_pair(nullptr, nullptr); 6691 6692 // Upper - Lower [- 1] + Step 6693 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6694 if (!NewStep.isUsable()) 6695 return std::make_pair(nullptr, nullptr); 6696 6697 // Parentheses (for dumping/debugging purposes only). 6698 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6699 if (!Diff.isUsable()) 6700 return std::make_pair(nullptr, nullptr); 6701 6702 // (Upper - Lower [- 1]) / Step 6703 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6704 if (!Diff.isUsable()) 6705 return std::make_pair(nullptr, nullptr); 6706 6707 // ((Upper - Lower [- 1]) / Step) * Step 6708 // Parentheses (for dumping/debugging purposes only). 6709 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6710 if (!Diff.isUsable()) 6711 return std::make_pair(nullptr, nullptr); 6712 6713 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6714 if (!Diff.isUsable()) 6715 return std::make_pair(nullptr, nullptr); 6716 6717 // Convert to the original type or ptrdiff_t, if original type is pointer. 6718 if (!VarType->isAnyPointerType() && 6719 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6720 Diff = SemaRef.PerformImplicitConversion( 6721 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6722 } else if (VarType->isAnyPointerType() && 6723 !SemaRef.Context.hasSameType( 6724 Diff.get()->getType(), 6725 SemaRef.Context.getUnsignedPointerDiffType())) { 6726 Diff = SemaRef.PerformImplicitConversion( 6727 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6728 Sema::AA_Converting, /*AllowExplicit=*/true); 6729 } 6730 if (!Diff.isUsable()) 6731 return std::make_pair(nullptr, nullptr); 6732 6733 // Parentheses (for dumping/debugging purposes only). 6734 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6735 if (!Diff.isUsable()) 6736 return std::make_pair(nullptr, nullptr); 6737 6738 if (TestIsLessOp.getValue()) { 6739 // MinExpr = Lower; 6740 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6741 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6742 if (!Diff.isUsable()) 6743 return std::make_pair(nullptr, nullptr); 6744 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6745 if (!Diff.isUsable()) 6746 return std::make_pair(nullptr, nullptr); 6747 MaxExpr = Diff.get(); 6748 } else { 6749 // MaxExpr = Upper; 6750 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6751 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6752 if (!Diff.isUsable()) 6753 return std::make_pair(nullptr, nullptr); 6754 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6755 if (!Diff.isUsable()) 6756 return std::make_pair(nullptr, nullptr); 6757 MinExpr = Diff.get(); 6758 } 6759 6760 return std::make_pair(MinExpr, MaxExpr); 6761 } 6762 6763 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6764 if (InitDependOnLC || CondDependOnLC) 6765 return Condition; 6766 return nullptr; 6767 } 6768 6769 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6770 Scope *S, Expr *Cond, 6771 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6772 // Do not build a precondition when the condition/initialization is dependent 6773 // to prevent pessimistic early loop exit. 6774 // TODO: this can be improved by calculating min/max values but not sure that 6775 // it will be very effective. 6776 if (CondDependOnLC || InitDependOnLC) 6777 return SemaRef.PerformImplicitConversion( 6778 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6779 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6780 /*AllowExplicit=*/true).get(); 6781 6782 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6783 Sema::TentativeAnalysisScope Trap(SemaRef); 6784 6785 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6786 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6787 if (!NewLB.isUsable() || !NewUB.isUsable()) 6788 return nullptr; 6789 6790 ExprResult CondExpr = 6791 SemaRef.BuildBinOp(S, DefaultLoc, 6792 TestIsLessOp.getValue() ? 6793 (TestIsStrictOp ? BO_LT : BO_LE) : 6794 (TestIsStrictOp ? BO_GT : BO_GE), 6795 NewLB.get(), NewUB.get()); 6796 if (CondExpr.isUsable()) { 6797 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6798 SemaRef.Context.BoolTy)) 6799 CondExpr = SemaRef.PerformImplicitConversion( 6800 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6801 /*AllowExplicit=*/true); 6802 } 6803 6804 // Otherwise use original loop condition and evaluate it in runtime. 6805 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6806 } 6807 6808 /// Build reference expression to the counter be used for codegen. 6809 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6810 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6811 DSAStackTy &DSA) const { 6812 auto *VD = dyn_cast<VarDecl>(LCDecl); 6813 if (!VD) { 6814 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6815 DeclRefExpr *Ref = buildDeclRefExpr( 6816 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6817 const DSAStackTy::DSAVarData Data = 6818 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6819 // If the loop control decl is explicitly marked as private, do not mark it 6820 // as captured again. 6821 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6822 Captures.insert(std::make_pair(LCRef, Ref)); 6823 return Ref; 6824 } 6825 return cast<DeclRefExpr>(LCRef); 6826 } 6827 6828 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6829 if (LCDecl && !LCDecl->isInvalidDecl()) { 6830 QualType Type = LCDecl->getType().getNonReferenceType(); 6831 VarDecl *PrivateVar = buildVarDecl( 6832 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6833 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6834 isa<VarDecl>(LCDecl) 6835 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6836 : nullptr); 6837 if (PrivateVar->isInvalidDecl()) 6838 return nullptr; 6839 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6840 } 6841 return nullptr; 6842 } 6843 6844 /// Build initialization of the counter to be used for codegen. 6845 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6846 6847 /// Build step of the counter be used for codegen. 6848 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6849 6850 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6851 Scope *S, Expr *Counter, 6852 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6853 Expr *Inc, OverloadedOperatorKind OOK) { 6854 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6855 if (!Cnt) 6856 return nullptr; 6857 if (Inc) { 6858 assert((OOK == OO_Plus || OOK == OO_Minus) && 6859 "Expected only + or - operations for depend clauses."); 6860 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6861 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6862 if (!Cnt) 6863 return nullptr; 6864 } 6865 ExprResult Diff; 6866 QualType VarType = LCDecl->getType().getNonReferenceType(); 6867 if (VarType->isIntegerType() || VarType->isPointerType() || 6868 SemaRef.getLangOpts().CPlusPlus) { 6869 // Upper - Lower 6870 Expr *Upper = TestIsLessOp.getValue() 6871 ? Cnt 6872 : tryBuildCapture(SemaRef, UB, Captures).get(); 6873 Expr *Lower = TestIsLessOp.getValue() 6874 ? tryBuildCapture(SemaRef, LB, Captures).get() 6875 : Cnt; 6876 if (!Upper || !Lower) 6877 return nullptr; 6878 6879 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6880 6881 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6882 // BuildBinOp already emitted error, this one is to point user to upper 6883 // and lower bound, and to tell what is passed to 'operator-'. 6884 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6885 << Upper->getSourceRange() << Lower->getSourceRange(); 6886 return nullptr; 6887 } 6888 } 6889 6890 if (!Diff.isUsable()) 6891 return nullptr; 6892 6893 // Parentheses (for dumping/debugging purposes only). 6894 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6895 if (!Diff.isUsable()) 6896 return nullptr; 6897 6898 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6899 if (!NewStep.isUsable()) 6900 return nullptr; 6901 // (Upper - Lower) / Step 6902 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6903 if (!Diff.isUsable()) 6904 return nullptr; 6905 6906 return Diff.get(); 6907 } 6908 } // namespace 6909 6910 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6911 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6912 assert(Init && "Expected loop in canonical form."); 6913 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6914 if (AssociatedLoops > 0 && 6915 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6916 DSAStack->loopStart(); 6917 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6918 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6919 if (ValueDecl *D = ISC.getLoopDecl()) { 6920 auto *VD = dyn_cast<VarDecl>(D); 6921 DeclRefExpr *PrivateRef = nullptr; 6922 if (!VD) { 6923 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6924 VD = Private; 6925 } else { 6926 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6927 /*WithInit=*/false); 6928 VD = cast<VarDecl>(PrivateRef->getDecl()); 6929 } 6930 } 6931 DSAStack->addLoopControlVariable(D, VD); 6932 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6933 if (LD != D->getCanonicalDecl()) { 6934 DSAStack->resetPossibleLoopCounter(); 6935 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6936 MarkDeclarationsReferencedInExpr( 6937 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6938 Var->getType().getNonLValueExprType(Context), 6939 ForLoc, /*RefersToCapture=*/true)); 6940 } 6941 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6942 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6943 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6944 // associated for-loop of a simd construct with just one associated 6945 // for-loop may be listed in a linear clause with a constant-linear-step 6946 // that is the increment of the associated for-loop. The loop iteration 6947 // variable(s) in the associated for-loop(s) of a for or parallel for 6948 // construct may be listed in a private or lastprivate clause. 6949 DSAStackTy::DSAVarData DVar = 6950 DSAStack->getTopDSA(D, /*FromParent=*/false); 6951 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6952 // is declared in the loop and it is predetermined as a private. 6953 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6954 OpenMPClauseKind PredeterminedCKind = 6955 isOpenMPSimdDirective(DKind) 6956 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6957 : OMPC_private; 6958 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6959 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6960 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6961 DVar.CKind != OMPC_private))) || 6962 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6963 DKind == OMPD_master_taskloop || 6964 DKind == OMPD_parallel_master_taskloop || 6965 isOpenMPDistributeDirective(DKind)) && 6966 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6967 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6968 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6969 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6970 << getOpenMPClauseName(DVar.CKind) 6971 << getOpenMPDirectiveName(DKind) 6972 << getOpenMPClauseName(PredeterminedCKind); 6973 if (DVar.RefExpr == nullptr) 6974 DVar.CKind = PredeterminedCKind; 6975 reportOriginalDsa(*this, DSAStack, D, DVar, 6976 /*IsLoopIterVar=*/true); 6977 } else if (LoopDeclRefExpr) { 6978 // Make the loop iteration variable private (for worksharing 6979 // constructs), linear (for simd directives with the only one 6980 // associated loop) or lastprivate (for simd directives with several 6981 // collapsed or ordered loops). 6982 if (DVar.CKind == OMPC_unknown) 6983 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6984 PrivateRef); 6985 } 6986 } 6987 } 6988 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6989 } 6990 } 6991 6992 /// Called on a for stmt to check and extract its iteration space 6993 /// for further processing (such as collapsing). 6994 static bool checkOpenMPIterationSpace( 6995 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6996 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6997 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6998 Expr *OrderedLoopCountExpr, 6999 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7000 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7001 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7002 // OpenMP [2.9.1, Canonical Loop Form] 7003 // for (init-expr; test-expr; incr-expr) structured-block 7004 // for (range-decl: range-expr) structured-block 7005 auto *For = dyn_cast_or_null<ForStmt>(S); 7006 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7007 // Ranged for is supported only in OpenMP 5.0. 7008 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7009 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7010 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7011 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7012 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7013 if (TotalNestedLoopCount > 1) { 7014 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7015 SemaRef.Diag(DSA.getConstructLoc(), 7016 diag::note_omp_collapse_ordered_expr) 7017 << 2 << CollapseLoopCountExpr->getSourceRange() 7018 << OrderedLoopCountExpr->getSourceRange(); 7019 else if (CollapseLoopCountExpr) 7020 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7021 diag::note_omp_collapse_ordered_expr) 7022 << 0 << CollapseLoopCountExpr->getSourceRange(); 7023 else 7024 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7025 diag::note_omp_collapse_ordered_expr) 7026 << 1 << OrderedLoopCountExpr->getSourceRange(); 7027 } 7028 return true; 7029 } 7030 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7031 "No loop body."); 7032 7033 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7034 For ? For->getForLoc() : CXXFor->getForLoc()); 7035 7036 // Check init. 7037 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7038 if (ISC.checkAndSetInit(Init)) 7039 return true; 7040 7041 bool HasErrors = false; 7042 7043 // Check loop variable's type. 7044 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7045 // OpenMP [2.6, Canonical Loop Form] 7046 // Var is one of the following: 7047 // A variable of signed or unsigned integer type. 7048 // For C++, a variable of a random access iterator type. 7049 // For C, a variable of a pointer type. 7050 QualType VarType = LCDecl->getType().getNonReferenceType(); 7051 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7052 !VarType->isPointerType() && 7053 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7054 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7055 << SemaRef.getLangOpts().CPlusPlus; 7056 HasErrors = true; 7057 } 7058 7059 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7060 // a Construct 7061 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7062 // parallel for construct is (are) private. 7063 // The loop iteration variable in the associated for-loop of a simd 7064 // construct with just one associated for-loop is linear with a 7065 // constant-linear-step that is the increment of the associated for-loop. 7066 // Exclude loop var from the list of variables with implicitly defined data 7067 // sharing attributes. 7068 VarsWithImplicitDSA.erase(LCDecl); 7069 7070 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7071 7072 // Check test-expr. 7073 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7074 7075 // Check incr-expr. 7076 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7077 } 7078 7079 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7080 return HasErrors; 7081 7082 // Build the loop's iteration space representation. 7083 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7084 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7085 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7086 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7087 (isOpenMPWorksharingDirective(DKind) || 7088 isOpenMPTaskLoopDirective(DKind) || 7089 isOpenMPDistributeDirective(DKind)), 7090 Captures); 7091 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7092 ISC.buildCounterVar(Captures, DSA); 7093 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7094 ISC.buildPrivateCounterVar(); 7095 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7096 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7097 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7098 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7099 ISC.getConditionSrcRange(); 7100 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7101 ISC.getIncrementSrcRange(); 7102 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7103 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7104 ISC.isStrictTestOp(); 7105 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7106 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7107 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7108 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7109 ISC.buildFinalCondition(DSA.getCurScope()); 7110 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7111 ISC.doesInitDependOnLC(); 7112 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7113 ISC.doesCondDependOnLC(); 7114 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7115 ISC.getLoopDependentIdx(); 7116 7117 HasErrors |= 7118 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7119 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7120 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7121 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7122 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7123 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7124 if (!HasErrors && DSA.isOrderedRegion()) { 7125 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7126 if (CurrentNestedLoopCount < 7127 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7128 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7129 CurrentNestedLoopCount, 7130 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7131 DSA.getOrderedRegionParam().second->setLoopCounter( 7132 CurrentNestedLoopCount, 7133 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7134 } 7135 } 7136 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7137 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7138 // Erroneous case - clause has some problems. 7139 continue; 7140 } 7141 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7142 Pair.second.size() <= CurrentNestedLoopCount) { 7143 // Erroneous case - clause has some problems. 7144 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7145 continue; 7146 } 7147 Expr *CntValue; 7148 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7149 CntValue = ISC.buildOrderedLoopData( 7150 DSA.getCurScope(), 7151 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7152 Pair.first->getDependencyLoc()); 7153 else 7154 CntValue = ISC.buildOrderedLoopData( 7155 DSA.getCurScope(), 7156 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7157 Pair.first->getDependencyLoc(), 7158 Pair.second[CurrentNestedLoopCount].first, 7159 Pair.second[CurrentNestedLoopCount].second); 7160 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7161 } 7162 } 7163 7164 return HasErrors; 7165 } 7166 7167 /// Build 'VarRef = Start. 7168 static ExprResult 7169 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7170 ExprResult Start, bool IsNonRectangularLB, 7171 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7172 // Build 'VarRef = Start. 7173 ExprResult NewStart = IsNonRectangularLB 7174 ? Start.get() 7175 : tryBuildCapture(SemaRef, Start.get(), Captures); 7176 if (!NewStart.isUsable()) 7177 return ExprError(); 7178 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7179 VarRef.get()->getType())) { 7180 NewStart = SemaRef.PerformImplicitConversion( 7181 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7182 /*AllowExplicit=*/true); 7183 if (!NewStart.isUsable()) 7184 return ExprError(); 7185 } 7186 7187 ExprResult Init = 7188 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7189 return Init; 7190 } 7191 7192 /// Build 'VarRef = Start + Iter * Step'. 7193 static ExprResult buildCounterUpdate( 7194 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7195 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7196 bool IsNonRectangularLB, 7197 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7198 // Add parentheses (for debugging purposes only). 7199 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7200 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7201 !Step.isUsable()) 7202 return ExprError(); 7203 7204 ExprResult NewStep = Step; 7205 if (Captures) 7206 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7207 if (NewStep.isInvalid()) 7208 return ExprError(); 7209 ExprResult Update = 7210 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7211 if (!Update.isUsable()) 7212 return ExprError(); 7213 7214 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7215 // 'VarRef = Start (+|-) Iter * Step'. 7216 if (!Start.isUsable()) 7217 return ExprError(); 7218 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7219 if (!NewStart.isUsable()) 7220 return ExprError(); 7221 if (Captures && !IsNonRectangularLB) 7222 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7223 if (NewStart.isInvalid()) 7224 return ExprError(); 7225 7226 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7227 ExprResult SavedUpdate = Update; 7228 ExprResult UpdateVal; 7229 if (VarRef.get()->getType()->isOverloadableType() || 7230 NewStart.get()->getType()->isOverloadableType() || 7231 Update.get()->getType()->isOverloadableType()) { 7232 Sema::TentativeAnalysisScope Trap(SemaRef); 7233 7234 Update = 7235 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7236 if (Update.isUsable()) { 7237 UpdateVal = 7238 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7239 VarRef.get(), SavedUpdate.get()); 7240 if (UpdateVal.isUsable()) { 7241 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7242 UpdateVal.get()); 7243 } 7244 } 7245 } 7246 7247 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7248 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7249 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7250 NewStart.get(), SavedUpdate.get()); 7251 if (!Update.isUsable()) 7252 return ExprError(); 7253 7254 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7255 VarRef.get()->getType())) { 7256 Update = SemaRef.PerformImplicitConversion( 7257 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7258 if (!Update.isUsable()) 7259 return ExprError(); 7260 } 7261 7262 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7263 } 7264 return Update; 7265 } 7266 7267 /// Convert integer expression \a E to make it have at least \a Bits 7268 /// bits. 7269 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7270 if (E == nullptr) 7271 return ExprError(); 7272 ASTContext &C = SemaRef.Context; 7273 QualType OldType = E->getType(); 7274 unsigned HasBits = C.getTypeSize(OldType); 7275 if (HasBits >= Bits) 7276 return ExprResult(E); 7277 // OK to convert to signed, because new type has more bits than old. 7278 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7279 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7280 true); 7281 } 7282 7283 /// Check if the given expression \a E is a constant integer that fits 7284 /// into \a Bits bits. 7285 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7286 if (E == nullptr) 7287 return false; 7288 llvm::APSInt Result; 7289 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7290 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7291 return false; 7292 } 7293 7294 /// Build preinits statement for the given declarations. 7295 static Stmt *buildPreInits(ASTContext &Context, 7296 MutableArrayRef<Decl *> PreInits) { 7297 if (!PreInits.empty()) { 7298 return new (Context) DeclStmt( 7299 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7300 SourceLocation(), SourceLocation()); 7301 } 7302 return nullptr; 7303 } 7304 7305 /// Build preinits statement for the given declarations. 7306 static Stmt * 7307 buildPreInits(ASTContext &Context, 7308 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7309 if (!Captures.empty()) { 7310 SmallVector<Decl *, 16> PreInits; 7311 for (const auto &Pair : Captures) 7312 PreInits.push_back(Pair.second->getDecl()); 7313 return buildPreInits(Context, PreInits); 7314 } 7315 return nullptr; 7316 } 7317 7318 /// Build postupdate expression for the given list of postupdates expressions. 7319 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7320 Expr *PostUpdate = nullptr; 7321 if (!PostUpdates.empty()) { 7322 for (Expr *E : PostUpdates) { 7323 Expr *ConvE = S.BuildCStyleCastExpr( 7324 E->getExprLoc(), 7325 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7326 E->getExprLoc(), E) 7327 .get(); 7328 PostUpdate = PostUpdate 7329 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7330 PostUpdate, ConvE) 7331 .get() 7332 : ConvE; 7333 } 7334 } 7335 return PostUpdate; 7336 } 7337 7338 /// Called on a for stmt to check itself and nested loops (if any). 7339 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7340 /// number of collapsed loops otherwise. 7341 static unsigned 7342 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7343 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7344 DSAStackTy &DSA, 7345 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7346 OMPLoopDirective::HelperExprs &Built) { 7347 unsigned NestedLoopCount = 1; 7348 if (CollapseLoopCountExpr) { 7349 // Found 'collapse' clause - calculate collapse number. 7350 Expr::EvalResult Result; 7351 if (!CollapseLoopCountExpr->isValueDependent() && 7352 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7353 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7354 } else { 7355 Built.clear(/*Size=*/1); 7356 return 1; 7357 } 7358 } 7359 unsigned OrderedLoopCount = 1; 7360 if (OrderedLoopCountExpr) { 7361 // Found 'ordered' clause - calculate collapse number. 7362 Expr::EvalResult EVResult; 7363 if (!OrderedLoopCountExpr->isValueDependent() && 7364 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7365 SemaRef.getASTContext())) { 7366 llvm::APSInt Result = EVResult.Val.getInt(); 7367 if (Result.getLimitedValue() < NestedLoopCount) { 7368 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7369 diag::err_omp_wrong_ordered_loop_count) 7370 << OrderedLoopCountExpr->getSourceRange(); 7371 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7372 diag::note_collapse_loop_count) 7373 << CollapseLoopCountExpr->getSourceRange(); 7374 } 7375 OrderedLoopCount = Result.getLimitedValue(); 7376 } else { 7377 Built.clear(/*Size=*/1); 7378 return 1; 7379 } 7380 } 7381 // This is helper routine for loop directives (e.g., 'for', 'simd', 7382 // 'for simd', etc.). 7383 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7384 SmallVector<LoopIterationSpace, 4> IterSpaces( 7385 std::max(OrderedLoopCount, NestedLoopCount)); 7386 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7387 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7388 if (checkOpenMPIterationSpace( 7389 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7390 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7391 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7392 return 0; 7393 // Move on to the next nested for loop, or to the loop body. 7394 // OpenMP [2.8.1, simd construct, Restrictions] 7395 // All loops associated with the construct must be perfectly nested; that 7396 // is, there must be no intervening code nor any OpenMP directive between 7397 // any two loops. 7398 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7399 CurStmt = For->getBody(); 7400 } else { 7401 assert(isa<CXXForRangeStmt>(CurStmt) && 7402 "Expected canonical for or range-based for loops."); 7403 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7404 } 7405 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7406 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7407 } 7408 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7409 if (checkOpenMPIterationSpace( 7410 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7411 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7412 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7413 return 0; 7414 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7415 // Handle initialization of captured loop iterator variables. 7416 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7417 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7418 Captures[DRE] = DRE; 7419 } 7420 } 7421 // Move on to the next nested for loop, or to the loop body. 7422 // OpenMP [2.8.1, simd construct, Restrictions] 7423 // All loops associated with the construct must be perfectly nested; that 7424 // is, there must be no intervening code nor any OpenMP directive between 7425 // any two loops. 7426 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7427 CurStmt = For->getBody(); 7428 } else { 7429 assert(isa<CXXForRangeStmt>(CurStmt) && 7430 "Expected canonical for or range-based for loops."); 7431 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7432 } 7433 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7434 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7435 } 7436 7437 Built.clear(/* size */ NestedLoopCount); 7438 7439 if (SemaRef.CurContext->isDependentContext()) 7440 return NestedLoopCount; 7441 7442 // An example of what is generated for the following code: 7443 // 7444 // #pragma omp simd collapse(2) ordered(2) 7445 // for (i = 0; i < NI; ++i) 7446 // for (k = 0; k < NK; ++k) 7447 // for (j = J0; j < NJ; j+=2) { 7448 // <loop body> 7449 // } 7450 // 7451 // We generate the code below. 7452 // Note: the loop body may be outlined in CodeGen. 7453 // Note: some counters may be C++ classes, operator- is used to find number of 7454 // iterations and operator+= to calculate counter value. 7455 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7456 // or i64 is currently supported). 7457 // 7458 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7459 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7460 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7461 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7462 // // similar updates for vars in clauses (e.g. 'linear') 7463 // <loop body (using local i and j)> 7464 // } 7465 // i = NI; // assign final values of counters 7466 // j = NJ; 7467 // 7468 7469 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7470 // the iteration counts of the collapsed for loops. 7471 // Precondition tests if there is at least one iteration (all conditions are 7472 // true). 7473 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7474 Expr *N0 = IterSpaces[0].NumIterations; 7475 ExprResult LastIteration32 = 7476 widenIterationCount(/*Bits=*/32, 7477 SemaRef 7478 .PerformImplicitConversion( 7479 N0->IgnoreImpCasts(), N0->getType(), 7480 Sema::AA_Converting, /*AllowExplicit=*/true) 7481 .get(), 7482 SemaRef); 7483 ExprResult LastIteration64 = widenIterationCount( 7484 /*Bits=*/64, 7485 SemaRef 7486 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7487 Sema::AA_Converting, 7488 /*AllowExplicit=*/true) 7489 .get(), 7490 SemaRef); 7491 7492 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7493 return NestedLoopCount; 7494 7495 ASTContext &C = SemaRef.Context; 7496 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7497 7498 Scope *CurScope = DSA.getCurScope(); 7499 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7500 if (PreCond.isUsable()) { 7501 PreCond = 7502 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7503 PreCond.get(), IterSpaces[Cnt].PreCond); 7504 } 7505 Expr *N = IterSpaces[Cnt].NumIterations; 7506 SourceLocation Loc = N->getExprLoc(); 7507 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7508 if (LastIteration32.isUsable()) 7509 LastIteration32 = SemaRef.BuildBinOp( 7510 CurScope, Loc, BO_Mul, LastIteration32.get(), 7511 SemaRef 7512 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7513 Sema::AA_Converting, 7514 /*AllowExplicit=*/true) 7515 .get()); 7516 if (LastIteration64.isUsable()) 7517 LastIteration64 = SemaRef.BuildBinOp( 7518 CurScope, Loc, BO_Mul, LastIteration64.get(), 7519 SemaRef 7520 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7521 Sema::AA_Converting, 7522 /*AllowExplicit=*/true) 7523 .get()); 7524 } 7525 7526 // Choose either the 32-bit or 64-bit version. 7527 ExprResult LastIteration = LastIteration64; 7528 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7529 (LastIteration32.isUsable() && 7530 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7531 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7532 fitsInto( 7533 /*Bits=*/32, 7534 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7535 LastIteration64.get(), SemaRef)))) 7536 LastIteration = LastIteration32; 7537 QualType VType = LastIteration.get()->getType(); 7538 QualType RealVType = VType; 7539 QualType StrideVType = VType; 7540 if (isOpenMPTaskLoopDirective(DKind)) { 7541 VType = 7542 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7543 StrideVType = 7544 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7545 } 7546 7547 if (!LastIteration.isUsable()) 7548 return 0; 7549 7550 // Save the number of iterations. 7551 ExprResult NumIterations = LastIteration; 7552 { 7553 LastIteration = SemaRef.BuildBinOp( 7554 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7555 LastIteration.get(), 7556 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7557 if (!LastIteration.isUsable()) 7558 return 0; 7559 } 7560 7561 // Calculate the last iteration number beforehand instead of doing this on 7562 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7563 llvm::APSInt Result; 7564 bool IsConstant = 7565 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7566 ExprResult CalcLastIteration; 7567 if (!IsConstant) { 7568 ExprResult SaveRef = 7569 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7570 LastIteration = SaveRef; 7571 7572 // Prepare SaveRef + 1. 7573 NumIterations = SemaRef.BuildBinOp( 7574 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7575 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7576 if (!NumIterations.isUsable()) 7577 return 0; 7578 } 7579 7580 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7581 7582 // Build variables passed into runtime, necessary for worksharing directives. 7583 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7584 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7585 isOpenMPDistributeDirective(DKind)) { 7586 // Lower bound variable, initialized with zero. 7587 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7588 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7589 SemaRef.AddInitializerToDecl(LBDecl, 7590 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7591 /*DirectInit*/ false); 7592 7593 // Upper bound variable, initialized with last iteration number. 7594 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7595 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7596 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7597 /*DirectInit*/ false); 7598 7599 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7600 // This will be used to implement clause 'lastprivate'. 7601 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7602 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7603 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7604 SemaRef.AddInitializerToDecl(ILDecl, 7605 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7606 /*DirectInit*/ false); 7607 7608 // Stride variable returned by runtime (we initialize it to 1 by default). 7609 VarDecl *STDecl = 7610 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7611 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7612 SemaRef.AddInitializerToDecl(STDecl, 7613 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7614 /*DirectInit*/ false); 7615 7616 // Build expression: UB = min(UB, LastIteration) 7617 // It is necessary for CodeGen of directives with static scheduling. 7618 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7619 UB.get(), LastIteration.get()); 7620 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7621 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7622 LastIteration.get(), UB.get()); 7623 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7624 CondOp.get()); 7625 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7626 7627 // If we have a combined directive that combines 'distribute', 'for' or 7628 // 'simd' we need to be able to access the bounds of the schedule of the 7629 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7630 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7631 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7632 // Lower bound variable, initialized with zero. 7633 VarDecl *CombLBDecl = 7634 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7635 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7636 SemaRef.AddInitializerToDecl( 7637 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7638 /*DirectInit*/ false); 7639 7640 // Upper bound variable, initialized with last iteration number. 7641 VarDecl *CombUBDecl = 7642 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7643 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7644 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7645 /*DirectInit*/ false); 7646 7647 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7648 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7649 ExprResult CombCondOp = 7650 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7651 LastIteration.get(), CombUB.get()); 7652 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7653 CombCondOp.get()); 7654 CombEUB = 7655 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7656 7657 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7658 // We expect to have at least 2 more parameters than the 'parallel' 7659 // directive does - the lower and upper bounds of the previous schedule. 7660 assert(CD->getNumParams() >= 4 && 7661 "Unexpected number of parameters in loop combined directive"); 7662 7663 // Set the proper type for the bounds given what we learned from the 7664 // enclosed loops. 7665 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7666 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7667 7668 // Previous lower and upper bounds are obtained from the region 7669 // parameters. 7670 PrevLB = 7671 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7672 PrevUB = 7673 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7674 } 7675 } 7676 7677 // Build the iteration variable and its initialization before loop. 7678 ExprResult IV; 7679 ExprResult Init, CombInit; 7680 { 7681 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7682 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7683 Expr *RHS = 7684 (isOpenMPWorksharingDirective(DKind) || 7685 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7686 ? LB.get() 7687 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7688 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7689 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7690 7691 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7692 Expr *CombRHS = 7693 (isOpenMPWorksharingDirective(DKind) || 7694 isOpenMPTaskLoopDirective(DKind) || 7695 isOpenMPDistributeDirective(DKind)) 7696 ? CombLB.get() 7697 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7698 CombInit = 7699 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7700 CombInit = 7701 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7702 } 7703 } 7704 7705 bool UseStrictCompare = 7706 RealVType->hasUnsignedIntegerRepresentation() && 7707 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7708 return LIS.IsStrictCompare; 7709 }); 7710 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7711 // unsigned IV)) for worksharing loops. 7712 SourceLocation CondLoc = AStmt->getBeginLoc(); 7713 Expr *BoundUB = UB.get(); 7714 if (UseStrictCompare) { 7715 BoundUB = 7716 SemaRef 7717 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7718 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7719 .get(); 7720 BoundUB = 7721 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7722 } 7723 ExprResult Cond = 7724 (isOpenMPWorksharingDirective(DKind) || 7725 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7726 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7727 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7728 BoundUB) 7729 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7730 NumIterations.get()); 7731 ExprResult CombDistCond; 7732 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7733 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7734 NumIterations.get()); 7735 } 7736 7737 ExprResult CombCond; 7738 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7739 Expr *BoundCombUB = CombUB.get(); 7740 if (UseStrictCompare) { 7741 BoundCombUB = 7742 SemaRef 7743 .BuildBinOp( 7744 CurScope, CondLoc, BO_Add, BoundCombUB, 7745 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7746 .get(); 7747 BoundCombUB = 7748 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7749 .get(); 7750 } 7751 CombCond = 7752 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7753 IV.get(), BoundCombUB); 7754 } 7755 // Loop increment (IV = IV + 1) 7756 SourceLocation IncLoc = AStmt->getBeginLoc(); 7757 ExprResult Inc = 7758 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7759 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7760 if (!Inc.isUsable()) 7761 return 0; 7762 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7763 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7764 if (!Inc.isUsable()) 7765 return 0; 7766 7767 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7768 // Used for directives with static scheduling. 7769 // In combined construct, add combined version that use CombLB and CombUB 7770 // base variables for the update 7771 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7772 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7773 isOpenMPDistributeDirective(DKind)) { 7774 // LB + ST 7775 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7776 if (!NextLB.isUsable()) 7777 return 0; 7778 // LB = LB + ST 7779 NextLB = 7780 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7781 NextLB = 7782 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7783 if (!NextLB.isUsable()) 7784 return 0; 7785 // UB + ST 7786 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7787 if (!NextUB.isUsable()) 7788 return 0; 7789 // UB = UB + ST 7790 NextUB = 7791 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7792 NextUB = 7793 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7794 if (!NextUB.isUsable()) 7795 return 0; 7796 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7797 CombNextLB = 7798 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7799 if (!NextLB.isUsable()) 7800 return 0; 7801 // LB = LB + ST 7802 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7803 CombNextLB.get()); 7804 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7805 /*DiscardedValue*/ false); 7806 if (!CombNextLB.isUsable()) 7807 return 0; 7808 // UB + ST 7809 CombNextUB = 7810 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7811 if (!CombNextUB.isUsable()) 7812 return 0; 7813 // UB = UB + ST 7814 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7815 CombNextUB.get()); 7816 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7817 /*DiscardedValue*/ false); 7818 if (!CombNextUB.isUsable()) 7819 return 0; 7820 } 7821 } 7822 7823 // Create increment expression for distribute loop when combined in a same 7824 // directive with for as IV = IV + ST; ensure upper bound expression based 7825 // on PrevUB instead of NumIterations - used to implement 'for' when found 7826 // in combination with 'distribute', like in 'distribute parallel for' 7827 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7828 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7829 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7830 DistCond = SemaRef.BuildBinOp( 7831 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7832 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7833 7834 DistInc = 7835 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7836 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7837 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7838 DistInc.get()); 7839 DistInc = 7840 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7841 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7842 7843 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7844 // construct 7845 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7846 ExprResult IsUBGreater = 7847 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7848 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7849 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7850 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7851 CondOp.get()); 7852 PrevEUB = 7853 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7854 7855 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7856 // parallel for is in combination with a distribute directive with 7857 // schedule(static, 1) 7858 Expr *BoundPrevUB = PrevUB.get(); 7859 if (UseStrictCompare) { 7860 BoundPrevUB = 7861 SemaRef 7862 .BuildBinOp( 7863 CurScope, CondLoc, BO_Add, BoundPrevUB, 7864 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7865 .get(); 7866 BoundPrevUB = 7867 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7868 .get(); 7869 } 7870 ParForInDistCond = 7871 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7872 IV.get(), BoundPrevUB); 7873 } 7874 7875 // Build updates and final values of the loop counters. 7876 bool HasErrors = false; 7877 Built.Counters.resize(NestedLoopCount); 7878 Built.Inits.resize(NestedLoopCount); 7879 Built.Updates.resize(NestedLoopCount); 7880 Built.Finals.resize(NestedLoopCount); 7881 Built.DependentCounters.resize(NestedLoopCount); 7882 Built.DependentInits.resize(NestedLoopCount); 7883 Built.FinalsConditions.resize(NestedLoopCount); 7884 { 7885 // We implement the following algorithm for obtaining the 7886 // original loop iteration variable values based on the 7887 // value of the collapsed loop iteration variable IV. 7888 // 7889 // Let n+1 be the number of collapsed loops in the nest. 7890 // Iteration variables (I0, I1, .... In) 7891 // Iteration counts (N0, N1, ... Nn) 7892 // 7893 // Acc = IV; 7894 // 7895 // To compute Ik for loop k, 0 <= k <= n, generate: 7896 // Prod = N(k+1) * N(k+2) * ... * Nn; 7897 // Ik = Acc / Prod; 7898 // Acc -= Ik * Prod; 7899 // 7900 ExprResult Acc = IV; 7901 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7902 LoopIterationSpace &IS = IterSpaces[Cnt]; 7903 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7904 ExprResult Iter; 7905 7906 // Compute prod 7907 ExprResult Prod = 7908 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7909 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7910 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7911 IterSpaces[K].NumIterations); 7912 7913 // Iter = Acc / Prod 7914 // If there is at least one more inner loop to avoid 7915 // multiplication by 1. 7916 if (Cnt + 1 < NestedLoopCount) 7917 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7918 Acc.get(), Prod.get()); 7919 else 7920 Iter = Acc; 7921 if (!Iter.isUsable()) { 7922 HasErrors = true; 7923 break; 7924 } 7925 7926 // Update Acc: 7927 // Acc -= Iter * Prod 7928 // Check if there is at least one more inner loop to avoid 7929 // multiplication by 1. 7930 if (Cnt + 1 < NestedLoopCount) 7931 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7932 Iter.get(), Prod.get()); 7933 else 7934 Prod = Iter; 7935 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7936 Acc.get(), Prod.get()); 7937 7938 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7939 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7940 DeclRefExpr *CounterVar = buildDeclRefExpr( 7941 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7942 /*RefersToCapture=*/true); 7943 ExprResult Init = 7944 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7945 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7946 if (!Init.isUsable()) { 7947 HasErrors = true; 7948 break; 7949 } 7950 ExprResult Update = buildCounterUpdate( 7951 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7952 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7953 if (!Update.isUsable()) { 7954 HasErrors = true; 7955 break; 7956 } 7957 7958 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7959 ExprResult Final = 7960 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7961 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7962 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7963 if (!Final.isUsable()) { 7964 HasErrors = true; 7965 break; 7966 } 7967 7968 if (!Update.isUsable() || !Final.isUsable()) { 7969 HasErrors = true; 7970 break; 7971 } 7972 // Save results 7973 Built.Counters[Cnt] = IS.CounterVar; 7974 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7975 Built.Inits[Cnt] = Init.get(); 7976 Built.Updates[Cnt] = Update.get(); 7977 Built.Finals[Cnt] = Final.get(); 7978 Built.DependentCounters[Cnt] = nullptr; 7979 Built.DependentInits[Cnt] = nullptr; 7980 Built.FinalsConditions[Cnt] = nullptr; 7981 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7982 Built.DependentCounters[Cnt] = 7983 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7984 Built.DependentInits[Cnt] = 7985 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7986 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7987 } 7988 } 7989 } 7990 7991 if (HasErrors) 7992 return 0; 7993 7994 // Save results 7995 Built.IterationVarRef = IV.get(); 7996 Built.LastIteration = LastIteration.get(); 7997 Built.NumIterations = NumIterations.get(); 7998 Built.CalcLastIteration = SemaRef 7999 .ActOnFinishFullExpr(CalcLastIteration.get(), 8000 /*DiscardedValue=*/false) 8001 .get(); 8002 Built.PreCond = PreCond.get(); 8003 Built.PreInits = buildPreInits(C, Captures); 8004 Built.Cond = Cond.get(); 8005 Built.Init = Init.get(); 8006 Built.Inc = Inc.get(); 8007 Built.LB = LB.get(); 8008 Built.UB = UB.get(); 8009 Built.IL = IL.get(); 8010 Built.ST = ST.get(); 8011 Built.EUB = EUB.get(); 8012 Built.NLB = NextLB.get(); 8013 Built.NUB = NextUB.get(); 8014 Built.PrevLB = PrevLB.get(); 8015 Built.PrevUB = PrevUB.get(); 8016 Built.DistInc = DistInc.get(); 8017 Built.PrevEUB = PrevEUB.get(); 8018 Built.DistCombinedFields.LB = CombLB.get(); 8019 Built.DistCombinedFields.UB = CombUB.get(); 8020 Built.DistCombinedFields.EUB = CombEUB.get(); 8021 Built.DistCombinedFields.Init = CombInit.get(); 8022 Built.DistCombinedFields.Cond = CombCond.get(); 8023 Built.DistCombinedFields.NLB = CombNextLB.get(); 8024 Built.DistCombinedFields.NUB = CombNextUB.get(); 8025 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8026 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8027 8028 return NestedLoopCount; 8029 } 8030 8031 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8032 auto CollapseClauses = 8033 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8034 if (CollapseClauses.begin() != CollapseClauses.end()) 8035 return (*CollapseClauses.begin())->getNumForLoops(); 8036 return nullptr; 8037 } 8038 8039 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8040 auto OrderedClauses = 8041 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8042 if (OrderedClauses.begin() != OrderedClauses.end()) 8043 return (*OrderedClauses.begin())->getNumForLoops(); 8044 return nullptr; 8045 } 8046 8047 static bool checkSimdlenSafelenSpecified(Sema &S, 8048 const ArrayRef<OMPClause *> Clauses) { 8049 const OMPSafelenClause *Safelen = nullptr; 8050 const OMPSimdlenClause *Simdlen = nullptr; 8051 8052 for (const OMPClause *Clause : Clauses) { 8053 if (Clause->getClauseKind() == OMPC_safelen) 8054 Safelen = cast<OMPSafelenClause>(Clause); 8055 else if (Clause->getClauseKind() == OMPC_simdlen) 8056 Simdlen = cast<OMPSimdlenClause>(Clause); 8057 if (Safelen && Simdlen) 8058 break; 8059 } 8060 8061 if (Simdlen && Safelen) { 8062 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8063 const Expr *SafelenLength = Safelen->getSafelen(); 8064 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8065 SimdlenLength->isInstantiationDependent() || 8066 SimdlenLength->containsUnexpandedParameterPack()) 8067 return false; 8068 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8069 SafelenLength->isInstantiationDependent() || 8070 SafelenLength->containsUnexpandedParameterPack()) 8071 return false; 8072 Expr::EvalResult SimdlenResult, SafelenResult; 8073 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8074 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8075 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8076 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8077 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8078 // If both simdlen and safelen clauses are specified, the value of the 8079 // simdlen parameter must be less than or equal to the value of the safelen 8080 // parameter. 8081 if (SimdlenRes > SafelenRes) { 8082 S.Diag(SimdlenLength->getExprLoc(), 8083 diag::err_omp_wrong_simdlen_safelen_values) 8084 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8085 return true; 8086 } 8087 } 8088 return false; 8089 } 8090 8091 StmtResult 8092 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8093 SourceLocation StartLoc, SourceLocation EndLoc, 8094 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8095 if (!AStmt) 8096 return StmtError(); 8097 8098 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8099 OMPLoopDirective::HelperExprs B; 8100 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8101 // define the nested loops number. 8102 unsigned NestedLoopCount = checkOpenMPLoop( 8103 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8104 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8105 if (NestedLoopCount == 0) 8106 return StmtError(); 8107 8108 assert((CurContext->isDependentContext() || B.builtAll()) && 8109 "omp simd loop exprs were not built"); 8110 8111 if (!CurContext->isDependentContext()) { 8112 // Finalize the clauses that need pre-built expressions for CodeGen. 8113 for (OMPClause *C : Clauses) { 8114 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8115 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8116 B.NumIterations, *this, CurScope, 8117 DSAStack)) 8118 return StmtError(); 8119 } 8120 } 8121 8122 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8123 return StmtError(); 8124 8125 setFunctionHasBranchProtectedScope(); 8126 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8127 Clauses, AStmt, B); 8128 } 8129 8130 StmtResult 8131 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8132 SourceLocation StartLoc, SourceLocation EndLoc, 8133 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8134 if (!AStmt) 8135 return StmtError(); 8136 8137 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8138 OMPLoopDirective::HelperExprs B; 8139 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8140 // define the nested loops number. 8141 unsigned NestedLoopCount = checkOpenMPLoop( 8142 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8143 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8144 if (NestedLoopCount == 0) 8145 return StmtError(); 8146 8147 assert((CurContext->isDependentContext() || B.builtAll()) && 8148 "omp for loop exprs were not built"); 8149 8150 if (!CurContext->isDependentContext()) { 8151 // Finalize the clauses that need pre-built expressions for CodeGen. 8152 for (OMPClause *C : Clauses) { 8153 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8154 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8155 B.NumIterations, *this, CurScope, 8156 DSAStack)) 8157 return StmtError(); 8158 } 8159 } 8160 8161 setFunctionHasBranchProtectedScope(); 8162 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8163 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8164 } 8165 8166 StmtResult Sema::ActOnOpenMPForSimdDirective( 8167 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8168 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8169 if (!AStmt) 8170 return StmtError(); 8171 8172 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8173 OMPLoopDirective::HelperExprs B; 8174 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8175 // define the nested loops number. 8176 unsigned NestedLoopCount = 8177 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8178 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8179 VarsWithImplicitDSA, B); 8180 if (NestedLoopCount == 0) 8181 return StmtError(); 8182 8183 assert((CurContext->isDependentContext() || B.builtAll()) && 8184 "omp for simd loop exprs were not built"); 8185 8186 if (!CurContext->isDependentContext()) { 8187 // Finalize the clauses that need pre-built expressions for CodeGen. 8188 for (OMPClause *C : Clauses) { 8189 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8190 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8191 B.NumIterations, *this, CurScope, 8192 DSAStack)) 8193 return StmtError(); 8194 } 8195 } 8196 8197 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8198 return StmtError(); 8199 8200 setFunctionHasBranchProtectedScope(); 8201 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8202 Clauses, AStmt, B); 8203 } 8204 8205 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8206 Stmt *AStmt, 8207 SourceLocation StartLoc, 8208 SourceLocation EndLoc) { 8209 if (!AStmt) 8210 return StmtError(); 8211 8212 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8213 auto BaseStmt = AStmt; 8214 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8215 BaseStmt = CS->getCapturedStmt(); 8216 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8217 auto S = C->children(); 8218 if (S.begin() == S.end()) 8219 return StmtError(); 8220 // All associated statements must be '#pragma omp section' except for 8221 // the first one. 8222 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8223 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8224 if (SectionStmt) 8225 Diag(SectionStmt->getBeginLoc(), 8226 diag::err_omp_sections_substmt_not_section); 8227 return StmtError(); 8228 } 8229 cast<OMPSectionDirective>(SectionStmt) 8230 ->setHasCancel(DSAStack->isCancelRegion()); 8231 } 8232 } else { 8233 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8234 return StmtError(); 8235 } 8236 8237 setFunctionHasBranchProtectedScope(); 8238 8239 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8240 DSAStack->isCancelRegion()); 8241 } 8242 8243 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8244 SourceLocation StartLoc, 8245 SourceLocation EndLoc) { 8246 if (!AStmt) 8247 return StmtError(); 8248 8249 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8250 8251 setFunctionHasBranchProtectedScope(); 8252 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8253 8254 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8255 DSAStack->isCancelRegion()); 8256 } 8257 8258 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8259 Stmt *AStmt, 8260 SourceLocation StartLoc, 8261 SourceLocation EndLoc) { 8262 if (!AStmt) 8263 return StmtError(); 8264 8265 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8266 8267 setFunctionHasBranchProtectedScope(); 8268 8269 // OpenMP [2.7.3, single Construct, Restrictions] 8270 // The copyprivate clause must not be used with the nowait clause. 8271 const OMPClause *Nowait = nullptr; 8272 const OMPClause *Copyprivate = nullptr; 8273 for (const OMPClause *Clause : Clauses) { 8274 if (Clause->getClauseKind() == OMPC_nowait) 8275 Nowait = Clause; 8276 else if (Clause->getClauseKind() == OMPC_copyprivate) 8277 Copyprivate = Clause; 8278 if (Copyprivate && Nowait) { 8279 Diag(Copyprivate->getBeginLoc(), 8280 diag::err_omp_single_copyprivate_with_nowait); 8281 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8282 return StmtError(); 8283 } 8284 } 8285 8286 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8287 } 8288 8289 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8290 SourceLocation StartLoc, 8291 SourceLocation EndLoc) { 8292 if (!AStmt) 8293 return StmtError(); 8294 8295 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8296 8297 setFunctionHasBranchProtectedScope(); 8298 8299 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8300 } 8301 8302 StmtResult Sema::ActOnOpenMPCriticalDirective( 8303 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8304 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8305 if (!AStmt) 8306 return StmtError(); 8307 8308 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8309 8310 bool ErrorFound = false; 8311 llvm::APSInt Hint; 8312 SourceLocation HintLoc; 8313 bool DependentHint = false; 8314 for (const OMPClause *C : Clauses) { 8315 if (C->getClauseKind() == OMPC_hint) { 8316 if (!DirName.getName()) { 8317 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8318 ErrorFound = true; 8319 } 8320 Expr *E = cast<OMPHintClause>(C)->getHint(); 8321 if (E->isTypeDependent() || E->isValueDependent() || 8322 E->isInstantiationDependent()) { 8323 DependentHint = true; 8324 } else { 8325 Hint = E->EvaluateKnownConstInt(Context); 8326 HintLoc = C->getBeginLoc(); 8327 } 8328 } 8329 } 8330 if (ErrorFound) 8331 return StmtError(); 8332 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8333 if (Pair.first && DirName.getName() && !DependentHint) { 8334 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8335 Diag(StartLoc, diag::err_omp_critical_with_hint); 8336 if (HintLoc.isValid()) 8337 Diag(HintLoc, diag::note_omp_critical_hint_here) 8338 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8339 else 8340 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8341 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8342 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8343 << 1 8344 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8345 /*Radix=*/10, /*Signed=*/false); 8346 } else { 8347 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8348 } 8349 } 8350 } 8351 8352 setFunctionHasBranchProtectedScope(); 8353 8354 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8355 Clauses, AStmt); 8356 if (!Pair.first && DirName.getName() && !DependentHint) 8357 DSAStack->addCriticalWithHint(Dir, Hint); 8358 return Dir; 8359 } 8360 8361 StmtResult Sema::ActOnOpenMPParallelForDirective( 8362 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8363 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8364 if (!AStmt) 8365 return StmtError(); 8366 8367 auto *CS = cast<CapturedStmt>(AStmt); 8368 // 1.2.2 OpenMP Language Terminology 8369 // Structured block - An executable statement with a single entry at the 8370 // top and a single exit at the bottom. 8371 // The point of exit cannot be a branch out of the structured block. 8372 // longjmp() and throw() must not violate the entry/exit criteria. 8373 CS->getCapturedDecl()->setNothrow(); 8374 8375 OMPLoopDirective::HelperExprs B; 8376 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8377 // define the nested loops number. 8378 unsigned NestedLoopCount = 8379 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8380 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8381 VarsWithImplicitDSA, B); 8382 if (NestedLoopCount == 0) 8383 return StmtError(); 8384 8385 assert((CurContext->isDependentContext() || B.builtAll()) && 8386 "omp parallel for loop exprs were not built"); 8387 8388 if (!CurContext->isDependentContext()) { 8389 // Finalize the clauses that need pre-built expressions for CodeGen. 8390 for (OMPClause *C : Clauses) { 8391 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8392 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8393 B.NumIterations, *this, CurScope, 8394 DSAStack)) 8395 return StmtError(); 8396 } 8397 } 8398 8399 setFunctionHasBranchProtectedScope(); 8400 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8401 NestedLoopCount, Clauses, AStmt, B, 8402 DSAStack->isCancelRegion()); 8403 } 8404 8405 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8406 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8407 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8408 if (!AStmt) 8409 return StmtError(); 8410 8411 auto *CS = cast<CapturedStmt>(AStmt); 8412 // 1.2.2 OpenMP Language Terminology 8413 // Structured block - An executable statement with a single entry at the 8414 // top and a single exit at the bottom. 8415 // The point of exit cannot be a branch out of the structured block. 8416 // longjmp() and throw() must not violate the entry/exit criteria. 8417 CS->getCapturedDecl()->setNothrow(); 8418 8419 OMPLoopDirective::HelperExprs B; 8420 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8421 // define the nested loops number. 8422 unsigned NestedLoopCount = 8423 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8424 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8425 VarsWithImplicitDSA, B); 8426 if (NestedLoopCount == 0) 8427 return StmtError(); 8428 8429 if (!CurContext->isDependentContext()) { 8430 // Finalize the clauses that need pre-built expressions for CodeGen. 8431 for (OMPClause *C : Clauses) { 8432 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8433 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8434 B.NumIterations, *this, CurScope, 8435 DSAStack)) 8436 return StmtError(); 8437 } 8438 } 8439 8440 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8441 return StmtError(); 8442 8443 setFunctionHasBranchProtectedScope(); 8444 return OMPParallelForSimdDirective::Create( 8445 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8446 } 8447 8448 StmtResult 8449 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8450 Stmt *AStmt, SourceLocation StartLoc, 8451 SourceLocation EndLoc) { 8452 if (!AStmt) 8453 return StmtError(); 8454 8455 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8456 auto *CS = cast<CapturedStmt>(AStmt); 8457 // 1.2.2 OpenMP Language Terminology 8458 // Structured block - An executable statement with a single entry at the 8459 // top and a single exit at the bottom. 8460 // The point of exit cannot be a branch out of the structured block. 8461 // longjmp() and throw() must not violate the entry/exit criteria. 8462 CS->getCapturedDecl()->setNothrow(); 8463 8464 setFunctionHasBranchProtectedScope(); 8465 8466 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8467 AStmt); 8468 } 8469 8470 StmtResult 8471 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8472 Stmt *AStmt, SourceLocation StartLoc, 8473 SourceLocation EndLoc) { 8474 if (!AStmt) 8475 return StmtError(); 8476 8477 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8478 auto BaseStmt = AStmt; 8479 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8480 BaseStmt = CS->getCapturedStmt(); 8481 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8482 auto S = C->children(); 8483 if (S.begin() == S.end()) 8484 return StmtError(); 8485 // All associated statements must be '#pragma omp section' except for 8486 // the first one. 8487 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8488 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8489 if (SectionStmt) 8490 Diag(SectionStmt->getBeginLoc(), 8491 diag::err_omp_parallel_sections_substmt_not_section); 8492 return StmtError(); 8493 } 8494 cast<OMPSectionDirective>(SectionStmt) 8495 ->setHasCancel(DSAStack->isCancelRegion()); 8496 } 8497 } else { 8498 Diag(AStmt->getBeginLoc(), 8499 diag::err_omp_parallel_sections_not_compound_stmt); 8500 return StmtError(); 8501 } 8502 8503 setFunctionHasBranchProtectedScope(); 8504 8505 return OMPParallelSectionsDirective::Create( 8506 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8507 } 8508 8509 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8510 Stmt *AStmt, SourceLocation StartLoc, 8511 SourceLocation EndLoc) { 8512 if (!AStmt) 8513 return StmtError(); 8514 8515 auto *CS = cast<CapturedStmt>(AStmt); 8516 // 1.2.2 OpenMP Language Terminology 8517 // Structured block - An executable statement with a single entry at the 8518 // top and a single exit at the bottom. 8519 // The point of exit cannot be a branch out of the structured block. 8520 // longjmp() and throw() must not violate the entry/exit criteria. 8521 CS->getCapturedDecl()->setNothrow(); 8522 8523 setFunctionHasBranchProtectedScope(); 8524 8525 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8526 DSAStack->isCancelRegion()); 8527 } 8528 8529 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8530 SourceLocation EndLoc) { 8531 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8532 } 8533 8534 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8535 SourceLocation EndLoc) { 8536 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8537 } 8538 8539 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8540 SourceLocation EndLoc) { 8541 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8542 } 8543 8544 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8545 Stmt *AStmt, 8546 SourceLocation StartLoc, 8547 SourceLocation EndLoc) { 8548 if (!AStmt) 8549 return StmtError(); 8550 8551 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8552 8553 setFunctionHasBranchProtectedScope(); 8554 8555 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8556 AStmt, 8557 DSAStack->getTaskgroupReductionRef()); 8558 } 8559 8560 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8561 SourceLocation StartLoc, 8562 SourceLocation EndLoc) { 8563 OMPFlushClause *FC = nullptr; 8564 OMPClause *OrderClause = nullptr; 8565 for (OMPClause *C : Clauses) { 8566 if (C->getClauseKind() == OMPC_flush) 8567 FC = cast<OMPFlushClause>(C); 8568 else 8569 OrderClause = C; 8570 } 8571 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8572 SourceLocation MemOrderLoc; 8573 for (const OMPClause *C : Clauses) { 8574 if (C->getClauseKind() == OMPC_acq_rel || 8575 C->getClauseKind() == OMPC_acquire || 8576 C->getClauseKind() == OMPC_release) { 8577 if (MemOrderKind != OMPC_unknown) { 8578 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8579 << getOpenMPDirectiveName(OMPD_flush) << 1 8580 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8581 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8582 << getOpenMPClauseName(MemOrderKind); 8583 } else { 8584 MemOrderKind = C->getClauseKind(); 8585 MemOrderLoc = C->getBeginLoc(); 8586 } 8587 } 8588 } 8589 if (FC && OrderClause) { 8590 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 8591 << getOpenMPClauseName(OrderClause->getClauseKind()); 8592 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 8593 << getOpenMPClauseName(OrderClause->getClauseKind()); 8594 return StmtError(); 8595 } 8596 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8597 } 8598 8599 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8600 Stmt *AStmt, 8601 SourceLocation StartLoc, 8602 SourceLocation EndLoc) { 8603 const OMPClause *DependFound = nullptr; 8604 const OMPClause *DependSourceClause = nullptr; 8605 const OMPClause *DependSinkClause = nullptr; 8606 bool ErrorFound = false; 8607 const OMPThreadsClause *TC = nullptr; 8608 const OMPSIMDClause *SC = nullptr; 8609 for (const OMPClause *C : Clauses) { 8610 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8611 DependFound = C; 8612 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8613 if (DependSourceClause) { 8614 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8615 << getOpenMPDirectiveName(OMPD_ordered) 8616 << getOpenMPClauseName(OMPC_depend) << 2; 8617 ErrorFound = true; 8618 } else { 8619 DependSourceClause = C; 8620 } 8621 if (DependSinkClause) { 8622 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8623 << 0; 8624 ErrorFound = true; 8625 } 8626 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8627 if (DependSourceClause) { 8628 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8629 << 1; 8630 ErrorFound = true; 8631 } 8632 DependSinkClause = C; 8633 } 8634 } else if (C->getClauseKind() == OMPC_threads) { 8635 TC = cast<OMPThreadsClause>(C); 8636 } else if (C->getClauseKind() == OMPC_simd) { 8637 SC = cast<OMPSIMDClause>(C); 8638 } 8639 } 8640 if (!ErrorFound && !SC && 8641 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8642 // OpenMP [2.8.1,simd Construct, Restrictions] 8643 // An ordered construct with the simd clause is the only OpenMP construct 8644 // that can appear in the simd region. 8645 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8646 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8647 ErrorFound = true; 8648 } else if (DependFound && (TC || SC)) { 8649 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8650 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8651 ErrorFound = true; 8652 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8653 Diag(DependFound->getBeginLoc(), 8654 diag::err_omp_ordered_directive_without_param); 8655 ErrorFound = true; 8656 } else if (TC || Clauses.empty()) { 8657 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8658 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8659 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8660 << (TC != nullptr); 8661 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 8662 ErrorFound = true; 8663 } 8664 } 8665 if ((!AStmt && !DependFound) || ErrorFound) 8666 return StmtError(); 8667 8668 if (AStmt) { 8669 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8670 8671 setFunctionHasBranchProtectedScope(); 8672 } 8673 8674 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8675 } 8676 8677 namespace { 8678 /// Helper class for checking expression in 'omp atomic [update]' 8679 /// construct. 8680 class OpenMPAtomicUpdateChecker { 8681 /// Error results for atomic update expressions. 8682 enum ExprAnalysisErrorCode { 8683 /// A statement is not an expression statement. 8684 NotAnExpression, 8685 /// Expression is not builtin binary or unary operation. 8686 NotABinaryOrUnaryExpression, 8687 /// Unary operation is not post-/pre- increment/decrement operation. 8688 NotAnUnaryIncDecExpression, 8689 /// An expression is not of scalar type. 8690 NotAScalarType, 8691 /// A binary operation is not an assignment operation. 8692 NotAnAssignmentOp, 8693 /// RHS part of the binary operation is not a binary expression. 8694 NotABinaryExpression, 8695 /// RHS part is not additive/multiplicative/shift/biwise binary 8696 /// expression. 8697 NotABinaryOperator, 8698 /// RHS binary operation does not have reference to the updated LHS 8699 /// part. 8700 NotAnUpdateExpression, 8701 /// No errors is found. 8702 NoError 8703 }; 8704 /// Reference to Sema. 8705 Sema &SemaRef; 8706 /// A location for note diagnostics (when error is found). 8707 SourceLocation NoteLoc; 8708 /// 'x' lvalue part of the source atomic expression. 8709 Expr *X; 8710 /// 'expr' rvalue part of the source atomic expression. 8711 Expr *E; 8712 /// Helper expression of the form 8713 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8714 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8715 Expr *UpdateExpr; 8716 /// Is 'x' a LHS in a RHS part of full update expression. It is 8717 /// important for non-associative operations. 8718 bool IsXLHSInRHSPart; 8719 BinaryOperatorKind Op; 8720 SourceLocation OpLoc; 8721 /// true if the source expression is a postfix unary operation, false 8722 /// if it is a prefix unary operation. 8723 bool IsPostfixUpdate; 8724 8725 public: 8726 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8727 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8728 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8729 /// Check specified statement that it is suitable for 'atomic update' 8730 /// constructs and extract 'x', 'expr' and Operation from the original 8731 /// expression. If DiagId and NoteId == 0, then only check is performed 8732 /// without error notification. 8733 /// \param DiagId Diagnostic which should be emitted if error is found. 8734 /// \param NoteId Diagnostic note for the main error message. 8735 /// \return true if statement is not an update expression, false otherwise. 8736 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8737 /// Return the 'x' lvalue part of the source atomic expression. 8738 Expr *getX() const { return X; } 8739 /// Return the 'expr' rvalue part of the source atomic expression. 8740 Expr *getExpr() const { return E; } 8741 /// Return the update expression used in calculation of the updated 8742 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8743 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8744 Expr *getUpdateExpr() const { return UpdateExpr; } 8745 /// Return true if 'x' is LHS in RHS part of full update expression, 8746 /// false otherwise. 8747 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8748 8749 /// true if the source expression is a postfix unary operation, false 8750 /// if it is a prefix unary operation. 8751 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8752 8753 private: 8754 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8755 unsigned NoteId = 0); 8756 }; 8757 } // namespace 8758 8759 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8760 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8761 ExprAnalysisErrorCode ErrorFound = NoError; 8762 SourceLocation ErrorLoc, NoteLoc; 8763 SourceRange ErrorRange, NoteRange; 8764 // Allowed constructs are: 8765 // x = x binop expr; 8766 // x = expr binop x; 8767 if (AtomicBinOp->getOpcode() == BO_Assign) { 8768 X = AtomicBinOp->getLHS(); 8769 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8770 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8771 if (AtomicInnerBinOp->isMultiplicativeOp() || 8772 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8773 AtomicInnerBinOp->isBitwiseOp()) { 8774 Op = AtomicInnerBinOp->getOpcode(); 8775 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8776 Expr *LHS = AtomicInnerBinOp->getLHS(); 8777 Expr *RHS = AtomicInnerBinOp->getRHS(); 8778 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8779 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8780 /*Canonical=*/true); 8781 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8782 /*Canonical=*/true); 8783 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8784 /*Canonical=*/true); 8785 if (XId == LHSId) { 8786 E = RHS; 8787 IsXLHSInRHSPart = true; 8788 } else if (XId == RHSId) { 8789 E = LHS; 8790 IsXLHSInRHSPart = false; 8791 } else { 8792 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8793 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8794 NoteLoc = X->getExprLoc(); 8795 NoteRange = X->getSourceRange(); 8796 ErrorFound = NotAnUpdateExpression; 8797 } 8798 } else { 8799 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8800 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8801 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8802 NoteRange = SourceRange(NoteLoc, NoteLoc); 8803 ErrorFound = NotABinaryOperator; 8804 } 8805 } else { 8806 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8807 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8808 ErrorFound = NotABinaryExpression; 8809 } 8810 } else { 8811 ErrorLoc = AtomicBinOp->getExprLoc(); 8812 ErrorRange = AtomicBinOp->getSourceRange(); 8813 NoteLoc = AtomicBinOp->getOperatorLoc(); 8814 NoteRange = SourceRange(NoteLoc, NoteLoc); 8815 ErrorFound = NotAnAssignmentOp; 8816 } 8817 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8818 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8819 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8820 return true; 8821 } 8822 if (SemaRef.CurContext->isDependentContext()) 8823 E = X = UpdateExpr = nullptr; 8824 return ErrorFound != NoError; 8825 } 8826 8827 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8828 unsigned NoteId) { 8829 ExprAnalysisErrorCode ErrorFound = NoError; 8830 SourceLocation ErrorLoc, NoteLoc; 8831 SourceRange ErrorRange, NoteRange; 8832 // Allowed constructs are: 8833 // x++; 8834 // x--; 8835 // ++x; 8836 // --x; 8837 // x binop= expr; 8838 // x = x binop expr; 8839 // x = expr binop x; 8840 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8841 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8842 if (AtomicBody->getType()->isScalarType() || 8843 AtomicBody->isInstantiationDependent()) { 8844 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8845 AtomicBody->IgnoreParenImpCasts())) { 8846 // Check for Compound Assignment Operation 8847 Op = BinaryOperator::getOpForCompoundAssignment( 8848 AtomicCompAssignOp->getOpcode()); 8849 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8850 E = AtomicCompAssignOp->getRHS(); 8851 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8852 IsXLHSInRHSPart = true; 8853 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8854 AtomicBody->IgnoreParenImpCasts())) { 8855 // Check for Binary Operation 8856 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8857 return true; 8858 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8859 AtomicBody->IgnoreParenImpCasts())) { 8860 // Check for Unary Operation 8861 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8862 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8863 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8864 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8865 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8866 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8867 IsXLHSInRHSPart = true; 8868 } else { 8869 ErrorFound = NotAnUnaryIncDecExpression; 8870 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8871 ErrorRange = AtomicUnaryOp->getSourceRange(); 8872 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8873 NoteRange = SourceRange(NoteLoc, NoteLoc); 8874 } 8875 } else if (!AtomicBody->isInstantiationDependent()) { 8876 ErrorFound = NotABinaryOrUnaryExpression; 8877 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8878 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8879 } 8880 } else { 8881 ErrorFound = NotAScalarType; 8882 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8883 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8884 } 8885 } else { 8886 ErrorFound = NotAnExpression; 8887 NoteLoc = ErrorLoc = S->getBeginLoc(); 8888 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8889 } 8890 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8891 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8892 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8893 return true; 8894 } 8895 if (SemaRef.CurContext->isDependentContext()) 8896 E = X = UpdateExpr = nullptr; 8897 if (ErrorFound == NoError && E && X) { 8898 // Build an update expression of form 'OpaqueValueExpr(x) binop 8899 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8900 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8901 auto *OVEX = new (SemaRef.getASTContext()) 8902 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8903 auto *OVEExpr = new (SemaRef.getASTContext()) 8904 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8905 ExprResult Update = 8906 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8907 IsXLHSInRHSPart ? OVEExpr : OVEX); 8908 if (Update.isInvalid()) 8909 return true; 8910 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8911 Sema::AA_Casting); 8912 if (Update.isInvalid()) 8913 return true; 8914 UpdateExpr = Update.get(); 8915 } 8916 return ErrorFound != NoError; 8917 } 8918 8919 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8920 Stmt *AStmt, 8921 SourceLocation StartLoc, 8922 SourceLocation EndLoc) { 8923 // Register location of the first atomic directive. 8924 DSAStack->addAtomicDirectiveLoc(StartLoc); 8925 if (!AStmt) 8926 return StmtError(); 8927 8928 auto *CS = cast<CapturedStmt>(AStmt); 8929 // 1.2.2 OpenMP Language Terminology 8930 // Structured block - An executable statement with a single entry at the 8931 // top and a single exit at the bottom. 8932 // The point of exit cannot be a branch out of the structured block. 8933 // longjmp() and throw() must not violate the entry/exit criteria. 8934 OpenMPClauseKind AtomicKind = OMPC_unknown; 8935 SourceLocation AtomicKindLoc; 8936 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8937 SourceLocation MemOrderLoc; 8938 for (const OMPClause *C : Clauses) { 8939 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8940 C->getClauseKind() == OMPC_update || 8941 C->getClauseKind() == OMPC_capture) { 8942 if (AtomicKind != OMPC_unknown) { 8943 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8944 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8945 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 8946 << getOpenMPClauseName(AtomicKind); 8947 } else { 8948 AtomicKind = C->getClauseKind(); 8949 AtomicKindLoc = C->getBeginLoc(); 8950 } 8951 } 8952 if (C->getClauseKind() == OMPC_seq_cst || 8953 C->getClauseKind() == OMPC_acq_rel || 8954 C->getClauseKind() == OMPC_acquire || 8955 C->getClauseKind() == OMPC_release || 8956 C->getClauseKind() == OMPC_relaxed) { 8957 if (MemOrderKind != OMPC_unknown) { 8958 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8959 << getOpenMPDirectiveName(OMPD_atomic) << 0 8960 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8961 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8962 << getOpenMPClauseName(MemOrderKind); 8963 } else { 8964 MemOrderKind = C->getClauseKind(); 8965 MemOrderLoc = C->getBeginLoc(); 8966 } 8967 } 8968 } 8969 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 8970 // If atomic-clause is read then memory-order-clause must not be acq_rel or 8971 // release. 8972 // If atomic-clause is write then memory-order-clause must not be acq_rel or 8973 // acquire. 8974 // If atomic-clause is update or not present then memory-order-clause must not 8975 // be acq_rel or acquire. 8976 if ((AtomicKind == OMPC_read && 8977 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 8978 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 8979 AtomicKind == OMPC_unknown) && 8980 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 8981 SourceLocation Loc = AtomicKindLoc; 8982 if (AtomicKind == OMPC_unknown) 8983 Loc = StartLoc; 8984 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 8985 << getOpenMPClauseName(AtomicKind) 8986 << (AtomicKind == OMPC_unknown ? 1 : 0) 8987 << getOpenMPClauseName(MemOrderKind); 8988 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8989 << getOpenMPClauseName(MemOrderKind); 8990 } 8991 8992 Stmt *Body = CS->getCapturedStmt(); 8993 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8994 Body = EWC->getSubExpr(); 8995 8996 Expr *X = nullptr; 8997 Expr *V = nullptr; 8998 Expr *E = nullptr; 8999 Expr *UE = nullptr; 9000 bool IsXLHSInRHSPart = false; 9001 bool IsPostfixUpdate = false; 9002 // OpenMP [2.12.6, atomic Construct] 9003 // In the next expressions: 9004 // * x and v (as applicable) are both l-value expressions with scalar type. 9005 // * During the execution of an atomic region, multiple syntactic 9006 // occurrences of x must designate the same storage location. 9007 // * Neither of v and expr (as applicable) may access the storage location 9008 // designated by x. 9009 // * Neither of x and expr (as applicable) may access the storage location 9010 // designated by v. 9011 // * expr is an expression with scalar type. 9012 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9013 // * binop, binop=, ++, and -- are not overloaded operators. 9014 // * The expression x binop expr must be numerically equivalent to x binop 9015 // (expr). This requirement is satisfied if the operators in expr have 9016 // precedence greater than binop, or by using parentheses around expr or 9017 // subexpressions of expr. 9018 // * The expression expr binop x must be numerically equivalent to (expr) 9019 // binop x. This requirement is satisfied if the operators in expr have 9020 // precedence equal to or greater than binop, or by using parentheses around 9021 // expr or subexpressions of expr. 9022 // * For forms that allow multiple occurrences of x, the number of times 9023 // that x is evaluated is unspecified. 9024 if (AtomicKind == OMPC_read) { 9025 enum { 9026 NotAnExpression, 9027 NotAnAssignmentOp, 9028 NotAScalarType, 9029 NotAnLValue, 9030 NoError 9031 } ErrorFound = NoError; 9032 SourceLocation ErrorLoc, NoteLoc; 9033 SourceRange ErrorRange, NoteRange; 9034 // If clause is read: 9035 // v = x; 9036 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9037 const auto *AtomicBinOp = 9038 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9039 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9040 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9041 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9042 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9043 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9044 if (!X->isLValue() || !V->isLValue()) { 9045 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9046 ErrorFound = NotAnLValue; 9047 ErrorLoc = AtomicBinOp->getExprLoc(); 9048 ErrorRange = AtomicBinOp->getSourceRange(); 9049 NoteLoc = NotLValueExpr->getExprLoc(); 9050 NoteRange = NotLValueExpr->getSourceRange(); 9051 } 9052 } else if (!X->isInstantiationDependent() || 9053 !V->isInstantiationDependent()) { 9054 const Expr *NotScalarExpr = 9055 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9056 ? V 9057 : X; 9058 ErrorFound = NotAScalarType; 9059 ErrorLoc = AtomicBinOp->getExprLoc(); 9060 ErrorRange = AtomicBinOp->getSourceRange(); 9061 NoteLoc = NotScalarExpr->getExprLoc(); 9062 NoteRange = NotScalarExpr->getSourceRange(); 9063 } 9064 } else if (!AtomicBody->isInstantiationDependent()) { 9065 ErrorFound = NotAnAssignmentOp; 9066 ErrorLoc = AtomicBody->getExprLoc(); 9067 ErrorRange = AtomicBody->getSourceRange(); 9068 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9069 : AtomicBody->getExprLoc(); 9070 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9071 : AtomicBody->getSourceRange(); 9072 } 9073 } else { 9074 ErrorFound = NotAnExpression; 9075 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9076 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9077 } 9078 if (ErrorFound != NoError) { 9079 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9080 << ErrorRange; 9081 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9082 << NoteRange; 9083 return StmtError(); 9084 } 9085 if (CurContext->isDependentContext()) 9086 V = X = nullptr; 9087 } else if (AtomicKind == OMPC_write) { 9088 enum { 9089 NotAnExpression, 9090 NotAnAssignmentOp, 9091 NotAScalarType, 9092 NotAnLValue, 9093 NoError 9094 } ErrorFound = NoError; 9095 SourceLocation ErrorLoc, NoteLoc; 9096 SourceRange ErrorRange, NoteRange; 9097 // If clause is write: 9098 // x = expr; 9099 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9100 const auto *AtomicBinOp = 9101 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9102 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9103 X = AtomicBinOp->getLHS(); 9104 E = AtomicBinOp->getRHS(); 9105 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9106 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9107 if (!X->isLValue()) { 9108 ErrorFound = NotAnLValue; 9109 ErrorLoc = AtomicBinOp->getExprLoc(); 9110 ErrorRange = AtomicBinOp->getSourceRange(); 9111 NoteLoc = X->getExprLoc(); 9112 NoteRange = X->getSourceRange(); 9113 } 9114 } else if (!X->isInstantiationDependent() || 9115 !E->isInstantiationDependent()) { 9116 const Expr *NotScalarExpr = 9117 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9118 ? E 9119 : X; 9120 ErrorFound = NotAScalarType; 9121 ErrorLoc = AtomicBinOp->getExprLoc(); 9122 ErrorRange = AtomicBinOp->getSourceRange(); 9123 NoteLoc = NotScalarExpr->getExprLoc(); 9124 NoteRange = NotScalarExpr->getSourceRange(); 9125 } 9126 } else if (!AtomicBody->isInstantiationDependent()) { 9127 ErrorFound = NotAnAssignmentOp; 9128 ErrorLoc = AtomicBody->getExprLoc(); 9129 ErrorRange = AtomicBody->getSourceRange(); 9130 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9131 : AtomicBody->getExprLoc(); 9132 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9133 : AtomicBody->getSourceRange(); 9134 } 9135 } else { 9136 ErrorFound = NotAnExpression; 9137 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9138 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9139 } 9140 if (ErrorFound != NoError) { 9141 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9142 << ErrorRange; 9143 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9144 << NoteRange; 9145 return StmtError(); 9146 } 9147 if (CurContext->isDependentContext()) 9148 E = X = nullptr; 9149 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9150 // If clause is update: 9151 // x++; 9152 // x--; 9153 // ++x; 9154 // --x; 9155 // x binop= expr; 9156 // x = x binop expr; 9157 // x = expr binop x; 9158 OpenMPAtomicUpdateChecker Checker(*this); 9159 if (Checker.checkStatement( 9160 Body, (AtomicKind == OMPC_update) 9161 ? diag::err_omp_atomic_update_not_expression_statement 9162 : diag::err_omp_atomic_not_expression_statement, 9163 diag::note_omp_atomic_update)) 9164 return StmtError(); 9165 if (!CurContext->isDependentContext()) { 9166 E = Checker.getExpr(); 9167 X = Checker.getX(); 9168 UE = Checker.getUpdateExpr(); 9169 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9170 } 9171 } else if (AtomicKind == OMPC_capture) { 9172 enum { 9173 NotAnAssignmentOp, 9174 NotACompoundStatement, 9175 NotTwoSubstatements, 9176 NotASpecificExpression, 9177 NoError 9178 } ErrorFound = NoError; 9179 SourceLocation ErrorLoc, NoteLoc; 9180 SourceRange ErrorRange, NoteRange; 9181 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9182 // If clause is a capture: 9183 // v = x++; 9184 // v = x--; 9185 // v = ++x; 9186 // v = --x; 9187 // v = x binop= expr; 9188 // v = x = x binop expr; 9189 // v = x = expr binop x; 9190 const auto *AtomicBinOp = 9191 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9192 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9193 V = AtomicBinOp->getLHS(); 9194 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9195 OpenMPAtomicUpdateChecker Checker(*this); 9196 if (Checker.checkStatement( 9197 Body, diag::err_omp_atomic_capture_not_expression_statement, 9198 diag::note_omp_atomic_update)) 9199 return StmtError(); 9200 E = Checker.getExpr(); 9201 X = Checker.getX(); 9202 UE = Checker.getUpdateExpr(); 9203 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9204 IsPostfixUpdate = Checker.isPostfixUpdate(); 9205 } else if (!AtomicBody->isInstantiationDependent()) { 9206 ErrorLoc = AtomicBody->getExprLoc(); 9207 ErrorRange = AtomicBody->getSourceRange(); 9208 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9209 : AtomicBody->getExprLoc(); 9210 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9211 : AtomicBody->getSourceRange(); 9212 ErrorFound = NotAnAssignmentOp; 9213 } 9214 if (ErrorFound != NoError) { 9215 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9216 << ErrorRange; 9217 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9218 return StmtError(); 9219 } 9220 if (CurContext->isDependentContext()) 9221 UE = V = E = X = nullptr; 9222 } else { 9223 // If clause is a capture: 9224 // { v = x; x = expr; } 9225 // { v = x; x++; } 9226 // { v = x; x--; } 9227 // { v = x; ++x; } 9228 // { v = x; --x; } 9229 // { v = x; x binop= expr; } 9230 // { v = x; x = x binop expr; } 9231 // { v = x; x = expr binop x; } 9232 // { x++; v = x; } 9233 // { x--; v = x; } 9234 // { ++x; v = x; } 9235 // { --x; v = x; } 9236 // { x binop= expr; v = x; } 9237 // { x = x binop expr; v = x; } 9238 // { x = expr binop x; v = x; } 9239 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9240 // Check that this is { expr1; expr2; } 9241 if (CS->size() == 2) { 9242 Stmt *First = CS->body_front(); 9243 Stmt *Second = CS->body_back(); 9244 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9245 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9246 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9247 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9248 // Need to find what subexpression is 'v' and what is 'x'. 9249 OpenMPAtomicUpdateChecker Checker(*this); 9250 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9251 BinaryOperator *BinOp = nullptr; 9252 if (IsUpdateExprFound) { 9253 BinOp = dyn_cast<BinaryOperator>(First); 9254 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9255 } 9256 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9257 // { v = x; x++; } 9258 // { v = x; x--; } 9259 // { v = x; ++x; } 9260 // { v = x; --x; } 9261 // { v = x; x binop= expr; } 9262 // { v = x; x = x binop expr; } 9263 // { v = x; x = expr binop x; } 9264 // Check that the first expression has form v = x. 9265 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9266 llvm::FoldingSetNodeID XId, PossibleXId; 9267 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9268 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9269 IsUpdateExprFound = XId == PossibleXId; 9270 if (IsUpdateExprFound) { 9271 V = BinOp->getLHS(); 9272 X = Checker.getX(); 9273 E = Checker.getExpr(); 9274 UE = Checker.getUpdateExpr(); 9275 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9276 IsPostfixUpdate = true; 9277 } 9278 } 9279 if (!IsUpdateExprFound) { 9280 IsUpdateExprFound = !Checker.checkStatement(First); 9281 BinOp = nullptr; 9282 if (IsUpdateExprFound) { 9283 BinOp = dyn_cast<BinaryOperator>(Second); 9284 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9285 } 9286 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9287 // { x++; v = x; } 9288 // { x--; v = x; } 9289 // { ++x; v = x; } 9290 // { --x; v = x; } 9291 // { x binop= expr; v = x; } 9292 // { x = x binop expr; v = x; } 9293 // { x = expr binop x; v = x; } 9294 // Check that the second expression has form v = x. 9295 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9296 llvm::FoldingSetNodeID XId, PossibleXId; 9297 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9298 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9299 IsUpdateExprFound = XId == PossibleXId; 9300 if (IsUpdateExprFound) { 9301 V = BinOp->getLHS(); 9302 X = Checker.getX(); 9303 E = Checker.getExpr(); 9304 UE = Checker.getUpdateExpr(); 9305 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9306 IsPostfixUpdate = false; 9307 } 9308 } 9309 } 9310 if (!IsUpdateExprFound) { 9311 // { v = x; x = expr; } 9312 auto *FirstExpr = dyn_cast<Expr>(First); 9313 auto *SecondExpr = dyn_cast<Expr>(Second); 9314 if (!FirstExpr || !SecondExpr || 9315 !(FirstExpr->isInstantiationDependent() || 9316 SecondExpr->isInstantiationDependent())) { 9317 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9318 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9319 ErrorFound = NotAnAssignmentOp; 9320 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9321 : First->getBeginLoc(); 9322 NoteRange = ErrorRange = FirstBinOp 9323 ? FirstBinOp->getSourceRange() 9324 : SourceRange(ErrorLoc, ErrorLoc); 9325 } else { 9326 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9327 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9328 ErrorFound = NotAnAssignmentOp; 9329 NoteLoc = ErrorLoc = SecondBinOp 9330 ? SecondBinOp->getOperatorLoc() 9331 : Second->getBeginLoc(); 9332 NoteRange = ErrorRange = 9333 SecondBinOp ? SecondBinOp->getSourceRange() 9334 : SourceRange(ErrorLoc, ErrorLoc); 9335 } else { 9336 Expr *PossibleXRHSInFirst = 9337 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9338 Expr *PossibleXLHSInSecond = 9339 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9340 llvm::FoldingSetNodeID X1Id, X2Id; 9341 PossibleXRHSInFirst->Profile(X1Id, Context, 9342 /*Canonical=*/true); 9343 PossibleXLHSInSecond->Profile(X2Id, Context, 9344 /*Canonical=*/true); 9345 IsUpdateExprFound = X1Id == X2Id; 9346 if (IsUpdateExprFound) { 9347 V = FirstBinOp->getLHS(); 9348 X = SecondBinOp->getLHS(); 9349 E = SecondBinOp->getRHS(); 9350 UE = nullptr; 9351 IsXLHSInRHSPart = false; 9352 IsPostfixUpdate = true; 9353 } else { 9354 ErrorFound = NotASpecificExpression; 9355 ErrorLoc = FirstBinOp->getExprLoc(); 9356 ErrorRange = FirstBinOp->getSourceRange(); 9357 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9358 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9359 } 9360 } 9361 } 9362 } 9363 } 9364 } else { 9365 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9366 NoteRange = ErrorRange = 9367 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9368 ErrorFound = NotTwoSubstatements; 9369 } 9370 } else { 9371 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9372 NoteRange = ErrorRange = 9373 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9374 ErrorFound = NotACompoundStatement; 9375 } 9376 if (ErrorFound != NoError) { 9377 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9378 << ErrorRange; 9379 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9380 return StmtError(); 9381 } 9382 if (CurContext->isDependentContext()) 9383 UE = V = E = X = nullptr; 9384 } 9385 } 9386 9387 setFunctionHasBranchProtectedScope(); 9388 9389 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9390 X, V, E, UE, IsXLHSInRHSPart, 9391 IsPostfixUpdate); 9392 } 9393 9394 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9395 Stmt *AStmt, 9396 SourceLocation StartLoc, 9397 SourceLocation EndLoc) { 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); 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 // OpenMP [2.16, Nesting of Regions] 9420 // If specified, a teams construct must be contained within a target 9421 // construct. That target construct must contain no statements or directives 9422 // outside of the teams construct. 9423 if (DSAStack->hasInnerTeamsRegion()) { 9424 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9425 bool OMPTeamsFound = true; 9426 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9427 auto I = CS->body_begin(); 9428 while (I != CS->body_end()) { 9429 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9430 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9431 OMPTeamsFound) { 9432 9433 OMPTeamsFound = false; 9434 break; 9435 } 9436 ++I; 9437 } 9438 assert(I != CS->body_end() && "Not found statement"); 9439 S = *I; 9440 } else { 9441 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9442 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9443 } 9444 if (!OMPTeamsFound) { 9445 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9446 Diag(DSAStack->getInnerTeamsRegionLoc(), 9447 diag::note_omp_nested_teams_construct_here); 9448 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9449 << isa<OMPExecutableDirective>(S); 9450 return StmtError(); 9451 } 9452 } 9453 9454 setFunctionHasBranchProtectedScope(); 9455 9456 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9457 } 9458 9459 StmtResult 9460 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9461 Stmt *AStmt, SourceLocation StartLoc, 9462 SourceLocation EndLoc) { 9463 if (!AStmt) 9464 return StmtError(); 9465 9466 auto *CS = cast<CapturedStmt>(AStmt); 9467 // 1.2.2 OpenMP Language Terminology 9468 // Structured block - An executable statement with a single entry at the 9469 // top and a single exit at the bottom. 9470 // The point of exit cannot be a branch out of the structured block. 9471 // longjmp() and throw() must not violate the entry/exit criteria. 9472 CS->getCapturedDecl()->setNothrow(); 9473 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9474 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9475 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9476 // 1.2.2 OpenMP Language Terminology 9477 // Structured block - An executable statement with a single entry at the 9478 // top and a single exit at the bottom. 9479 // The point of exit cannot be a branch out of the structured block. 9480 // longjmp() and throw() must not violate the entry/exit criteria. 9481 CS->getCapturedDecl()->setNothrow(); 9482 } 9483 9484 setFunctionHasBranchProtectedScope(); 9485 9486 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9487 AStmt); 9488 } 9489 9490 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9491 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9492 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9493 if (!AStmt) 9494 return StmtError(); 9495 9496 auto *CS = cast<CapturedStmt>(AStmt); 9497 // 1.2.2 OpenMP Language Terminology 9498 // Structured block - An executable statement with a single entry at the 9499 // top and a single exit at the bottom. 9500 // The point of exit cannot be a branch out of the structured block. 9501 // longjmp() and throw() must not violate the entry/exit criteria. 9502 CS->getCapturedDecl()->setNothrow(); 9503 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9504 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9505 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9506 // 1.2.2 OpenMP Language Terminology 9507 // Structured block - An executable statement with a single entry at the 9508 // top and a single exit at the bottom. 9509 // The point of exit cannot be a branch out of the structured block. 9510 // longjmp() and throw() must not violate the entry/exit criteria. 9511 CS->getCapturedDecl()->setNothrow(); 9512 } 9513 9514 OMPLoopDirective::HelperExprs B; 9515 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9516 // define the nested loops number. 9517 unsigned NestedLoopCount = 9518 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9519 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9520 VarsWithImplicitDSA, B); 9521 if (NestedLoopCount == 0) 9522 return StmtError(); 9523 9524 assert((CurContext->isDependentContext() || B.builtAll()) && 9525 "omp target parallel for loop exprs were not built"); 9526 9527 if (!CurContext->isDependentContext()) { 9528 // Finalize the clauses that need pre-built expressions for CodeGen. 9529 for (OMPClause *C : Clauses) { 9530 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9531 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9532 B.NumIterations, *this, CurScope, 9533 DSAStack)) 9534 return StmtError(); 9535 } 9536 } 9537 9538 setFunctionHasBranchProtectedScope(); 9539 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9540 NestedLoopCount, Clauses, AStmt, 9541 B, DSAStack->isCancelRegion()); 9542 } 9543 9544 /// Check for existence of a map clause in the list of clauses. 9545 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9546 const OpenMPClauseKind K) { 9547 return llvm::any_of( 9548 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9549 } 9550 9551 template <typename... Params> 9552 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9553 const Params... ClauseTypes) { 9554 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9555 } 9556 9557 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9558 Stmt *AStmt, 9559 SourceLocation StartLoc, 9560 SourceLocation EndLoc) { 9561 if (!AStmt) 9562 return StmtError(); 9563 9564 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9565 9566 // OpenMP [2.10.1, Restrictions, p. 97] 9567 // At least one map clause must appear on the directive. 9568 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9569 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9570 << "'map' or 'use_device_ptr'" 9571 << getOpenMPDirectiveName(OMPD_target_data); 9572 return StmtError(); 9573 } 9574 9575 setFunctionHasBranchProtectedScope(); 9576 9577 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9578 AStmt); 9579 } 9580 9581 StmtResult 9582 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9583 SourceLocation StartLoc, 9584 SourceLocation EndLoc, Stmt *AStmt) { 9585 if (!AStmt) 9586 return StmtError(); 9587 9588 auto *CS = cast<CapturedStmt>(AStmt); 9589 // 1.2.2 OpenMP Language Terminology 9590 // Structured block - An executable statement with a single entry at the 9591 // top and a single exit at the bottom. 9592 // The point of exit cannot be a branch out of the structured block. 9593 // longjmp() and throw() must not violate the entry/exit criteria. 9594 CS->getCapturedDecl()->setNothrow(); 9595 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9596 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9597 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9598 // 1.2.2 OpenMP Language Terminology 9599 // Structured block - An executable statement with a single entry at the 9600 // top and a single exit at the bottom. 9601 // The point of exit cannot be a branch out of the structured block. 9602 // longjmp() and throw() must not violate the entry/exit criteria. 9603 CS->getCapturedDecl()->setNothrow(); 9604 } 9605 9606 // OpenMP [2.10.2, Restrictions, p. 99] 9607 // At least one map clause must appear on the directive. 9608 if (!hasClauses(Clauses, OMPC_map)) { 9609 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9610 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9611 return StmtError(); 9612 } 9613 9614 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9615 AStmt); 9616 } 9617 9618 StmtResult 9619 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9620 SourceLocation StartLoc, 9621 SourceLocation EndLoc, Stmt *AStmt) { 9622 if (!AStmt) 9623 return StmtError(); 9624 9625 auto *CS = cast<CapturedStmt>(AStmt); 9626 // 1.2.2 OpenMP Language Terminology 9627 // Structured block - An executable statement with a single entry at the 9628 // top and a single exit at the bottom. 9629 // The point of exit cannot be a branch out of the structured block. 9630 // longjmp() and throw() must not violate the entry/exit criteria. 9631 CS->getCapturedDecl()->setNothrow(); 9632 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9633 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9634 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9635 // 1.2.2 OpenMP Language Terminology 9636 // Structured block - An executable statement with a single entry at the 9637 // top and a single exit at the bottom. 9638 // The point of exit cannot be a branch out of the structured block. 9639 // longjmp() and throw() must not violate the entry/exit criteria. 9640 CS->getCapturedDecl()->setNothrow(); 9641 } 9642 9643 // OpenMP [2.10.3, Restrictions, p. 102] 9644 // At least one map clause must appear on the directive. 9645 if (!hasClauses(Clauses, OMPC_map)) { 9646 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9647 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9648 return StmtError(); 9649 } 9650 9651 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9652 AStmt); 9653 } 9654 9655 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9656 SourceLocation StartLoc, 9657 SourceLocation EndLoc, 9658 Stmt *AStmt) { 9659 if (!AStmt) 9660 return StmtError(); 9661 9662 auto *CS = cast<CapturedStmt>(AStmt); 9663 // 1.2.2 OpenMP Language Terminology 9664 // Structured block - An executable statement with a single entry at the 9665 // top and a single exit at the bottom. 9666 // The point of exit cannot be a branch out of the structured block. 9667 // longjmp() and throw() must not violate the entry/exit criteria. 9668 CS->getCapturedDecl()->setNothrow(); 9669 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9670 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9671 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9672 // 1.2.2 OpenMP Language Terminology 9673 // Structured block - An executable statement with a single entry at the 9674 // top and a single exit at the bottom. 9675 // The point of exit cannot be a branch out of the structured block. 9676 // longjmp() and throw() must not violate the entry/exit criteria. 9677 CS->getCapturedDecl()->setNothrow(); 9678 } 9679 9680 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9681 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9682 return StmtError(); 9683 } 9684 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9685 AStmt); 9686 } 9687 9688 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9689 Stmt *AStmt, SourceLocation StartLoc, 9690 SourceLocation EndLoc) { 9691 if (!AStmt) 9692 return StmtError(); 9693 9694 auto *CS = cast<CapturedStmt>(AStmt); 9695 // 1.2.2 OpenMP Language Terminology 9696 // Structured block - An executable statement with a single entry at the 9697 // top and a single exit at the bottom. 9698 // The point of exit cannot be a branch out of the structured block. 9699 // longjmp() and throw() must not violate the entry/exit criteria. 9700 CS->getCapturedDecl()->setNothrow(); 9701 9702 setFunctionHasBranchProtectedScope(); 9703 9704 DSAStack->setParentTeamsRegionLoc(StartLoc); 9705 9706 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9707 } 9708 9709 StmtResult 9710 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9711 SourceLocation EndLoc, 9712 OpenMPDirectiveKind CancelRegion) { 9713 if (DSAStack->isParentNowaitRegion()) { 9714 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9715 return StmtError(); 9716 } 9717 if (DSAStack->isParentOrderedRegion()) { 9718 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9719 return StmtError(); 9720 } 9721 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9722 CancelRegion); 9723 } 9724 9725 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9726 SourceLocation StartLoc, 9727 SourceLocation EndLoc, 9728 OpenMPDirectiveKind CancelRegion) { 9729 if (DSAStack->isParentNowaitRegion()) { 9730 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9731 return StmtError(); 9732 } 9733 if (DSAStack->isParentOrderedRegion()) { 9734 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9735 return StmtError(); 9736 } 9737 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9738 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9739 CancelRegion); 9740 } 9741 9742 static bool checkGrainsizeNumTasksClauses(Sema &S, 9743 ArrayRef<OMPClause *> Clauses) { 9744 const OMPClause *PrevClause = nullptr; 9745 bool ErrorFound = false; 9746 for (const OMPClause *C : Clauses) { 9747 if (C->getClauseKind() == OMPC_grainsize || 9748 C->getClauseKind() == OMPC_num_tasks) { 9749 if (!PrevClause) 9750 PrevClause = C; 9751 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9752 S.Diag(C->getBeginLoc(), 9753 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9754 << getOpenMPClauseName(C->getClauseKind()) 9755 << getOpenMPClauseName(PrevClause->getClauseKind()); 9756 S.Diag(PrevClause->getBeginLoc(), 9757 diag::note_omp_previous_grainsize_num_tasks) 9758 << getOpenMPClauseName(PrevClause->getClauseKind()); 9759 ErrorFound = true; 9760 } 9761 } 9762 } 9763 return ErrorFound; 9764 } 9765 9766 static bool checkReductionClauseWithNogroup(Sema &S, 9767 ArrayRef<OMPClause *> Clauses) { 9768 const OMPClause *ReductionClause = nullptr; 9769 const OMPClause *NogroupClause = nullptr; 9770 for (const OMPClause *C : Clauses) { 9771 if (C->getClauseKind() == OMPC_reduction) { 9772 ReductionClause = C; 9773 if (NogroupClause) 9774 break; 9775 continue; 9776 } 9777 if (C->getClauseKind() == OMPC_nogroup) { 9778 NogroupClause = C; 9779 if (ReductionClause) 9780 break; 9781 continue; 9782 } 9783 } 9784 if (ReductionClause && NogroupClause) { 9785 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9786 << SourceRange(NogroupClause->getBeginLoc(), 9787 NogroupClause->getEndLoc()); 9788 return true; 9789 } 9790 return false; 9791 } 9792 9793 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9794 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9795 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9796 if (!AStmt) 9797 return StmtError(); 9798 9799 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9800 OMPLoopDirective::HelperExprs B; 9801 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9802 // define the nested loops number. 9803 unsigned NestedLoopCount = 9804 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9805 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9806 VarsWithImplicitDSA, B); 9807 if (NestedLoopCount == 0) 9808 return StmtError(); 9809 9810 assert((CurContext->isDependentContext() || B.builtAll()) && 9811 "omp for loop exprs were not built"); 9812 9813 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9814 // The grainsize clause and num_tasks clause are mutually exclusive and may 9815 // not appear on the same taskloop directive. 9816 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9817 return StmtError(); 9818 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9819 // If a reduction clause is present on the taskloop directive, the nogroup 9820 // clause must not be specified. 9821 if (checkReductionClauseWithNogroup(*this, Clauses)) 9822 return StmtError(); 9823 9824 setFunctionHasBranchProtectedScope(); 9825 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9826 NestedLoopCount, Clauses, AStmt, B, 9827 DSAStack->isCancelRegion()); 9828 } 9829 9830 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9831 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9832 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9833 if (!AStmt) 9834 return StmtError(); 9835 9836 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9837 OMPLoopDirective::HelperExprs B; 9838 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9839 // define the nested loops number. 9840 unsigned NestedLoopCount = 9841 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9842 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9843 VarsWithImplicitDSA, B); 9844 if (NestedLoopCount == 0) 9845 return StmtError(); 9846 9847 assert((CurContext->isDependentContext() || B.builtAll()) && 9848 "omp for loop exprs were not built"); 9849 9850 if (!CurContext->isDependentContext()) { 9851 // Finalize the clauses that need pre-built expressions for CodeGen. 9852 for (OMPClause *C : Clauses) { 9853 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9854 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9855 B.NumIterations, *this, CurScope, 9856 DSAStack)) 9857 return StmtError(); 9858 } 9859 } 9860 9861 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9862 // The grainsize clause and num_tasks clause are mutually exclusive and may 9863 // not appear on the same taskloop directive. 9864 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9865 return StmtError(); 9866 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9867 // If a reduction clause is present on the taskloop directive, the nogroup 9868 // clause must not be specified. 9869 if (checkReductionClauseWithNogroup(*this, Clauses)) 9870 return StmtError(); 9871 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9872 return StmtError(); 9873 9874 setFunctionHasBranchProtectedScope(); 9875 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9876 NestedLoopCount, Clauses, AStmt, B); 9877 } 9878 9879 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9880 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9881 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9882 if (!AStmt) 9883 return StmtError(); 9884 9885 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9886 OMPLoopDirective::HelperExprs B; 9887 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9888 // define the nested loops number. 9889 unsigned NestedLoopCount = 9890 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9891 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9892 VarsWithImplicitDSA, B); 9893 if (NestedLoopCount == 0) 9894 return StmtError(); 9895 9896 assert((CurContext->isDependentContext() || B.builtAll()) && 9897 "omp for loop exprs were not built"); 9898 9899 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9900 // The grainsize clause and num_tasks clause are mutually exclusive and may 9901 // not appear on the same taskloop directive. 9902 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9903 return StmtError(); 9904 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9905 // If a reduction clause is present on the taskloop directive, the nogroup 9906 // clause must not be specified. 9907 if (checkReductionClauseWithNogroup(*this, Clauses)) 9908 return StmtError(); 9909 9910 setFunctionHasBranchProtectedScope(); 9911 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9912 NestedLoopCount, Clauses, AStmt, B, 9913 DSAStack->isCancelRegion()); 9914 } 9915 9916 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9917 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9918 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9919 if (!AStmt) 9920 return StmtError(); 9921 9922 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9923 OMPLoopDirective::HelperExprs B; 9924 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9925 // define the nested loops number. 9926 unsigned NestedLoopCount = 9927 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9928 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9929 VarsWithImplicitDSA, B); 9930 if (NestedLoopCount == 0) 9931 return StmtError(); 9932 9933 assert((CurContext->isDependentContext() || B.builtAll()) && 9934 "omp for loop exprs were not built"); 9935 9936 if (!CurContext->isDependentContext()) { 9937 // Finalize the clauses that need pre-built expressions for CodeGen. 9938 for (OMPClause *C : Clauses) { 9939 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9940 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9941 B.NumIterations, *this, CurScope, 9942 DSAStack)) 9943 return StmtError(); 9944 } 9945 } 9946 9947 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9948 // The grainsize clause and num_tasks clause are mutually exclusive and may 9949 // not appear on the same taskloop directive. 9950 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9951 return StmtError(); 9952 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9953 // If a reduction clause is present on the taskloop directive, the nogroup 9954 // clause must not be specified. 9955 if (checkReductionClauseWithNogroup(*this, Clauses)) 9956 return StmtError(); 9957 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9958 return StmtError(); 9959 9960 setFunctionHasBranchProtectedScope(); 9961 return OMPMasterTaskLoopSimdDirective::Create( 9962 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9963 } 9964 9965 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9966 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9967 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9968 if (!AStmt) 9969 return StmtError(); 9970 9971 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9972 auto *CS = cast<CapturedStmt>(AStmt); 9973 // 1.2.2 OpenMP Language Terminology 9974 // Structured block - An executable statement with a single entry at the 9975 // top and a single exit at the bottom. 9976 // The point of exit cannot be a branch out of the structured block. 9977 // longjmp() and throw() must not violate the entry/exit criteria. 9978 CS->getCapturedDecl()->setNothrow(); 9979 for (int ThisCaptureLevel = 9980 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9981 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9982 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9983 // 1.2.2 OpenMP Language Terminology 9984 // Structured block - An executable statement with a single entry at the 9985 // top and a single exit at the bottom. 9986 // The point of exit cannot be a branch out of the structured block. 9987 // longjmp() and throw() must not violate the entry/exit criteria. 9988 CS->getCapturedDecl()->setNothrow(); 9989 } 9990 9991 OMPLoopDirective::HelperExprs B; 9992 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9993 // define the nested loops number. 9994 unsigned NestedLoopCount = checkOpenMPLoop( 9995 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9996 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9997 VarsWithImplicitDSA, B); 9998 if (NestedLoopCount == 0) 9999 return StmtError(); 10000 10001 assert((CurContext->isDependentContext() || B.builtAll()) && 10002 "omp for loop exprs were not built"); 10003 10004 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10005 // The grainsize clause and num_tasks clause are mutually exclusive and may 10006 // not appear on the same taskloop directive. 10007 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10008 return StmtError(); 10009 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10010 // If a reduction clause is present on the taskloop directive, the nogroup 10011 // clause must not be specified. 10012 if (checkReductionClauseWithNogroup(*this, Clauses)) 10013 return StmtError(); 10014 10015 setFunctionHasBranchProtectedScope(); 10016 return OMPParallelMasterTaskLoopDirective::Create( 10017 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10018 DSAStack->isCancelRegion()); 10019 } 10020 10021 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10022 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10023 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10024 if (!AStmt) 10025 return StmtError(); 10026 10027 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10028 auto *CS = cast<CapturedStmt>(AStmt); 10029 // 1.2.2 OpenMP Language Terminology 10030 // Structured block - An executable statement with a single entry at the 10031 // top and a single exit at the bottom. 10032 // The point of exit cannot be a branch out of the structured block. 10033 // longjmp() and throw() must not violate the entry/exit criteria. 10034 CS->getCapturedDecl()->setNothrow(); 10035 for (int ThisCaptureLevel = 10036 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10037 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10038 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10039 // 1.2.2 OpenMP Language Terminology 10040 // Structured block - An executable statement with a single entry at the 10041 // top and a single exit at the bottom. 10042 // The point of exit cannot be a branch out of the structured block. 10043 // longjmp() and throw() must not violate the entry/exit criteria. 10044 CS->getCapturedDecl()->setNothrow(); 10045 } 10046 10047 OMPLoopDirective::HelperExprs B; 10048 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10049 // define the nested loops number. 10050 unsigned NestedLoopCount = checkOpenMPLoop( 10051 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10052 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10053 VarsWithImplicitDSA, B); 10054 if (NestedLoopCount == 0) 10055 return StmtError(); 10056 10057 assert((CurContext->isDependentContext() || B.builtAll()) && 10058 "omp for loop exprs were not built"); 10059 10060 if (!CurContext->isDependentContext()) { 10061 // Finalize the clauses that need pre-built expressions for CodeGen. 10062 for (OMPClause *C : Clauses) { 10063 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10064 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10065 B.NumIterations, *this, CurScope, 10066 DSAStack)) 10067 return StmtError(); 10068 } 10069 } 10070 10071 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10072 // The grainsize clause and num_tasks clause are mutually exclusive and may 10073 // not appear on the same taskloop directive. 10074 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10075 return StmtError(); 10076 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10077 // If a reduction clause is present on the taskloop directive, the nogroup 10078 // clause must not be specified. 10079 if (checkReductionClauseWithNogroup(*this, Clauses)) 10080 return StmtError(); 10081 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10082 return StmtError(); 10083 10084 setFunctionHasBranchProtectedScope(); 10085 return OMPParallelMasterTaskLoopSimdDirective::Create( 10086 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10087 } 10088 10089 StmtResult Sema::ActOnOpenMPDistributeDirective( 10090 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10091 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10092 if (!AStmt) 10093 return StmtError(); 10094 10095 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10096 OMPLoopDirective::HelperExprs B; 10097 // In presence of clause 'collapse' with number of loops, it will 10098 // define the nested loops number. 10099 unsigned NestedLoopCount = 10100 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10101 nullptr /*ordered not a clause on distribute*/, AStmt, 10102 *this, *DSAStack, VarsWithImplicitDSA, B); 10103 if (NestedLoopCount == 0) 10104 return StmtError(); 10105 10106 assert((CurContext->isDependentContext() || B.builtAll()) && 10107 "omp for loop exprs were not built"); 10108 10109 setFunctionHasBranchProtectedScope(); 10110 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10111 NestedLoopCount, Clauses, AStmt, B); 10112 } 10113 10114 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10115 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10116 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10117 if (!AStmt) 10118 return StmtError(); 10119 10120 auto *CS = cast<CapturedStmt>(AStmt); 10121 // 1.2.2 OpenMP Language Terminology 10122 // Structured block - An executable statement with a single entry at the 10123 // top and a single exit at the bottom. 10124 // The point of exit cannot be a branch out of the structured block. 10125 // longjmp() and throw() must not violate the entry/exit criteria. 10126 CS->getCapturedDecl()->setNothrow(); 10127 for (int ThisCaptureLevel = 10128 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10129 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10130 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10131 // 1.2.2 OpenMP Language Terminology 10132 // Structured block - An executable statement with a single entry at the 10133 // top and a single exit at the bottom. 10134 // The point of exit cannot be a branch out of the structured block. 10135 // longjmp() and throw() must not violate the entry/exit criteria. 10136 CS->getCapturedDecl()->setNothrow(); 10137 } 10138 10139 OMPLoopDirective::HelperExprs B; 10140 // In presence of clause 'collapse' with number of loops, it will 10141 // define the nested loops number. 10142 unsigned NestedLoopCount = checkOpenMPLoop( 10143 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10144 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10145 VarsWithImplicitDSA, B); 10146 if (NestedLoopCount == 0) 10147 return StmtError(); 10148 10149 assert((CurContext->isDependentContext() || B.builtAll()) && 10150 "omp for loop exprs were not built"); 10151 10152 setFunctionHasBranchProtectedScope(); 10153 return OMPDistributeParallelForDirective::Create( 10154 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10155 DSAStack->isCancelRegion()); 10156 } 10157 10158 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10159 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10160 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10161 if (!AStmt) 10162 return StmtError(); 10163 10164 auto *CS = cast<CapturedStmt>(AStmt); 10165 // 1.2.2 OpenMP Language Terminology 10166 // Structured block - An executable statement with a single entry at the 10167 // top and a single exit at the bottom. 10168 // The point of exit cannot be a branch out of the structured block. 10169 // longjmp() and throw() must not violate the entry/exit criteria. 10170 CS->getCapturedDecl()->setNothrow(); 10171 for (int ThisCaptureLevel = 10172 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10173 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10174 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10175 // 1.2.2 OpenMP Language Terminology 10176 // Structured block - An executable statement with a single entry at the 10177 // top and a single exit at the bottom. 10178 // The point of exit cannot be a branch out of the structured block. 10179 // longjmp() and throw() must not violate the entry/exit criteria. 10180 CS->getCapturedDecl()->setNothrow(); 10181 } 10182 10183 OMPLoopDirective::HelperExprs B; 10184 // In presence of clause 'collapse' with number of loops, it will 10185 // define the nested loops number. 10186 unsigned NestedLoopCount = checkOpenMPLoop( 10187 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10188 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10189 VarsWithImplicitDSA, B); 10190 if (NestedLoopCount == 0) 10191 return StmtError(); 10192 10193 assert((CurContext->isDependentContext() || B.builtAll()) && 10194 "omp for loop exprs were not built"); 10195 10196 if (!CurContext->isDependentContext()) { 10197 // Finalize the clauses that need pre-built expressions for CodeGen. 10198 for (OMPClause *C : Clauses) { 10199 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10200 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10201 B.NumIterations, *this, CurScope, 10202 DSAStack)) 10203 return StmtError(); 10204 } 10205 } 10206 10207 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10208 return StmtError(); 10209 10210 setFunctionHasBranchProtectedScope(); 10211 return OMPDistributeParallelForSimdDirective::Create( 10212 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10213 } 10214 10215 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10216 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10217 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10218 if (!AStmt) 10219 return StmtError(); 10220 10221 auto *CS = cast<CapturedStmt>(AStmt); 10222 // 1.2.2 OpenMP Language Terminology 10223 // Structured block - An executable statement with a single entry at the 10224 // top and a single exit at the bottom. 10225 // The point of exit cannot be a branch out of the structured block. 10226 // longjmp() and throw() must not violate the entry/exit criteria. 10227 CS->getCapturedDecl()->setNothrow(); 10228 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10229 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10230 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10231 // 1.2.2 OpenMP Language Terminology 10232 // Structured block - An executable statement with a single entry at the 10233 // top and a single exit at the bottom. 10234 // The point of exit cannot be a branch out of the structured block. 10235 // longjmp() and throw() must not violate the entry/exit criteria. 10236 CS->getCapturedDecl()->setNothrow(); 10237 } 10238 10239 OMPLoopDirective::HelperExprs B; 10240 // In presence of clause 'collapse' with number of loops, it will 10241 // define the nested loops number. 10242 unsigned NestedLoopCount = 10243 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10244 nullptr /*ordered not a clause on distribute*/, CS, *this, 10245 *DSAStack, VarsWithImplicitDSA, B); 10246 if (NestedLoopCount == 0) 10247 return StmtError(); 10248 10249 assert((CurContext->isDependentContext() || B.builtAll()) && 10250 "omp for loop exprs were not built"); 10251 10252 if (!CurContext->isDependentContext()) { 10253 // Finalize the clauses that need pre-built expressions for CodeGen. 10254 for (OMPClause *C : Clauses) { 10255 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10256 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10257 B.NumIterations, *this, CurScope, 10258 DSAStack)) 10259 return StmtError(); 10260 } 10261 } 10262 10263 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10264 return StmtError(); 10265 10266 setFunctionHasBranchProtectedScope(); 10267 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10268 NestedLoopCount, Clauses, AStmt, B); 10269 } 10270 10271 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10272 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10273 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10274 if (!AStmt) 10275 return StmtError(); 10276 10277 auto *CS = cast<CapturedStmt>(AStmt); 10278 // 1.2.2 OpenMP Language Terminology 10279 // Structured block - An executable statement with a single entry at the 10280 // top and a single exit at the bottom. 10281 // The point of exit cannot be a branch out of the structured block. 10282 // longjmp() and throw() must not violate the entry/exit criteria. 10283 CS->getCapturedDecl()->setNothrow(); 10284 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10285 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10286 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10287 // 1.2.2 OpenMP Language Terminology 10288 // Structured block - An executable statement with a single entry at the 10289 // top and a single exit at the bottom. 10290 // The point of exit cannot be a branch out of the structured block. 10291 // longjmp() and throw() must not violate the entry/exit criteria. 10292 CS->getCapturedDecl()->setNothrow(); 10293 } 10294 10295 OMPLoopDirective::HelperExprs B; 10296 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10297 // define the nested loops number. 10298 unsigned NestedLoopCount = checkOpenMPLoop( 10299 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10300 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10301 VarsWithImplicitDSA, B); 10302 if (NestedLoopCount == 0) 10303 return StmtError(); 10304 10305 assert((CurContext->isDependentContext() || B.builtAll()) && 10306 "omp target parallel for simd loop exprs were not built"); 10307 10308 if (!CurContext->isDependentContext()) { 10309 // Finalize the clauses that need pre-built expressions for CodeGen. 10310 for (OMPClause *C : Clauses) { 10311 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10312 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10313 B.NumIterations, *this, CurScope, 10314 DSAStack)) 10315 return StmtError(); 10316 } 10317 } 10318 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10319 return StmtError(); 10320 10321 setFunctionHasBranchProtectedScope(); 10322 return OMPTargetParallelForSimdDirective::Create( 10323 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10324 } 10325 10326 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10327 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10328 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10329 if (!AStmt) 10330 return StmtError(); 10331 10332 auto *CS = cast<CapturedStmt>(AStmt); 10333 // 1.2.2 OpenMP Language Terminology 10334 // Structured block - An executable statement with a single entry at the 10335 // top and a single exit at the bottom. 10336 // The point of exit cannot be a branch out of the structured block. 10337 // longjmp() and throw() must not violate the entry/exit criteria. 10338 CS->getCapturedDecl()->setNothrow(); 10339 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10340 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10341 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10342 // 1.2.2 OpenMP Language Terminology 10343 // Structured block - An executable statement with a single entry at the 10344 // top and a single exit at the bottom. 10345 // The point of exit cannot be a branch out of the structured block. 10346 // longjmp() and throw() must not violate the entry/exit criteria. 10347 CS->getCapturedDecl()->setNothrow(); 10348 } 10349 10350 OMPLoopDirective::HelperExprs B; 10351 // In presence of clause 'collapse' with number of loops, it will define the 10352 // nested loops number. 10353 unsigned NestedLoopCount = 10354 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10355 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10356 VarsWithImplicitDSA, B); 10357 if (NestedLoopCount == 0) 10358 return StmtError(); 10359 10360 assert((CurContext->isDependentContext() || B.builtAll()) && 10361 "omp target simd loop exprs were not built"); 10362 10363 if (!CurContext->isDependentContext()) { 10364 // Finalize the clauses that need pre-built expressions for CodeGen. 10365 for (OMPClause *C : Clauses) { 10366 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10367 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10368 B.NumIterations, *this, CurScope, 10369 DSAStack)) 10370 return StmtError(); 10371 } 10372 } 10373 10374 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10375 return StmtError(); 10376 10377 setFunctionHasBranchProtectedScope(); 10378 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10379 NestedLoopCount, Clauses, AStmt, B); 10380 } 10381 10382 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10383 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10384 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10385 if (!AStmt) 10386 return StmtError(); 10387 10388 auto *CS = cast<CapturedStmt>(AStmt); 10389 // 1.2.2 OpenMP Language Terminology 10390 // Structured block - An executable statement with a single entry at the 10391 // top and a single exit at the bottom. 10392 // The point of exit cannot be a branch out of the structured block. 10393 // longjmp() and throw() must not violate the entry/exit criteria. 10394 CS->getCapturedDecl()->setNothrow(); 10395 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10396 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10397 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10398 // 1.2.2 OpenMP Language Terminology 10399 // Structured block - An executable statement with a single entry at the 10400 // top and a single exit at the bottom. 10401 // The point of exit cannot be a branch out of the structured block. 10402 // longjmp() and throw() must not violate the entry/exit criteria. 10403 CS->getCapturedDecl()->setNothrow(); 10404 } 10405 10406 OMPLoopDirective::HelperExprs B; 10407 // In presence of clause 'collapse' with number of loops, it will 10408 // define the nested loops number. 10409 unsigned NestedLoopCount = 10410 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10411 nullptr /*ordered not a clause on distribute*/, CS, *this, 10412 *DSAStack, VarsWithImplicitDSA, B); 10413 if (NestedLoopCount == 0) 10414 return StmtError(); 10415 10416 assert((CurContext->isDependentContext() || B.builtAll()) && 10417 "omp teams distribute loop exprs were not built"); 10418 10419 setFunctionHasBranchProtectedScope(); 10420 10421 DSAStack->setParentTeamsRegionLoc(StartLoc); 10422 10423 return OMPTeamsDistributeDirective::Create( 10424 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10425 } 10426 10427 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10428 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10429 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10430 if (!AStmt) 10431 return StmtError(); 10432 10433 auto *CS = cast<CapturedStmt>(AStmt); 10434 // 1.2.2 OpenMP Language Terminology 10435 // Structured block - An executable statement with a single entry at the 10436 // top and a single exit at the bottom. 10437 // The point of exit cannot be a branch out of the structured block. 10438 // longjmp() and throw() must not violate the entry/exit criteria. 10439 CS->getCapturedDecl()->setNothrow(); 10440 for (int ThisCaptureLevel = 10441 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10442 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10443 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10444 // 1.2.2 OpenMP Language Terminology 10445 // Structured block - An executable statement with a single entry at the 10446 // top and a single exit at the bottom. 10447 // The point of exit cannot be a branch out of the structured block. 10448 // longjmp() and throw() must not violate the entry/exit criteria. 10449 CS->getCapturedDecl()->setNothrow(); 10450 } 10451 10452 OMPLoopDirective::HelperExprs B; 10453 // In presence of clause 'collapse' with number of loops, it will 10454 // define the nested loops number. 10455 unsigned NestedLoopCount = checkOpenMPLoop( 10456 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10457 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10458 VarsWithImplicitDSA, B); 10459 10460 if (NestedLoopCount == 0) 10461 return StmtError(); 10462 10463 assert((CurContext->isDependentContext() || B.builtAll()) && 10464 "omp teams distribute simd loop exprs were not built"); 10465 10466 if (!CurContext->isDependentContext()) { 10467 // Finalize the clauses that need pre-built expressions for CodeGen. 10468 for (OMPClause *C : Clauses) { 10469 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10470 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10471 B.NumIterations, *this, CurScope, 10472 DSAStack)) 10473 return StmtError(); 10474 } 10475 } 10476 10477 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10478 return StmtError(); 10479 10480 setFunctionHasBranchProtectedScope(); 10481 10482 DSAStack->setParentTeamsRegionLoc(StartLoc); 10483 10484 return OMPTeamsDistributeSimdDirective::Create( 10485 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10486 } 10487 10488 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10489 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10490 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10491 if (!AStmt) 10492 return StmtError(); 10493 10494 auto *CS = cast<CapturedStmt>(AStmt); 10495 // 1.2.2 OpenMP Language Terminology 10496 // Structured block - An executable statement with a single entry at the 10497 // top and a single exit at the bottom. 10498 // The point of exit cannot be a branch out of the structured block. 10499 // longjmp() and throw() must not violate the entry/exit criteria. 10500 CS->getCapturedDecl()->setNothrow(); 10501 10502 for (int ThisCaptureLevel = 10503 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10504 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10505 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10506 // 1.2.2 OpenMP Language Terminology 10507 // Structured block - An executable statement with a single entry at the 10508 // top and a single exit at the bottom. 10509 // The point of exit cannot be a branch out of the structured block. 10510 // longjmp() and throw() must not violate the entry/exit criteria. 10511 CS->getCapturedDecl()->setNothrow(); 10512 } 10513 10514 OMPLoopDirective::HelperExprs B; 10515 // In presence of clause 'collapse' with number of loops, it will 10516 // define the nested loops number. 10517 unsigned NestedLoopCount = checkOpenMPLoop( 10518 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10519 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10520 VarsWithImplicitDSA, B); 10521 10522 if (NestedLoopCount == 0) 10523 return StmtError(); 10524 10525 assert((CurContext->isDependentContext() || B.builtAll()) && 10526 "omp for loop exprs were not built"); 10527 10528 if (!CurContext->isDependentContext()) { 10529 // Finalize the clauses that need pre-built expressions for CodeGen. 10530 for (OMPClause *C : Clauses) { 10531 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10532 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10533 B.NumIterations, *this, CurScope, 10534 DSAStack)) 10535 return StmtError(); 10536 } 10537 } 10538 10539 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10540 return StmtError(); 10541 10542 setFunctionHasBranchProtectedScope(); 10543 10544 DSAStack->setParentTeamsRegionLoc(StartLoc); 10545 10546 return OMPTeamsDistributeParallelForSimdDirective::Create( 10547 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10548 } 10549 10550 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10551 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10552 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10553 if (!AStmt) 10554 return StmtError(); 10555 10556 auto *CS = cast<CapturedStmt>(AStmt); 10557 // 1.2.2 OpenMP Language Terminology 10558 // Structured block - An executable statement with a single entry at the 10559 // top and a single exit at the bottom. 10560 // The point of exit cannot be a branch out of the structured block. 10561 // longjmp() and throw() must not violate the entry/exit criteria. 10562 CS->getCapturedDecl()->setNothrow(); 10563 10564 for (int ThisCaptureLevel = 10565 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10566 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10567 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10568 // 1.2.2 OpenMP Language Terminology 10569 // Structured block - An executable statement with a single entry at the 10570 // top and a single exit at the bottom. 10571 // The point of exit cannot be a branch out of the structured block. 10572 // longjmp() and throw() must not violate the entry/exit criteria. 10573 CS->getCapturedDecl()->setNothrow(); 10574 } 10575 10576 OMPLoopDirective::HelperExprs B; 10577 // In presence of clause 'collapse' with number of loops, it will 10578 // define the nested loops number. 10579 unsigned NestedLoopCount = checkOpenMPLoop( 10580 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10581 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10582 VarsWithImplicitDSA, B); 10583 10584 if (NestedLoopCount == 0) 10585 return StmtError(); 10586 10587 assert((CurContext->isDependentContext() || B.builtAll()) && 10588 "omp for loop exprs were not built"); 10589 10590 setFunctionHasBranchProtectedScope(); 10591 10592 DSAStack->setParentTeamsRegionLoc(StartLoc); 10593 10594 return OMPTeamsDistributeParallelForDirective::Create( 10595 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10596 DSAStack->isCancelRegion()); 10597 } 10598 10599 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10600 Stmt *AStmt, 10601 SourceLocation StartLoc, 10602 SourceLocation EndLoc) { 10603 if (!AStmt) 10604 return StmtError(); 10605 10606 auto *CS = cast<CapturedStmt>(AStmt); 10607 // 1.2.2 OpenMP Language Terminology 10608 // Structured block - An executable statement with a single entry at the 10609 // top and a single exit at the bottom. 10610 // The point of exit cannot be a branch out of the structured block. 10611 // longjmp() and throw() must not violate the entry/exit criteria. 10612 CS->getCapturedDecl()->setNothrow(); 10613 10614 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10615 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10616 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10617 // 1.2.2 OpenMP Language Terminology 10618 // Structured block - An executable statement with a single entry at the 10619 // top and a single exit at the bottom. 10620 // The point of exit cannot be a branch out of the structured block. 10621 // longjmp() and throw() must not violate the entry/exit criteria. 10622 CS->getCapturedDecl()->setNothrow(); 10623 } 10624 setFunctionHasBranchProtectedScope(); 10625 10626 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10627 AStmt); 10628 } 10629 10630 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10631 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10632 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10633 if (!AStmt) 10634 return StmtError(); 10635 10636 auto *CS = cast<CapturedStmt>(AStmt); 10637 // 1.2.2 OpenMP Language Terminology 10638 // Structured block - An executable statement with a single entry at the 10639 // top and a single exit at the bottom. 10640 // The point of exit cannot be a branch out of the structured block. 10641 // longjmp() and throw() must not violate the entry/exit criteria. 10642 CS->getCapturedDecl()->setNothrow(); 10643 for (int ThisCaptureLevel = 10644 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10645 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10646 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10647 // 1.2.2 OpenMP Language Terminology 10648 // Structured block - An executable statement with a single entry at the 10649 // top and a single exit at the bottom. 10650 // The point of exit cannot be a branch out of the structured block. 10651 // longjmp() and throw() must not violate the entry/exit criteria. 10652 CS->getCapturedDecl()->setNothrow(); 10653 } 10654 10655 OMPLoopDirective::HelperExprs B; 10656 // In presence of clause 'collapse' with number of loops, it will 10657 // define the nested loops number. 10658 unsigned NestedLoopCount = checkOpenMPLoop( 10659 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10660 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10661 VarsWithImplicitDSA, B); 10662 if (NestedLoopCount == 0) 10663 return StmtError(); 10664 10665 assert((CurContext->isDependentContext() || B.builtAll()) && 10666 "omp target teams distribute loop exprs were not built"); 10667 10668 setFunctionHasBranchProtectedScope(); 10669 return OMPTargetTeamsDistributeDirective::Create( 10670 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10671 } 10672 10673 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10674 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10675 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10676 if (!AStmt) 10677 return StmtError(); 10678 10679 auto *CS = cast<CapturedStmt>(AStmt); 10680 // 1.2.2 OpenMP Language Terminology 10681 // Structured block - An executable statement with a single entry at the 10682 // top and a single exit at the bottom. 10683 // The point of exit cannot be a branch out of the structured block. 10684 // longjmp() and throw() must not violate the entry/exit criteria. 10685 CS->getCapturedDecl()->setNothrow(); 10686 for (int ThisCaptureLevel = 10687 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10688 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10689 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10690 // 1.2.2 OpenMP Language Terminology 10691 // Structured block - An executable statement with a single entry at the 10692 // top and a single exit at the bottom. 10693 // The point of exit cannot be a branch out of the structured block. 10694 // longjmp() and throw() must not violate the entry/exit criteria. 10695 CS->getCapturedDecl()->setNothrow(); 10696 } 10697 10698 OMPLoopDirective::HelperExprs B; 10699 // In presence of clause 'collapse' with number of loops, it will 10700 // define the nested loops number. 10701 unsigned NestedLoopCount = checkOpenMPLoop( 10702 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10703 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10704 VarsWithImplicitDSA, B); 10705 if (NestedLoopCount == 0) 10706 return StmtError(); 10707 10708 assert((CurContext->isDependentContext() || B.builtAll()) && 10709 "omp target teams distribute parallel for loop exprs were not built"); 10710 10711 if (!CurContext->isDependentContext()) { 10712 // Finalize the clauses that need pre-built expressions for CodeGen. 10713 for (OMPClause *C : Clauses) { 10714 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10715 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10716 B.NumIterations, *this, CurScope, 10717 DSAStack)) 10718 return StmtError(); 10719 } 10720 } 10721 10722 setFunctionHasBranchProtectedScope(); 10723 return OMPTargetTeamsDistributeParallelForDirective::Create( 10724 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10725 DSAStack->isCancelRegion()); 10726 } 10727 10728 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10729 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10730 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10731 if (!AStmt) 10732 return StmtError(); 10733 10734 auto *CS = cast<CapturedStmt>(AStmt); 10735 // 1.2.2 OpenMP Language Terminology 10736 // Structured block - An executable statement with a single entry at the 10737 // top and a single exit at the bottom. 10738 // The point of exit cannot be a branch out of the structured block. 10739 // longjmp() and throw() must not violate the entry/exit criteria. 10740 CS->getCapturedDecl()->setNothrow(); 10741 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10742 OMPD_target_teams_distribute_parallel_for_simd); 10743 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10744 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10745 // 1.2.2 OpenMP Language Terminology 10746 // Structured block - An executable statement with a single entry at the 10747 // top and a single exit at the bottom. 10748 // The point of exit cannot be a branch out of the structured block. 10749 // longjmp() and throw() must not violate the entry/exit criteria. 10750 CS->getCapturedDecl()->setNothrow(); 10751 } 10752 10753 OMPLoopDirective::HelperExprs B; 10754 // In presence of clause 'collapse' with number of loops, it will 10755 // define the nested loops number. 10756 unsigned NestedLoopCount = 10757 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10758 getCollapseNumberExpr(Clauses), 10759 nullptr /*ordered not a clause on distribute*/, CS, *this, 10760 *DSAStack, VarsWithImplicitDSA, B); 10761 if (NestedLoopCount == 0) 10762 return StmtError(); 10763 10764 assert((CurContext->isDependentContext() || B.builtAll()) && 10765 "omp target teams distribute parallel for simd loop exprs were not " 10766 "built"); 10767 10768 if (!CurContext->isDependentContext()) { 10769 // Finalize the clauses that need pre-built expressions for CodeGen. 10770 for (OMPClause *C : Clauses) { 10771 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10772 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10773 B.NumIterations, *this, CurScope, 10774 DSAStack)) 10775 return StmtError(); 10776 } 10777 } 10778 10779 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10780 return StmtError(); 10781 10782 setFunctionHasBranchProtectedScope(); 10783 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10784 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10785 } 10786 10787 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10788 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10789 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10790 if (!AStmt) 10791 return StmtError(); 10792 10793 auto *CS = cast<CapturedStmt>(AStmt); 10794 // 1.2.2 OpenMP Language Terminology 10795 // Structured block - An executable statement with a single entry at the 10796 // top and a single exit at the bottom. 10797 // The point of exit cannot be a branch out of the structured block. 10798 // longjmp() and throw() must not violate the entry/exit criteria. 10799 CS->getCapturedDecl()->setNothrow(); 10800 for (int ThisCaptureLevel = 10801 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10802 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10803 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10804 // 1.2.2 OpenMP Language Terminology 10805 // Structured block - An executable statement with a single entry at the 10806 // top and a single exit at the bottom. 10807 // The point of exit cannot be a branch out of the structured block. 10808 // longjmp() and throw() must not violate the entry/exit criteria. 10809 CS->getCapturedDecl()->setNothrow(); 10810 } 10811 10812 OMPLoopDirective::HelperExprs B; 10813 // In presence of clause 'collapse' with number of loops, it will 10814 // define the nested loops number. 10815 unsigned NestedLoopCount = checkOpenMPLoop( 10816 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10817 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10818 VarsWithImplicitDSA, B); 10819 if (NestedLoopCount == 0) 10820 return StmtError(); 10821 10822 assert((CurContext->isDependentContext() || B.builtAll()) && 10823 "omp target teams distribute simd loop exprs were not built"); 10824 10825 if (!CurContext->isDependentContext()) { 10826 // Finalize the clauses that need pre-built expressions for CodeGen. 10827 for (OMPClause *C : Clauses) { 10828 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10829 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10830 B.NumIterations, *this, CurScope, 10831 DSAStack)) 10832 return StmtError(); 10833 } 10834 } 10835 10836 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10837 return StmtError(); 10838 10839 setFunctionHasBranchProtectedScope(); 10840 return OMPTargetTeamsDistributeSimdDirective::Create( 10841 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10842 } 10843 10844 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10845 SourceLocation StartLoc, 10846 SourceLocation LParenLoc, 10847 SourceLocation EndLoc) { 10848 OMPClause *Res = nullptr; 10849 switch (Kind) { 10850 case OMPC_final: 10851 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10852 break; 10853 case OMPC_num_threads: 10854 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10855 break; 10856 case OMPC_safelen: 10857 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10858 break; 10859 case OMPC_simdlen: 10860 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10861 break; 10862 case OMPC_allocator: 10863 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10864 break; 10865 case OMPC_collapse: 10866 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10867 break; 10868 case OMPC_ordered: 10869 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10870 break; 10871 case OMPC_device: 10872 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10873 break; 10874 case OMPC_num_teams: 10875 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10876 break; 10877 case OMPC_thread_limit: 10878 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10879 break; 10880 case OMPC_priority: 10881 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10882 break; 10883 case OMPC_grainsize: 10884 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10885 break; 10886 case OMPC_num_tasks: 10887 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10888 break; 10889 case OMPC_hint: 10890 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10891 break; 10892 case OMPC_if: 10893 case OMPC_default: 10894 case OMPC_proc_bind: 10895 case OMPC_schedule: 10896 case OMPC_private: 10897 case OMPC_firstprivate: 10898 case OMPC_lastprivate: 10899 case OMPC_shared: 10900 case OMPC_reduction: 10901 case OMPC_task_reduction: 10902 case OMPC_in_reduction: 10903 case OMPC_linear: 10904 case OMPC_aligned: 10905 case OMPC_copyin: 10906 case OMPC_copyprivate: 10907 case OMPC_nowait: 10908 case OMPC_untied: 10909 case OMPC_mergeable: 10910 case OMPC_threadprivate: 10911 case OMPC_allocate: 10912 case OMPC_flush: 10913 case OMPC_read: 10914 case OMPC_write: 10915 case OMPC_update: 10916 case OMPC_capture: 10917 case OMPC_seq_cst: 10918 case OMPC_acq_rel: 10919 case OMPC_acquire: 10920 case OMPC_release: 10921 case OMPC_relaxed: 10922 case OMPC_depend: 10923 case OMPC_threads: 10924 case OMPC_simd: 10925 case OMPC_map: 10926 case OMPC_nogroup: 10927 case OMPC_dist_schedule: 10928 case OMPC_defaultmap: 10929 case OMPC_unknown: 10930 case OMPC_uniform: 10931 case OMPC_to: 10932 case OMPC_from: 10933 case OMPC_use_device_ptr: 10934 case OMPC_is_device_ptr: 10935 case OMPC_unified_address: 10936 case OMPC_unified_shared_memory: 10937 case OMPC_reverse_offload: 10938 case OMPC_dynamic_allocators: 10939 case OMPC_atomic_default_mem_order: 10940 case OMPC_device_type: 10941 case OMPC_match: 10942 case OMPC_nontemporal: 10943 case OMPC_order: 10944 llvm_unreachable("Clause is not allowed."); 10945 } 10946 return Res; 10947 } 10948 10949 // An OpenMP directive such as 'target parallel' has two captured regions: 10950 // for the 'target' and 'parallel' respectively. This function returns 10951 // the region in which to capture expressions associated with a clause. 10952 // A return value of OMPD_unknown signifies that the expression should not 10953 // be captured. 10954 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10955 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 10956 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10957 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10958 switch (CKind) { 10959 case OMPC_if: 10960 switch (DKind) { 10961 case OMPD_target_parallel_for_simd: 10962 if (OpenMPVersion >= 50 && 10963 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10964 CaptureRegion = OMPD_parallel; 10965 break; 10966 } 10967 LLVM_FALLTHROUGH; 10968 case OMPD_target_parallel: 10969 case OMPD_target_parallel_for: 10970 // If this clause applies to the nested 'parallel' region, capture within 10971 // the 'target' region, otherwise do not capture. 10972 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10973 CaptureRegion = OMPD_target; 10974 break; 10975 case OMPD_target_teams_distribute_parallel_for_simd: 10976 if (OpenMPVersion >= 50 && 10977 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10978 CaptureRegion = OMPD_parallel; 10979 break; 10980 } 10981 LLVM_FALLTHROUGH; 10982 case OMPD_target_teams_distribute_parallel_for: 10983 // If this clause applies to the nested 'parallel' region, capture within 10984 // the 'teams' region, otherwise do not capture. 10985 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10986 CaptureRegion = OMPD_teams; 10987 break; 10988 case OMPD_teams_distribute_parallel_for_simd: 10989 if (OpenMPVersion >= 50 && 10990 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10991 CaptureRegion = OMPD_parallel; 10992 break; 10993 } 10994 LLVM_FALLTHROUGH; 10995 case OMPD_teams_distribute_parallel_for: 10996 CaptureRegion = OMPD_teams; 10997 break; 10998 case OMPD_target_update: 10999 case OMPD_target_enter_data: 11000 case OMPD_target_exit_data: 11001 CaptureRegion = OMPD_task; 11002 break; 11003 case OMPD_parallel_master_taskloop: 11004 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11005 CaptureRegion = OMPD_parallel; 11006 break; 11007 case OMPD_parallel_master_taskloop_simd: 11008 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11009 NameModifier == OMPD_taskloop) { 11010 CaptureRegion = OMPD_parallel; 11011 break; 11012 } 11013 if (OpenMPVersion <= 45) 11014 break; 11015 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11016 CaptureRegion = OMPD_taskloop; 11017 break; 11018 case OMPD_parallel_for_simd: 11019 if (OpenMPVersion <= 45) 11020 break; 11021 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11022 CaptureRegion = OMPD_parallel; 11023 break; 11024 case OMPD_taskloop_simd: 11025 case OMPD_master_taskloop_simd: 11026 if (OpenMPVersion <= 45) 11027 break; 11028 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11029 CaptureRegion = OMPD_taskloop; 11030 break; 11031 case OMPD_distribute_parallel_for_simd: 11032 if (OpenMPVersion <= 45) 11033 break; 11034 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11035 CaptureRegion = OMPD_parallel; 11036 break; 11037 case OMPD_target_simd: 11038 if (OpenMPVersion >= 50 && 11039 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11040 CaptureRegion = OMPD_target; 11041 break; 11042 case OMPD_teams_distribute_simd: 11043 case OMPD_target_teams_distribute_simd: 11044 if (OpenMPVersion >= 50 && 11045 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11046 CaptureRegion = OMPD_teams; 11047 break; 11048 case OMPD_cancel: 11049 case OMPD_parallel: 11050 case OMPD_parallel_master: 11051 case OMPD_parallel_sections: 11052 case OMPD_parallel_for: 11053 case OMPD_target: 11054 case OMPD_target_teams: 11055 case OMPD_target_teams_distribute: 11056 case OMPD_distribute_parallel_for: 11057 case OMPD_task: 11058 case OMPD_taskloop: 11059 case OMPD_master_taskloop: 11060 case OMPD_target_data: 11061 case OMPD_simd: 11062 case OMPD_for_simd: 11063 case OMPD_distribute_simd: 11064 // Do not capture if-clause expressions. 11065 break; 11066 case OMPD_threadprivate: 11067 case OMPD_allocate: 11068 case OMPD_taskyield: 11069 case OMPD_barrier: 11070 case OMPD_taskwait: 11071 case OMPD_cancellation_point: 11072 case OMPD_flush: 11073 case OMPD_declare_reduction: 11074 case OMPD_declare_mapper: 11075 case OMPD_declare_simd: 11076 case OMPD_declare_variant: 11077 case OMPD_declare_target: 11078 case OMPD_end_declare_target: 11079 case OMPD_teams: 11080 case OMPD_for: 11081 case OMPD_sections: 11082 case OMPD_section: 11083 case OMPD_single: 11084 case OMPD_master: 11085 case OMPD_critical: 11086 case OMPD_taskgroup: 11087 case OMPD_distribute: 11088 case OMPD_ordered: 11089 case OMPD_atomic: 11090 case OMPD_teams_distribute: 11091 case OMPD_requires: 11092 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11093 case OMPD_unknown: 11094 llvm_unreachable("Unknown OpenMP directive"); 11095 } 11096 break; 11097 case OMPC_num_threads: 11098 switch (DKind) { 11099 case OMPD_target_parallel: 11100 case OMPD_target_parallel_for: 11101 case OMPD_target_parallel_for_simd: 11102 CaptureRegion = OMPD_target; 11103 break; 11104 case OMPD_teams_distribute_parallel_for: 11105 case OMPD_teams_distribute_parallel_for_simd: 11106 case OMPD_target_teams_distribute_parallel_for: 11107 case OMPD_target_teams_distribute_parallel_for_simd: 11108 CaptureRegion = OMPD_teams; 11109 break; 11110 case OMPD_parallel: 11111 case OMPD_parallel_master: 11112 case OMPD_parallel_sections: 11113 case OMPD_parallel_for: 11114 case OMPD_parallel_for_simd: 11115 case OMPD_distribute_parallel_for: 11116 case OMPD_distribute_parallel_for_simd: 11117 case OMPD_parallel_master_taskloop: 11118 case OMPD_parallel_master_taskloop_simd: 11119 // Do not capture num_threads-clause expressions. 11120 break; 11121 case OMPD_target_data: 11122 case OMPD_target_enter_data: 11123 case OMPD_target_exit_data: 11124 case OMPD_target_update: 11125 case OMPD_target: 11126 case OMPD_target_simd: 11127 case OMPD_target_teams: 11128 case OMPD_target_teams_distribute: 11129 case OMPD_target_teams_distribute_simd: 11130 case OMPD_cancel: 11131 case OMPD_task: 11132 case OMPD_taskloop: 11133 case OMPD_taskloop_simd: 11134 case OMPD_master_taskloop: 11135 case OMPD_master_taskloop_simd: 11136 case OMPD_threadprivate: 11137 case OMPD_allocate: 11138 case OMPD_taskyield: 11139 case OMPD_barrier: 11140 case OMPD_taskwait: 11141 case OMPD_cancellation_point: 11142 case OMPD_flush: 11143 case OMPD_declare_reduction: 11144 case OMPD_declare_mapper: 11145 case OMPD_declare_simd: 11146 case OMPD_declare_variant: 11147 case OMPD_declare_target: 11148 case OMPD_end_declare_target: 11149 case OMPD_teams: 11150 case OMPD_simd: 11151 case OMPD_for: 11152 case OMPD_for_simd: 11153 case OMPD_sections: 11154 case OMPD_section: 11155 case OMPD_single: 11156 case OMPD_master: 11157 case OMPD_critical: 11158 case OMPD_taskgroup: 11159 case OMPD_distribute: 11160 case OMPD_ordered: 11161 case OMPD_atomic: 11162 case OMPD_distribute_simd: 11163 case OMPD_teams_distribute: 11164 case OMPD_teams_distribute_simd: 11165 case OMPD_requires: 11166 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11167 case OMPD_unknown: 11168 llvm_unreachable("Unknown OpenMP directive"); 11169 } 11170 break; 11171 case OMPC_num_teams: 11172 switch (DKind) { 11173 case OMPD_target_teams: 11174 case OMPD_target_teams_distribute: 11175 case OMPD_target_teams_distribute_simd: 11176 case OMPD_target_teams_distribute_parallel_for: 11177 case OMPD_target_teams_distribute_parallel_for_simd: 11178 CaptureRegion = OMPD_target; 11179 break; 11180 case OMPD_teams_distribute_parallel_for: 11181 case OMPD_teams_distribute_parallel_for_simd: 11182 case OMPD_teams: 11183 case OMPD_teams_distribute: 11184 case OMPD_teams_distribute_simd: 11185 // Do not capture num_teams-clause expressions. 11186 break; 11187 case OMPD_distribute_parallel_for: 11188 case OMPD_distribute_parallel_for_simd: 11189 case OMPD_task: 11190 case OMPD_taskloop: 11191 case OMPD_taskloop_simd: 11192 case OMPD_master_taskloop: 11193 case OMPD_master_taskloop_simd: 11194 case OMPD_parallel_master_taskloop: 11195 case OMPD_parallel_master_taskloop_simd: 11196 case OMPD_target_data: 11197 case OMPD_target_enter_data: 11198 case OMPD_target_exit_data: 11199 case OMPD_target_update: 11200 case OMPD_cancel: 11201 case OMPD_parallel: 11202 case OMPD_parallel_master: 11203 case OMPD_parallel_sections: 11204 case OMPD_parallel_for: 11205 case OMPD_parallel_for_simd: 11206 case OMPD_target: 11207 case OMPD_target_simd: 11208 case OMPD_target_parallel: 11209 case OMPD_target_parallel_for: 11210 case OMPD_target_parallel_for_simd: 11211 case OMPD_threadprivate: 11212 case OMPD_allocate: 11213 case OMPD_taskyield: 11214 case OMPD_barrier: 11215 case OMPD_taskwait: 11216 case OMPD_cancellation_point: 11217 case OMPD_flush: 11218 case OMPD_declare_reduction: 11219 case OMPD_declare_mapper: 11220 case OMPD_declare_simd: 11221 case OMPD_declare_variant: 11222 case OMPD_declare_target: 11223 case OMPD_end_declare_target: 11224 case OMPD_simd: 11225 case OMPD_for: 11226 case OMPD_for_simd: 11227 case OMPD_sections: 11228 case OMPD_section: 11229 case OMPD_single: 11230 case OMPD_master: 11231 case OMPD_critical: 11232 case OMPD_taskgroup: 11233 case OMPD_distribute: 11234 case OMPD_ordered: 11235 case OMPD_atomic: 11236 case OMPD_distribute_simd: 11237 case OMPD_requires: 11238 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11239 case OMPD_unknown: 11240 llvm_unreachable("Unknown OpenMP directive"); 11241 } 11242 break; 11243 case OMPC_thread_limit: 11244 switch (DKind) { 11245 case OMPD_target_teams: 11246 case OMPD_target_teams_distribute: 11247 case OMPD_target_teams_distribute_simd: 11248 case OMPD_target_teams_distribute_parallel_for: 11249 case OMPD_target_teams_distribute_parallel_for_simd: 11250 CaptureRegion = OMPD_target; 11251 break; 11252 case OMPD_teams_distribute_parallel_for: 11253 case OMPD_teams_distribute_parallel_for_simd: 11254 case OMPD_teams: 11255 case OMPD_teams_distribute: 11256 case OMPD_teams_distribute_simd: 11257 // Do not capture thread_limit-clause expressions. 11258 break; 11259 case OMPD_distribute_parallel_for: 11260 case OMPD_distribute_parallel_for_simd: 11261 case OMPD_task: 11262 case OMPD_taskloop: 11263 case OMPD_taskloop_simd: 11264 case OMPD_master_taskloop: 11265 case OMPD_master_taskloop_simd: 11266 case OMPD_parallel_master_taskloop: 11267 case OMPD_parallel_master_taskloop_simd: 11268 case OMPD_target_data: 11269 case OMPD_target_enter_data: 11270 case OMPD_target_exit_data: 11271 case OMPD_target_update: 11272 case OMPD_cancel: 11273 case OMPD_parallel: 11274 case OMPD_parallel_master: 11275 case OMPD_parallel_sections: 11276 case OMPD_parallel_for: 11277 case OMPD_parallel_for_simd: 11278 case OMPD_target: 11279 case OMPD_target_simd: 11280 case OMPD_target_parallel: 11281 case OMPD_target_parallel_for: 11282 case OMPD_target_parallel_for_simd: 11283 case OMPD_threadprivate: 11284 case OMPD_allocate: 11285 case OMPD_taskyield: 11286 case OMPD_barrier: 11287 case OMPD_taskwait: 11288 case OMPD_cancellation_point: 11289 case OMPD_flush: 11290 case OMPD_declare_reduction: 11291 case OMPD_declare_mapper: 11292 case OMPD_declare_simd: 11293 case OMPD_declare_variant: 11294 case OMPD_declare_target: 11295 case OMPD_end_declare_target: 11296 case OMPD_simd: 11297 case OMPD_for: 11298 case OMPD_for_simd: 11299 case OMPD_sections: 11300 case OMPD_section: 11301 case OMPD_single: 11302 case OMPD_master: 11303 case OMPD_critical: 11304 case OMPD_taskgroup: 11305 case OMPD_distribute: 11306 case OMPD_ordered: 11307 case OMPD_atomic: 11308 case OMPD_distribute_simd: 11309 case OMPD_requires: 11310 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11311 case OMPD_unknown: 11312 llvm_unreachable("Unknown OpenMP directive"); 11313 } 11314 break; 11315 case OMPC_schedule: 11316 switch (DKind) { 11317 case OMPD_parallel_for: 11318 case OMPD_parallel_for_simd: 11319 case OMPD_distribute_parallel_for: 11320 case OMPD_distribute_parallel_for_simd: 11321 case OMPD_teams_distribute_parallel_for: 11322 case OMPD_teams_distribute_parallel_for_simd: 11323 case OMPD_target_parallel_for: 11324 case OMPD_target_parallel_for_simd: 11325 case OMPD_target_teams_distribute_parallel_for: 11326 case OMPD_target_teams_distribute_parallel_for_simd: 11327 CaptureRegion = OMPD_parallel; 11328 break; 11329 case OMPD_for: 11330 case OMPD_for_simd: 11331 // Do not capture schedule-clause expressions. 11332 break; 11333 case OMPD_task: 11334 case OMPD_taskloop: 11335 case OMPD_taskloop_simd: 11336 case OMPD_master_taskloop: 11337 case OMPD_master_taskloop_simd: 11338 case OMPD_parallel_master_taskloop: 11339 case OMPD_parallel_master_taskloop_simd: 11340 case OMPD_target_data: 11341 case OMPD_target_enter_data: 11342 case OMPD_target_exit_data: 11343 case OMPD_target_update: 11344 case OMPD_teams: 11345 case OMPD_teams_distribute: 11346 case OMPD_teams_distribute_simd: 11347 case OMPD_target_teams_distribute: 11348 case OMPD_target_teams_distribute_simd: 11349 case OMPD_target: 11350 case OMPD_target_simd: 11351 case OMPD_target_parallel: 11352 case OMPD_cancel: 11353 case OMPD_parallel: 11354 case OMPD_parallel_master: 11355 case OMPD_parallel_sections: 11356 case OMPD_threadprivate: 11357 case OMPD_allocate: 11358 case OMPD_taskyield: 11359 case OMPD_barrier: 11360 case OMPD_taskwait: 11361 case OMPD_cancellation_point: 11362 case OMPD_flush: 11363 case OMPD_declare_reduction: 11364 case OMPD_declare_mapper: 11365 case OMPD_declare_simd: 11366 case OMPD_declare_variant: 11367 case OMPD_declare_target: 11368 case OMPD_end_declare_target: 11369 case OMPD_simd: 11370 case OMPD_sections: 11371 case OMPD_section: 11372 case OMPD_single: 11373 case OMPD_master: 11374 case OMPD_critical: 11375 case OMPD_taskgroup: 11376 case OMPD_distribute: 11377 case OMPD_ordered: 11378 case OMPD_atomic: 11379 case OMPD_distribute_simd: 11380 case OMPD_target_teams: 11381 case OMPD_requires: 11382 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11383 case OMPD_unknown: 11384 llvm_unreachable("Unknown OpenMP directive"); 11385 } 11386 break; 11387 case OMPC_dist_schedule: 11388 switch (DKind) { 11389 case OMPD_teams_distribute_parallel_for: 11390 case OMPD_teams_distribute_parallel_for_simd: 11391 case OMPD_teams_distribute: 11392 case OMPD_teams_distribute_simd: 11393 case OMPD_target_teams_distribute_parallel_for: 11394 case OMPD_target_teams_distribute_parallel_for_simd: 11395 case OMPD_target_teams_distribute: 11396 case OMPD_target_teams_distribute_simd: 11397 CaptureRegion = OMPD_teams; 11398 break; 11399 case OMPD_distribute_parallel_for: 11400 case OMPD_distribute_parallel_for_simd: 11401 case OMPD_distribute: 11402 case OMPD_distribute_simd: 11403 // Do not capture thread_limit-clause expressions. 11404 break; 11405 case OMPD_parallel_for: 11406 case OMPD_parallel_for_simd: 11407 case OMPD_target_parallel_for_simd: 11408 case OMPD_target_parallel_for: 11409 case OMPD_task: 11410 case OMPD_taskloop: 11411 case OMPD_taskloop_simd: 11412 case OMPD_master_taskloop: 11413 case OMPD_master_taskloop_simd: 11414 case OMPD_parallel_master_taskloop: 11415 case OMPD_parallel_master_taskloop_simd: 11416 case OMPD_target_data: 11417 case OMPD_target_enter_data: 11418 case OMPD_target_exit_data: 11419 case OMPD_target_update: 11420 case OMPD_teams: 11421 case OMPD_target: 11422 case OMPD_target_simd: 11423 case OMPD_target_parallel: 11424 case OMPD_cancel: 11425 case OMPD_parallel: 11426 case OMPD_parallel_master: 11427 case OMPD_parallel_sections: 11428 case OMPD_threadprivate: 11429 case OMPD_allocate: 11430 case OMPD_taskyield: 11431 case OMPD_barrier: 11432 case OMPD_taskwait: 11433 case OMPD_cancellation_point: 11434 case OMPD_flush: 11435 case OMPD_declare_reduction: 11436 case OMPD_declare_mapper: 11437 case OMPD_declare_simd: 11438 case OMPD_declare_variant: 11439 case OMPD_declare_target: 11440 case OMPD_end_declare_target: 11441 case OMPD_simd: 11442 case OMPD_for: 11443 case OMPD_for_simd: 11444 case OMPD_sections: 11445 case OMPD_section: 11446 case OMPD_single: 11447 case OMPD_master: 11448 case OMPD_critical: 11449 case OMPD_taskgroup: 11450 case OMPD_ordered: 11451 case OMPD_atomic: 11452 case OMPD_target_teams: 11453 case OMPD_requires: 11454 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11455 case OMPD_unknown: 11456 llvm_unreachable("Unknown OpenMP directive"); 11457 } 11458 break; 11459 case OMPC_device: 11460 switch (DKind) { 11461 case OMPD_target_update: 11462 case OMPD_target_enter_data: 11463 case OMPD_target_exit_data: 11464 case OMPD_target: 11465 case OMPD_target_simd: 11466 case OMPD_target_teams: 11467 case OMPD_target_parallel: 11468 case OMPD_target_teams_distribute: 11469 case OMPD_target_teams_distribute_simd: 11470 case OMPD_target_parallel_for: 11471 case OMPD_target_parallel_for_simd: 11472 case OMPD_target_teams_distribute_parallel_for: 11473 case OMPD_target_teams_distribute_parallel_for_simd: 11474 CaptureRegion = OMPD_task; 11475 break; 11476 case OMPD_target_data: 11477 // Do not capture device-clause expressions. 11478 break; 11479 case OMPD_teams_distribute_parallel_for: 11480 case OMPD_teams_distribute_parallel_for_simd: 11481 case OMPD_teams: 11482 case OMPD_teams_distribute: 11483 case OMPD_teams_distribute_simd: 11484 case OMPD_distribute_parallel_for: 11485 case OMPD_distribute_parallel_for_simd: 11486 case OMPD_task: 11487 case OMPD_taskloop: 11488 case OMPD_taskloop_simd: 11489 case OMPD_master_taskloop: 11490 case OMPD_master_taskloop_simd: 11491 case OMPD_parallel_master_taskloop: 11492 case OMPD_parallel_master_taskloop_simd: 11493 case OMPD_cancel: 11494 case OMPD_parallel: 11495 case OMPD_parallel_master: 11496 case OMPD_parallel_sections: 11497 case OMPD_parallel_for: 11498 case OMPD_parallel_for_simd: 11499 case OMPD_threadprivate: 11500 case OMPD_allocate: 11501 case OMPD_taskyield: 11502 case OMPD_barrier: 11503 case OMPD_taskwait: 11504 case OMPD_cancellation_point: 11505 case OMPD_flush: 11506 case OMPD_declare_reduction: 11507 case OMPD_declare_mapper: 11508 case OMPD_declare_simd: 11509 case OMPD_declare_variant: 11510 case OMPD_declare_target: 11511 case OMPD_end_declare_target: 11512 case OMPD_simd: 11513 case OMPD_for: 11514 case OMPD_for_simd: 11515 case OMPD_sections: 11516 case OMPD_section: 11517 case OMPD_single: 11518 case OMPD_master: 11519 case OMPD_critical: 11520 case OMPD_taskgroup: 11521 case OMPD_distribute: 11522 case OMPD_ordered: 11523 case OMPD_atomic: 11524 case OMPD_distribute_simd: 11525 case OMPD_requires: 11526 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11527 case OMPD_unknown: 11528 llvm_unreachable("Unknown OpenMP directive"); 11529 } 11530 break; 11531 case OMPC_grainsize: 11532 case OMPC_num_tasks: 11533 case OMPC_final: 11534 case OMPC_priority: 11535 switch (DKind) { 11536 case OMPD_task: 11537 case OMPD_taskloop: 11538 case OMPD_taskloop_simd: 11539 case OMPD_master_taskloop: 11540 case OMPD_master_taskloop_simd: 11541 break; 11542 case OMPD_parallel_master_taskloop: 11543 case OMPD_parallel_master_taskloop_simd: 11544 CaptureRegion = OMPD_parallel; 11545 break; 11546 case OMPD_target_update: 11547 case OMPD_target_enter_data: 11548 case OMPD_target_exit_data: 11549 case OMPD_target: 11550 case OMPD_target_simd: 11551 case OMPD_target_teams: 11552 case OMPD_target_parallel: 11553 case OMPD_target_teams_distribute: 11554 case OMPD_target_teams_distribute_simd: 11555 case OMPD_target_parallel_for: 11556 case OMPD_target_parallel_for_simd: 11557 case OMPD_target_teams_distribute_parallel_for: 11558 case OMPD_target_teams_distribute_parallel_for_simd: 11559 case OMPD_target_data: 11560 case OMPD_teams_distribute_parallel_for: 11561 case OMPD_teams_distribute_parallel_for_simd: 11562 case OMPD_teams: 11563 case OMPD_teams_distribute: 11564 case OMPD_teams_distribute_simd: 11565 case OMPD_distribute_parallel_for: 11566 case OMPD_distribute_parallel_for_simd: 11567 case OMPD_cancel: 11568 case OMPD_parallel: 11569 case OMPD_parallel_master: 11570 case OMPD_parallel_sections: 11571 case OMPD_parallel_for: 11572 case OMPD_parallel_for_simd: 11573 case OMPD_threadprivate: 11574 case OMPD_allocate: 11575 case OMPD_taskyield: 11576 case OMPD_barrier: 11577 case OMPD_taskwait: 11578 case OMPD_cancellation_point: 11579 case OMPD_flush: 11580 case OMPD_declare_reduction: 11581 case OMPD_declare_mapper: 11582 case OMPD_declare_simd: 11583 case OMPD_declare_variant: 11584 case OMPD_declare_target: 11585 case OMPD_end_declare_target: 11586 case OMPD_simd: 11587 case OMPD_for: 11588 case OMPD_for_simd: 11589 case OMPD_sections: 11590 case OMPD_section: 11591 case OMPD_single: 11592 case OMPD_master: 11593 case OMPD_critical: 11594 case OMPD_taskgroup: 11595 case OMPD_distribute: 11596 case OMPD_ordered: 11597 case OMPD_atomic: 11598 case OMPD_distribute_simd: 11599 case OMPD_requires: 11600 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11601 case OMPD_unknown: 11602 llvm_unreachable("Unknown OpenMP directive"); 11603 } 11604 break; 11605 case OMPC_firstprivate: 11606 case OMPC_lastprivate: 11607 case OMPC_reduction: 11608 case OMPC_task_reduction: 11609 case OMPC_in_reduction: 11610 case OMPC_linear: 11611 case OMPC_default: 11612 case OMPC_proc_bind: 11613 case OMPC_safelen: 11614 case OMPC_simdlen: 11615 case OMPC_allocator: 11616 case OMPC_collapse: 11617 case OMPC_private: 11618 case OMPC_shared: 11619 case OMPC_aligned: 11620 case OMPC_copyin: 11621 case OMPC_copyprivate: 11622 case OMPC_ordered: 11623 case OMPC_nowait: 11624 case OMPC_untied: 11625 case OMPC_mergeable: 11626 case OMPC_threadprivate: 11627 case OMPC_allocate: 11628 case OMPC_flush: 11629 case OMPC_read: 11630 case OMPC_write: 11631 case OMPC_update: 11632 case OMPC_capture: 11633 case OMPC_seq_cst: 11634 case OMPC_acq_rel: 11635 case OMPC_acquire: 11636 case OMPC_release: 11637 case OMPC_relaxed: 11638 case OMPC_depend: 11639 case OMPC_threads: 11640 case OMPC_simd: 11641 case OMPC_map: 11642 case OMPC_nogroup: 11643 case OMPC_hint: 11644 case OMPC_defaultmap: 11645 case OMPC_unknown: 11646 case OMPC_uniform: 11647 case OMPC_to: 11648 case OMPC_from: 11649 case OMPC_use_device_ptr: 11650 case OMPC_is_device_ptr: 11651 case OMPC_unified_address: 11652 case OMPC_unified_shared_memory: 11653 case OMPC_reverse_offload: 11654 case OMPC_dynamic_allocators: 11655 case OMPC_atomic_default_mem_order: 11656 case OMPC_device_type: 11657 case OMPC_match: 11658 case OMPC_nontemporal: 11659 case OMPC_order: 11660 llvm_unreachable("Unexpected OpenMP clause."); 11661 } 11662 return CaptureRegion; 11663 } 11664 11665 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11666 Expr *Condition, SourceLocation StartLoc, 11667 SourceLocation LParenLoc, 11668 SourceLocation NameModifierLoc, 11669 SourceLocation ColonLoc, 11670 SourceLocation EndLoc) { 11671 Expr *ValExpr = Condition; 11672 Stmt *HelperValStmt = nullptr; 11673 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11674 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11675 !Condition->isInstantiationDependent() && 11676 !Condition->containsUnexpandedParameterPack()) { 11677 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11678 if (Val.isInvalid()) 11679 return nullptr; 11680 11681 ValExpr = Val.get(); 11682 11683 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11684 CaptureRegion = getOpenMPCaptureRegionForClause( 11685 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 11686 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11687 ValExpr = MakeFullExpr(ValExpr).get(); 11688 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11689 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11690 HelperValStmt = buildPreInits(Context, Captures); 11691 } 11692 } 11693 11694 return new (Context) 11695 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11696 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11697 } 11698 11699 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11700 SourceLocation StartLoc, 11701 SourceLocation LParenLoc, 11702 SourceLocation EndLoc) { 11703 Expr *ValExpr = Condition; 11704 Stmt *HelperValStmt = nullptr; 11705 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11706 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11707 !Condition->isInstantiationDependent() && 11708 !Condition->containsUnexpandedParameterPack()) { 11709 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11710 if (Val.isInvalid()) 11711 return nullptr; 11712 11713 ValExpr = MakeFullExpr(Val.get()).get(); 11714 11715 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11716 CaptureRegion = 11717 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 11718 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11719 ValExpr = MakeFullExpr(ValExpr).get(); 11720 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11721 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11722 HelperValStmt = buildPreInits(Context, Captures); 11723 } 11724 } 11725 11726 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11727 StartLoc, LParenLoc, EndLoc); 11728 } 11729 11730 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11731 Expr *Op) { 11732 if (!Op) 11733 return ExprError(); 11734 11735 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11736 public: 11737 IntConvertDiagnoser() 11738 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11739 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11740 QualType T) override { 11741 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11742 } 11743 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11744 QualType T) override { 11745 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11746 } 11747 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11748 QualType T, 11749 QualType ConvTy) override { 11750 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11751 } 11752 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11753 QualType ConvTy) override { 11754 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11755 << ConvTy->isEnumeralType() << ConvTy; 11756 } 11757 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11758 QualType T) override { 11759 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11760 } 11761 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11762 QualType ConvTy) override { 11763 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11764 << ConvTy->isEnumeralType() << ConvTy; 11765 } 11766 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11767 QualType) override { 11768 llvm_unreachable("conversion functions are permitted"); 11769 } 11770 } ConvertDiagnoser; 11771 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11772 } 11773 11774 static bool 11775 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11776 bool StrictlyPositive, bool BuildCapture = false, 11777 OpenMPDirectiveKind DKind = OMPD_unknown, 11778 OpenMPDirectiveKind *CaptureRegion = nullptr, 11779 Stmt **HelperValStmt = nullptr) { 11780 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11781 !ValExpr->isInstantiationDependent()) { 11782 SourceLocation Loc = ValExpr->getExprLoc(); 11783 ExprResult Value = 11784 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11785 if (Value.isInvalid()) 11786 return false; 11787 11788 ValExpr = Value.get(); 11789 // The expression must evaluate to a non-negative integer value. 11790 llvm::APSInt Result; 11791 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11792 Result.isSigned() && 11793 !((!StrictlyPositive && Result.isNonNegative()) || 11794 (StrictlyPositive && Result.isStrictlyPositive()))) { 11795 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11796 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11797 << ValExpr->getSourceRange(); 11798 return false; 11799 } 11800 if (!BuildCapture) 11801 return true; 11802 *CaptureRegion = 11803 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 11804 if (*CaptureRegion != OMPD_unknown && 11805 !SemaRef.CurContext->isDependentContext()) { 11806 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11807 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11808 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11809 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11810 } 11811 } 11812 return true; 11813 } 11814 11815 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11816 SourceLocation StartLoc, 11817 SourceLocation LParenLoc, 11818 SourceLocation EndLoc) { 11819 Expr *ValExpr = NumThreads; 11820 Stmt *HelperValStmt = nullptr; 11821 11822 // OpenMP [2.5, Restrictions] 11823 // The num_threads expression must evaluate to a positive integer value. 11824 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11825 /*StrictlyPositive=*/true)) 11826 return nullptr; 11827 11828 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11829 OpenMPDirectiveKind CaptureRegion = 11830 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 11831 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11832 ValExpr = MakeFullExpr(ValExpr).get(); 11833 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11834 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11835 HelperValStmt = buildPreInits(Context, Captures); 11836 } 11837 11838 return new (Context) OMPNumThreadsClause( 11839 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11840 } 11841 11842 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11843 OpenMPClauseKind CKind, 11844 bool StrictlyPositive) { 11845 if (!E) 11846 return ExprError(); 11847 if (E->isValueDependent() || E->isTypeDependent() || 11848 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11849 return E; 11850 llvm::APSInt Result; 11851 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11852 if (ICE.isInvalid()) 11853 return ExprError(); 11854 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11855 (!StrictlyPositive && !Result.isNonNegative())) { 11856 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11857 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11858 << E->getSourceRange(); 11859 return ExprError(); 11860 } 11861 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11862 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11863 << E->getSourceRange(); 11864 return ExprError(); 11865 } 11866 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11867 DSAStack->setAssociatedLoops(Result.getExtValue()); 11868 else if (CKind == OMPC_ordered) 11869 DSAStack->setAssociatedLoops(Result.getExtValue()); 11870 return ICE; 11871 } 11872 11873 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11874 SourceLocation LParenLoc, 11875 SourceLocation EndLoc) { 11876 // OpenMP [2.8.1, simd construct, Description] 11877 // The parameter of the safelen clause must be a constant 11878 // positive integer expression. 11879 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11880 if (Safelen.isInvalid()) 11881 return nullptr; 11882 return new (Context) 11883 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11884 } 11885 11886 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11887 SourceLocation LParenLoc, 11888 SourceLocation EndLoc) { 11889 // OpenMP [2.8.1, simd construct, Description] 11890 // The parameter of the simdlen clause must be a constant 11891 // positive integer expression. 11892 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11893 if (Simdlen.isInvalid()) 11894 return nullptr; 11895 return new (Context) 11896 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11897 } 11898 11899 /// Tries to find omp_allocator_handle_t type. 11900 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11901 DSAStackTy *Stack) { 11902 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11903 if (!OMPAllocatorHandleT.isNull()) 11904 return true; 11905 // Build the predefined allocator expressions. 11906 bool ErrorFound = false; 11907 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11908 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11909 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11910 StringRef Allocator = 11911 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11912 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11913 auto *VD = dyn_cast_or_null<ValueDecl>( 11914 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11915 if (!VD) { 11916 ErrorFound = true; 11917 break; 11918 } 11919 QualType AllocatorType = 11920 VD->getType().getNonLValueExprType(S.getASTContext()); 11921 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11922 if (!Res.isUsable()) { 11923 ErrorFound = true; 11924 break; 11925 } 11926 if (OMPAllocatorHandleT.isNull()) 11927 OMPAllocatorHandleT = AllocatorType; 11928 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11929 ErrorFound = true; 11930 break; 11931 } 11932 Stack->setAllocator(AllocatorKind, Res.get()); 11933 } 11934 if (ErrorFound) { 11935 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11936 return false; 11937 } 11938 OMPAllocatorHandleT.addConst(); 11939 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11940 return true; 11941 } 11942 11943 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11944 SourceLocation LParenLoc, 11945 SourceLocation EndLoc) { 11946 // OpenMP [2.11.3, allocate Directive, Description] 11947 // allocator is an expression of omp_allocator_handle_t type. 11948 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11949 return nullptr; 11950 11951 ExprResult Allocator = DefaultLvalueConversion(A); 11952 if (Allocator.isInvalid()) 11953 return nullptr; 11954 Allocator = PerformImplicitConversion(Allocator.get(), 11955 DSAStack->getOMPAllocatorHandleT(), 11956 Sema::AA_Initializing, 11957 /*AllowExplicit=*/true); 11958 if (Allocator.isInvalid()) 11959 return nullptr; 11960 return new (Context) 11961 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11962 } 11963 11964 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11965 SourceLocation StartLoc, 11966 SourceLocation LParenLoc, 11967 SourceLocation EndLoc) { 11968 // OpenMP [2.7.1, loop construct, Description] 11969 // OpenMP [2.8.1, simd construct, Description] 11970 // OpenMP [2.9.6, distribute construct, Description] 11971 // The parameter of the collapse clause must be a constant 11972 // positive integer expression. 11973 ExprResult NumForLoopsResult = 11974 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11975 if (NumForLoopsResult.isInvalid()) 11976 return nullptr; 11977 return new (Context) 11978 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11979 } 11980 11981 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11982 SourceLocation EndLoc, 11983 SourceLocation LParenLoc, 11984 Expr *NumForLoops) { 11985 // OpenMP [2.7.1, loop construct, Description] 11986 // OpenMP [2.8.1, simd construct, Description] 11987 // OpenMP [2.9.6, distribute construct, Description] 11988 // The parameter of the ordered clause must be a constant 11989 // positive integer expression if any. 11990 if (NumForLoops && LParenLoc.isValid()) { 11991 ExprResult NumForLoopsResult = 11992 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11993 if (NumForLoopsResult.isInvalid()) 11994 return nullptr; 11995 NumForLoops = NumForLoopsResult.get(); 11996 } else { 11997 NumForLoops = nullptr; 11998 } 11999 auto *Clause = OMPOrderedClause::Create( 12000 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12001 StartLoc, LParenLoc, EndLoc); 12002 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12003 return Clause; 12004 } 12005 12006 OMPClause *Sema::ActOnOpenMPSimpleClause( 12007 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12008 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12009 OMPClause *Res = nullptr; 12010 switch (Kind) { 12011 case OMPC_default: 12012 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12013 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12014 break; 12015 case OMPC_proc_bind: 12016 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12017 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12018 break; 12019 case OMPC_atomic_default_mem_order: 12020 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12021 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12022 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12023 break; 12024 case OMPC_order: 12025 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12026 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12027 break; 12028 case OMPC_if: 12029 case OMPC_final: 12030 case OMPC_num_threads: 12031 case OMPC_safelen: 12032 case OMPC_simdlen: 12033 case OMPC_allocator: 12034 case OMPC_collapse: 12035 case OMPC_schedule: 12036 case OMPC_private: 12037 case OMPC_firstprivate: 12038 case OMPC_lastprivate: 12039 case OMPC_shared: 12040 case OMPC_reduction: 12041 case OMPC_task_reduction: 12042 case OMPC_in_reduction: 12043 case OMPC_linear: 12044 case OMPC_aligned: 12045 case OMPC_copyin: 12046 case OMPC_copyprivate: 12047 case OMPC_ordered: 12048 case OMPC_nowait: 12049 case OMPC_untied: 12050 case OMPC_mergeable: 12051 case OMPC_threadprivate: 12052 case OMPC_allocate: 12053 case OMPC_flush: 12054 case OMPC_read: 12055 case OMPC_write: 12056 case OMPC_update: 12057 case OMPC_capture: 12058 case OMPC_seq_cst: 12059 case OMPC_acq_rel: 12060 case OMPC_acquire: 12061 case OMPC_release: 12062 case OMPC_relaxed: 12063 case OMPC_depend: 12064 case OMPC_device: 12065 case OMPC_threads: 12066 case OMPC_simd: 12067 case OMPC_map: 12068 case OMPC_num_teams: 12069 case OMPC_thread_limit: 12070 case OMPC_priority: 12071 case OMPC_grainsize: 12072 case OMPC_nogroup: 12073 case OMPC_num_tasks: 12074 case OMPC_hint: 12075 case OMPC_dist_schedule: 12076 case OMPC_defaultmap: 12077 case OMPC_unknown: 12078 case OMPC_uniform: 12079 case OMPC_to: 12080 case OMPC_from: 12081 case OMPC_use_device_ptr: 12082 case OMPC_is_device_ptr: 12083 case OMPC_unified_address: 12084 case OMPC_unified_shared_memory: 12085 case OMPC_reverse_offload: 12086 case OMPC_dynamic_allocators: 12087 case OMPC_device_type: 12088 case OMPC_match: 12089 case OMPC_nontemporal: 12090 llvm_unreachable("Clause is not allowed."); 12091 } 12092 return Res; 12093 } 12094 12095 static std::string 12096 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12097 ArrayRef<unsigned> Exclude = llvm::None) { 12098 SmallString<256> Buffer; 12099 llvm::raw_svector_ostream Out(Buffer); 12100 unsigned Skipped = Exclude.size(); 12101 auto S = Exclude.begin(), E = Exclude.end(); 12102 for (unsigned I = First; I < Last; ++I) { 12103 if (std::find(S, E, I) != E) { 12104 --Skipped; 12105 continue; 12106 } 12107 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12108 if (I + Skipped + 2 == Last) 12109 Out << " or "; 12110 else if (I + Skipped + 1 != Last) 12111 Out << ", "; 12112 } 12113 return std::string(Out.str()); 12114 } 12115 12116 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12117 SourceLocation KindKwLoc, 12118 SourceLocation StartLoc, 12119 SourceLocation LParenLoc, 12120 SourceLocation EndLoc) { 12121 if (Kind == OMP_DEFAULT_unknown) { 12122 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12123 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12124 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12125 << getOpenMPClauseName(OMPC_default); 12126 return nullptr; 12127 } 12128 if (Kind == OMP_DEFAULT_none) 12129 DSAStack->setDefaultDSANone(KindKwLoc); 12130 else if (Kind == OMP_DEFAULT_shared) 12131 DSAStack->setDefaultDSAShared(KindKwLoc); 12132 12133 return new (Context) 12134 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12135 } 12136 12137 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12138 SourceLocation KindKwLoc, 12139 SourceLocation StartLoc, 12140 SourceLocation LParenLoc, 12141 SourceLocation EndLoc) { 12142 if (Kind == OMP_PROC_BIND_unknown) { 12143 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12144 << getListOfPossibleValues(OMPC_proc_bind, 12145 /*First=*/unsigned(OMP_PROC_BIND_master), 12146 /*Last=*/5) 12147 << getOpenMPClauseName(OMPC_proc_bind); 12148 return nullptr; 12149 } 12150 return new (Context) 12151 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12152 } 12153 12154 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12155 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12156 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12157 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12158 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12159 << getListOfPossibleValues( 12160 OMPC_atomic_default_mem_order, /*First=*/0, 12161 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12162 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12163 return nullptr; 12164 } 12165 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12166 LParenLoc, EndLoc); 12167 } 12168 12169 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12170 SourceLocation KindKwLoc, 12171 SourceLocation StartLoc, 12172 SourceLocation LParenLoc, 12173 SourceLocation EndLoc) { 12174 if (Kind == OMPC_ORDER_unknown) { 12175 static_assert(OMPC_ORDER_unknown > 0, 12176 "OMPC_ORDER_unknown not greater than 0"); 12177 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12178 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12179 /*Last=*/OMPC_ORDER_unknown) 12180 << getOpenMPClauseName(OMPC_order); 12181 return nullptr; 12182 } 12183 return new (Context) 12184 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12185 } 12186 12187 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12188 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12189 SourceLocation StartLoc, SourceLocation LParenLoc, 12190 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12191 SourceLocation EndLoc) { 12192 OMPClause *Res = nullptr; 12193 switch (Kind) { 12194 case OMPC_schedule: 12195 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12196 assert(Argument.size() == NumberOfElements && 12197 ArgumentLoc.size() == NumberOfElements); 12198 Res = ActOnOpenMPScheduleClause( 12199 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12200 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12201 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12202 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12203 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12204 break; 12205 case OMPC_if: 12206 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12207 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12208 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12209 DelimLoc, EndLoc); 12210 break; 12211 case OMPC_dist_schedule: 12212 Res = ActOnOpenMPDistScheduleClause( 12213 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12214 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12215 break; 12216 case OMPC_defaultmap: 12217 enum { Modifier, DefaultmapKind }; 12218 Res = ActOnOpenMPDefaultmapClause( 12219 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12220 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12221 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12222 EndLoc); 12223 break; 12224 case OMPC_final: 12225 case OMPC_num_threads: 12226 case OMPC_safelen: 12227 case OMPC_simdlen: 12228 case OMPC_allocator: 12229 case OMPC_collapse: 12230 case OMPC_default: 12231 case OMPC_proc_bind: 12232 case OMPC_private: 12233 case OMPC_firstprivate: 12234 case OMPC_lastprivate: 12235 case OMPC_shared: 12236 case OMPC_reduction: 12237 case OMPC_task_reduction: 12238 case OMPC_in_reduction: 12239 case OMPC_linear: 12240 case OMPC_aligned: 12241 case OMPC_copyin: 12242 case OMPC_copyprivate: 12243 case OMPC_ordered: 12244 case OMPC_nowait: 12245 case OMPC_untied: 12246 case OMPC_mergeable: 12247 case OMPC_threadprivate: 12248 case OMPC_allocate: 12249 case OMPC_flush: 12250 case OMPC_read: 12251 case OMPC_write: 12252 case OMPC_update: 12253 case OMPC_capture: 12254 case OMPC_seq_cst: 12255 case OMPC_acq_rel: 12256 case OMPC_acquire: 12257 case OMPC_release: 12258 case OMPC_relaxed: 12259 case OMPC_depend: 12260 case OMPC_device: 12261 case OMPC_threads: 12262 case OMPC_simd: 12263 case OMPC_map: 12264 case OMPC_num_teams: 12265 case OMPC_thread_limit: 12266 case OMPC_priority: 12267 case OMPC_grainsize: 12268 case OMPC_nogroup: 12269 case OMPC_num_tasks: 12270 case OMPC_hint: 12271 case OMPC_unknown: 12272 case OMPC_uniform: 12273 case OMPC_to: 12274 case OMPC_from: 12275 case OMPC_use_device_ptr: 12276 case OMPC_is_device_ptr: 12277 case OMPC_unified_address: 12278 case OMPC_unified_shared_memory: 12279 case OMPC_reverse_offload: 12280 case OMPC_dynamic_allocators: 12281 case OMPC_atomic_default_mem_order: 12282 case OMPC_device_type: 12283 case OMPC_match: 12284 case OMPC_nontemporal: 12285 case OMPC_order: 12286 llvm_unreachable("Clause is not allowed."); 12287 } 12288 return Res; 12289 } 12290 12291 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12292 OpenMPScheduleClauseModifier M2, 12293 SourceLocation M1Loc, SourceLocation M2Loc) { 12294 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12295 SmallVector<unsigned, 2> Excluded; 12296 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12297 Excluded.push_back(M2); 12298 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12299 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12300 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12301 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12302 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12303 << getListOfPossibleValues(OMPC_schedule, 12304 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12305 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12306 Excluded) 12307 << getOpenMPClauseName(OMPC_schedule); 12308 return true; 12309 } 12310 return false; 12311 } 12312 12313 OMPClause *Sema::ActOnOpenMPScheduleClause( 12314 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12315 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12316 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12317 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12318 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12319 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12320 return nullptr; 12321 // OpenMP, 2.7.1, Loop Construct, Restrictions 12322 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12323 // but not both. 12324 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12325 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12326 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12327 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12328 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12329 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12330 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12331 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12332 return nullptr; 12333 } 12334 if (Kind == OMPC_SCHEDULE_unknown) { 12335 std::string Values; 12336 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12337 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12338 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12339 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12340 Exclude); 12341 } else { 12342 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12343 /*Last=*/OMPC_SCHEDULE_unknown); 12344 } 12345 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12346 << Values << getOpenMPClauseName(OMPC_schedule); 12347 return nullptr; 12348 } 12349 // OpenMP, 2.7.1, Loop Construct, Restrictions 12350 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12351 // schedule(guided). 12352 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12353 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12354 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12355 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12356 diag::err_omp_schedule_nonmonotonic_static); 12357 return nullptr; 12358 } 12359 Expr *ValExpr = ChunkSize; 12360 Stmt *HelperValStmt = nullptr; 12361 if (ChunkSize) { 12362 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12363 !ChunkSize->isInstantiationDependent() && 12364 !ChunkSize->containsUnexpandedParameterPack()) { 12365 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12366 ExprResult Val = 12367 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12368 if (Val.isInvalid()) 12369 return nullptr; 12370 12371 ValExpr = Val.get(); 12372 12373 // OpenMP [2.7.1, Restrictions] 12374 // chunk_size must be a loop invariant integer expression with a positive 12375 // value. 12376 llvm::APSInt Result; 12377 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12378 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12379 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12380 << "schedule" << 1 << ChunkSize->getSourceRange(); 12381 return nullptr; 12382 } 12383 } else if (getOpenMPCaptureRegionForClause( 12384 DSAStack->getCurrentDirective(), OMPC_schedule, 12385 LangOpts.OpenMP) != OMPD_unknown && 12386 !CurContext->isDependentContext()) { 12387 ValExpr = MakeFullExpr(ValExpr).get(); 12388 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12389 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12390 HelperValStmt = buildPreInits(Context, Captures); 12391 } 12392 } 12393 } 12394 12395 return new (Context) 12396 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12397 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12398 } 12399 12400 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12401 SourceLocation StartLoc, 12402 SourceLocation EndLoc) { 12403 OMPClause *Res = nullptr; 12404 switch (Kind) { 12405 case OMPC_ordered: 12406 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12407 break; 12408 case OMPC_nowait: 12409 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12410 break; 12411 case OMPC_untied: 12412 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12413 break; 12414 case OMPC_mergeable: 12415 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12416 break; 12417 case OMPC_read: 12418 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12419 break; 12420 case OMPC_write: 12421 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12422 break; 12423 case OMPC_update: 12424 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12425 break; 12426 case OMPC_capture: 12427 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12428 break; 12429 case OMPC_seq_cst: 12430 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12431 break; 12432 case OMPC_acq_rel: 12433 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 12434 break; 12435 case OMPC_acquire: 12436 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 12437 break; 12438 case OMPC_release: 12439 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 12440 break; 12441 case OMPC_relaxed: 12442 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 12443 break; 12444 case OMPC_threads: 12445 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12446 break; 12447 case OMPC_simd: 12448 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12449 break; 12450 case OMPC_nogroup: 12451 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12452 break; 12453 case OMPC_unified_address: 12454 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12455 break; 12456 case OMPC_unified_shared_memory: 12457 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12458 break; 12459 case OMPC_reverse_offload: 12460 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12461 break; 12462 case OMPC_dynamic_allocators: 12463 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12464 break; 12465 case OMPC_if: 12466 case OMPC_final: 12467 case OMPC_num_threads: 12468 case OMPC_safelen: 12469 case OMPC_simdlen: 12470 case OMPC_allocator: 12471 case OMPC_collapse: 12472 case OMPC_schedule: 12473 case OMPC_private: 12474 case OMPC_firstprivate: 12475 case OMPC_lastprivate: 12476 case OMPC_shared: 12477 case OMPC_reduction: 12478 case OMPC_task_reduction: 12479 case OMPC_in_reduction: 12480 case OMPC_linear: 12481 case OMPC_aligned: 12482 case OMPC_copyin: 12483 case OMPC_copyprivate: 12484 case OMPC_default: 12485 case OMPC_proc_bind: 12486 case OMPC_threadprivate: 12487 case OMPC_allocate: 12488 case OMPC_flush: 12489 case OMPC_depend: 12490 case OMPC_device: 12491 case OMPC_map: 12492 case OMPC_num_teams: 12493 case OMPC_thread_limit: 12494 case OMPC_priority: 12495 case OMPC_grainsize: 12496 case OMPC_num_tasks: 12497 case OMPC_hint: 12498 case OMPC_dist_schedule: 12499 case OMPC_defaultmap: 12500 case OMPC_unknown: 12501 case OMPC_uniform: 12502 case OMPC_to: 12503 case OMPC_from: 12504 case OMPC_use_device_ptr: 12505 case OMPC_is_device_ptr: 12506 case OMPC_atomic_default_mem_order: 12507 case OMPC_device_type: 12508 case OMPC_match: 12509 case OMPC_nontemporal: 12510 case OMPC_order: 12511 llvm_unreachable("Clause is not allowed."); 12512 } 12513 return Res; 12514 } 12515 12516 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12517 SourceLocation EndLoc) { 12518 DSAStack->setNowaitRegion(); 12519 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12520 } 12521 12522 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12523 SourceLocation EndLoc) { 12524 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12525 } 12526 12527 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12528 SourceLocation EndLoc) { 12529 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12530 } 12531 12532 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12533 SourceLocation EndLoc) { 12534 return new (Context) OMPReadClause(StartLoc, EndLoc); 12535 } 12536 12537 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12538 SourceLocation EndLoc) { 12539 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12540 } 12541 12542 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12543 SourceLocation EndLoc) { 12544 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 12545 } 12546 12547 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12548 SourceLocation EndLoc) { 12549 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12550 } 12551 12552 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12553 SourceLocation EndLoc) { 12554 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12555 } 12556 12557 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 12558 SourceLocation EndLoc) { 12559 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 12560 } 12561 12562 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 12563 SourceLocation EndLoc) { 12564 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 12565 } 12566 12567 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 12568 SourceLocation EndLoc) { 12569 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 12570 } 12571 12572 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 12573 SourceLocation EndLoc) { 12574 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 12575 } 12576 12577 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12578 SourceLocation EndLoc) { 12579 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12580 } 12581 12582 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12583 SourceLocation EndLoc) { 12584 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12585 } 12586 12587 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12588 SourceLocation EndLoc) { 12589 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12590 } 12591 12592 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12593 SourceLocation EndLoc) { 12594 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12595 } 12596 12597 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12598 SourceLocation EndLoc) { 12599 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12600 } 12601 12602 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12603 SourceLocation EndLoc) { 12604 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12605 } 12606 12607 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12608 SourceLocation EndLoc) { 12609 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12610 } 12611 12612 OMPClause *Sema::ActOnOpenMPVarListClause( 12613 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12614 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12615 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12616 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 12617 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12618 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 12619 SourceLocation DepLinMapLastLoc) { 12620 SourceLocation StartLoc = Locs.StartLoc; 12621 SourceLocation LParenLoc = Locs.LParenLoc; 12622 SourceLocation EndLoc = Locs.EndLoc; 12623 OMPClause *Res = nullptr; 12624 switch (Kind) { 12625 case OMPC_private: 12626 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12627 break; 12628 case OMPC_firstprivate: 12629 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12630 break; 12631 case OMPC_lastprivate: 12632 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 12633 "Unexpected lastprivate modifier."); 12634 Res = ActOnOpenMPLastprivateClause( 12635 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 12636 DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 12637 break; 12638 case OMPC_shared: 12639 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12640 break; 12641 case OMPC_reduction: 12642 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12643 EndLoc, ReductionOrMapperIdScopeSpec, 12644 ReductionOrMapperId); 12645 break; 12646 case OMPC_task_reduction: 12647 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12648 EndLoc, ReductionOrMapperIdScopeSpec, 12649 ReductionOrMapperId); 12650 break; 12651 case OMPC_in_reduction: 12652 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12653 EndLoc, ReductionOrMapperIdScopeSpec, 12654 ReductionOrMapperId); 12655 break; 12656 case OMPC_linear: 12657 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 12658 "Unexpected linear modifier."); 12659 Res = ActOnOpenMPLinearClause( 12660 VarList, TailExpr, StartLoc, LParenLoc, 12661 static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc, 12662 ColonLoc, EndLoc); 12663 break; 12664 case OMPC_aligned: 12665 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12666 ColonLoc, EndLoc); 12667 break; 12668 case OMPC_copyin: 12669 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12670 break; 12671 case OMPC_copyprivate: 12672 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12673 break; 12674 case OMPC_flush: 12675 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12676 break; 12677 case OMPC_depend: 12678 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 12679 "Unexpected depend modifier."); 12680 Res = ActOnOpenMPDependClause( 12681 static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc, 12682 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 12683 break; 12684 case OMPC_map: 12685 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 12686 "Unexpected map modifier."); 12687 Res = ActOnOpenMPMapClause( 12688 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 12689 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 12690 IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs); 12691 break; 12692 case OMPC_to: 12693 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12694 ReductionOrMapperId, Locs); 12695 break; 12696 case OMPC_from: 12697 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12698 ReductionOrMapperId, Locs); 12699 break; 12700 case OMPC_use_device_ptr: 12701 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12702 break; 12703 case OMPC_is_device_ptr: 12704 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12705 break; 12706 case OMPC_allocate: 12707 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12708 ColonLoc, EndLoc); 12709 break; 12710 case OMPC_nontemporal: 12711 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 12712 break; 12713 case OMPC_if: 12714 case OMPC_final: 12715 case OMPC_num_threads: 12716 case OMPC_safelen: 12717 case OMPC_simdlen: 12718 case OMPC_allocator: 12719 case OMPC_collapse: 12720 case OMPC_default: 12721 case OMPC_proc_bind: 12722 case OMPC_schedule: 12723 case OMPC_ordered: 12724 case OMPC_nowait: 12725 case OMPC_untied: 12726 case OMPC_mergeable: 12727 case OMPC_threadprivate: 12728 case OMPC_read: 12729 case OMPC_write: 12730 case OMPC_update: 12731 case OMPC_capture: 12732 case OMPC_seq_cst: 12733 case OMPC_acq_rel: 12734 case OMPC_acquire: 12735 case OMPC_release: 12736 case OMPC_relaxed: 12737 case OMPC_device: 12738 case OMPC_threads: 12739 case OMPC_simd: 12740 case OMPC_num_teams: 12741 case OMPC_thread_limit: 12742 case OMPC_priority: 12743 case OMPC_grainsize: 12744 case OMPC_nogroup: 12745 case OMPC_num_tasks: 12746 case OMPC_hint: 12747 case OMPC_dist_schedule: 12748 case OMPC_defaultmap: 12749 case OMPC_unknown: 12750 case OMPC_uniform: 12751 case OMPC_unified_address: 12752 case OMPC_unified_shared_memory: 12753 case OMPC_reverse_offload: 12754 case OMPC_dynamic_allocators: 12755 case OMPC_atomic_default_mem_order: 12756 case OMPC_device_type: 12757 case OMPC_match: 12758 case OMPC_order: 12759 llvm_unreachable("Clause is not allowed."); 12760 } 12761 return Res; 12762 } 12763 12764 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12765 ExprObjectKind OK, SourceLocation Loc) { 12766 ExprResult Res = BuildDeclRefExpr( 12767 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12768 if (!Res.isUsable()) 12769 return ExprError(); 12770 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12771 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12772 if (!Res.isUsable()) 12773 return ExprError(); 12774 } 12775 if (VK != VK_LValue && Res.get()->isGLValue()) { 12776 Res = DefaultLvalueConversion(Res.get()); 12777 if (!Res.isUsable()) 12778 return ExprError(); 12779 } 12780 return Res; 12781 } 12782 12783 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12784 SourceLocation StartLoc, 12785 SourceLocation LParenLoc, 12786 SourceLocation EndLoc) { 12787 SmallVector<Expr *, 8> Vars; 12788 SmallVector<Expr *, 8> PrivateCopies; 12789 for (Expr *RefExpr : VarList) { 12790 assert(RefExpr && "NULL expr in OpenMP private clause."); 12791 SourceLocation ELoc; 12792 SourceRange ERange; 12793 Expr *SimpleRefExpr = RefExpr; 12794 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12795 if (Res.second) { 12796 // It will be analyzed later. 12797 Vars.push_back(RefExpr); 12798 PrivateCopies.push_back(nullptr); 12799 } 12800 ValueDecl *D = Res.first; 12801 if (!D) 12802 continue; 12803 12804 QualType Type = D->getType(); 12805 auto *VD = dyn_cast<VarDecl>(D); 12806 12807 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12808 // A variable that appears in a private clause must not have an incomplete 12809 // type or a reference type. 12810 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12811 continue; 12812 Type = Type.getNonReferenceType(); 12813 12814 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12815 // A variable that is privatized must not have a const-qualified type 12816 // unless it is of class type with a mutable member. This restriction does 12817 // not apply to the firstprivate clause. 12818 // 12819 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12820 // A variable that appears in a private clause must not have a 12821 // const-qualified type unless it is of class type with a mutable member. 12822 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12823 continue; 12824 12825 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12826 // in a Construct] 12827 // Variables with the predetermined data-sharing attributes may not be 12828 // listed in data-sharing attributes clauses, except for the cases 12829 // listed below. For these exceptions only, listing a predetermined 12830 // variable in a data-sharing attribute clause is allowed and overrides 12831 // the variable's predetermined data-sharing attributes. 12832 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12833 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12834 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12835 << getOpenMPClauseName(OMPC_private); 12836 reportOriginalDsa(*this, DSAStack, D, DVar); 12837 continue; 12838 } 12839 12840 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12841 // Variably modified types are not supported for tasks. 12842 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12843 isOpenMPTaskingDirective(CurrDir)) { 12844 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12845 << getOpenMPClauseName(OMPC_private) << Type 12846 << getOpenMPDirectiveName(CurrDir); 12847 bool IsDecl = 12848 !VD || 12849 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12850 Diag(D->getLocation(), 12851 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12852 << D; 12853 continue; 12854 } 12855 12856 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12857 // A list item cannot appear in both a map clause and a data-sharing 12858 // attribute clause on the same construct 12859 // 12860 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12861 // A list item cannot appear in both a map clause and a data-sharing 12862 // attribute clause on the same construct unless the construct is a 12863 // combined construct. 12864 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12865 CurrDir == OMPD_target) { 12866 OpenMPClauseKind ConflictKind; 12867 if (DSAStack->checkMappableExprComponentListsForDecl( 12868 VD, /*CurrentRegionOnly=*/true, 12869 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12870 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12871 ConflictKind = WhereFoundClauseKind; 12872 return true; 12873 })) { 12874 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12875 << getOpenMPClauseName(OMPC_private) 12876 << getOpenMPClauseName(ConflictKind) 12877 << getOpenMPDirectiveName(CurrDir); 12878 reportOriginalDsa(*this, DSAStack, D, DVar); 12879 continue; 12880 } 12881 } 12882 12883 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12884 // A variable of class type (or array thereof) that appears in a private 12885 // clause requires an accessible, unambiguous default constructor for the 12886 // class type. 12887 // Generate helper private variable and initialize it with the default 12888 // value. The address of the original variable is replaced by the address of 12889 // the new private variable in CodeGen. This new variable is not added to 12890 // IdResolver, so the code in the OpenMP region uses original variable for 12891 // proper diagnostics. 12892 Type = Type.getUnqualifiedType(); 12893 VarDecl *VDPrivate = 12894 buildVarDecl(*this, ELoc, Type, D->getName(), 12895 D->hasAttrs() ? &D->getAttrs() : nullptr, 12896 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12897 ActOnUninitializedDecl(VDPrivate); 12898 if (VDPrivate->isInvalidDecl()) 12899 continue; 12900 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12901 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12902 12903 DeclRefExpr *Ref = nullptr; 12904 if (!VD && !CurContext->isDependentContext()) 12905 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12906 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12907 Vars.push_back((VD || CurContext->isDependentContext()) 12908 ? RefExpr->IgnoreParens() 12909 : Ref); 12910 PrivateCopies.push_back(VDPrivateRefExpr); 12911 } 12912 12913 if (Vars.empty()) 12914 return nullptr; 12915 12916 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12917 PrivateCopies); 12918 } 12919 12920 namespace { 12921 class DiagsUninitializedSeveretyRAII { 12922 private: 12923 DiagnosticsEngine &Diags; 12924 SourceLocation SavedLoc; 12925 bool IsIgnored = false; 12926 12927 public: 12928 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12929 bool IsIgnored) 12930 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12931 if (!IsIgnored) { 12932 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12933 /*Map*/ diag::Severity::Ignored, Loc); 12934 } 12935 } 12936 ~DiagsUninitializedSeveretyRAII() { 12937 if (!IsIgnored) 12938 Diags.popMappings(SavedLoc); 12939 } 12940 }; 12941 } 12942 12943 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12944 SourceLocation StartLoc, 12945 SourceLocation LParenLoc, 12946 SourceLocation EndLoc) { 12947 SmallVector<Expr *, 8> Vars; 12948 SmallVector<Expr *, 8> PrivateCopies; 12949 SmallVector<Expr *, 8> Inits; 12950 SmallVector<Decl *, 4> ExprCaptures; 12951 bool IsImplicitClause = 12952 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12953 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12954 12955 for (Expr *RefExpr : VarList) { 12956 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12957 SourceLocation ELoc; 12958 SourceRange ERange; 12959 Expr *SimpleRefExpr = RefExpr; 12960 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12961 if (Res.second) { 12962 // It will be analyzed later. 12963 Vars.push_back(RefExpr); 12964 PrivateCopies.push_back(nullptr); 12965 Inits.push_back(nullptr); 12966 } 12967 ValueDecl *D = Res.first; 12968 if (!D) 12969 continue; 12970 12971 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12972 QualType Type = D->getType(); 12973 auto *VD = dyn_cast<VarDecl>(D); 12974 12975 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12976 // A variable that appears in a private clause must not have an incomplete 12977 // type or a reference type. 12978 if (RequireCompleteType(ELoc, Type, 12979 diag::err_omp_firstprivate_incomplete_type)) 12980 continue; 12981 Type = Type.getNonReferenceType(); 12982 12983 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12984 // A variable of class type (or array thereof) that appears in a private 12985 // clause requires an accessible, unambiguous copy constructor for the 12986 // class type. 12987 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12988 12989 // If an implicit firstprivate variable found it was checked already. 12990 DSAStackTy::DSAVarData TopDVar; 12991 if (!IsImplicitClause) { 12992 DSAStackTy::DSAVarData DVar = 12993 DSAStack->getTopDSA(D, /*FromParent=*/false); 12994 TopDVar = DVar; 12995 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12996 bool IsConstant = ElemType.isConstant(Context); 12997 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12998 // A list item that specifies a given variable may not appear in more 12999 // than one clause on the same directive, except that a variable may be 13000 // specified in both firstprivate and lastprivate clauses. 13001 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13002 // A list item may appear in a firstprivate or lastprivate clause but not 13003 // both. 13004 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13005 (isOpenMPDistributeDirective(CurrDir) || 13006 DVar.CKind != OMPC_lastprivate) && 13007 DVar.RefExpr) { 13008 Diag(ELoc, diag::err_omp_wrong_dsa) 13009 << getOpenMPClauseName(DVar.CKind) 13010 << getOpenMPClauseName(OMPC_firstprivate); 13011 reportOriginalDsa(*this, DSAStack, D, DVar); 13012 continue; 13013 } 13014 13015 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13016 // in a Construct] 13017 // Variables with the predetermined data-sharing attributes may not be 13018 // listed in data-sharing attributes clauses, except for the cases 13019 // listed below. For these exceptions only, listing a predetermined 13020 // variable in a data-sharing attribute clause is allowed and overrides 13021 // the variable's predetermined data-sharing attributes. 13022 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13023 // in a Construct, C/C++, p.2] 13024 // Variables with const-qualified type having no mutable member may be 13025 // listed in a firstprivate clause, even if they are static data members. 13026 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13027 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13028 Diag(ELoc, diag::err_omp_wrong_dsa) 13029 << getOpenMPClauseName(DVar.CKind) 13030 << getOpenMPClauseName(OMPC_firstprivate); 13031 reportOriginalDsa(*this, DSAStack, D, DVar); 13032 continue; 13033 } 13034 13035 // OpenMP [2.9.3.4, Restrictions, p.2] 13036 // A list item that is private within a parallel region must not appear 13037 // in a firstprivate clause on a worksharing construct if any of the 13038 // worksharing regions arising from the worksharing construct ever bind 13039 // to any of the parallel regions arising from the parallel construct. 13040 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13041 // A list item that is private within a teams region must not appear in a 13042 // firstprivate clause on a distribute construct if any of the distribute 13043 // regions arising from the distribute construct ever bind to any of the 13044 // teams regions arising from the teams construct. 13045 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13046 // A list item that appears in a reduction clause of a teams construct 13047 // must not appear in a firstprivate clause on a distribute construct if 13048 // any of the distribute regions arising from the distribute construct 13049 // ever bind to any of the teams regions arising from the teams construct. 13050 if ((isOpenMPWorksharingDirective(CurrDir) || 13051 isOpenMPDistributeDirective(CurrDir)) && 13052 !isOpenMPParallelDirective(CurrDir) && 13053 !isOpenMPTeamsDirective(CurrDir)) { 13054 DVar = DSAStack->getImplicitDSA(D, true); 13055 if (DVar.CKind != OMPC_shared && 13056 (isOpenMPParallelDirective(DVar.DKind) || 13057 isOpenMPTeamsDirective(DVar.DKind) || 13058 DVar.DKind == OMPD_unknown)) { 13059 Diag(ELoc, diag::err_omp_required_access) 13060 << getOpenMPClauseName(OMPC_firstprivate) 13061 << getOpenMPClauseName(OMPC_shared); 13062 reportOriginalDsa(*this, DSAStack, D, DVar); 13063 continue; 13064 } 13065 } 13066 // OpenMP [2.9.3.4, Restrictions, p.3] 13067 // A list item that appears in a reduction clause of a parallel construct 13068 // must not appear in a firstprivate clause on a worksharing or task 13069 // construct if any of the worksharing or task regions arising from the 13070 // worksharing or task construct ever bind to any of the parallel regions 13071 // arising from the parallel construct. 13072 // OpenMP [2.9.3.4, Restrictions, p.4] 13073 // A list item that appears in a reduction clause in worksharing 13074 // construct must not appear in a firstprivate clause in a task construct 13075 // encountered during execution of any of the worksharing regions arising 13076 // from the worksharing construct. 13077 if (isOpenMPTaskingDirective(CurrDir)) { 13078 DVar = DSAStack->hasInnermostDSA( 13079 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13080 [](OpenMPDirectiveKind K) { 13081 return isOpenMPParallelDirective(K) || 13082 isOpenMPWorksharingDirective(K) || 13083 isOpenMPTeamsDirective(K); 13084 }, 13085 /*FromParent=*/true); 13086 if (DVar.CKind == OMPC_reduction && 13087 (isOpenMPParallelDirective(DVar.DKind) || 13088 isOpenMPWorksharingDirective(DVar.DKind) || 13089 isOpenMPTeamsDirective(DVar.DKind))) { 13090 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13091 << getOpenMPDirectiveName(DVar.DKind); 13092 reportOriginalDsa(*this, DSAStack, D, DVar); 13093 continue; 13094 } 13095 } 13096 13097 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13098 // A list item cannot appear in both a map clause and a data-sharing 13099 // attribute clause on the same construct 13100 // 13101 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13102 // A list item cannot appear in both a map clause and a data-sharing 13103 // attribute clause on the same construct unless the construct is a 13104 // combined construct. 13105 if ((LangOpts.OpenMP <= 45 && 13106 isOpenMPTargetExecutionDirective(CurrDir)) || 13107 CurrDir == OMPD_target) { 13108 OpenMPClauseKind ConflictKind; 13109 if (DSAStack->checkMappableExprComponentListsForDecl( 13110 VD, /*CurrentRegionOnly=*/true, 13111 [&ConflictKind]( 13112 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13113 OpenMPClauseKind WhereFoundClauseKind) { 13114 ConflictKind = WhereFoundClauseKind; 13115 return true; 13116 })) { 13117 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13118 << getOpenMPClauseName(OMPC_firstprivate) 13119 << getOpenMPClauseName(ConflictKind) 13120 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13121 reportOriginalDsa(*this, DSAStack, D, DVar); 13122 continue; 13123 } 13124 } 13125 } 13126 13127 // Variably modified types are not supported for tasks. 13128 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13129 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13130 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13131 << getOpenMPClauseName(OMPC_firstprivate) << Type 13132 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13133 bool IsDecl = 13134 !VD || 13135 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13136 Diag(D->getLocation(), 13137 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13138 << D; 13139 continue; 13140 } 13141 13142 Type = Type.getUnqualifiedType(); 13143 VarDecl *VDPrivate = 13144 buildVarDecl(*this, ELoc, Type, D->getName(), 13145 D->hasAttrs() ? &D->getAttrs() : nullptr, 13146 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13147 // Generate helper private variable and initialize it with the value of the 13148 // original variable. The address of the original variable is replaced by 13149 // the address of the new private variable in the CodeGen. This new variable 13150 // is not added to IdResolver, so the code in the OpenMP region uses 13151 // original variable for proper diagnostics and variable capturing. 13152 Expr *VDInitRefExpr = nullptr; 13153 // For arrays generate initializer for single element and replace it by the 13154 // original array element in CodeGen. 13155 if (Type->isArrayType()) { 13156 VarDecl *VDInit = 13157 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13158 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13159 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13160 ElemType = ElemType.getUnqualifiedType(); 13161 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13162 ".firstprivate.temp"); 13163 InitializedEntity Entity = 13164 InitializedEntity::InitializeVariable(VDInitTemp); 13165 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13166 13167 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13168 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13169 if (Result.isInvalid()) 13170 VDPrivate->setInvalidDecl(); 13171 else 13172 VDPrivate->setInit(Result.getAs<Expr>()); 13173 // Remove temp variable declaration. 13174 Context.Deallocate(VDInitTemp); 13175 } else { 13176 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13177 ".firstprivate.temp"); 13178 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13179 RefExpr->getExprLoc()); 13180 AddInitializerToDecl(VDPrivate, 13181 DefaultLvalueConversion(VDInitRefExpr).get(), 13182 /*DirectInit=*/false); 13183 } 13184 if (VDPrivate->isInvalidDecl()) { 13185 if (IsImplicitClause) { 13186 Diag(RefExpr->getExprLoc(), 13187 diag::note_omp_task_predetermined_firstprivate_here); 13188 } 13189 continue; 13190 } 13191 CurContext->addDecl(VDPrivate); 13192 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13193 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13194 RefExpr->getExprLoc()); 13195 DeclRefExpr *Ref = nullptr; 13196 if (!VD && !CurContext->isDependentContext()) { 13197 if (TopDVar.CKind == OMPC_lastprivate) { 13198 Ref = TopDVar.PrivateCopy; 13199 } else { 13200 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13201 if (!isOpenMPCapturedDecl(D)) 13202 ExprCaptures.push_back(Ref->getDecl()); 13203 } 13204 } 13205 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13206 Vars.push_back((VD || CurContext->isDependentContext()) 13207 ? RefExpr->IgnoreParens() 13208 : Ref); 13209 PrivateCopies.push_back(VDPrivateRefExpr); 13210 Inits.push_back(VDInitRefExpr); 13211 } 13212 13213 if (Vars.empty()) 13214 return nullptr; 13215 13216 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13217 Vars, PrivateCopies, Inits, 13218 buildPreInits(Context, ExprCaptures)); 13219 } 13220 13221 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13222 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13223 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13224 SourceLocation LParenLoc, SourceLocation EndLoc) { 13225 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13226 assert(ColonLoc.isValid() && "Colon location must be valid."); 13227 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13228 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13229 /*Last=*/OMPC_LASTPRIVATE_unknown) 13230 << getOpenMPClauseName(OMPC_lastprivate); 13231 return nullptr; 13232 } 13233 13234 SmallVector<Expr *, 8> Vars; 13235 SmallVector<Expr *, 8> SrcExprs; 13236 SmallVector<Expr *, 8> DstExprs; 13237 SmallVector<Expr *, 8> AssignmentOps; 13238 SmallVector<Decl *, 4> ExprCaptures; 13239 SmallVector<Expr *, 4> ExprPostUpdates; 13240 for (Expr *RefExpr : VarList) { 13241 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13242 SourceLocation ELoc; 13243 SourceRange ERange; 13244 Expr *SimpleRefExpr = RefExpr; 13245 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13246 if (Res.second) { 13247 // It will be analyzed later. 13248 Vars.push_back(RefExpr); 13249 SrcExprs.push_back(nullptr); 13250 DstExprs.push_back(nullptr); 13251 AssignmentOps.push_back(nullptr); 13252 } 13253 ValueDecl *D = Res.first; 13254 if (!D) 13255 continue; 13256 13257 QualType Type = D->getType(); 13258 auto *VD = dyn_cast<VarDecl>(D); 13259 13260 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13261 // A variable that appears in a lastprivate clause must not have an 13262 // incomplete type or a reference type. 13263 if (RequireCompleteType(ELoc, Type, 13264 diag::err_omp_lastprivate_incomplete_type)) 13265 continue; 13266 Type = Type.getNonReferenceType(); 13267 13268 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13269 // A variable that is privatized must not have a const-qualified type 13270 // unless it is of class type with a mutable member. This restriction does 13271 // not apply to the firstprivate clause. 13272 // 13273 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13274 // A variable that appears in a lastprivate clause must not have a 13275 // const-qualified type unless it is of class type with a mutable member. 13276 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13277 continue; 13278 13279 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13280 // A list item that appears in a lastprivate clause with the conditional 13281 // modifier must be a scalar variable. 13282 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13283 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13284 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13285 VarDecl::DeclarationOnly; 13286 Diag(D->getLocation(), 13287 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13288 << D; 13289 continue; 13290 } 13291 13292 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13293 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13294 // in a Construct] 13295 // Variables with the predetermined data-sharing attributes may not be 13296 // listed in data-sharing attributes clauses, except for the cases 13297 // listed below. 13298 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13299 // A list item may appear in a firstprivate or lastprivate clause but not 13300 // both. 13301 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13302 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13303 (isOpenMPDistributeDirective(CurrDir) || 13304 DVar.CKind != OMPC_firstprivate) && 13305 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13306 Diag(ELoc, diag::err_omp_wrong_dsa) 13307 << getOpenMPClauseName(DVar.CKind) 13308 << getOpenMPClauseName(OMPC_lastprivate); 13309 reportOriginalDsa(*this, DSAStack, D, DVar); 13310 continue; 13311 } 13312 13313 // OpenMP [2.14.3.5, Restrictions, p.2] 13314 // A list item that is private within a parallel region, or that appears in 13315 // the reduction clause of a parallel construct, must not appear in a 13316 // lastprivate clause on a worksharing construct if any of the corresponding 13317 // worksharing regions ever binds to any of the corresponding parallel 13318 // regions. 13319 DSAStackTy::DSAVarData TopDVar = DVar; 13320 if (isOpenMPWorksharingDirective(CurrDir) && 13321 !isOpenMPParallelDirective(CurrDir) && 13322 !isOpenMPTeamsDirective(CurrDir)) { 13323 DVar = DSAStack->getImplicitDSA(D, true); 13324 if (DVar.CKind != OMPC_shared) { 13325 Diag(ELoc, diag::err_omp_required_access) 13326 << getOpenMPClauseName(OMPC_lastprivate) 13327 << getOpenMPClauseName(OMPC_shared); 13328 reportOriginalDsa(*this, DSAStack, D, DVar); 13329 continue; 13330 } 13331 } 13332 13333 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13334 // A variable of class type (or array thereof) that appears in a 13335 // lastprivate clause requires an accessible, unambiguous default 13336 // constructor for the class type, unless the list item is also specified 13337 // in a firstprivate clause. 13338 // A variable of class type (or array thereof) that appears in a 13339 // lastprivate clause requires an accessible, unambiguous copy assignment 13340 // operator for the class type. 13341 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13342 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13343 Type.getUnqualifiedType(), ".lastprivate.src", 13344 D->hasAttrs() ? &D->getAttrs() : nullptr); 13345 DeclRefExpr *PseudoSrcExpr = 13346 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13347 VarDecl *DstVD = 13348 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13349 D->hasAttrs() ? &D->getAttrs() : nullptr); 13350 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13351 // For arrays generate assignment operation for single element and replace 13352 // it by the original array element in CodeGen. 13353 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13354 PseudoDstExpr, PseudoSrcExpr); 13355 if (AssignmentOp.isInvalid()) 13356 continue; 13357 AssignmentOp = 13358 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13359 if (AssignmentOp.isInvalid()) 13360 continue; 13361 13362 DeclRefExpr *Ref = nullptr; 13363 if (!VD && !CurContext->isDependentContext()) { 13364 if (TopDVar.CKind == OMPC_firstprivate) { 13365 Ref = TopDVar.PrivateCopy; 13366 } else { 13367 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13368 if (!isOpenMPCapturedDecl(D)) 13369 ExprCaptures.push_back(Ref->getDecl()); 13370 } 13371 if (TopDVar.CKind == OMPC_firstprivate || 13372 (!isOpenMPCapturedDecl(D) && 13373 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13374 ExprResult RefRes = DefaultLvalueConversion(Ref); 13375 if (!RefRes.isUsable()) 13376 continue; 13377 ExprResult PostUpdateRes = 13378 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13379 RefRes.get()); 13380 if (!PostUpdateRes.isUsable()) 13381 continue; 13382 ExprPostUpdates.push_back( 13383 IgnoredValueConversions(PostUpdateRes.get()).get()); 13384 } 13385 } 13386 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13387 Vars.push_back((VD || CurContext->isDependentContext()) 13388 ? RefExpr->IgnoreParens() 13389 : Ref); 13390 SrcExprs.push_back(PseudoSrcExpr); 13391 DstExprs.push_back(PseudoDstExpr); 13392 AssignmentOps.push_back(AssignmentOp.get()); 13393 } 13394 13395 if (Vars.empty()) 13396 return nullptr; 13397 13398 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13399 Vars, SrcExprs, DstExprs, AssignmentOps, 13400 LPKind, LPKindLoc, ColonLoc, 13401 buildPreInits(Context, ExprCaptures), 13402 buildPostUpdate(*this, ExprPostUpdates)); 13403 } 13404 13405 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13406 SourceLocation StartLoc, 13407 SourceLocation LParenLoc, 13408 SourceLocation EndLoc) { 13409 SmallVector<Expr *, 8> Vars; 13410 for (Expr *RefExpr : VarList) { 13411 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13412 SourceLocation ELoc; 13413 SourceRange ERange; 13414 Expr *SimpleRefExpr = RefExpr; 13415 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13416 if (Res.second) { 13417 // It will be analyzed later. 13418 Vars.push_back(RefExpr); 13419 } 13420 ValueDecl *D = Res.first; 13421 if (!D) 13422 continue; 13423 13424 auto *VD = dyn_cast<VarDecl>(D); 13425 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13426 // in a Construct] 13427 // Variables with the predetermined data-sharing attributes may not be 13428 // listed in data-sharing attributes clauses, except for the cases 13429 // listed below. For these exceptions only, listing a predetermined 13430 // variable in a data-sharing attribute clause is allowed and overrides 13431 // the variable's predetermined data-sharing attributes. 13432 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13433 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13434 DVar.RefExpr) { 13435 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13436 << getOpenMPClauseName(OMPC_shared); 13437 reportOriginalDsa(*this, DSAStack, D, DVar); 13438 continue; 13439 } 13440 13441 DeclRefExpr *Ref = nullptr; 13442 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13443 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13444 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13445 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13446 ? RefExpr->IgnoreParens() 13447 : Ref); 13448 } 13449 13450 if (Vars.empty()) 13451 return nullptr; 13452 13453 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13454 } 13455 13456 namespace { 13457 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13458 DSAStackTy *Stack; 13459 13460 public: 13461 bool VisitDeclRefExpr(DeclRefExpr *E) { 13462 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13463 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13464 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13465 return false; 13466 if (DVar.CKind != OMPC_unknown) 13467 return true; 13468 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13469 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13470 /*FromParent=*/true); 13471 return DVarPrivate.CKind != OMPC_unknown; 13472 } 13473 return false; 13474 } 13475 bool VisitStmt(Stmt *S) { 13476 for (Stmt *Child : S->children()) { 13477 if (Child && Visit(Child)) 13478 return true; 13479 } 13480 return false; 13481 } 13482 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13483 }; 13484 } // namespace 13485 13486 namespace { 13487 // Transform MemberExpression for specified FieldDecl of current class to 13488 // DeclRefExpr to specified OMPCapturedExprDecl. 13489 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13490 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13491 ValueDecl *Field = nullptr; 13492 DeclRefExpr *CapturedExpr = nullptr; 13493 13494 public: 13495 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13496 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13497 13498 ExprResult TransformMemberExpr(MemberExpr *E) { 13499 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13500 E->getMemberDecl() == Field) { 13501 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13502 return CapturedExpr; 13503 } 13504 return BaseTransform::TransformMemberExpr(E); 13505 } 13506 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13507 }; 13508 } // namespace 13509 13510 template <typename T, typename U> 13511 static T filterLookupForUDReductionAndMapper( 13512 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13513 for (U &Set : Lookups) { 13514 for (auto *D : Set) { 13515 if (T Res = Gen(cast<ValueDecl>(D))) 13516 return Res; 13517 } 13518 } 13519 return T(); 13520 } 13521 13522 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13523 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13524 13525 for (auto RD : D->redecls()) { 13526 // Don't bother with extra checks if we already know this one isn't visible. 13527 if (RD == D) 13528 continue; 13529 13530 auto ND = cast<NamedDecl>(RD); 13531 if (LookupResult::isVisible(SemaRef, ND)) 13532 return ND; 13533 } 13534 13535 return nullptr; 13536 } 13537 13538 static void 13539 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13540 SourceLocation Loc, QualType Ty, 13541 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13542 // Find all of the associated namespaces and classes based on the 13543 // arguments we have. 13544 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13545 Sema::AssociatedClassSet AssociatedClasses; 13546 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13547 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13548 AssociatedClasses); 13549 13550 // C++ [basic.lookup.argdep]p3: 13551 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13552 // and let Y be the lookup set produced by argument dependent 13553 // lookup (defined as follows). If X contains [...] then Y is 13554 // empty. Otherwise Y is the set of declarations found in the 13555 // namespaces associated with the argument types as described 13556 // below. The set of declarations found by the lookup of the name 13557 // is the union of X and Y. 13558 // 13559 // Here, we compute Y and add its members to the overloaded 13560 // candidate set. 13561 for (auto *NS : AssociatedNamespaces) { 13562 // When considering an associated namespace, the lookup is the 13563 // same as the lookup performed when the associated namespace is 13564 // used as a qualifier (3.4.3.2) except that: 13565 // 13566 // -- Any using-directives in the associated namespace are 13567 // ignored. 13568 // 13569 // -- Any namespace-scope friend functions declared in 13570 // associated classes are visible within their respective 13571 // namespaces even if they are not visible during an ordinary 13572 // lookup (11.4). 13573 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13574 for (auto *D : R) { 13575 auto *Underlying = D; 13576 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13577 Underlying = USD->getTargetDecl(); 13578 13579 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13580 !isa<OMPDeclareMapperDecl>(Underlying)) 13581 continue; 13582 13583 if (!SemaRef.isVisible(D)) { 13584 D = findAcceptableDecl(SemaRef, D); 13585 if (!D) 13586 continue; 13587 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13588 Underlying = USD->getTargetDecl(); 13589 } 13590 Lookups.emplace_back(); 13591 Lookups.back().addDecl(Underlying); 13592 } 13593 } 13594 } 13595 13596 static ExprResult 13597 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13598 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13599 const DeclarationNameInfo &ReductionId, QualType Ty, 13600 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13601 if (ReductionIdScopeSpec.isInvalid()) 13602 return ExprError(); 13603 SmallVector<UnresolvedSet<8>, 4> Lookups; 13604 if (S) { 13605 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13606 Lookup.suppressDiagnostics(); 13607 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13608 NamedDecl *D = Lookup.getRepresentativeDecl(); 13609 do { 13610 S = S->getParent(); 13611 } while (S && !S->isDeclScope(D)); 13612 if (S) 13613 S = S->getParent(); 13614 Lookups.emplace_back(); 13615 Lookups.back().append(Lookup.begin(), Lookup.end()); 13616 Lookup.clear(); 13617 } 13618 } else if (auto *ULE = 13619 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13620 Lookups.push_back(UnresolvedSet<8>()); 13621 Decl *PrevD = nullptr; 13622 for (NamedDecl *D : ULE->decls()) { 13623 if (D == PrevD) 13624 Lookups.push_back(UnresolvedSet<8>()); 13625 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13626 Lookups.back().addDecl(DRD); 13627 PrevD = D; 13628 } 13629 } 13630 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13631 Ty->isInstantiationDependentType() || 13632 Ty->containsUnexpandedParameterPack() || 13633 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13634 return !D->isInvalidDecl() && 13635 (D->getType()->isDependentType() || 13636 D->getType()->isInstantiationDependentType() || 13637 D->getType()->containsUnexpandedParameterPack()); 13638 })) { 13639 UnresolvedSet<8> ResSet; 13640 for (const UnresolvedSet<8> &Set : Lookups) { 13641 if (Set.empty()) 13642 continue; 13643 ResSet.append(Set.begin(), Set.end()); 13644 // The last item marks the end of all declarations at the specified scope. 13645 ResSet.addDecl(Set[Set.size() - 1]); 13646 } 13647 return UnresolvedLookupExpr::Create( 13648 SemaRef.Context, /*NamingClass=*/nullptr, 13649 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13650 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13651 } 13652 // Lookup inside the classes. 13653 // C++ [over.match.oper]p3: 13654 // For a unary operator @ with an operand of a type whose 13655 // cv-unqualified version is T1, and for a binary operator @ with 13656 // a left operand of a type whose cv-unqualified version is T1 and 13657 // a right operand of a type whose cv-unqualified version is T2, 13658 // three sets of candidate functions, designated member 13659 // candidates, non-member candidates and built-in candidates, are 13660 // constructed as follows: 13661 // -- If T1 is a complete class type or a class currently being 13662 // defined, the set of member candidates is the result of the 13663 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13664 // the set of member candidates is empty. 13665 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13666 Lookup.suppressDiagnostics(); 13667 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13668 // Complete the type if it can be completed. 13669 // If the type is neither complete nor being defined, bail out now. 13670 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13671 TyRec->getDecl()->getDefinition()) { 13672 Lookup.clear(); 13673 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13674 if (Lookup.empty()) { 13675 Lookups.emplace_back(); 13676 Lookups.back().append(Lookup.begin(), Lookup.end()); 13677 } 13678 } 13679 } 13680 // Perform ADL. 13681 if (SemaRef.getLangOpts().CPlusPlus) 13682 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13683 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13684 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13685 if (!D->isInvalidDecl() && 13686 SemaRef.Context.hasSameType(D->getType(), Ty)) 13687 return D; 13688 return nullptr; 13689 })) 13690 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13691 VK_LValue, Loc); 13692 if (SemaRef.getLangOpts().CPlusPlus) { 13693 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13694 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13695 if (!D->isInvalidDecl() && 13696 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13697 !Ty.isMoreQualifiedThan(D->getType())) 13698 return D; 13699 return nullptr; 13700 })) { 13701 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13702 /*DetectVirtual=*/false); 13703 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13704 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13705 VD->getType().getUnqualifiedType()))) { 13706 if (SemaRef.CheckBaseClassAccess( 13707 Loc, VD->getType(), Ty, Paths.front(), 13708 /*DiagID=*/0) != Sema::AR_inaccessible) { 13709 SemaRef.BuildBasePathArray(Paths, BasePath); 13710 return SemaRef.BuildDeclRefExpr( 13711 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13712 } 13713 } 13714 } 13715 } 13716 } 13717 if (ReductionIdScopeSpec.isSet()) { 13718 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 13719 << Ty << Range; 13720 return ExprError(); 13721 } 13722 return ExprEmpty(); 13723 } 13724 13725 namespace { 13726 /// Data for the reduction-based clauses. 13727 struct ReductionData { 13728 /// List of original reduction items. 13729 SmallVector<Expr *, 8> Vars; 13730 /// List of private copies of the reduction items. 13731 SmallVector<Expr *, 8> Privates; 13732 /// LHS expressions for the reduction_op expressions. 13733 SmallVector<Expr *, 8> LHSs; 13734 /// RHS expressions for the reduction_op expressions. 13735 SmallVector<Expr *, 8> RHSs; 13736 /// Reduction operation expression. 13737 SmallVector<Expr *, 8> ReductionOps; 13738 /// Taskgroup descriptors for the corresponding reduction items in 13739 /// in_reduction clauses. 13740 SmallVector<Expr *, 8> TaskgroupDescriptors; 13741 /// List of captures for clause. 13742 SmallVector<Decl *, 4> ExprCaptures; 13743 /// List of postupdate expressions. 13744 SmallVector<Expr *, 4> ExprPostUpdates; 13745 ReductionData() = delete; 13746 /// Reserves required memory for the reduction data. 13747 ReductionData(unsigned Size) { 13748 Vars.reserve(Size); 13749 Privates.reserve(Size); 13750 LHSs.reserve(Size); 13751 RHSs.reserve(Size); 13752 ReductionOps.reserve(Size); 13753 TaskgroupDescriptors.reserve(Size); 13754 ExprCaptures.reserve(Size); 13755 ExprPostUpdates.reserve(Size); 13756 } 13757 /// Stores reduction item and reduction operation only (required for dependent 13758 /// reduction item). 13759 void push(Expr *Item, Expr *ReductionOp) { 13760 Vars.emplace_back(Item); 13761 Privates.emplace_back(nullptr); 13762 LHSs.emplace_back(nullptr); 13763 RHSs.emplace_back(nullptr); 13764 ReductionOps.emplace_back(ReductionOp); 13765 TaskgroupDescriptors.emplace_back(nullptr); 13766 } 13767 /// Stores reduction data. 13768 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13769 Expr *TaskgroupDescriptor) { 13770 Vars.emplace_back(Item); 13771 Privates.emplace_back(Private); 13772 LHSs.emplace_back(LHS); 13773 RHSs.emplace_back(RHS); 13774 ReductionOps.emplace_back(ReductionOp); 13775 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13776 } 13777 }; 13778 } // namespace 13779 13780 static bool checkOMPArraySectionConstantForReduction( 13781 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13782 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13783 const Expr *Length = OASE->getLength(); 13784 if (Length == nullptr) { 13785 // For array sections of the form [1:] or [:], we would need to analyze 13786 // the lower bound... 13787 if (OASE->getColonLoc().isValid()) 13788 return false; 13789 13790 // This is an array subscript which has implicit length 1! 13791 SingleElement = true; 13792 ArraySizes.push_back(llvm::APSInt::get(1)); 13793 } else { 13794 Expr::EvalResult Result; 13795 if (!Length->EvaluateAsInt(Result, Context)) 13796 return false; 13797 13798 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13799 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13800 ArraySizes.push_back(ConstantLengthValue); 13801 } 13802 13803 // Get the base of this array section and walk up from there. 13804 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13805 13806 // We require length = 1 for all array sections except the right-most to 13807 // guarantee that the memory region is contiguous and has no holes in it. 13808 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13809 Length = TempOASE->getLength(); 13810 if (Length == nullptr) { 13811 // For array sections of the form [1:] or [:], we would need to analyze 13812 // the lower bound... 13813 if (OASE->getColonLoc().isValid()) 13814 return false; 13815 13816 // This is an array subscript which has implicit length 1! 13817 ArraySizes.push_back(llvm::APSInt::get(1)); 13818 } else { 13819 Expr::EvalResult Result; 13820 if (!Length->EvaluateAsInt(Result, Context)) 13821 return false; 13822 13823 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13824 if (ConstantLengthValue.getSExtValue() != 1) 13825 return false; 13826 13827 ArraySizes.push_back(ConstantLengthValue); 13828 } 13829 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13830 } 13831 13832 // If we have a single element, we don't need to add the implicit lengths. 13833 if (!SingleElement) { 13834 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13835 // Has implicit length 1! 13836 ArraySizes.push_back(llvm::APSInt::get(1)); 13837 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13838 } 13839 } 13840 13841 // This array section can be privatized as a single value or as a constant 13842 // sized array. 13843 return true; 13844 } 13845 13846 static bool actOnOMPReductionKindClause( 13847 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13848 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13849 SourceLocation ColonLoc, SourceLocation EndLoc, 13850 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13851 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13852 DeclarationName DN = ReductionId.getName(); 13853 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13854 BinaryOperatorKind BOK = BO_Comma; 13855 13856 ASTContext &Context = S.Context; 13857 // OpenMP [2.14.3.6, reduction clause] 13858 // C 13859 // reduction-identifier is either an identifier or one of the following 13860 // operators: +, -, *, &, |, ^, && and || 13861 // C++ 13862 // reduction-identifier is either an id-expression or one of the following 13863 // operators: +, -, *, &, |, ^, && and || 13864 switch (OOK) { 13865 case OO_Plus: 13866 case OO_Minus: 13867 BOK = BO_Add; 13868 break; 13869 case OO_Star: 13870 BOK = BO_Mul; 13871 break; 13872 case OO_Amp: 13873 BOK = BO_And; 13874 break; 13875 case OO_Pipe: 13876 BOK = BO_Or; 13877 break; 13878 case OO_Caret: 13879 BOK = BO_Xor; 13880 break; 13881 case OO_AmpAmp: 13882 BOK = BO_LAnd; 13883 break; 13884 case OO_PipePipe: 13885 BOK = BO_LOr; 13886 break; 13887 case OO_New: 13888 case OO_Delete: 13889 case OO_Array_New: 13890 case OO_Array_Delete: 13891 case OO_Slash: 13892 case OO_Percent: 13893 case OO_Tilde: 13894 case OO_Exclaim: 13895 case OO_Equal: 13896 case OO_Less: 13897 case OO_Greater: 13898 case OO_LessEqual: 13899 case OO_GreaterEqual: 13900 case OO_PlusEqual: 13901 case OO_MinusEqual: 13902 case OO_StarEqual: 13903 case OO_SlashEqual: 13904 case OO_PercentEqual: 13905 case OO_CaretEqual: 13906 case OO_AmpEqual: 13907 case OO_PipeEqual: 13908 case OO_LessLess: 13909 case OO_GreaterGreater: 13910 case OO_LessLessEqual: 13911 case OO_GreaterGreaterEqual: 13912 case OO_EqualEqual: 13913 case OO_ExclaimEqual: 13914 case OO_Spaceship: 13915 case OO_PlusPlus: 13916 case OO_MinusMinus: 13917 case OO_Comma: 13918 case OO_ArrowStar: 13919 case OO_Arrow: 13920 case OO_Call: 13921 case OO_Subscript: 13922 case OO_Conditional: 13923 case OO_Coawait: 13924 case NUM_OVERLOADED_OPERATORS: 13925 llvm_unreachable("Unexpected reduction identifier"); 13926 case OO_None: 13927 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13928 if (II->isStr("max")) 13929 BOK = BO_GT; 13930 else if (II->isStr("min")) 13931 BOK = BO_LT; 13932 } 13933 break; 13934 } 13935 SourceRange ReductionIdRange; 13936 if (ReductionIdScopeSpec.isValid()) 13937 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13938 else 13939 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13940 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13941 13942 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13943 bool FirstIter = true; 13944 for (Expr *RefExpr : VarList) { 13945 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13946 // OpenMP [2.1, C/C++] 13947 // A list item is a variable or array section, subject to the restrictions 13948 // specified in Section 2.4 on page 42 and in each of the sections 13949 // describing clauses and directives for which a list appears. 13950 // OpenMP [2.14.3.3, Restrictions, p.1] 13951 // A variable that is part of another variable (as an array or 13952 // structure element) cannot appear in a private clause. 13953 if (!FirstIter && IR != ER) 13954 ++IR; 13955 FirstIter = false; 13956 SourceLocation ELoc; 13957 SourceRange ERange; 13958 Expr *SimpleRefExpr = RefExpr; 13959 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13960 /*AllowArraySection=*/true); 13961 if (Res.second) { 13962 // Try to find 'declare reduction' corresponding construct before using 13963 // builtin/overloaded operators. 13964 QualType Type = Context.DependentTy; 13965 CXXCastPath BasePath; 13966 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13967 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13968 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13969 Expr *ReductionOp = nullptr; 13970 if (S.CurContext->isDependentContext() && 13971 (DeclareReductionRef.isUnset() || 13972 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13973 ReductionOp = DeclareReductionRef.get(); 13974 // It will be analyzed later. 13975 RD.push(RefExpr, ReductionOp); 13976 } 13977 ValueDecl *D = Res.first; 13978 if (!D) 13979 continue; 13980 13981 Expr *TaskgroupDescriptor = nullptr; 13982 QualType Type; 13983 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13984 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13985 if (ASE) { 13986 Type = ASE->getType().getNonReferenceType(); 13987 } else if (OASE) { 13988 QualType BaseType = 13989 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13990 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13991 Type = ATy->getElementType(); 13992 else 13993 Type = BaseType->getPointeeType(); 13994 Type = Type.getNonReferenceType(); 13995 } else { 13996 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13997 } 13998 auto *VD = dyn_cast<VarDecl>(D); 13999 14000 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14001 // A variable that appears in a private clause must not have an incomplete 14002 // type or a reference type. 14003 if (S.RequireCompleteType(ELoc, D->getType(), 14004 diag::err_omp_reduction_incomplete_type)) 14005 continue; 14006 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14007 // A list item that appears in a reduction clause must not be 14008 // const-qualified. 14009 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14010 /*AcceptIfMutable*/ false, ASE || OASE)) 14011 continue; 14012 14013 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14014 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14015 // If a list-item is a reference type then it must bind to the same object 14016 // for all threads of the team. 14017 if (!ASE && !OASE) { 14018 if (VD) { 14019 VarDecl *VDDef = VD->getDefinition(); 14020 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14021 DSARefChecker Check(Stack); 14022 if (Check.Visit(VDDef->getInit())) { 14023 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14024 << getOpenMPClauseName(ClauseKind) << ERange; 14025 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14026 continue; 14027 } 14028 } 14029 } 14030 14031 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14032 // in a Construct] 14033 // Variables with the predetermined data-sharing attributes may not be 14034 // listed in data-sharing attributes clauses, except for the cases 14035 // listed below. For these exceptions only, listing a predetermined 14036 // variable in a data-sharing attribute clause is allowed and overrides 14037 // the variable's predetermined data-sharing attributes. 14038 // OpenMP [2.14.3.6, Restrictions, p.3] 14039 // Any number of reduction clauses can be specified on the directive, 14040 // but a list item can appear only once in the reduction clauses for that 14041 // directive. 14042 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14043 if (DVar.CKind == OMPC_reduction) { 14044 S.Diag(ELoc, diag::err_omp_once_referenced) 14045 << getOpenMPClauseName(ClauseKind); 14046 if (DVar.RefExpr) 14047 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14048 continue; 14049 } 14050 if (DVar.CKind != OMPC_unknown) { 14051 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14052 << getOpenMPClauseName(DVar.CKind) 14053 << getOpenMPClauseName(OMPC_reduction); 14054 reportOriginalDsa(S, Stack, D, DVar); 14055 continue; 14056 } 14057 14058 // OpenMP [2.14.3.6, Restrictions, p.1] 14059 // A list item that appears in a reduction clause of a worksharing 14060 // construct must be shared in the parallel regions to which any of the 14061 // worksharing regions arising from the worksharing construct bind. 14062 if (isOpenMPWorksharingDirective(CurrDir) && 14063 !isOpenMPParallelDirective(CurrDir) && 14064 !isOpenMPTeamsDirective(CurrDir)) { 14065 DVar = Stack->getImplicitDSA(D, true); 14066 if (DVar.CKind != OMPC_shared) { 14067 S.Diag(ELoc, diag::err_omp_required_access) 14068 << getOpenMPClauseName(OMPC_reduction) 14069 << getOpenMPClauseName(OMPC_shared); 14070 reportOriginalDsa(S, Stack, D, DVar); 14071 continue; 14072 } 14073 } 14074 } 14075 14076 // Try to find 'declare reduction' corresponding construct before using 14077 // builtin/overloaded operators. 14078 CXXCastPath BasePath; 14079 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14080 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14081 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14082 if (DeclareReductionRef.isInvalid()) 14083 continue; 14084 if (S.CurContext->isDependentContext() && 14085 (DeclareReductionRef.isUnset() || 14086 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14087 RD.push(RefExpr, DeclareReductionRef.get()); 14088 continue; 14089 } 14090 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14091 // Not allowed reduction identifier is found. 14092 S.Diag(ReductionId.getBeginLoc(), 14093 diag::err_omp_unknown_reduction_identifier) 14094 << Type << ReductionIdRange; 14095 continue; 14096 } 14097 14098 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14099 // The type of a list item that appears in a reduction clause must be valid 14100 // for the reduction-identifier. For a max or min reduction in C, the type 14101 // of the list item must be an allowed arithmetic data type: char, int, 14102 // float, double, or _Bool, possibly modified with long, short, signed, or 14103 // unsigned. For a max or min reduction in C++, the type of the list item 14104 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14105 // double, or bool, possibly modified with long, short, signed, or unsigned. 14106 if (DeclareReductionRef.isUnset()) { 14107 if ((BOK == BO_GT || BOK == BO_LT) && 14108 !(Type->isScalarType() || 14109 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14110 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14111 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14112 if (!ASE && !OASE) { 14113 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14114 VarDecl::DeclarationOnly; 14115 S.Diag(D->getLocation(), 14116 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14117 << D; 14118 } 14119 continue; 14120 } 14121 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14122 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14123 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14124 << getOpenMPClauseName(ClauseKind); 14125 if (!ASE && !OASE) { 14126 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14127 VarDecl::DeclarationOnly; 14128 S.Diag(D->getLocation(), 14129 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14130 << D; 14131 } 14132 continue; 14133 } 14134 } 14135 14136 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14137 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14138 D->hasAttrs() ? &D->getAttrs() : nullptr); 14139 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14140 D->hasAttrs() ? &D->getAttrs() : nullptr); 14141 QualType PrivateTy = Type; 14142 14143 // Try if we can determine constant lengths for all array sections and avoid 14144 // the VLA. 14145 bool ConstantLengthOASE = false; 14146 if (OASE) { 14147 bool SingleElement; 14148 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14149 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14150 Context, OASE, SingleElement, ArraySizes); 14151 14152 // If we don't have a single element, we must emit a constant array type. 14153 if (ConstantLengthOASE && !SingleElement) { 14154 for (llvm::APSInt &Size : ArraySizes) 14155 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14156 ArrayType::Normal, 14157 /*IndexTypeQuals=*/0); 14158 } 14159 } 14160 14161 if ((OASE && !ConstantLengthOASE) || 14162 (!OASE && !ASE && 14163 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14164 if (!Context.getTargetInfo().isVLASupported()) { 14165 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14166 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14167 S.Diag(ELoc, diag::note_vla_unsupported); 14168 } else { 14169 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14170 S.targetDiag(ELoc, diag::note_vla_unsupported); 14171 } 14172 continue; 14173 } 14174 // For arrays/array sections only: 14175 // Create pseudo array type for private copy. The size for this array will 14176 // be generated during codegen. 14177 // For array subscripts or single variables Private Ty is the same as Type 14178 // (type of the variable or single array element). 14179 PrivateTy = Context.getVariableArrayType( 14180 Type, 14181 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14182 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14183 } else if (!ASE && !OASE && 14184 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14185 PrivateTy = D->getType().getNonReferenceType(); 14186 } 14187 // Private copy. 14188 VarDecl *PrivateVD = 14189 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14190 D->hasAttrs() ? &D->getAttrs() : nullptr, 14191 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14192 // Add initializer for private variable. 14193 Expr *Init = nullptr; 14194 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14195 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14196 if (DeclareReductionRef.isUsable()) { 14197 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14198 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14199 if (DRD->getInitializer()) { 14200 Init = DRDRef; 14201 RHSVD->setInit(DRDRef); 14202 RHSVD->setInitStyle(VarDecl::CallInit); 14203 } 14204 } else { 14205 switch (BOK) { 14206 case BO_Add: 14207 case BO_Xor: 14208 case BO_Or: 14209 case BO_LOr: 14210 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14211 if (Type->isScalarType() || Type->isAnyComplexType()) 14212 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14213 break; 14214 case BO_Mul: 14215 case BO_LAnd: 14216 if (Type->isScalarType() || Type->isAnyComplexType()) { 14217 // '*' and '&&' reduction ops - initializer is '1'. 14218 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14219 } 14220 break; 14221 case BO_And: { 14222 // '&' reduction op - initializer is '~0'. 14223 QualType OrigType = Type; 14224 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14225 Type = ComplexTy->getElementType(); 14226 if (Type->isRealFloatingType()) { 14227 llvm::APFloat InitValue = 14228 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14229 /*isIEEE=*/true); 14230 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14231 Type, ELoc); 14232 } else if (Type->isScalarType()) { 14233 uint64_t Size = Context.getTypeSize(Type); 14234 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14235 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14236 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14237 } 14238 if (Init && OrigType->isAnyComplexType()) { 14239 // Init = 0xFFFF + 0xFFFFi; 14240 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14241 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14242 } 14243 Type = OrigType; 14244 break; 14245 } 14246 case BO_LT: 14247 case BO_GT: { 14248 // 'min' reduction op - initializer is 'Largest representable number in 14249 // the reduction list item type'. 14250 // 'max' reduction op - initializer is 'Least representable number in 14251 // the reduction list item type'. 14252 if (Type->isIntegerType() || Type->isPointerType()) { 14253 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14254 uint64_t Size = Context.getTypeSize(Type); 14255 QualType IntTy = 14256 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14257 llvm::APInt InitValue = 14258 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14259 : llvm::APInt::getMinValue(Size) 14260 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14261 : llvm::APInt::getMaxValue(Size); 14262 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14263 if (Type->isPointerType()) { 14264 // Cast to pointer type. 14265 ExprResult CastExpr = S.BuildCStyleCastExpr( 14266 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14267 if (CastExpr.isInvalid()) 14268 continue; 14269 Init = CastExpr.get(); 14270 } 14271 } else if (Type->isRealFloatingType()) { 14272 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14273 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14274 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14275 Type, ELoc); 14276 } 14277 break; 14278 } 14279 case BO_PtrMemD: 14280 case BO_PtrMemI: 14281 case BO_MulAssign: 14282 case BO_Div: 14283 case BO_Rem: 14284 case BO_Sub: 14285 case BO_Shl: 14286 case BO_Shr: 14287 case BO_LE: 14288 case BO_GE: 14289 case BO_EQ: 14290 case BO_NE: 14291 case BO_Cmp: 14292 case BO_AndAssign: 14293 case BO_XorAssign: 14294 case BO_OrAssign: 14295 case BO_Assign: 14296 case BO_AddAssign: 14297 case BO_SubAssign: 14298 case BO_DivAssign: 14299 case BO_RemAssign: 14300 case BO_ShlAssign: 14301 case BO_ShrAssign: 14302 case BO_Comma: 14303 llvm_unreachable("Unexpected reduction operation"); 14304 } 14305 } 14306 if (Init && DeclareReductionRef.isUnset()) 14307 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14308 else if (!Init) 14309 S.ActOnUninitializedDecl(RHSVD); 14310 if (RHSVD->isInvalidDecl()) 14311 continue; 14312 if (!RHSVD->hasInit() && 14313 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14314 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14315 << Type << ReductionIdRange; 14316 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14317 VarDecl::DeclarationOnly; 14318 S.Diag(D->getLocation(), 14319 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14320 << D; 14321 continue; 14322 } 14323 // Store initializer for single element in private copy. Will be used during 14324 // codegen. 14325 PrivateVD->setInit(RHSVD->getInit()); 14326 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14327 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14328 ExprResult ReductionOp; 14329 if (DeclareReductionRef.isUsable()) { 14330 QualType RedTy = DeclareReductionRef.get()->getType(); 14331 QualType PtrRedTy = Context.getPointerType(RedTy); 14332 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14333 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14334 if (!BasePath.empty()) { 14335 LHS = S.DefaultLvalueConversion(LHS.get()); 14336 RHS = S.DefaultLvalueConversion(RHS.get()); 14337 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14338 CK_UncheckedDerivedToBase, LHS.get(), 14339 &BasePath, LHS.get()->getValueKind()); 14340 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14341 CK_UncheckedDerivedToBase, RHS.get(), 14342 &BasePath, RHS.get()->getValueKind()); 14343 } 14344 FunctionProtoType::ExtProtoInfo EPI; 14345 QualType Params[] = {PtrRedTy, PtrRedTy}; 14346 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14347 auto *OVE = new (Context) OpaqueValueExpr( 14348 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14349 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14350 Expr *Args[] = {LHS.get(), RHS.get()}; 14351 ReductionOp = 14352 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14353 } else { 14354 ReductionOp = S.BuildBinOp( 14355 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14356 if (ReductionOp.isUsable()) { 14357 if (BOK != BO_LT && BOK != BO_GT) { 14358 ReductionOp = 14359 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14360 BO_Assign, LHSDRE, ReductionOp.get()); 14361 } else { 14362 auto *ConditionalOp = new (Context) 14363 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14364 Type, VK_LValue, OK_Ordinary); 14365 ReductionOp = 14366 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14367 BO_Assign, LHSDRE, ConditionalOp); 14368 } 14369 if (ReductionOp.isUsable()) 14370 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14371 /*DiscardedValue*/ false); 14372 } 14373 if (!ReductionOp.isUsable()) 14374 continue; 14375 } 14376 14377 // OpenMP [2.15.4.6, Restrictions, p.2] 14378 // A list item that appears in an in_reduction clause of a task construct 14379 // must appear in a task_reduction clause of a construct associated with a 14380 // taskgroup region that includes the participating task in its taskgroup 14381 // set. The construct associated with the innermost region that meets this 14382 // condition must specify the same reduction-identifier as the in_reduction 14383 // clause. 14384 if (ClauseKind == OMPC_in_reduction) { 14385 SourceRange ParentSR; 14386 BinaryOperatorKind ParentBOK; 14387 const Expr *ParentReductionOp; 14388 Expr *ParentBOKTD, *ParentReductionOpTD; 14389 DSAStackTy::DSAVarData ParentBOKDSA = 14390 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14391 ParentBOKTD); 14392 DSAStackTy::DSAVarData ParentReductionOpDSA = 14393 Stack->getTopMostTaskgroupReductionData( 14394 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14395 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14396 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14397 if (!IsParentBOK && !IsParentReductionOp) { 14398 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 14399 continue; 14400 } 14401 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14402 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 14403 IsParentReductionOp) { 14404 bool EmitError = true; 14405 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14406 llvm::FoldingSetNodeID RedId, ParentRedId; 14407 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14408 DeclareReductionRef.get()->Profile(RedId, Context, 14409 /*Canonical=*/true); 14410 EmitError = RedId != ParentRedId; 14411 } 14412 if (EmitError) { 14413 S.Diag(ReductionId.getBeginLoc(), 14414 diag::err_omp_reduction_identifier_mismatch) 14415 << ReductionIdRange << RefExpr->getSourceRange(); 14416 S.Diag(ParentSR.getBegin(), 14417 diag::note_omp_previous_reduction_identifier) 14418 << ParentSR 14419 << (IsParentBOK ? ParentBOKDSA.RefExpr 14420 : ParentReductionOpDSA.RefExpr) 14421 ->getSourceRange(); 14422 continue; 14423 } 14424 } 14425 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14426 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 14427 } 14428 14429 DeclRefExpr *Ref = nullptr; 14430 Expr *VarsExpr = RefExpr->IgnoreParens(); 14431 if (!VD && !S.CurContext->isDependentContext()) { 14432 if (ASE || OASE) { 14433 TransformExprToCaptures RebuildToCapture(S, D); 14434 VarsExpr = 14435 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14436 Ref = RebuildToCapture.getCapturedExpr(); 14437 } else { 14438 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14439 } 14440 if (!S.isOpenMPCapturedDecl(D)) { 14441 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14442 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14443 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14444 if (!RefRes.isUsable()) 14445 continue; 14446 ExprResult PostUpdateRes = 14447 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14448 RefRes.get()); 14449 if (!PostUpdateRes.isUsable()) 14450 continue; 14451 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14452 Stack->getCurrentDirective() == OMPD_taskgroup) { 14453 S.Diag(RefExpr->getExprLoc(), 14454 diag::err_omp_reduction_non_addressable_expression) 14455 << RefExpr->getSourceRange(); 14456 continue; 14457 } 14458 RD.ExprPostUpdates.emplace_back( 14459 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14460 } 14461 } 14462 } 14463 // All reduction items are still marked as reduction (to do not increase 14464 // code base size). 14465 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 14466 if (CurrDir == OMPD_taskgroup) { 14467 if (DeclareReductionRef.isUsable()) 14468 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14469 DeclareReductionRef.get()); 14470 else 14471 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14472 } 14473 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14474 TaskgroupDescriptor); 14475 } 14476 return RD.Vars.empty(); 14477 } 14478 14479 OMPClause *Sema::ActOnOpenMPReductionClause( 14480 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14481 SourceLocation ColonLoc, SourceLocation EndLoc, 14482 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14483 ArrayRef<Expr *> UnresolvedReductions) { 14484 ReductionData RD(VarList.size()); 14485 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14486 StartLoc, LParenLoc, ColonLoc, EndLoc, 14487 ReductionIdScopeSpec, ReductionId, 14488 UnresolvedReductions, RD)) 14489 return nullptr; 14490 14491 return OMPReductionClause::Create( 14492 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14493 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14494 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14495 buildPreInits(Context, RD.ExprCaptures), 14496 buildPostUpdate(*this, RD.ExprPostUpdates)); 14497 } 14498 14499 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14500 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14501 SourceLocation ColonLoc, SourceLocation EndLoc, 14502 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14503 ArrayRef<Expr *> UnresolvedReductions) { 14504 ReductionData RD(VarList.size()); 14505 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14506 StartLoc, LParenLoc, ColonLoc, EndLoc, 14507 ReductionIdScopeSpec, ReductionId, 14508 UnresolvedReductions, RD)) 14509 return nullptr; 14510 14511 return OMPTaskReductionClause::Create( 14512 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14513 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14514 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14515 buildPreInits(Context, RD.ExprCaptures), 14516 buildPostUpdate(*this, RD.ExprPostUpdates)); 14517 } 14518 14519 OMPClause *Sema::ActOnOpenMPInReductionClause( 14520 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14521 SourceLocation ColonLoc, SourceLocation EndLoc, 14522 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14523 ArrayRef<Expr *> UnresolvedReductions) { 14524 ReductionData RD(VarList.size()); 14525 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14526 StartLoc, LParenLoc, ColonLoc, EndLoc, 14527 ReductionIdScopeSpec, ReductionId, 14528 UnresolvedReductions, RD)) 14529 return nullptr; 14530 14531 return OMPInReductionClause::Create( 14532 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14533 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14534 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14535 buildPreInits(Context, RD.ExprCaptures), 14536 buildPostUpdate(*this, RD.ExprPostUpdates)); 14537 } 14538 14539 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14540 SourceLocation LinLoc) { 14541 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14542 LinKind == OMPC_LINEAR_unknown) { 14543 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14544 return true; 14545 } 14546 return false; 14547 } 14548 14549 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14550 OpenMPLinearClauseKind LinKind, 14551 QualType Type) { 14552 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14553 // A variable must not have an incomplete type or a reference type. 14554 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14555 return true; 14556 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14557 !Type->isReferenceType()) { 14558 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14559 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14560 return true; 14561 } 14562 Type = Type.getNonReferenceType(); 14563 14564 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14565 // A variable that is privatized must not have a const-qualified type 14566 // unless it is of class type with a mutable member. This restriction does 14567 // not apply to the firstprivate clause. 14568 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14569 return true; 14570 14571 // A list item must be of integral or pointer type. 14572 Type = Type.getUnqualifiedType().getCanonicalType(); 14573 const auto *Ty = Type.getTypePtrOrNull(); 14574 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 14575 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 14576 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14577 if (D) { 14578 bool IsDecl = 14579 !VD || 14580 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14581 Diag(D->getLocation(), 14582 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14583 << D; 14584 } 14585 return true; 14586 } 14587 return false; 14588 } 14589 14590 OMPClause *Sema::ActOnOpenMPLinearClause( 14591 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14592 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14593 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14594 SmallVector<Expr *, 8> Vars; 14595 SmallVector<Expr *, 8> Privates; 14596 SmallVector<Expr *, 8> Inits; 14597 SmallVector<Decl *, 4> ExprCaptures; 14598 SmallVector<Expr *, 4> ExprPostUpdates; 14599 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14600 LinKind = OMPC_LINEAR_val; 14601 for (Expr *RefExpr : VarList) { 14602 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14603 SourceLocation ELoc; 14604 SourceRange ERange; 14605 Expr *SimpleRefExpr = RefExpr; 14606 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14607 if (Res.second) { 14608 // It will be analyzed later. 14609 Vars.push_back(RefExpr); 14610 Privates.push_back(nullptr); 14611 Inits.push_back(nullptr); 14612 } 14613 ValueDecl *D = Res.first; 14614 if (!D) 14615 continue; 14616 14617 QualType Type = D->getType(); 14618 auto *VD = dyn_cast<VarDecl>(D); 14619 14620 // OpenMP [2.14.3.7, linear clause] 14621 // A list-item cannot appear in more than one linear clause. 14622 // A list-item that appears in a linear clause cannot appear in any 14623 // other data-sharing attribute clause. 14624 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14625 if (DVar.RefExpr) { 14626 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14627 << getOpenMPClauseName(OMPC_linear); 14628 reportOriginalDsa(*this, DSAStack, D, DVar); 14629 continue; 14630 } 14631 14632 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14633 continue; 14634 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14635 14636 // Build private copy of original var. 14637 VarDecl *Private = 14638 buildVarDecl(*this, ELoc, Type, D->getName(), 14639 D->hasAttrs() ? &D->getAttrs() : nullptr, 14640 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14641 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14642 // Build var to save initial value. 14643 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14644 Expr *InitExpr; 14645 DeclRefExpr *Ref = nullptr; 14646 if (!VD && !CurContext->isDependentContext()) { 14647 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14648 if (!isOpenMPCapturedDecl(D)) { 14649 ExprCaptures.push_back(Ref->getDecl()); 14650 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14651 ExprResult RefRes = DefaultLvalueConversion(Ref); 14652 if (!RefRes.isUsable()) 14653 continue; 14654 ExprResult PostUpdateRes = 14655 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14656 SimpleRefExpr, RefRes.get()); 14657 if (!PostUpdateRes.isUsable()) 14658 continue; 14659 ExprPostUpdates.push_back( 14660 IgnoredValueConversions(PostUpdateRes.get()).get()); 14661 } 14662 } 14663 } 14664 if (LinKind == OMPC_LINEAR_uval) 14665 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14666 else 14667 InitExpr = VD ? SimpleRefExpr : Ref; 14668 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14669 /*DirectInit=*/false); 14670 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14671 14672 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14673 Vars.push_back((VD || CurContext->isDependentContext()) 14674 ? RefExpr->IgnoreParens() 14675 : Ref); 14676 Privates.push_back(PrivateRef); 14677 Inits.push_back(InitRef); 14678 } 14679 14680 if (Vars.empty()) 14681 return nullptr; 14682 14683 Expr *StepExpr = Step; 14684 Expr *CalcStepExpr = nullptr; 14685 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14686 !Step->isInstantiationDependent() && 14687 !Step->containsUnexpandedParameterPack()) { 14688 SourceLocation StepLoc = Step->getBeginLoc(); 14689 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14690 if (Val.isInvalid()) 14691 return nullptr; 14692 StepExpr = Val.get(); 14693 14694 // Build var to save the step value. 14695 VarDecl *SaveVar = 14696 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14697 ExprResult SaveRef = 14698 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14699 ExprResult CalcStep = 14700 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14701 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14702 14703 // Warn about zero linear step (it would be probably better specified as 14704 // making corresponding variables 'const'). 14705 llvm::APSInt Result; 14706 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14707 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14708 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14709 << (Vars.size() > 1); 14710 if (!IsConstant && CalcStep.isUsable()) { 14711 // Calculate the step beforehand instead of doing this on each iteration. 14712 // (This is not used if the number of iterations may be kfold-ed). 14713 CalcStepExpr = CalcStep.get(); 14714 } 14715 } 14716 14717 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14718 ColonLoc, EndLoc, Vars, Privates, Inits, 14719 StepExpr, CalcStepExpr, 14720 buildPreInits(Context, ExprCaptures), 14721 buildPostUpdate(*this, ExprPostUpdates)); 14722 } 14723 14724 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14725 Expr *NumIterations, Sema &SemaRef, 14726 Scope *S, DSAStackTy *Stack) { 14727 // Walk the vars and build update/final expressions for the CodeGen. 14728 SmallVector<Expr *, 8> Updates; 14729 SmallVector<Expr *, 8> Finals; 14730 SmallVector<Expr *, 8> UsedExprs; 14731 Expr *Step = Clause.getStep(); 14732 Expr *CalcStep = Clause.getCalcStep(); 14733 // OpenMP [2.14.3.7, linear clause] 14734 // If linear-step is not specified it is assumed to be 1. 14735 if (!Step) 14736 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14737 else if (CalcStep) 14738 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14739 bool HasErrors = false; 14740 auto CurInit = Clause.inits().begin(); 14741 auto CurPrivate = Clause.privates().begin(); 14742 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14743 for (Expr *RefExpr : Clause.varlists()) { 14744 SourceLocation ELoc; 14745 SourceRange ERange; 14746 Expr *SimpleRefExpr = RefExpr; 14747 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14748 ValueDecl *D = Res.first; 14749 if (Res.second || !D) { 14750 Updates.push_back(nullptr); 14751 Finals.push_back(nullptr); 14752 HasErrors = true; 14753 continue; 14754 } 14755 auto &&Info = Stack->isLoopControlVariable(D); 14756 // OpenMP [2.15.11, distribute simd Construct] 14757 // A list item may not appear in a linear clause, unless it is the loop 14758 // iteration variable. 14759 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14760 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14761 SemaRef.Diag(ELoc, 14762 diag::err_omp_linear_distribute_var_non_loop_iteration); 14763 Updates.push_back(nullptr); 14764 Finals.push_back(nullptr); 14765 HasErrors = true; 14766 continue; 14767 } 14768 Expr *InitExpr = *CurInit; 14769 14770 // Build privatized reference to the current linear var. 14771 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14772 Expr *CapturedRef; 14773 if (LinKind == OMPC_LINEAR_uval) 14774 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14775 else 14776 CapturedRef = 14777 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14778 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14779 /*RefersToCapture=*/true); 14780 14781 // Build update: Var = InitExpr + IV * Step 14782 ExprResult Update; 14783 if (!Info.first) 14784 Update = buildCounterUpdate( 14785 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14786 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14787 else 14788 Update = *CurPrivate; 14789 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14790 /*DiscardedValue*/ false); 14791 14792 // Build final: Var = InitExpr + NumIterations * Step 14793 ExprResult Final; 14794 if (!Info.first) 14795 Final = 14796 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14797 InitExpr, NumIterations, Step, /*Subtract=*/false, 14798 /*IsNonRectangularLB=*/false); 14799 else 14800 Final = *CurPrivate; 14801 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14802 /*DiscardedValue*/ false); 14803 14804 if (!Update.isUsable() || !Final.isUsable()) { 14805 Updates.push_back(nullptr); 14806 Finals.push_back(nullptr); 14807 UsedExprs.push_back(nullptr); 14808 HasErrors = true; 14809 } else { 14810 Updates.push_back(Update.get()); 14811 Finals.push_back(Final.get()); 14812 if (!Info.first) 14813 UsedExprs.push_back(SimpleRefExpr); 14814 } 14815 ++CurInit; 14816 ++CurPrivate; 14817 } 14818 if (Expr *S = Clause.getStep()) 14819 UsedExprs.push_back(S); 14820 // Fill the remaining part with the nullptr. 14821 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14822 Clause.setUpdates(Updates); 14823 Clause.setFinals(Finals); 14824 Clause.setUsedExprs(UsedExprs); 14825 return HasErrors; 14826 } 14827 14828 OMPClause *Sema::ActOnOpenMPAlignedClause( 14829 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14830 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14831 SmallVector<Expr *, 8> Vars; 14832 for (Expr *RefExpr : VarList) { 14833 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14834 SourceLocation ELoc; 14835 SourceRange ERange; 14836 Expr *SimpleRefExpr = RefExpr; 14837 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14838 if (Res.second) { 14839 // It will be analyzed later. 14840 Vars.push_back(RefExpr); 14841 } 14842 ValueDecl *D = Res.first; 14843 if (!D) 14844 continue; 14845 14846 QualType QType = D->getType(); 14847 auto *VD = dyn_cast<VarDecl>(D); 14848 14849 // OpenMP [2.8.1, simd construct, Restrictions] 14850 // The type of list items appearing in the aligned clause must be 14851 // array, pointer, reference to array, or reference to pointer. 14852 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14853 const Type *Ty = QType.getTypePtrOrNull(); 14854 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14855 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14856 << QType << getLangOpts().CPlusPlus << ERange; 14857 bool IsDecl = 14858 !VD || 14859 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14860 Diag(D->getLocation(), 14861 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14862 << D; 14863 continue; 14864 } 14865 14866 // OpenMP [2.8.1, simd construct, Restrictions] 14867 // A list-item cannot appear in more than one aligned clause. 14868 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14869 Diag(ELoc, diag::err_omp_used_in_clause_twice) 14870 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 14871 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14872 << getOpenMPClauseName(OMPC_aligned); 14873 continue; 14874 } 14875 14876 DeclRefExpr *Ref = nullptr; 14877 if (!VD && isOpenMPCapturedDecl(D)) 14878 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14879 Vars.push_back(DefaultFunctionArrayConversion( 14880 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14881 .get()); 14882 } 14883 14884 // OpenMP [2.8.1, simd construct, Description] 14885 // The parameter of the aligned clause, alignment, must be a constant 14886 // positive integer expression. 14887 // If no optional parameter is specified, implementation-defined default 14888 // alignments for SIMD instructions on the target platforms are assumed. 14889 if (Alignment != nullptr) { 14890 ExprResult AlignResult = 14891 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14892 if (AlignResult.isInvalid()) 14893 return nullptr; 14894 Alignment = AlignResult.get(); 14895 } 14896 if (Vars.empty()) 14897 return nullptr; 14898 14899 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14900 EndLoc, Vars, Alignment); 14901 } 14902 14903 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14904 SourceLocation StartLoc, 14905 SourceLocation LParenLoc, 14906 SourceLocation EndLoc) { 14907 SmallVector<Expr *, 8> Vars; 14908 SmallVector<Expr *, 8> SrcExprs; 14909 SmallVector<Expr *, 8> DstExprs; 14910 SmallVector<Expr *, 8> AssignmentOps; 14911 for (Expr *RefExpr : VarList) { 14912 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14913 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14914 // It will be analyzed later. 14915 Vars.push_back(RefExpr); 14916 SrcExprs.push_back(nullptr); 14917 DstExprs.push_back(nullptr); 14918 AssignmentOps.push_back(nullptr); 14919 continue; 14920 } 14921 14922 SourceLocation ELoc = RefExpr->getExprLoc(); 14923 // OpenMP [2.1, C/C++] 14924 // A list item is a variable name. 14925 // OpenMP [2.14.4.1, Restrictions, p.1] 14926 // A list item that appears in a copyin clause must be threadprivate. 14927 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14928 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14929 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14930 << 0 << RefExpr->getSourceRange(); 14931 continue; 14932 } 14933 14934 Decl *D = DE->getDecl(); 14935 auto *VD = cast<VarDecl>(D); 14936 14937 QualType Type = VD->getType(); 14938 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14939 // It will be analyzed later. 14940 Vars.push_back(DE); 14941 SrcExprs.push_back(nullptr); 14942 DstExprs.push_back(nullptr); 14943 AssignmentOps.push_back(nullptr); 14944 continue; 14945 } 14946 14947 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14948 // A list item that appears in a copyin clause must be threadprivate. 14949 if (!DSAStack->isThreadPrivate(VD)) { 14950 Diag(ELoc, diag::err_omp_required_access) 14951 << getOpenMPClauseName(OMPC_copyin) 14952 << getOpenMPDirectiveName(OMPD_threadprivate); 14953 continue; 14954 } 14955 14956 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14957 // A variable of class type (or array thereof) that appears in a 14958 // copyin clause requires an accessible, unambiguous copy assignment 14959 // operator for the class type. 14960 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14961 VarDecl *SrcVD = 14962 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14963 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14964 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14965 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14966 VarDecl *DstVD = 14967 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14968 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14969 DeclRefExpr *PseudoDstExpr = 14970 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14971 // For arrays generate assignment operation for single element and replace 14972 // it by the original array element in CodeGen. 14973 ExprResult AssignmentOp = 14974 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14975 PseudoSrcExpr); 14976 if (AssignmentOp.isInvalid()) 14977 continue; 14978 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14979 /*DiscardedValue*/ false); 14980 if (AssignmentOp.isInvalid()) 14981 continue; 14982 14983 DSAStack->addDSA(VD, DE, OMPC_copyin); 14984 Vars.push_back(DE); 14985 SrcExprs.push_back(PseudoSrcExpr); 14986 DstExprs.push_back(PseudoDstExpr); 14987 AssignmentOps.push_back(AssignmentOp.get()); 14988 } 14989 14990 if (Vars.empty()) 14991 return nullptr; 14992 14993 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14994 SrcExprs, DstExprs, AssignmentOps); 14995 } 14996 14997 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14998 SourceLocation StartLoc, 14999 SourceLocation LParenLoc, 15000 SourceLocation EndLoc) { 15001 SmallVector<Expr *, 8> Vars; 15002 SmallVector<Expr *, 8> SrcExprs; 15003 SmallVector<Expr *, 8> DstExprs; 15004 SmallVector<Expr *, 8> AssignmentOps; 15005 for (Expr *RefExpr : VarList) { 15006 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15007 SourceLocation ELoc; 15008 SourceRange ERange; 15009 Expr *SimpleRefExpr = RefExpr; 15010 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15011 if (Res.second) { 15012 // It will be analyzed later. 15013 Vars.push_back(RefExpr); 15014 SrcExprs.push_back(nullptr); 15015 DstExprs.push_back(nullptr); 15016 AssignmentOps.push_back(nullptr); 15017 } 15018 ValueDecl *D = Res.first; 15019 if (!D) 15020 continue; 15021 15022 QualType Type = D->getType(); 15023 auto *VD = dyn_cast<VarDecl>(D); 15024 15025 // OpenMP [2.14.4.2, Restrictions, p.2] 15026 // A list item that appears in a copyprivate clause may not appear in a 15027 // private or firstprivate clause on the single construct. 15028 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15029 DSAStackTy::DSAVarData DVar = 15030 DSAStack->getTopDSA(D, /*FromParent=*/false); 15031 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15032 DVar.RefExpr) { 15033 Diag(ELoc, diag::err_omp_wrong_dsa) 15034 << getOpenMPClauseName(DVar.CKind) 15035 << getOpenMPClauseName(OMPC_copyprivate); 15036 reportOriginalDsa(*this, DSAStack, D, DVar); 15037 continue; 15038 } 15039 15040 // OpenMP [2.11.4.2, Restrictions, p.1] 15041 // All list items that appear in a copyprivate clause must be either 15042 // threadprivate or private in the enclosing context. 15043 if (DVar.CKind == OMPC_unknown) { 15044 DVar = DSAStack->getImplicitDSA(D, false); 15045 if (DVar.CKind == OMPC_shared) { 15046 Diag(ELoc, diag::err_omp_required_access) 15047 << getOpenMPClauseName(OMPC_copyprivate) 15048 << "threadprivate or private in the enclosing context"; 15049 reportOriginalDsa(*this, DSAStack, D, DVar); 15050 continue; 15051 } 15052 } 15053 } 15054 15055 // Variably modified types are not supported. 15056 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15057 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15058 << getOpenMPClauseName(OMPC_copyprivate) << Type 15059 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15060 bool IsDecl = 15061 !VD || 15062 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15063 Diag(D->getLocation(), 15064 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15065 << D; 15066 continue; 15067 } 15068 15069 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15070 // A variable of class type (or array thereof) that appears in a 15071 // copyin clause requires an accessible, unambiguous copy assignment 15072 // operator for the class type. 15073 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15074 .getUnqualifiedType(); 15075 VarDecl *SrcVD = 15076 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15077 D->hasAttrs() ? &D->getAttrs() : nullptr); 15078 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15079 VarDecl *DstVD = 15080 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15081 D->hasAttrs() ? &D->getAttrs() : nullptr); 15082 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15083 ExprResult AssignmentOp = BuildBinOp( 15084 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15085 if (AssignmentOp.isInvalid()) 15086 continue; 15087 AssignmentOp = 15088 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15089 if (AssignmentOp.isInvalid()) 15090 continue; 15091 15092 // No need to mark vars as copyprivate, they are already threadprivate or 15093 // implicitly private. 15094 assert(VD || isOpenMPCapturedDecl(D)); 15095 Vars.push_back( 15096 VD ? RefExpr->IgnoreParens() 15097 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15098 SrcExprs.push_back(PseudoSrcExpr); 15099 DstExprs.push_back(PseudoDstExpr); 15100 AssignmentOps.push_back(AssignmentOp.get()); 15101 } 15102 15103 if (Vars.empty()) 15104 return nullptr; 15105 15106 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15107 Vars, SrcExprs, DstExprs, AssignmentOps); 15108 } 15109 15110 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15111 SourceLocation StartLoc, 15112 SourceLocation LParenLoc, 15113 SourceLocation EndLoc) { 15114 if (VarList.empty()) 15115 return nullptr; 15116 15117 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15118 } 15119 15120 OMPClause * 15121 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 15122 SourceLocation DepLoc, SourceLocation ColonLoc, 15123 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15124 SourceLocation LParenLoc, SourceLocation EndLoc) { 15125 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15126 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15127 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15128 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15129 return nullptr; 15130 } 15131 if (DSAStack->getCurrentDirective() != OMPD_ordered && 15132 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15133 DepKind == OMPC_DEPEND_sink)) { 15134 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 15135 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15136 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 15137 /*Last=*/OMPC_DEPEND_unknown, Except) 15138 << getOpenMPClauseName(OMPC_depend); 15139 return nullptr; 15140 } 15141 SmallVector<Expr *, 8> Vars; 15142 DSAStackTy::OperatorOffsetTy OpsOffs; 15143 llvm::APSInt DepCounter(/*BitWidth=*/32); 15144 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15145 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15146 if (const Expr *OrderedCountExpr = 15147 DSAStack->getParentOrderedRegionParam().first) { 15148 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15149 TotalDepCount.setIsUnsigned(/*Val=*/true); 15150 } 15151 } 15152 for (Expr *RefExpr : VarList) { 15153 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15154 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15155 // It will be analyzed later. 15156 Vars.push_back(RefExpr); 15157 continue; 15158 } 15159 15160 SourceLocation ELoc = RefExpr->getExprLoc(); 15161 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15162 if (DepKind == OMPC_DEPEND_sink) { 15163 if (DSAStack->getParentOrderedRegionParam().first && 15164 DepCounter >= TotalDepCount) { 15165 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15166 continue; 15167 } 15168 ++DepCounter; 15169 // OpenMP [2.13.9, Summary] 15170 // depend(dependence-type : vec), where dependence-type is: 15171 // 'sink' and where vec is the iteration vector, which has the form: 15172 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15173 // where n is the value specified by the ordered clause in the loop 15174 // directive, xi denotes the loop iteration variable of the i-th nested 15175 // loop associated with the loop directive, and di is a constant 15176 // non-negative integer. 15177 if (CurContext->isDependentContext()) { 15178 // It will be analyzed later. 15179 Vars.push_back(RefExpr); 15180 continue; 15181 } 15182 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15183 OverloadedOperatorKind OOK = OO_None; 15184 SourceLocation OOLoc; 15185 Expr *LHS = SimpleExpr; 15186 Expr *RHS = nullptr; 15187 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15188 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15189 OOLoc = BO->getOperatorLoc(); 15190 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15191 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15192 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15193 OOK = OCE->getOperator(); 15194 OOLoc = OCE->getOperatorLoc(); 15195 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15196 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15197 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15198 OOK = MCE->getMethodDecl() 15199 ->getNameInfo() 15200 .getName() 15201 .getCXXOverloadedOperator(); 15202 OOLoc = MCE->getCallee()->getExprLoc(); 15203 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15204 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15205 } 15206 SourceLocation ELoc; 15207 SourceRange ERange; 15208 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15209 if (Res.second) { 15210 // It will be analyzed later. 15211 Vars.push_back(RefExpr); 15212 } 15213 ValueDecl *D = Res.first; 15214 if (!D) 15215 continue; 15216 15217 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15218 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15219 continue; 15220 } 15221 if (RHS) { 15222 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15223 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15224 if (RHSRes.isInvalid()) 15225 continue; 15226 } 15227 if (!CurContext->isDependentContext() && 15228 DSAStack->getParentOrderedRegionParam().first && 15229 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15230 const ValueDecl *VD = 15231 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15232 if (VD) 15233 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15234 << 1 << VD; 15235 else 15236 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15237 continue; 15238 } 15239 OpsOffs.emplace_back(RHS, OOK); 15240 } else { 15241 // OpenMP 5.0 [2.17.11, Restrictions] 15242 // List items used in depend clauses cannot be zero-length array sections. 15243 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15244 if (OASE) { 15245 const Expr *Length = OASE->getLength(); 15246 Expr::EvalResult Result; 15247 if (Length && !Length->isValueDependent() && 15248 Length->EvaluateAsInt(Result, Context) && 15249 Result.Val.getInt().isNullValue()) { 15250 Diag(ELoc, 15251 diag::err_omp_depend_zero_length_array_section_not_allowed) 15252 << SimpleExpr->getSourceRange(); 15253 continue; 15254 } 15255 } 15256 15257 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15258 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15259 (ASE && 15260 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 15261 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15262 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15263 << RefExpr->getSourceRange(); 15264 continue; 15265 } 15266 15267 ExprResult Res; 15268 { 15269 Sema::TentativeAnalysisScope Trap(*this); 15270 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15271 RefExpr->IgnoreParenImpCasts()); 15272 } 15273 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 15274 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15275 << RefExpr->getSourceRange(); 15276 continue; 15277 } 15278 } 15279 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15280 } 15281 15282 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15283 TotalDepCount > VarList.size() && 15284 DSAStack->getParentOrderedRegionParam().first && 15285 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15286 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15287 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15288 } 15289 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15290 Vars.empty()) 15291 return nullptr; 15292 15293 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15294 DepKind, DepLoc, ColonLoc, Vars, 15295 TotalDepCount.getZExtValue()); 15296 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15297 DSAStack->isParentOrderedRegion()) 15298 DSAStack->addDoacrossDependClause(C, OpsOffs); 15299 return C; 15300 } 15301 15302 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 15303 SourceLocation LParenLoc, 15304 SourceLocation EndLoc) { 15305 Expr *ValExpr = Device; 15306 Stmt *HelperValStmt = nullptr; 15307 15308 // OpenMP [2.9.1, Restrictions] 15309 // The device expression must evaluate to a non-negative integer value. 15310 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15311 /*StrictlyPositive=*/false)) 15312 return nullptr; 15313 15314 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15315 OpenMPDirectiveKind CaptureRegion = 15316 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15317 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15318 ValExpr = MakeFullExpr(ValExpr).get(); 15319 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15320 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15321 HelperValStmt = buildPreInits(Context, Captures); 15322 } 15323 15324 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 15325 StartLoc, LParenLoc, EndLoc); 15326 } 15327 15328 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15329 DSAStackTy *Stack, QualType QTy, 15330 bool FullCheck = true) { 15331 NamedDecl *ND; 15332 if (QTy->isIncompleteType(&ND)) { 15333 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15334 return false; 15335 } 15336 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15337 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15338 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15339 return true; 15340 } 15341 15342 /// Return true if it can be proven that the provided array expression 15343 /// (array section or array subscript) does NOT specify the whole size of the 15344 /// array whose base type is \a BaseQTy. 15345 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15346 const Expr *E, 15347 QualType BaseQTy) { 15348 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15349 15350 // If this is an array subscript, it refers to the whole size if the size of 15351 // the dimension is constant and equals 1. Also, an array section assumes the 15352 // format of an array subscript if no colon is used. 15353 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15354 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15355 return ATy->getSize().getSExtValue() != 1; 15356 // Size can't be evaluated statically. 15357 return false; 15358 } 15359 15360 assert(OASE && "Expecting array section if not an array subscript."); 15361 const Expr *LowerBound = OASE->getLowerBound(); 15362 const Expr *Length = OASE->getLength(); 15363 15364 // If there is a lower bound that does not evaluates to zero, we are not 15365 // covering the whole dimension. 15366 if (LowerBound) { 15367 Expr::EvalResult Result; 15368 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15369 return false; // Can't get the integer value as a constant. 15370 15371 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15372 if (ConstLowerBound.getSExtValue()) 15373 return true; 15374 } 15375 15376 // If we don't have a length we covering the whole dimension. 15377 if (!Length) 15378 return false; 15379 15380 // If the base is a pointer, we don't have a way to get the size of the 15381 // pointee. 15382 if (BaseQTy->isPointerType()) 15383 return false; 15384 15385 // We can only check if the length is the same as the size of the dimension 15386 // if we have a constant array. 15387 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15388 if (!CATy) 15389 return false; 15390 15391 Expr::EvalResult Result; 15392 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15393 return false; // Can't get the integer value as a constant. 15394 15395 llvm::APSInt ConstLength = Result.Val.getInt(); 15396 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15397 } 15398 15399 // Return true if it can be proven that the provided array expression (array 15400 // section or array subscript) does NOT specify a single element of the array 15401 // whose base type is \a BaseQTy. 15402 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15403 const Expr *E, 15404 QualType BaseQTy) { 15405 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15406 15407 // An array subscript always refer to a single element. Also, an array section 15408 // assumes the format of an array subscript if no colon is used. 15409 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 15410 return false; 15411 15412 assert(OASE && "Expecting array section if not an array subscript."); 15413 const Expr *Length = OASE->getLength(); 15414 15415 // If we don't have a length we have to check if the array has unitary size 15416 // for this dimension. Also, we should always expect a length if the base type 15417 // is pointer. 15418 if (!Length) { 15419 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15420 return ATy->getSize().getSExtValue() != 1; 15421 // We cannot assume anything. 15422 return false; 15423 } 15424 15425 // Check if the length evaluates to 1. 15426 Expr::EvalResult Result; 15427 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15428 return false; // Can't get the integer value as a constant. 15429 15430 llvm::APSInt ConstLength = Result.Val.getInt(); 15431 return ConstLength.getSExtValue() != 1; 15432 } 15433 15434 // The base of elements of list in a map clause have to be either: 15435 // - a reference to variable or field. 15436 // - a member expression. 15437 // - an array expression. 15438 // 15439 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 15440 // reference to 'r'. 15441 // 15442 // If we have: 15443 // 15444 // struct SS { 15445 // Bla S; 15446 // foo() { 15447 // #pragma omp target map (S.Arr[:12]); 15448 // } 15449 // } 15450 // 15451 // We want to retrieve the member expression 'this->S'; 15452 15453 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 15454 // If a list item is an array section, it must specify contiguous storage. 15455 // 15456 // For this restriction it is sufficient that we make sure only references 15457 // to variables or fields and array expressions, and that no array sections 15458 // exist except in the rightmost expression (unless they cover the whole 15459 // dimension of the array). E.g. these would be invalid: 15460 // 15461 // r.ArrS[3:5].Arr[6:7] 15462 // 15463 // r.ArrS[3:5].x 15464 // 15465 // but these would be valid: 15466 // r.ArrS[3].Arr[6:7] 15467 // 15468 // r.ArrS[3].x 15469 namespace { 15470 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 15471 Sema &SemaRef; 15472 OpenMPClauseKind CKind = OMPC_unknown; 15473 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 15474 bool NoDiagnose = false; 15475 const Expr *RelevantExpr = nullptr; 15476 bool AllowUnitySizeArraySection = true; 15477 bool AllowWholeSizeArraySection = true; 15478 SourceLocation ELoc; 15479 SourceRange ERange; 15480 15481 void emitErrorMsg() { 15482 if (!NoDiagnose) { 15483 // If nothing else worked, this is not a valid map clause expression. 15484 SemaRef.Diag(ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15485 << ERange; 15486 } 15487 } 15488 15489 public: 15490 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 15491 if (!isa<VarDecl>(DRE->getDecl())) { 15492 emitErrorMsg(); 15493 return false; 15494 } 15495 RelevantExpr = DRE; 15496 // Record the component. 15497 Components.emplace_back(DRE, DRE->getDecl()); 15498 return true; 15499 } 15500 15501 bool VisitMemberExpr(MemberExpr *ME) { 15502 Expr *E = ME; 15503 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 15504 15505 if (isa<CXXThisExpr>(BaseE)) 15506 // We found a base expression: this->Val. 15507 RelevantExpr = ME; 15508 else 15509 E = BaseE; 15510 15511 if (!isa<FieldDecl>(ME->getMemberDecl())) { 15512 if (!NoDiagnose) { 15513 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15514 << ME->getSourceRange(); 15515 return false; 15516 } 15517 if (RelevantExpr) 15518 return false; 15519 return Visit(E); 15520 } 15521 15522 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 15523 15524 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15525 // A bit-field cannot appear in a map clause. 15526 // 15527 if (FD->isBitField()) { 15528 if (!NoDiagnose) { 15529 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15530 << ME->getSourceRange() << getOpenMPClauseName(CKind); 15531 return false; 15532 } 15533 if (RelevantExpr) 15534 return false; 15535 return Visit(E); 15536 } 15537 15538 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15539 // If the type of a list item is a reference to a type T then the type 15540 // will be considered to be T for all purposes of this clause. 15541 QualType CurType = BaseE->getType().getNonReferenceType(); 15542 15543 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15544 // A list item cannot be a variable that is a member of a structure with 15545 // a union type. 15546 // 15547 if (CurType->isUnionType()) { 15548 if (!NoDiagnose) { 15549 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15550 << ME->getSourceRange(); 15551 return false; 15552 } 15553 return RelevantExpr || Visit(E); 15554 } 15555 15556 // If we got a member expression, we should not expect any array section 15557 // before that: 15558 // 15559 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15560 // If a list item is an element of a structure, only the rightmost symbol 15561 // of the variable reference can be an array section. 15562 // 15563 AllowUnitySizeArraySection = false; 15564 AllowWholeSizeArraySection = false; 15565 15566 // Record the component. 15567 Components.emplace_back(ME, FD); 15568 return RelevantExpr || Visit(E); 15569 } 15570 15571 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 15572 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 15573 15574 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15575 if (!NoDiagnose) { 15576 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15577 << 0 << AE->getSourceRange(); 15578 return false; 15579 } 15580 return RelevantExpr || Visit(E); 15581 } 15582 15583 // If we got an array subscript that express the whole dimension we 15584 // can have any array expressions before. If it only expressing part of 15585 // the dimension, we can only have unitary-size array expressions. 15586 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 15587 E->getType())) 15588 AllowWholeSizeArraySection = false; 15589 15590 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 15591 Expr::EvalResult Result; 15592 if (!AE->getIdx()->isValueDependent() && 15593 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 15594 !Result.Val.getInt().isNullValue()) { 15595 SemaRef.Diag(AE->getIdx()->getExprLoc(), 15596 diag::err_omp_invalid_map_this_expr); 15597 SemaRef.Diag(AE->getIdx()->getExprLoc(), 15598 diag::note_omp_invalid_subscript_on_this_ptr_map); 15599 } 15600 RelevantExpr = TE; 15601 } 15602 15603 // Record the component - we don't have any declaration associated. 15604 Components.emplace_back(AE, nullptr); 15605 15606 return RelevantExpr || Visit(E); 15607 } 15608 15609 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 15610 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15611 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15612 QualType CurType = 15613 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15614 15615 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15616 // If the type of a list item is a reference to a type T then the type 15617 // will be considered to be T for all purposes of this clause. 15618 if (CurType->isReferenceType()) 15619 CurType = CurType->getPointeeType(); 15620 15621 bool IsPointer = CurType->isAnyPointerType(); 15622 15623 if (!IsPointer && !CurType->isArrayType()) { 15624 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15625 << 0 << OASE->getSourceRange(); 15626 return false; 15627 } 15628 15629 bool NotWhole = 15630 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 15631 bool NotUnity = 15632 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 15633 15634 if (AllowWholeSizeArraySection) { 15635 // Any array section is currently allowed. Allowing a whole size array 15636 // section implies allowing a unity array section as well. 15637 // 15638 // If this array section refers to the whole dimension we can still 15639 // accept other array sections before this one, except if the base is a 15640 // pointer. Otherwise, only unitary sections are accepted. 15641 if (NotWhole || IsPointer) 15642 AllowWholeSizeArraySection = false; 15643 } else if (AllowUnitySizeArraySection && NotUnity) { 15644 // A unity or whole array section is not allowed and that is not 15645 // compatible with the properties of the current array section. 15646 SemaRef.Diag( 15647 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15648 << OASE->getSourceRange(); 15649 return false; 15650 } 15651 15652 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15653 Expr::EvalResult ResultR; 15654 Expr::EvalResult ResultL; 15655 if (!OASE->getLength()->isValueDependent() && 15656 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 15657 !ResultR.Val.getInt().isOneValue()) { 15658 SemaRef.Diag(OASE->getLength()->getExprLoc(), 15659 diag::err_omp_invalid_map_this_expr); 15660 SemaRef.Diag(OASE->getLength()->getExprLoc(), 15661 diag::note_omp_invalid_length_on_this_ptr_mapping); 15662 } 15663 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 15664 OASE->getLowerBound()->EvaluateAsInt(ResultL, 15665 SemaRef.getASTContext()) && 15666 !ResultL.Val.getInt().isNullValue()) { 15667 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 15668 diag::err_omp_invalid_map_this_expr); 15669 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 15670 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15671 } 15672 RelevantExpr = TE; 15673 } 15674 15675 // Record the component - we don't have any declaration associated. 15676 Components.emplace_back(OASE, nullptr); 15677 return RelevantExpr || Visit(E); 15678 } 15679 bool VisitStmt(Stmt *) { 15680 emitErrorMsg(); 15681 return false; 15682 } 15683 const Expr *getFoundBase() const { 15684 return RelevantExpr; 15685 } 15686 explicit MapBaseChecker( 15687 Sema &SemaRef, OpenMPClauseKind CKind, 15688 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 15689 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 15690 : SemaRef(SemaRef), CKind(CKind), Components(Components), 15691 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 15692 }; 15693 } // namespace 15694 15695 /// Return the expression of the base of the mappable expression or null if it 15696 /// cannot be determined and do all the necessary checks to see if the expression 15697 /// is valid as a standalone mappable expression. In the process, record all the 15698 /// components of the expression. 15699 static const Expr *checkMapClauseExpressionBase( 15700 Sema &SemaRef, Expr *E, 15701 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 15702 OpenMPClauseKind CKind, bool NoDiagnose) { 15703 SourceLocation ELoc = E->getExprLoc(); 15704 SourceRange ERange = E->getSourceRange(); 15705 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 15706 ERange); 15707 if (Checker.Visit(E->IgnoreParenImpCasts())) 15708 return Checker.getFoundBase(); 15709 return nullptr; 15710 } 15711 15712 // Return true if expression E associated with value VD has conflicts with other 15713 // map information. 15714 static bool checkMapConflicts( 15715 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15716 bool CurrentRegionOnly, 15717 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15718 OpenMPClauseKind CKind) { 15719 assert(VD && E); 15720 SourceLocation ELoc = E->getExprLoc(); 15721 SourceRange ERange = E->getSourceRange(); 15722 15723 // In order to easily check the conflicts we need to match each component of 15724 // the expression under test with the components of the expressions that are 15725 // already in the stack. 15726 15727 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15728 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15729 "Map clause expression with unexpected base!"); 15730 15731 // Variables to help detecting enclosing problems in data environment nests. 15732 bool IsEnclosedByDataEnvironmentExpr = false; 15733 const Expr *EnclosingExpr = nullptr; 15734 15735 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15736 VD, CurrentRegionOnly, 15737 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15738 ERange, CKind, &EnclosingExpr, 15739 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15740 StackComponents, 15741 OpenMPClauseKind) { 15742 assert(!StackComponents.empty() && 15743 "Map clause expression with no components!"); 15744 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15745 "Map clause expression with unexpected base!"); 15746 (void)VD; 15747 15748 // The whole expression in the stack. 15749 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15750 15751 // Expressions must start from the same base. Here we detect at which 15752 // point both expressions diverge from each other and see if we can 15753 // detect if the memory referred to both expressions is contiguous and 15754 // do not overlap. 15755 auto CI = CurComponents.rbegin(); 15756 auto CE = CurComponents.rend(); 15757 auto SI = StackComponents.rbegin(); 15758 auto SE = StackComponents.rend(); 15759 for (; CI != CE && SI != SE; ++CI, ++SI) { 15760 15761 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15762 // At most one list item can be an array item derived from a given 15763 // variable in map clauses of the same construct. 15764 if (CurrentRegionOnly && 15765 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15766 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15767 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15768 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15769 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15770 diag::err_omp_multiple_array_items_in_map_clause) 15771 << CI->getAssociatedExpression()->getSourceRange(); 15772 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15773 diag::note_used_here) 15774 << SI->getAssociatedExpression()->getSourceRange(); 15775 return true; 15776 } 15777 15778 // Do both expressions have the same kind? 15779 if (CI->getAssociatedExpression()->getStmtClass() != 15780 SI->getAssociatedExpression()->getStmtClass()) 15781 break; 15782 15783 // Are we dealing with different variables/fields? 15784 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15785 break; 15786 } 15787 // Check if the extra components of the expressions in the enclosing 15788 // data environment are redundant for the current base declaration. 15789 // If they are, the maps completely overlap, which is legal. 15790 for (; SI != SE; ++SI) { 15791 QualType Type; 15792 if (const auto *ASE = 15793 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15794 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15795 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15796 SI->getAssociatedExpression())) { 15797 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15798 Type = 15799 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15800 } 15801 if (Type.isNull() || Type->isAnyPointerType() || 15802 checkArrayExpressionDoesNotReferToWholeSize( 15803 SemaRef, SI->getAssociatedExpression(), Type)) 15804 break; 15805 } 15806 15807 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15808 // List items of map clauses in the same construct must not share 15809 // original storage. 15810 // 15811 // If the expressions are exactly the same or one is a subset of the 15812 // other, it means they are sharing storage. 15813 if (CI == CE && SI == SE) { 15814 if (CurrentRegionOnly) { 15815 if (CKind == OMPC_map) { 15816 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15817 } else { 15818 assert(CKind == OMPC_to || CKind == OMPC_from); 15819 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15820 << ERange; 15821 } 15822 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15823 << RE->getSourceRange(); 15824 return true; 15825 } 15826 // If we find the same expression in the enclosing data environment, 15827 // that is legal. 15828 IsEnclosedByDataEnvironmentExpr = true; 15829 return false; 15830 } 15831 15832 QualType DerivedType = 15833 std::prev(CI)->getAssociatedDeclaration()->getType(); 15834 SourceLocation DerivedLoc = 15835 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15836 15837 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15838 // If the type of a list item is a reference to a type T then the type 15839 // will be considered to be T for all purposes of this clause. 15840 DerivedType = DerivedType.getNonReferenceType(); 15841 15842 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15843 // A variable for which the type is pointer and an array section 15844 // derived from that variable must not appear as list items of map 15845 // clauses of the same construct. 15846 // 15847 // Also, cover one of the cases in: 15848 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15849 // If any part of the original storage of a list item has corresponding 15850 // storage in the device data environment, all of the original storage 15851 // must have corresponding storage in the device data environment. 15852 // 15853 if (DerivedType->isAnyPointerType()) { 15854 if (CI == CE || SI == SE) { 15855 SemaRef.Diag( 15856 DerivedLoc, 15857 diag::err_omp_pointer_mapped_along_with_derived_section) 15858 << DerivedLoc; 15859 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15860 << RE->getSourceRange(); 15861 return true; 15862 } 15863 if (CI->getAssociatedExpression()->getStmtClass() != 15864 SI->getAssociatedExpression()->getStmtClass() || 15865 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15866 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15867 assert(CI != CE && SI != SE); 15868 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15869 << DerivedLoc; 15870 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15871 << RE->getSourceRange(); 15872 return true; 15873 } 15874 } 15875 15876 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15877 // List items of map clauses in the same construct must not share 15878 // original storage. 15879 // 15880 // An expression is a subset of the other. 15881 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15882 if (CKind == OMPC_map) { 15883 if (CI != CE || SI != SE) { 15884 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15885 // a pointer. 15886 auto Begin = 15887 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15888 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15889 auto It = Begin; 15890 while (It != End && !It->getAssociatedDeclaration()) 15891 std::advance(It, 1); 15892 assert(It != End && 15893 "Expected at least one component with the declaration."); 15894 if (It != Begin && It->getAssociatedDeclaration() 15895 ->getType() 15896 .getCanonicalType() 15897 ->isAnyPointerType()) { 15898 IsEnclosedByDataEnvironmentExpr = false; 15899 EnclosingExpr = nullptr; 15900 return false; 15901 } 15902 } 15903 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15904 } else { 15905 assert(CKind == OMPC_to || CKind == OMPC_from); 15906 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15907 << ERange; 15908 } 15909 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15910 << RE->getSourceRange(); 15911 return true; 15912 } 15913 15914 // The current expression uses the same base as other expression in the 15915 // data environment but does not contain it completely. 15916 if (!CurrentRegionOnly && SI != SE) 15917 EnclosingExpr = RE; 15918 15919 // The current expression is a subset of the expression in the data 15920 // environment. 15921 IsEnclosedByDataEnvironmentExpr |= 15922 (!CurrentRegionOnly && CI != CE && SI == SE); 15923 15924 return false; 15925 }); 15926 15927 if (CurrentRegionOnly) 15928 return FoundError; 15929 15930 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15931 // If any part of the original storage of a list item has corresponding 15932 // storage in the device data environment, all of the original storage must 15933 // have corresponding storage in the device data environment. 15934 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15935 // If a list item is an element of a structure, and a different element of 15936 // the structure has a corresponding list item in the device data environment 15937 // prior to a task encountering the construct associated with the map clause, 15938 // then the list item must also have a corresponding list item in the device 15939 // data environment prior to the task encountering the construct. 15940 // 15941 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15942 SemaRef.Diag(ELoc, 15943 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15944 << ERange; 15945 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15946 << EnclosingExpr->getSourceRange(); 15947 return true; 15948 } 15949 15950 return FoundError; 15951 } 15952 15953 // Look up the user-defined mapper given the mapper name and mapped type, and 15954 // build a reference to it. 15955 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15956 CXXScopeSpec &MapperIdScopeSpec, 15957 const DeclarationNameInfo &MapperId, 15958 QualType Type, 15959 Expr *UnresolvedMapper) { 15960 if (MapperIdScopeSpec.isInvalid()) 15961 return ExprError(); 15962 // Get the actual type for the array type. 15963 if (Type->isArrayType()) { 15964 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15965 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15966 } 15967 // Find all user-defined mappers with the given MapperId. 15968 SmallVector<UnresolvedSet<8>, 4> Lookups; 15969 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15970 Lookup.suppressDiagnostics(); 15971 if (S) { 15972 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15973 NamedDecl *D = Lookup.getRepresentativeDecl(); 15974 while (S && !S->isDeclScope(D)) 15975 S = S->getParent(); 15976 if (S) 15977 S = S->getParent(); 15978 Lookups.emplace_back(); 15979 Lookups.back().append(Lookup.begin(), Lookup.end()); 15980 Lookup.clear(); 15981 } 15982 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15983 // Extract the user-defined mappers with the given MapperId. 15984 Lookups.push_back(UnresolvedSet<8>()); 15985 for (NamedDecl *D : ULE->decls()) { 15986 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15987 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15988 Lookups.back().addDecl(DMD); 15989 } 15990 } 15991 // Defer the lookup for dependent types. The results will be passed through 15992 // UnresolvedMapper on instantiation. 15993 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15994 Type->isInstantiationDependentType() || 15995 Type->containsUnexpandedParameterPack() || 15996 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15997 return !D->isInvalidDecl() && 15998 (D->getType()->isDependentType() || 15999 D->getType()->isInstantiationDependentType() || 16000 D->getType()->containsUnexpandedParameterPack()); 16001 })) { 16002 UnresolvedSet<8> URS; 16003 for (const UnresolvedSet<8> &Set : Lookups) { 16004 if (Set.empty()) 16005 continue; 16006 URS.append(Set.begin(), Set.end()); 16007 } 16008 return UnresolvedLookupExpr::Create( 16009 SemaRef.Context, /*NamingClass=*/nullptr, 16010 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16011 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16012 } 16013 SourceLocation Loc = MapperId.getLoc(); 16014 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16015 // The type must be of struct, union or class type in C and C++ 16016 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16017 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16018 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16019 return ExprError(); 16020 } 16021 // Perform argument dependent lookup. 16022 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16023 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16024 // Return the first user-defined mapper with the desired type. 16025 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16026 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16027 if (!D->isInvalidDecl() && 16028 SemaRef.Context.hasSameType(D->getType(), Type)) 16029 return D; 16030 return nullptr; 16031 })) 16032 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16033 // Find the first user-defined mapper with a type derived from the desired 16034 // type. 16035 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16036 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16037 if (!D->isInvalidDecl() && 16038 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16039 !Type.isMoreQualifiedThan(D->getType())) 16040 return D; 16041 return nullptr; 16042 })) { 16043 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16044 /*DetectVirtual=*/false); 16045 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16046 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16047 VD->getType().getUnqualifiedType()))) { 16048 if (SemaRef.CheckBaseClassAccess( 16049 Loc, VD->getType(), Type, Paths.front(), 16050 /*DiagID=*/0) != Sema::AR_inaccessible) { 16051 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16052 } 16053 } 16054 } 16055 } 16056 // Report error if a mapper is specified, but cannot be found. 16057 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 16058 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 16059 << Type << MapperId.getName(); 16060 return ExprError(); 16061 } 16062 return ExprEmpty(); 16063 } 16064 16065 namespace { 16066 // Utility struct that gathers all the related lists associated with a mappable 16067 // expression. 16068 struct MappableVarListInfo { 16069 // The list of expressions. 16070 ArrayRef<Expr *> VarList; 16071 // The list of processed expressions. 16072 SmallVector<Expr *, 16> ProcessedVarList; 16073 // The mappble components for each expression. 16074 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 16075 // The base declaration of the variable. 16076 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 16077 // The reference to the user-defined mapper associated with every expression. 16078 SmallVector<Expr *, 16> UDMapperList; 16079 16080 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 16081 // We have a list of components and base declarations for each entry in the 16082 // variable list. 16083 VarComponents.reserve(VarList.size()); 16084 VarBaseDeclarations.reserve(VarList.size()); 16085 } 16086 }; 16087 } 16088 16089 // Check the validity of the provided variable list for the provided clause kind 16090 // \a CKind. In the check process the valid expressions, mappable expression 16091 // components, variables, and user-defined mappers are extracted and used to 16092 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 16093 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 16094 // and \a MapperId are expected to be valid if the clause kind is 'map'. 16095 static void checkMappableExpressionList( 16096 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 16097 MappableVarListInfo &MVLI, SourceLocation StartLoc, 16098 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 16099 ArrayRef<Expr *> UnresolvedMappers, 16100 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 16101 bool IsMapTypeImplicit = false) { 16102 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 16103 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 16104 "Unexpected clause kind with mappable expressions!"); 16105 16106 // If the identifier of user-defined mapper is not specified, it is "default". 16107 // We do not change the actual name in this clause to distinguish whether a 16108 // mapper is specified explicitly, i.e., it is not explicitly specified when 16109 // MapperId.getName() is empty. 16110 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 16111 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 16112 MapperId.setName(DeclNames.getIdentifier( 16113 &SemaRef.getASTContext().Idents.get("default"))); 16114 } 16115 16116 // Iterators to find the current unresolved mapper expression. 16117 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 16118 bool UpdateUMIt = false; 16119 Expr *UnresolvedMapper = nullptr; 16120 16121 // Keep track of the mappable components and base declarations in this clause. 16122 // Each entry in the list is going to have a list of components associated. We 16123 // record each set of the components so that we can build the clause later on. 16124 // In the end we should have the same amount of declarations and component 16125 // lists. 16126 16127 for (Expr *RE : MVLI.VarList) { 16128 assert(RE && "Null expr in omp to/from/map clause"); 16129 SourceLocation ELoc = RE->getExprLoc(); 16130 16131 // Find the current unresolved mapper expression. 16132 if (UpdateUMIt && UMIt != UMEnd) { 16133 UMIt++; 16134 assert( 16135 UMIt != UMEnd && 16136 "Expect the size of UnresolvedMappers to match with that of VarList"); 16137 } 16138 UpdateUMIt = true; 16139 if (UMIt != UMEnd) 16140 UnresolvedMapper = *UMIt; 16141 16142 const Expr *VE = RE->IgnoreParenLValueCasts(); 16143 16144 if (VE->isValueDependent() || VE->isTypeDependent() || 16145 VE->isInstantiationDependent() || 16146 VE->containsUnexpandedParameterPack()) { 16147 // Try to find the associated user-defined mapper. 16148 ExprResult ER = buildUserDefinedMapperRef( 16149 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16150 VE->getType().getCanonicalType(), UnresolvedMapper); 16151 if (ER.isInvalid()) 16152 continue; 16153 MVLI.UDMapperList.push_back(ER.get()); 16154 // We can only analyze this information once the missing information is 16155 // resolved. 16156 MVLI.ProcessedVarList.push_back(RE); 16157 continue; 16158 } 16159 16160 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16161 16162 if (!RE->IgnoreParenImpCasts()->isLValue()) { 16163 SemaRef.Diag(ELoc, 16164 diag::err_omp_expected_named_var_member_or_array_expression) 16165 << RE->getSourceRange(); 16166 continue; 16167 } 16168 16169 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16170 ValueDecl *CurDeclaration = nullptr; 16171 16172 // Obtain the array or member expression bases if required. Also, fill the 16173 // components array with all the components identified in the process. 16174 const Expr *BE = checkMapClauseExpressionBase( 16175 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16176 if (!BE) 16177 continue; 16178 16179 assert(!CurComponents.empty() && 16180 "Invalid mappable expression information."); 16181 16182 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16183 // Add store "this" pointer to class in DSAStackTy for future checking 16184 DSAS->addMappedClassesQualTypes(TE->getType()); 16185 // Try to find the associated user-defined mapper. 16186 ExprResult ER = buildUserDefinedMapperRef( 16187 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16188 VE->getType().getCanonicalType(), UnresolvedMapper); 16189 if (ER.isInvalid()) 16190 continue; 16191 MVLI.UDMapperList.push_back(ER.get()); 16192 // Skip restriction checking for variable or field declarations 16193 MVLI.ProcessedVarList.push_back(RE); 16194 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16195 MVLI.VarComponents.back().append(CurComponents.begin(), 16196 CurComponents.end()); 16197 MVLI.VarBaseDeclarations.push_back(nullptr); 16198 continue; 16199 } 16200 16201 // For the following checks, we rely on the base declaration which is 16202 // expected to be associated with the last component. The declaration is 16203 // expected to be a variable or a field (if 'this' is being mapped). 16204 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16205 assert(CurDeclaration && "Null decl on map clause."); 16206 assert( 16207 CurDeclaration->isCanonicalDecl() && 16208 "Expecting components to have associated only canonical declarations."); 16209 16210 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16211 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16212 16213 assert((VD || FD) && "Only variables or fields are expected here!"); 16214 (void)FD; 16215 16216 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16217 // threadprivate variables cannot appear in a map clause. 16218 // OpenMP 4.5 [2.10.5, target update Construct] 16219 // threadprivate variables cannot appear in a from clause. 16220 if (VD && DSAS->isThreadPrivate(VD)) { 16221 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16222 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16223 << getOpenMPClauseName(CKind); 16224 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16225 continue; 16226 } 16227 16228 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16229 // A list item cannot appear in both a map clause and a data-sharing 16230 // attribute clause on the same construct. 16231 16232 // Check conflicts with other map clause expressions. We check the conflicts 16233 // with the current construct separately from the enclosing data 16234 // environment, because the restrictions are different. We only have to 16235 // check conflicts across regions for the map clauses. 16236 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16237 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16238 break; 16239 if (CKind == OMPC_map && 16240 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16241 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16242 break; 16243 16244 // OpenMP 4.5 [2.10.5, target update Construct] 16245 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16246 // If the type of a list item is a reference to a type T then the type will 16247 // be considered to be T for all purposes of this clause. 16248 auto I = llvm::find_if( 16249 CurComponents, 16250 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16251 return MC.getAssociatedDeclaration(); 16252 }); 16253 assert(I != CurComponents.end() && "Null decl on map clause."); 16254 QualType Type; 16255 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16256 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16257 if (ASE) { 16258 Type = ASE->getType().getNonReferenceType(); 16259 } else if (OASE) { 16260 QualType BaseType = 16261 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16262 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16263 Type = ATy->getElementType(); 16264 else 16265 Type = BaseType->getPointeeType(); 16266 Type = Type.getNonReferenceType(); 16267 } else { 16268 Type = VE->getType(); 16269 } 16270 16271 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16272 // A list item in a to or from clause must have a mappable type. 16273 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16274 // A list item must have a mappable type. 16275 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16276 DSAS, Type)) 16277 continue; 16278 16279 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16280 16281 if (CKind == OMPC_map) { 16282 // target enter data 16283 // OpenMP [2.10.2, Restrictions, p. 99] 16284 // A map-type must be specified in all map clauses and must be either 16285 // to or alloc. 16286 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16287 if (DKind == OMPD_target_enter_data && 16288 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16289 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16290 << (IsMapTypeImplicit ? 1 : 0) 16291 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16292 << getOpenMPDirectiveName(DKind); 16293 continue; 16294 } 16295 16296 // target exit_data 16297 // OpenMP [2.10.3, Restrictions, p. 102] 16298 // A map-type must be specified in all map clauses and must be either 16299 // from, release, or delete. 16300 if (DKind == OMPD_target_exit_data && 16301 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16302 MapType == OMPC_MAP_delete)) { 16303 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16304 << (IsMapTypeImplicit ? 1 : 0) 16305 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16306 << getOpenMPDirectiveName(DKind); 16307 continue; 16308 } 16309 16310 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 16311 // A list item cannot appear in both a map clause and a data-sharing 16312 // attribute clause on the same construct 16313 // 16314 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 16315 // A list item cannot appear in both a map clause and a data-sharing 16316 // attribute clause on the same construct unless the construct is a 16317 // combined construct. 16318 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 16319 isOpenMPTargetExecutionDirective(DKind)) || 16320 DKind == OMPD_target)) { 16321 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16322 if (isOpenMPPrivate(DVar.CKind)) { 16323 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16324 << getOpenMPClauseName(DVar.CKind) 16325 << getOpenMPClauseName(OMPC_map) 16326 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 16327 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 16328 continue; 16329 } 16330 } 16331 } 16332 16333 // Try to find the associated user-defined mapper. 16334 ExprResult ER = buildUserDefinedMapperRef( 16335 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16336 Type.getCanonicalType(), UnresolvedMapper); 16337 if (ER.isInvalid()) 16338 continue; 16339 MVLI.UDMapperList.push_back(ER.get()); 16340 16341 // Save the current expression. 16342 MVLI.ProcessedVarList.push_back(RE); 16343 16344 // Store the components in the stack so that they can be used to check 16345 // against other clauses later on. 16346 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 16347 /*WhereFoundClauseKind=*/OMPC_map); 16348 16349 // Save the components and declaration to create the clause. For purposes of 16350 // the clause creation, any component list that has has base 'this' uses 16351 // null as base declaration. 16352 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16353 MVLI.VarComponents.back().append(CurComponents.begin(), 16354 CurComponents.end()); 16355 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 16356 : CurDeclaration); 16357 } 16358 } 16359 16360 OMPClause *Sema::ActOnOpenMPMapClause( 16361 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 16362 ArrayRef<SourceLocation> MapTypeModifiersLoc, 16363 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 16364 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 16365 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 16366 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 16367 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 16368 OMPC_MAP_MODIFIER_unknown, 16369 OMPC_MAP_MODIFIER_unknown}; 16370 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 16371 16372 // Process map-type-modifiers, flag errors for duplicate modifiers. 16373 unsigned Count = 0; 16374 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 16375 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 16376 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 16377 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 16378 continue; 16379 } 16380 assert(Count < OMPMapClause::NumberOfModifiers && 16381 "Modifiers exceed the allowed number of map type modifiers"); 16382 Modifiers[Count] = MapTypeModifiers[I]; 16383 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 16384 ++Count; 16385 } 16386 16387 MappableVarListInfo MVLI(VarList); 16388 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 16389 MapperIdScopeSpec, MapperId, UnresolvedMappers, 16390 MapType, IsMapTypeImplicit); 16391 16392 // We need to produce a map clause even if we don't have variables so that 16393 // other diagnostics related with non-existing map clauses are accurate. 16394 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 16395 MVLI.VarBaseDeclarations, MVLI.VarComponents, 16396 MVLI.UDMapperList, Modifiers, ModifiersLoc, 16397 MapperIdScopeSpec.getWithLocInContext(Context), 16398 MapperId, MapType, IsMapTypeImplicit, MapLoc); 16399 } 16400 16401 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 16402 TypeResult ParsedType) { 16403 assert(ParsedType.isUsable()); 16404 16405 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 16406 if (ReductionType.isNull()) 16407 return QualType(); 16408 16409 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 16410 // A type name in a declare reduction directive cannot be a function type, an 16411 // array type, a reference type, or a type qualified with const, volatile or 16412 // restrict. 16413 if (ReductionType.hasQualifiers()) { 16414 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 16415 return QualType(); 16416 } 16417 16418 if (ReductionType->isFunctionType()) { 16419 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 16420 return QualType(); 16421 } 16422 if (ReductionType->isReferenceType()) { 16423 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 16424 return QualType(); 16425 } 16426 if (ReductionType->isArrayType()) { 16427 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 16428 return QualType(); 16429 } 16430 return ReductionType; 16431 } 16432 16433 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 16434 Scope *S, DeclContext *DC, DeclarationName Name, 16435 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 16436 AccessSpecifier AS, Decl *PrevDeclInScope) { 16437 SmallVector<Decl *, 8> Decls; 16438 Decls.reserve(ReductionTypes.size()); 16439 16440 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 16441 forRedeclarationInCurContext()); 16442 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 16443 // A reduction-identifier may not be re-declared in the current scope for the 16444 // same type or for a type that is compatible according to the base language 16445 // rules. 16446 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16447 OMPDeclareReductionDecl *PrevDRD = nullptr; 16448 bool InCompoundScope = true; 16449 if (S != nullptr) { 16450 // Find previous declaration with the same name not referenced in other 16451 // declarations. 16452 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16453 InCompoundScope = 16454 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16455 LookupName(Lookup, S); 16456 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16457 /*AllowInlineNamespace=*/false); 16458 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 16459 LookupResult::Filter Filter = Lookup.makeFilter(); 16460 while (Filter.hasNext()) { 16461 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 16462 if (InCompoundScope) { 16463 auto I = UsedAsPrevious.find(PrevDecl); 16464 if (I == UsedAsPrevious.end()) 16465 UsedAsPrevious[PrevDecl] = false; 16466 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 16467 UsedAsPrevious[D] = true; 16468 } 16469 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16470 PrevDecl->getLocation(); 16471 } 16472 Filter.done(); 16473 if (InCompoundScope) { 16474 for (const auto &PrevData : UsedAsPrevious) { 16475 if (!PrevData.second) { 16476 PrevDRD = PrevData.first; 16477 break; 16478 } 16479 } 16480 } 16481 } else if (PrevDeclInScope != nullptr) { 16482 auto *PrevDRDInScope = PrevDRD = 16483 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 16484 do { 16485 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 16486 PrevDRDInScope->getLocation(); 16487 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 16488 } while (PrevDRDInScope != nullptr); 16489 } 16490 for (const auto &TyData : ReductionTypes) { 16491 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 16492 bool Invalid = false; 16493 if (I != PreviousRedeclTypes.end()) { 16494 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 16495 << TyData.first; 16496 Diag(I->second, diag::note_previous_definition); 16497 Invalid = true; 16498 } 16499 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 16500 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 16501 Name, TyData.first, PrevDRD); 16502 DC->addDecl(DRD); 16503 DRD->setAccess(AS); 16504 Decls.push_back(DRD); 16505 if (Invalid) 16506 DRD->setInvalidDecl(); 16507 else 16508 PrevDRD = DRD; 16509 } 16510 16511 return DeclGroupPtrTy::make( 16512 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 16513 } 16514 16515 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 16516 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16517 16518 // Enter new function scope. 16519 PushFunctionScope(); 16520 setFunctionHasBranchProtectedScope(); 16521 getCurFunction()->setHasOMPDeclareReductionCombiner(); 16522 16523 if (S != nullptr) 16524 PushDeclContext(S, DRD); 16525 else 16526 CurContext = DRD; 16527 16528 PushExpressionEvaluationContext( 16529 ExpressionEvaluationContext::PotentiallyEvaluated); 16530 16531 QualType ReductionType = DRD->getType(); 16532 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 16533 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 16534 // uses semantics of argument handles by value, but it should be passed by 16535 // reference. C lang does not support references, so pass all parameters as 16536 // pointers. 16537 // Create 'T omp_in;' variable. 16538 VarDecl *OmpInParm = 16539 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16540 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16541 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16542 // uses semantics of argument handles by value, but it should be passed by 16543 // reference. C lang does not support references, so pass all parameters as 16544 // pointers. 16545 // Create 'T omp_out;' variable. 16546 VarDecl *OmpOutParm = 16547 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16548 if (S != nullptr) { 16549 PushOnScopeChains(OmpInParm, S); 16550 PushOnScopeChains(OmpOutParm, S); 16551 } else { 16552 DRD->addDecl(OmpInParm); 16553 DRD->addDecl(OmpOutParm); 16554 } 16555 Expr *InE = 16556 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16557 Expr *OutE = 16558 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16559 DRD->setCombinerData(InE, OutE); 16560 } 16561 16562 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16563 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16564 DiscardCleanupsInEvaluationContext(); 16565 PopExpressionEvaluationContext(); 16566 16567 PopDeclContext(); 16568 PopFunctionScopeInfo(); 16569 16570 if (Combiner != nullptr) 16571 DRD->setCombiner(Combiner); 16572 else 16573 DRD->setInvalidDecl(); 16574 } 16575 16576 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16577 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16578 16579 // Enter new function scope. 16580 PushFunctionScope(); 16581 setFunctionHasBranchProtectedScope(); 16582 16583 if (S != nullptr) 16584 PushDeclContext(S, DRD); 16585 else 16586 CurContext = DRD; 16587 16588 PushExpressionEvaluationContext( 16589 ExpressionEvaluationContext::PotentiallyEvaluated); 16590 16591 QualType ReductionType = DRD->getType(); 16592 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16593 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16594 // uses semantics of argument handles by value, but it should be passed by 16595 // reference. C lang does not support references, so pass all parameters as 16596 // pointers. 16597 // Create 'T omp_priv;' variable. 16598 VarDecl *OmpPrivParm = 16599 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16600 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16601 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16602 // uses semantics of argument handles by value, but it should be passed by 16603 // reference. C lang does not support references, so pass all parameters as 16604 // pointers. 16605 // Create 'T omp_orig;' variable. 16606 VarDecl *OmpOrigParm = 16607 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16608 if (S != nullptr) { 16609 PushOnScopeChains(OmpPrivParm, S); 16610 PushOnScopeChains(OmpOrigParm, S); 16611 } else { 16612 DRD->addDecl(OmpPrivParm); 16613 DRD->addDecl(OmpOrigParm); 16614 } 16615 Expr *OrigE = 16616 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16617 Expr *PrivE = 16618 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16619 DRD->setInitializerData(OrigE, PrivE); 16620 return OmpPrivParm; 16621 } 16622 16623 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16624 VarDecl *OmpPrivParm) { 16625 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16626 DiscardCleanupsInEvaluationContext(); 16627 PopExpressionEvaluationContext(); 16628 16629 PopDeclContext(); 16630 PopFunctionScopeInfo(); 16631 16632 if (Initializer != nullptr) { 16633 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16634 } else if (OmpPrivParm->hasInit()) { 16635 DRD->setInitializer(OmpPrivParm->getInit(), 16636 OmpPrivParm->isDirectInit() 16637 ? OMPDeclareReductionDecl::DirectInit 16638 : OMPDeclareReductionDecl::CopyInit); 16639 } else { 16640 DRD->setInvalidDecl(); 16641 } 16642 } 16643 16644 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16645 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16646 for (Decl *D : DeclReductions.get()) { 16647 if (IsValid) { 16648 if (S) 16649 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16650 /*AddToContext=*/false); 16651 } else { 16652 D->setInvalidDecl(); 16653 } 16654 } 16655 return DeclReductions; 16656 } 16657 16658 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16659 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16660 QualType T = TInfo->getType(); 16661 if (D.isInvalidType()) 16662 return true; 16663 16664 if (getLangOpts().CPlusPlus) { 16665 // Check that there are no default arguments (C++ only). 16666 CheckExtraCXXDefaultArguments(D); 16667 } 16668 16669 return CreateParsedType(T, TInfo); 16670 } 16671 16672 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16673 TypeResult ParsedType) { 16674 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16675 16676 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16677 assert(!MapperType.isNull() && "Expect valid mapper type"); 16678 16679 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16680 // The type must be of struct, union or class type in C and C++ 16681 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16682 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16683 return QualType(); 16684 } 16685 return MapperType; 16686 } 16687 16688 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16689 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16690 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16691 Decl *PrevDeclInScope) { 16692 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16693 forRedeclarationInCurContext()); 16694 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16695 // A mapper-identifier may not be redeclared in the current scope for the 16696 // same type or for a type that is compatible according to the base language 16697 // rules. 16698 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16699 OMPDeclareMapperDecl *PrevDMD = nullptr; 16700 bool InCompoundScope = true; 16701 if (S != nullptr) { 16702 // Find previous declaration with the same name not referenced in other 16703 // declarations. 16704 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16705 InCompoundScope = 16706 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16707 LookupName(Lookup, S); 16708 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16709 /*AllowInlineNamespace=*/false); 16710 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16711 LookupResult::Filter Filter = Lookup.makeFilter(); 16712 while (Filter.hasNext()) { 16713 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16714 if (InCompoundScope) { 16715 auto I = UsedAsPrevious.find(PrevDecl); 16716 if (I == UsedAsPrevious.end()) 16717 UsedAsPrevious[PrevDecl] = false; 16718 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16719 UsedAsPrevious[D] = true; 16720 } 16721 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16722 PrevDecl->getLocation(); 16723 } 16724 Filter.done(); 16725 if (InCompoundScope) { 16726 for (const auto &PrevData : UsedAsPrevious) { 16727 if (!PrevData.second) { 16728 PrevDMD = PrevData.first; 16729 break; 16730 } 16731 } 16732 } 16733 } else if (PrevDeclInScope) { 16734 auto *PrevDMDInScope = PrevDMD = 16735 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16736 do { 16737 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16738 PrevDMDInScope->getLocation(); 16739 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16740 } while (PrevDMDInScope != nullptr); 16741 } 16742 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16743 bool Invalid = false; 16744 if (I != PreviousRedeclTypes.end()) { 16745 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16746 << MapperType << Name; 16747 Diag(I->second, diag::note_previous_definition); 16748 Invalid = true; 16749 } 16750 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16751 MapperType, VN, PrevDMD); 16752 DC->addDecl(DMD); 16753 DMD->setAccess(AS); 16754 if (Invalid) 16755 DMD->setInvalidDecl(); 16756 16757 // Enter new function scope. 16758 PushFunctionScope(); 16759 setFunctionHasBranchProtectedScope(); 16760 16761 CurContext = DMD; 16762 16763 return DMD; 16764 } 16765 16766 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16767 Scope *S, 16768 QualType MapperType, 16769 SourceLocation StartLoc, 16770 DeclarationName VN) { 16771 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16772 if (S) 16773 PushOnScopeChains(VD, S); 16774 else 16775 DMD->addDecl(VD); 16776 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16777 DMD->setMapperVarRef(MapperVarRefExpr); 16778 } 16779 16780 Sema::DeclGroupPtrTy 16781 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16782 ArrayRef<OMPClause *> ClauseList) { 16783 PopDeclContext(); 16784 PopFunctionScopeInfo(); 16785 16786 if (D) { 16787 if (S) 16788 PushOnScopeChains(D, S, /*AddToContext=*/false); 16789 D->CreateClauses(Context, ClauseList); 16790 } 16791 16792 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16793 } 16794 16795 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16796 SourceLocation StartLoc, 16797 SourceLocation LParenLoc, 16798 SourceLocation EndLoc) { 16799 Expr *ValExpr = NumTeams; 16800 Stmt *HelperValStmt = nullptr; 16801 16802 // OpenMP [teams Constrcut, Restrictions] 16803 // The num_teams expression must evaluate to a positive integer value. 16804 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16805 /*StrictlyPositive=*/true)) 16806 return nullptr; 16807 16808 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16809 OpenMPDirectiveKind CaptureRegion = 16810 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 16811 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16812 ValExpr = MakeFullExpr(ValExpr).get(); 16813 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16814 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16815 HelperValStmt = buildPreInits(Context, Captures); 16816 } 16817 16818 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16819 StartLoc, LParenLoc, EndLoc); 16820 } 16821 16822 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16823 SourceLocation StartLoc, 16824 SourceLocation LParenLoc, 16825 SourceLocation EndLoc) { 16826 Expr *ValExpr = ThreadLimit; 16827 Stmt *HelperValStmt = nullptr; 16828 16829 // OpenMP [teams Constrcut, Restrictions] 16830 // The thread_limit expression must evaluate to a positive integer value. 16831 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16832 /*StrictlyPositive=*/true)) 16833 return nullptr; 16834 16835 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16836 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 16837 DKind, OMPC_thread_limit, LangOpts.OpenMP); 16838 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16839 ValExpr = MakeFullExpr(ValExpr).get(); 16840 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16841 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16842 HelperValStmt = buildPreInits(Context, Captures); 16843 } 16844 16845 return new (Context) OMPThreadLimitClause( 16846 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16847 } 16848 16849 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16850 SourceLocation StartLoc, 16851 SourceLocation LParenLoc, 16852 SourceLocation EndLoc) { 16853 Expr *ValExpr = Priority; 16854 Stmt *HelperValStmt = nullptr; 16855 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16856 16857 // OpenMP [2.9.1, task Constrcut] 16858 // The priority-value is a non-negative numerical scalar expression. 16859 if (!isNonNegativeIntegerValue( 16860 ValExpr, *this, OMPC_priority, 16861 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16862 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16863 return nullptr; 16864 16865 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16866 StartLoc, LParenLoc, EndLoc); 16867 } 16868 16869 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16870 SourceLocation StartLoc, 16871 SourceLocation LParenLoc, 16872 SourceLocation EndLoc) { 16873 Expr *ValExpr = Grainsize; 16874 Stmt *HelperValStmt = nullptr; 16875 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16876 16877 // OpenMP [2.9.2, taskloop Constrcut] 16878 // The parameter of the grainsize clause must be a positive integer 16879 // expression. 16880 if (!isNonNegativeIntegerValue( 16881 ValExpr, *this, OMPC_grainsize, 16882 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16883 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16884 return nullptr; 16885 16886 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16887 StartLoc, LParenLoc, EndLoc); 16888 } 16889 16890 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16891 SourceLocation StartLoc, 16892 SourceLocation LParenLoc, 16893 SourceLocation EndLoc) { 16894 Expr *ValExpr = NumTasks; 16895 Stmt *HelperValStmt = nullptr; 16896 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16897 16898 // OpenMP [2.9.2, taskloop Constrcut] 16899 // The parameter of the num_tasks clause must be a positive integer 16900 // expression. 16901 if (!isNonNegativeIntegerValue( 16902 ValExpr, *this, OMPC_num_tasks, 16903 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16904 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16905 return nullptr; 16906 16907 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16908 StartLoc, LParenLoc, EndLoc); 16909 } 16910 16911 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16912 SourceLocation LParenLoc, 16913 SourceLocation EndLoc) { 16914 // OpenMP [2.13.2, critical construct, Description] 16915 // ... where hint-expression is an integer constant expression that evaluates 16916 // to a valid lock hint. 16917 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16918 if (HintExpr.isInvalid()) 16919 return nullptr; 16920 return new (Context) 16921 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16922 } 16923 16924 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16925 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16926 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16927 SourceLocation EndLoc) { 16928 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16929 std::string Values; 16930 Values += "'"; 16931 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16932 Values += "'"; 16933 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16934 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16935 return nullptr; 16936 } 16937 Expr *ValExpr = ChunkSize; 16938 Stmt *HelperValStmt = nullptr; 16939 if (ChunkSize) { 16940 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16941 !ChunkSize->isInstantiationDependent() && 16942 !ChunkSize->containsUnexpandedParameterPack()) { 16943 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16944 ExprResult Val = 16945 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16946 if (Val.isInvalid()) 16947 return nullptr; 16948 16949 ValExpr = Val.get(); 16950 16951 // OpenMP [2.7.1, Restrictions] 16952 // chunk_size must be a loop invariant integer expression with a positive 16953 // value. 16954 llvm::APSInt Result; 16955 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16956 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16957 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16958 << "dist_schedule" << ChunkSize->getSourceRange(); 16959 return nullptr; 16960 } 16961 } else if (getOpenMPCaptureRegionForClause( 16962 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 16963 LangOpts.OpenMP) != OMPD_unknown && 16964 !CurContext->isDependentContext()) { 16965 ValExpr = MakeFullExpr(ValExpr).get(); 16966 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16967 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16968 HelperValStmt = buildPreInits(Context, Captures); 16969 } 16970 } 16971 } 16972 16973 return new (Context) 16974 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16975 Kind, ValExpr, HelperValStmt); 16976 } 16977 16978 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16979 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16980 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16981 SourceLocation KindLoc, SourceLocation EndLoc) { 16982 if (getLangOpts().OpenMP < 50) { 16983 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 16984 Kind != OMPC_DEFAULTMAP_scalar) { 16985 std::string Value; 16986 SourceLocation Loc; 16987 Value += "'"; 16988 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16989 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16990 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16991 Loc = MLoc; 16992 } else { 16993 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16994 OMPC_DEFAULTMAP_scalar); 16995 Loc = KindLoc; 16996 } 16997 Value += "'"; 16998 Diag(Loc, diag::err_omp_unexpected_clause_value) 16999 << Value << getOpenMPClauseName(OMPC_defaultmap); 17000 return nullptr; 17001 } 17002 } else { 17003 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 17004 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 17005 if (!isDefaultmapKind || !isDefaultmapModifier) { 17006 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 17007 "'firstprivate', 'none', 'default'"; 17008 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 17009 if (!isDefaultmapKind && isDefaultmapModifier) { 17010 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17011 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17012 } else if (isDefaultmapKind && !isDefaultmapModifier) { 17013 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17014 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17015 } else { 17016 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17017 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17018 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17019 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17020 } 17021 return nullptr; 17022 } 17023 17024 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 17025 // At most one defaultmap clause for each category can appear on the 17026 // directive. 17027 if (DSAStack->checkDefaultmapCategory(Kind)) { 17028 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 17029 return nullptr; 17030 } 17031 } 17032 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 17033 17034 return new (Context) 17035 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 17036 } 17037 17038 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 17039 DeclContext *CurLexicalContext = getCurLexicalContext(); 17040 if (!CurLexicalContext->isFileContext() && 17041 !CurLexicalContext->isExternCContext() && 17042 !CurLexicalContext->isExternCXXContext() && 17043 !isa<CXXRecordDecl>(CurLexicalContext) && 17044 !isa<ClassTemplateDecl>(CurLexicalContext) && 17045 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 17046 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 17047 Diag(Loc, diag::err_omp_region_not_file_context); 17048 return false; 17049 } 17050 ++DeclareTargetNestingLevel; 17051 return true; 17052 } 17053 17054 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 17055 assert(DeclareTargetNestingLevel > 0 && 17056 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 17057 --DeclareTargetNestingLevel; 17058 } 17059 17060 NamedDecl * 17061 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 17062 const DeclarationNameInfo &Id, 17063 NamedDeclSetType &SameDirectiveDecls) { 17064 LookupResult Lookup(*this, Id, LookupOrdinaryName); 17065 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 17066 17067 if (Lookup.isAmbiguous()) 17068 return nullptr; 17069 Lookup.suppressDiagnostics(); 17070 17071 if (!Lookup.isSingleResult()) { 17072 VarOrFuncDeclFilterCCC CCC(*this); 17073 if (TypoCorrection Corrected = 17074 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 17075 CTK_ErrorRecovery)) { 17076 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 17077 << Id.getName()); 17078 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 17079 return nullptr; 17080 } 17081 17082 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 17083 return nullptr; 17084 } 17085 17086 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 17087 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 17088 !isa<FunctionTemplateDecl>(ND)) { 17089 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 17090 return nullptr; 17091 } 17092 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 17093 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 17094 return ND; 17095 } 17096 17097 void Sema::ActOnOpenMPDeclareTargetName( 17098 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 17099 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 17100 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 17101 isa<FunctionTemplateDecl>(ND)) && 17102 "Expected variable, function or function template."); 17103 17104 // Diagnose marking after use as it may lead to incorrect diagnosis and 17105 // codegen. 17106 if (LangOpts.OpenMP >= 50 && 17107 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 17108 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 17109 17110 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17111 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 17112 if (DevTy.hasValue() && *DevTy != DT) { 17113 Diag(Loc, diag::err_omp_device_type_mismatch) 17114 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 17115 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 17116 return; 17117 } 17118 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17119 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 17120 if (!Res) { 17121 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 17122 SourceRange(Loc, Loc)); 17123 ND->addAttr(A); 17124 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17125 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 17126 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 17127 } else if (*Res != MT) { 17128 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 17129 } 17130 } 17131 17132 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 17133 Sema &SemaRef, Decl *D) { 17134 if (!D || !isa<VarDecl>(D)) 17135 return; 17136 auto *VD = cast<VarDecl>(D); 17137 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17138 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17139 if (SemaRef.LangOpts.OpenMP >= 50 && 17140 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 17141 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 17142 VD->hasGlobalStorage()) { 17143 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17144 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17145 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17146 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17147 // If a lambda declaration and definition appears between a 17148 // declare target directive and the matching end declare target 17149 // directive, all variables that are captured by the lambda 17150 // expression must also appear in a to clause. 17151 SemaRef.Diag(VD->getLocation(), 17152 diag::err_omp_lambda_capture_in_declare_target_not_to); 17153 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17154 << VD << 0 << SR; 17155 return; 17156 } 17157 } 17158 if (MapTy.hasValue()) 17159 return; 17160 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17161 SemaRef.Diag(SL, diag::note_used_here) << SR; 17162 } 17163 17164 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17165 Sema &SemaRef, DSAStackTy *Stack, 17166 ValueDecl *VD) { 17167 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17168 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17169 /*FullCheck=*/false); 17170 } 17171 17172 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17173 SourceLocation IdLoc) { 17174 if (!D || D->isInvalidDecl()) 17175 return; 17176 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 17177 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 17178 if (auto *VD = dyn_cast<VarDecl>(D)) { 17179 // Only global variables can be marked as declare target. 17180 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 17181 !VD->isStaticDataMember()) 17182 return; 17183 // 2.10.6: threadprivate variable cannot appear in a declare target 17184 // directive. 17185 if (DSAStack->isThreadPrivate(VD)) { 17186 Diag(SL, diag::err_omp_threadprivate_in_target); 17187 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 17188 return; 17189 } 17190 } 17191 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 17192 D = FTD->getTemplatedDecl(); 17193 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 17194 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17195 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 17196 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 17197 Diag(IdLoc, diag::err_omp_function_in_link_clause); 17198 Diag(FD->getLocation(), diag::note_defined_here) << FD; 17199 return; 17200 } 17201 // Mark the function as must be emitted for the device. 17202 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17203 OMPDeclareTargetDeclAttr::getDeviceType(FD); 17204 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17205 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 17206 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 17207 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17208 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 17209 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 17210 } 17211 if (auto *VD = dyn_cast<ValueDecl>(D)) { 17212 // Problem if any with var declared with incomplete type will be reported 17213 // as normal, so no need to check it here. 17214 if ((E || !VD->getType()->isIncompleteType()) && 17215 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 17216 return; 17217 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 17218 // Checking declaration inside declare target region. 17219 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 17220 isa<FunctionTemplateDecl>(D)) { 17221 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 17222 Context, OMPDeclareTargetDeclAttr::MT_To, 17223 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 17224 D->addAttr(A); 17225 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17226 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 17227 } 17228 return; 17229 } 17230 } 17231 if (!E) 17232 return; 17233 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 17234 } 17235 17236 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 17237 CXXScopeSpec &MapperIdScopeSpec, 17238 DeclarationNameInfo &MapperId, 17239 const OMPVarListLocTy &Locs, 17240 ArrayRef<Expr *> UnresolvedMappers) { 17241 MappableVarListInfo MVLI(VarList); 17242 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17243 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17244 if (MVLI.ProcessedVarList.empty()) 17245 return nullptr; 17246 17247 return OMPToClause::Create( 17248 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17249 MVLI.VarComponents, MVLI.UDMapperList, 17250 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17251 } 17252 17253 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17254 CXXScopeSpec &MapperIdScopeSpec, 17255 DeclarationNameInfo &MapperId, 17256 const OMPVarListLocTy &Locs, 17257 ArrayRef<Expr *> UnresolvedMappers) { 17258 MappableVarListInfo MVLI(VarList); 17259 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 17260 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17261 if (MVLI.ProcessedVarList.empty()) 17262 return nullptr; 17263 17264 return OMPFromClause::Create( 17265 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17266 MVLI.VarComponents, MVLI.UDMapperList, 17267 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17268 } 17269 17270 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 17271 const OMPVarListLocTy &Locs) { 17272 MappableVarListInfo MVLI(VarList); 17273 SmallVector<Expr *, 8> PrivateCopies; 17274 SmallVector<Expr *, 8> Inits; 17275 17276 for (Expr *RefExpr : VarList) { 17277 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 17278 SourceLocation ELoc; 17279 SourceRange ERange; 17280 Expr *SimpleRefExpr = RefExpr; 17281 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17282 if (Res.second) { 17283 // It will be analyzed later. 17284 MVLI.ProcessedVarList.push_back(RefExpr); 17285 PrivateCopies.push_back(nullptr); 17286 Inits.push_back(nullptr); 17287 } 17288 ValueDecl *D = Res.first; 17289 if (!D) 17290 continue; 17291 17292 QualType Type = D->getType(); 17293 Type = Type.getNonReferenceType().getUnqualifiedType(); 17294 17295 auto *VD = dyn_cast<VarDecl>(D); 17296 17297 // Item should be a pointer or reference to pointer. 17298 if (!Type->isPointerType()) { 17299 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 17300 << 0 << RefExpr->getSourceRange(); 17301 continue; 17302 } 17303 17304 // Build the private variable and the expression that refers to it. 17305 auto VDPrivate = 17306 buildVarDecl(*this, ELoc, Type, D->getName(), 17307 D->hasAttrs() ? &D->getAttrs() : nullptr, 17308 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17309 if (VDPrivate->isInvalidDecl()) 17310 continue; 17311 17312 CurContext->addDecl(VDPrivate); 17313 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17314 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17315 17316 // Add temporary variable to initialize the private copy of the pointer. 17317 VarDecl *VDInit = 17318 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 17319 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 17320 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 17321 AddInitializerToDecl(VDPrivate, 17322 DefaultLvalueConversion(VDInitRefExpr).get(), 17323 /*DirectInit=*/false); 17324 17325 // If required, build a capture to implement the privatization initialized 17326 // with the current list item value. 17327 DeclRefExpr *Ref = nullptr; 17328 if (!VD) 17329 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17330 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 17331 PrivateCopies.push_back(VDPrivateRefExpr); 17332 Inits.push_back(VDInitRefExpr); 17333 17334 // We need to add a data sharing attribute for this variable to make sure it 17335 // is correctly captured. A variable that shows up in a use_device_ptr has 17336 // similar properties of a first private variable. 17337 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17338 17339 // Create a mappable component for the list item. List items in this clause 17340 // only need a component. 17341 MVLI.VarBaseDeclarations.push_back(D); 17342 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17343 MVLI.VarComponents.back().push_back( 17344 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 17345 } 17346 17347 if (MVLI.ProcessedVarList.empty()) 17348 return nullptr; 17349 17350 return OMPUseDevicePtrClause::Create( 17351 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 17352 MVLI.VarBaseDeclarations, MVLI.VarComponents); 17353 } 17354 17355 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 17356 const OMPVarListLocTy &Locs) { 17357 MappableVarListInfo MVLI(VarList); 17358 for (Expr *RefExpr : VarList) { 17359 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 17360 SourceLocation ELoc; 17361 SourceRange ERange; 17362 Expr *SimpleRefExpr = RefExpr; 17363 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17364 if (Res.second) { 17365 // It will be analyzed later. 17366 MVLI.ProcessedVarList.push_back(RefExpr); 17367 } 17368 ValueDecl *D = Res.first; 17369 if (!D) 17370 continue; 17371 17372 QualType Type = D->getType(); 17373 // item should be a pointer or array or reference to pointer or array 17374 if (!Type.getNonReferenceType()->isPointerType() && 17375 !Type.getNonReferenceType()->isArrayType()) { 17376 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 17377 << 0 << RefExpr->getSourceRange(); 17378 continue; 17379 } 17380 17381 // Check if the declaration in the clause does not show up in any data 17382 // sharing attribute. 17383 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17384 if (isOpenMPPrivate(DVar.CKind)) { 17385 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17386 << getOpenMPClauseName(DVar.CKind) 17387 << getOpenMPClauseName(OMPC_is_device_ptr) 17388 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17389 reportOriginalDsa(*this, DSAStack, D, DVar); 17390 continue; 17391 } 17392 17393 const Expr *ConflictExpr; 17394 if (DSAStack->checkMappableExprComponentListsForDecl( 17395 D, /*CurrentRegionOnly=*/true, 17396 [&ConflictExpr]( 17397 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 17398 OpenMPClauseKind) -> bool { 17399 ConflictExpr = R.front().getAssociatedExpression(); 17400 return true; 17401 })) { 17402 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 17403 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 17404 << ConflictExpr->getSourceRange(); 17405 continue; 17406 } 17407 17408 // Store the components in the stack so that they can be used to check 17409 // against other clauses later on. 17410 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 17411 DSAStack->addMappableExpressionComponents( 17412 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 17413 17414 // Record the expression we've just processed. 17415 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 17416 17417 // Create a mappable component for the list item. List items in this clause 17418 // only need a component. We use a null declaration to signal fields in 17419 // 'this'. 17420 assert((isa<DeclRefExpr>(SimpleRefExpr) || 17421 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 17422 "Unexpected device pointer expression!"); 17423 MVLI.VarBaseDeclarations.push_back( 17424 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 17425 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17426 MVLI.VarComponents.back().push_back(MC); 17427 } 17428 17429 if (MVLI.ProcessedVarList.empty()) 17430 return nullptr; 17431 17432 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 17433 MVLI.VarBaseDeclarations, 17434 MVLI.VarComponents); 17435 } 17436 17437 OMPClause *Sema::ActOnOpenMPAllocateClause( 17438 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17439 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17440 if (Allocator) { 17441 // OpenMP [2.11.4 allocate Clause, Description] 17442 // allocator is an expression of omp_allocator_handle_t type. 17443 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 17444 return nullptr; 17445 17446 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 17447 if (AllocatorRes.isInvalid()) 17448 return nullptr; 17449 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 17450 DSAStack->getOMPAllocatorHandleT(), 17451 Sema::AA_Initializing, 17452 /*AllowExplicit=*/true); 17453 if (AllocatorRes.isInvalid()) 17454 return nullptr; 17455 Allocator = AllocatorRes.get(); 17456 } else { 17457 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 17458 // allocate clauses that appear on a target construct or on constructs in a 17459 // target region must specify an allocator expression unless a requires 17460 // directive with the dynamic_allocators clause is present in the same 17461 // compilation unit. 17462 if (LangOpts.OpenMPIsDevice && 17463 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 17464 targetDiag(StartLoc, diag::err_expected_allocator_expression); 17465 } 17466 // Analyze and build list of variables. 17467 SmallVector<Expr *, 8> Vars; 17468 for (Expr *RefExpr : VarList) { 17469 assert(RefExpr && "NULL expr in OpenMP private clause."); 17470 SourceLocation ELoc; 17471 SourceRange ERange; 17472 Expr *SimpleRefExpr = RefExpr; 17473 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17474 if (Res.second) { 17475 // It will be analyzed later. 17476 Vars.push_back(RefExpr); 17477 } 17478 ValueDecl *D = Res.first; 17479 if (!D) 17480 continue; 17481 17482 auto *VD = dyn_cast<VarDecl>(D); 17483 DeclRefExpr *Ref = nullptr; 17484 if (!VD && !CurContext->isDependentContext()) 17485 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17486 Vars.push_back((VD || CurContext->isDependentContext()) 17487 ? RefExpr->IgnoreParens() 17488 : Ref); 17489 } 17490 17491 if (Vars.empty()) 17492 return nullptr; 17493 17494 if (Allocator) 17495 DSAStack->addInnerAllocatorExpr(Allocator); 17496 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 17497 ColonLoc, EndLoc, Vars); 17498 } 17499 17500 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 17501 SourceLocation StartLoc, 17502 SourceLocation LParenLoc, 17503 SourceLocation EndLoc) { 17504 SmallVector<Expr *, 8> Vars; 17505 for (Expr *RefExpr : VarList) { 17506 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 17507 SourceLocation ELoc; 17508 SourceRange ERange; 17509 Expr *SimpleRefExpr = RefExpr; 17510 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17511 if (Res.second) 17512 // It will be analyzed later. 17513 Vars.push_back(RefExpr); 17514 ValueDecl *D = Res.first; 17515 if (!D) 17516 continue; 17517 17518 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 17519 // A list-item cannot appear in more than one nontemporal clause. 17520 if (const Expr *PrevRef = 17521 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 17522 Diag(ELoc, diag::err_omp_used_in_clause_twice) 17523 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 17524 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 17525 << getOpenMPClauseName(OMPC_nontemporal); 17526 continue; 17527 } 17528 17529 Vars.push_back(RefExpr); 17530 } 17531 17532 if (Vars.empty()) 17533 return nullptr; 17534 17535 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17536 Vars); 17537 } 17538