1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 bool HasMutipleLoops = false; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 bool BodyComplete = false; 148 SourceLocation InnerTeamsRegionLoc; 149 /// Reference to the taskgroup task_reduction reference expression. 150 Expr *TaskgroupReductionRef = nullptr; 151 llvm::DenseSet<QualType> MappedClassesQualTypes; 152 /// List of globals marked as declare target link in this target region 153 /// (isOpenMPTargetExecutionDirective(Directive) == true). 154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 156 Scope *CurScope, SourceLocation Loc) 157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 158 ConstructLoc(Loc) {} 159 SharingMapTy() = default; 160 }; 161 162 using StackTy = SmallVector<SharingMapTy, 4>; 163 164 /// Stack of used declaration and their data-sharing attributes. 165 DeclSAMapTy Threadprivates; 166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 168 /// true, if check for DSA must be from parent directive, false, if 169 /// from current directive. 170 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 171 Sema &SemaRef; 172 bool ForceCapturing = false; 173 /// true if all the vaiables in the target executable directives must be 174 /// captured by reference. 175 bool ForceCaptureByReferenceInTargetExecutable = false; 176 CriticalsWithHintsTy Criticals; 177 unsigned IgnoredStackElements = 0; 178 179 /// Iterators over the stack iterate in order from innermost to outermost 180 /// directive. 181 using const_iterator = StackTy::const_reverse_iterator; 182 const_iterator begin() const { 183 return Stack.empty() ? const_iterator() 184 : Stack.back().first.rbegin() + IgnoredStackElements; 185 } 186 const_iterator end() const { 187 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 188 } 189 using iterator = StackTy::reverse_iterator; 190 iterator begin() { 191 return Stack.empty() ? iterator() 192 : Stack.back().first.rbegin() + IgnoredStackElements; 193 } 194 iterator end() { 195 return Stack.empty() ? iterator() : Stack.back().first.rend(); 196 } 197 198 // Convenience operations to get at the elements of the stack. 199 200 bool isStackEmpty() const { 201 return Stack.empty() || 202 Stack.back().second != CurrentNonCapturingFunctionScope || 203 Stack.back().first.size() <= IgnoredStackElements; 204 } 205 size_t getStackSize() const { 206 return isStackEmpty() ? 0 207 : Stack.back().first.size() - IgnoredStackElements; 208 } 209 210 SharingMapTy *getTopOfStackOrNull() { 211 size_t Size = getStackSize(); 212 if (Size == 0) 213 return nullptr; 214 return &Stack.back().first[Size - 1]; 215 } 216 const SharingMapTy *getTopOfStackOrNull() const { 217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 218 } 219 SharingMapTy &getTopOfStack() { 220 assert(!isStackEmpty() && "no current directive"); 221 return *getTopOfStackOrNull(); 222 } 223 const SharingMapTy &getTopOfStack() const { 224 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 225 } 226 227 SharingMapTy *getSecondOnStackOrNull() { 228 size_t Size = getStackSize(); 229 if (Size <= 1) 230 return nullptr; 231 return &Stack.back().first[Size - 2]; 232 } 233 const SharingMapTy *getSecondOnStackOrNull() const { 234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 235 } 236 237 /// Get the stack element at a certain level (previously returned by 238 /// \c getNestingLevel). 239 /// 240 /// Note that nesting levels count from outermost to innermost, and this is 241 /// the reverse of our iteration order where new inner levels are pushed at 242 /// the front of the stack. 243 SharingMapTy &getStackElemAtLevel(unsigned Level) { 244 assert(Level < getStackSize() && "no such stack element"); 245 return Stack.back().first[Level]; 246 } 247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 249 } 250 251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 252 253 /// Checks if the variable is a local for OpenMP region. 254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 255 256 /// Vector of previously declared requires directives 257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 258 /// omp_allocator_handle_t type. 259 QualType OMPAllocatorHandleT; 260 /// Expression for the predefined allocators. 261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 262 nullptr}; 263 /// Vector of previously encountered target directives 264 SmallVector<SourceLocation, 2> TargetLocations; 265 266 public: 267 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 268 269 /// Sets omp_allocator_handle_t type. 270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 271 /// Gets omp_allocator_handle_t type. 272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 273 /// Sets the given default allocator. 274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 275 Expr *Allocator) { 276 OMPPredefinedAllocators[AllocatorKind] = Allocator; 277 } 278 /// Returns the specified default allocator. 279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 280 return OMPPredefinedAllocators[AllocatorKind]; 281 } 282 283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 284 OpenMPClauseKind getClauseParsingMode() const { 285 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 286 return ClauseKindMode; 287 } 288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 289 290 bool isBodyComplete() const { 291 const SharingMapTy *Top = getTopOfStackOrNull(); 292 return Top && Top->BodyComplete; 293 } 294 void setBodyComplete() { 295 getTopOfStack().BodyComplete = true; 296 } 297 298 bool isForceVarCapturing() const { return ForceCapturing; } 299 void setForceVarCapturing(bool V) { ForceCapturing = V; } 300 301 void setForceCaptureByReferenceInTargetExecutable(bool V) { 302 ForceCaptureByReferenceInTargetExecutable = V; 303 } 304 bool isForceCaptureByReferenceInTargetExecutable() const { 305 return ForceCaptureByReferenceInTargetExecutable; 306 } 307 308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 309 Scope *CurScope, SourceLocation Loc) { 310 assert(!IgnoredStackElements && 311 "cannot change stack while ignoring elements"); 312 if (Stack.empty() || 313 Stack.back().second != CurrentNonCapturingFunctionScope) 314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 316 Stack.back().first.back().DefaultAttrLoc = Loc; 317 } 318 319 void pop() { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 assert(!Stack.back().first.empty() && 323 "Data-sharing attributes stack is empty!"); 324 Stack.back().first.pop_back(); 325 } 326 327 /// RAII object to temporarily leave the scope of a directive when we want to 328 /// logically operate in its parent. 329 class ParentDirectiveScope { 330 DSAStackTy &Self; 331 bool Active; 332 public: 333 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 334 : Self(Self), Active(false) { 335 if (Activate) 336 enable(); 337 } 338 ~ParentDirectiveScope() { disable(); } 339 void disable() { 340 if (Active) { 341 --Self.IgnoredStackElements; 342 Active = false; 343 } 344 } 345 void enable() { 346 if (!Active) { 347 ++Self.IgnoredStackElements; 348 Active = true; 349 } 350 } 351 }; 352 353 /// Marks that we're started loop parsing. 354 void loopInit() { 355 assert(isOpenMPLoopDirective(getCurrentDirective()) && 356 "Expected loop-based directive."); 357 getTopOfStack().LoopStart = true; 358 } 359 /// Start capturing of the variables in the loop context. 360 void loopStart() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = false; 364 } 365 /// true, if variables are captured, false otherwise. 366 bool isLoopStarted() const { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 return !getTopOfStack().LoopStart; 370 } 371 /// Marks (or clears) declaration as possibly loop counter. 372 void resetPossibleLoopCounter(const Decl *D = nullptr) { 373 getTopOfStack().PossiblyLoopCounter = 374 D ? D->getCanonicalDecl() : D; 375 } 376 /// Gets the possible loop counter decl. 377 const Decl *getPossiblyLoopCunter() const { 378 return getTopOfStack().PossiblyLoopCounter; 379 } 380 /// Start new OpenMP region stack in new non-capturing function. 381 void pushFunction() { 382 assert(!IgnoredStackElements && 383 "cannot change stack while ignoring elements"); 384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 385 assert(!isa<CapturingScopeInfo>(CurFnScope)); 386 CurrentNonCapturingFunctionScope = CurFnScope; 387 } 388 /// Pop region stack for non-capturing function. 389 void popFunction(const FunctionScopeInfo *OldFSI) { 390 assert(!IgnoredStackElements && 391 "cannot change stack while ignoring elements"); 392 if (!Stack.empty() && Stack.back().second == OldFSI) { 393 assert(Stack.back().first.empty()); 394 Stack.pop_back(); 395 } 396 CurrentNonCapturingFunctionScope = nullptr; 397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 398 if (!isa<CapturingScopeInfo>(FSI)) { 399 CurrentNonCapturingFunctionScope = FSI; 400 break; 401 } 402 } 403 } 404 405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 407 } 408 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 409 getCriticalWithHint(const DeclarationNameInfo &Name) const { 410 auto I = Criticals.find(Name.getAsString()); 411 if (I != Criticals.end()) 412 return I->second; 413 return std::make_pair(nullptr, llvm::APSInt()); 414 } 415 /// If 'aligned' declaration for given variable \a D was not seen yet, 416 /// add it and return NULL; otherwise return previous occurrence's expression 417 /// for diagnostics. 418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 419 420 /// Register specified variable as loop control variable. 421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 422 /// Check if the specified variable is a loop control variable for 423 /// current region. 424 /// \return The index of the loop control variable in the list of associated 425 /// for-loops (from outer to inner). 426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 427 /// Check if the specified variable is a loop control variable for 428 /// parent region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 432 /// Get the loop control variable for the I-th loop (or nullptr) in 433 /// parent directive. 434 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 435 436 /// Adds explicit data sharing attribute to the specified declaration. 437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 438 DeclRefExpr *PrivateCopy = nullptr); 439 440 /// Adds additional information for the reduction items with the reduction id 441 /// represented as an operator. 442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 443 BinaryOperatorKind BOK); 444 /// Adds additional information for the reduction items with the reduction id 445 /// represented as reduction identifier. 446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 447 const Expr *ReductionRef); 448 /// Returns the location and reduction operation from the innermost parent 449 /// region for the given \p D. 450 const DSAVarData 451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 452 BinaryOperatorKind &BOK, 453 Expr *&TaskgroupDescriptor) const; 454 /// Returns the location and reduction operation from the innermost parent 455 /// region for the given \p D. 456 const DSAVarData 457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 458 const Expr *&ReductionRef, 459 Expr *&TaskgroupDescriptor) const; 460 /// Return reduction reference expression for the current taskgroup. 461 Expr *getTaskgroupReductionRef() const { 462 assert(getTopOfStack().Directive == OMPD_taskgroup && 463 "taskgroup reference expression requested for non taskgroup " 464 "directive."); 465 return getTopOfStack().TaskgroupReductionRef; 466 } 467 /// Checks if the given \p VD declaration is actually a taskgroup reduction 468 /// descriptor variable at the \p Level of OpenMP regions. 469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 470 return getStackElemAtLevel(Level).TaskgroupReductionRef && 471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 472 ->getDecl() == VD; 473 } 474 475 /// Returns data sharing attributes from top of the stack for the 476 /// specified declaration. 477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 478 /// Returns data-sharing attributes for the specified declaration. 479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 480 /// Checks if the specified variables has data-sharing attributes which 481 /// match specified \a CPred predicate in any directive which matches \a DPred 482 /// predicate. 483 const DSAVarData 484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 486 bool FromParent) const; 487 /// Checks if the specified variables has data-sharing attributes which 488 /// match specified \a CPred predicate in any innermost directive which 489 /// matches \a DPred predicate. 490 const DSAVarData 491 hasInnermostDSA(ValueDecl *D, 492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 494 bool FromParent) const; 495 /// Checks if the specified variables has explicit data-sharing 496 /// attributes which match specified \a CPred predicate at the specified 497 /// OpenMP region. 498 bool hasExplicitDSA(const ValueDecl *D, 499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 500 unsigned Level, bool NotLastprivate = false) const; 501 502 /// Returns true if the directive at level \Level matches in the 503 /// specified \a DPred predicate. 504 bool hasExplicitDirective( 505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 506 unsigned Level) const; 507 508 /// Finds a directive which matches specified \a DPred predicate. 509 bool hasDirective( 510 const llvm::function_ref<bool( 511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 512 DPred, 513 bool FromParent) const; 514 515 /// Returns currently analyzed directive. 516 OpenMPDirectiveKind getCurrentDirective() const { 517 const SharingMapTy *Top = getTopOfStackOrNull(); 518 return Top ? Top->Directive : OMPD_unknown; 519 } 520 /// Returns directive kind at specified level. 521 OpenMPDirectiveKind getDirective(unsigned Level) const { 522 assert(!isStackEmpty() && "No directive at specified level."); 523 return getStackElemAtLevel(Level).Directive; 524 } 525 /// Returns parent directive. 526 OpenMPDirectiveKind getParentDirective() const { 527 const SharingMapTy *Parent = getSecondOnStackOrNull(); 528 return Parent ? Parent->Directive : OMPD_unknown; 529 } 530 531 /// Add requires decl to internal vector 532 void addRequiresDecl(OMPRequiresDecl *RD) { 533 RequiresDecls.push_back(RD); 534 } 535 536 /// Checks if the defined 'requires' directive has specified type of clause. 537 template <typename ClauseType> 538 bool hasRequiresDeclWithClause() { 539 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 540 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 541 return isa<ClauseType>(C); 542 }); 543 }); 544 } 545 546 /// Checks for a duplicate clause amongst previously declared requires 547 /// directives 548 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 549 bool IsDuplicate = false; 550 for (OMPClause *CNew : ClauseList) { 551 for (const OMPRequiresDecl *D : RequiresDecls) { 552 for (const OMPClause *CPrev : D->clauselists()) { 553 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 554 SemaRef.Diag(CNew->getBeginLoc(), 555 diag::err_omp_requires_clause_redeclaration) 556 << getOpenMPClauseName(CNew->getClauseKind()); 557 SemaRef.Diag(CPrev->getBeginLoc(), 558 diag::note_omp_requires_previous_clause) 559 << getOpenMPClauseName(CPrev->getClauseKind()); 560 IsDuplicate = true; 561 } 562 } 563 } 564 } 565 return IsDuplicate; 566 } 567 568 /// Add location of previously encountered target to internal vector 569 void addTargetDirLocation(SourceLocation LocStart) { 570 TargetLocations.push_back(LocStart); 571 } 572 573 // Return previously encountered target region locations. 574 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 575 return TargetLocations; 576 } 577 578 /// Set default data sharing attribute to none. 579 void setDefaultDSANone(SourceLocation Loc) { 580 getTopOfStack().DefaultAttr = DSA_none; 581 getTopOfStack().DefaultAttrLoc = Loc; 582 } 583 /// Set default data sharing attribute to shared. 584 void setDefaultDSAShared(SourceLocation Loc) { 585 getTopOfStack().DefaultAttr = DSA_shared; 586 getTopOfStack().DefaultAttrLoc = Loc; 587 } 588 /// Set default data mapping attribute to 'tofrom:scalar'. 589 void setDefaultDMAToFromScalar(SourceLocation Loc) { 590 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 591 getTopOfStack().DefaultMapAttrLoc = Loc; 592 } 593 594 DefaultDataSharingAttributes getDefaultDSA() const { 595 return isStackEmpty() ? DSA_unspecified 596 : getTopOfStack().DefaultAttr; 597 } 598 SourceLocation getDefaultDSALocation() const { 599 return isStackEmpty() ? SourceLocation() 600 : getTopOfStack().DefaultAttrLoc; 601 } 602 DefaultMapAttributes getDefaultDMA() const { 603 return isStackEmpty() ? DMA_unspecified 604 : getTopOfStack().DefaultMapAttr; 605 } 606 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 607 return getStackElemAtLevel(Level).DefaultMapAttr; 608 } 609 SourceLocation getDefaultDMALocation() const { 610 return isStackEmpty() ? SourceLocation() 611 : getTopOfStack().DefaultMapAttrLoc; 612 } 613 614 /// Checks if the specified variable is a threadprivate. 615 bool isThreadPrivate(VarDecl *D) { 616 const DSAVarData DVar = getTopDSA(D, false); 617 return isOpenMPThreadPrivate(DVar.CKind); 618 } 619 620 /// Marks current region as ordered (it has an 'ordered' clause). 621 void setOrderedRegion(bool IsOrdered, const Expr *Param, 622 OMPOrderedClause *Clause) { 623 if (IsOrdered) 624 getTopOfStack().OrderedRegion.emplace(Param, Clause); 625 else 626 getTopOfStack().OrderedRegion.reset(); 627 } 628 /// Returns true, if region is ordered (has associated 'ordered' clause), 629 /// false - otherwise. 630 bool isOrderedRegion() const { 631 if (const SharingMapTy *Top = getTopOfStackOrNull()) 632 return Top->OrderedRegion.hasValue(); 633 return false; 634 } 635 /// Returns optional parameter for the ordered region. 636 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 637 if (const SharingMapTy *Top = getTopOfStackOrNull()) 638 if (Top->OrderedRegion.hasValue()) 639 return Top->OrderedRegion.getValue(); 640 return std::make_pair(nullptr, nullptr); 641 } 642 /// Returns true, if parent region is ordered (has associated 643 /// 'ordered' clause), false - otherwise. 644 bool isParentOrderedRegion() const { 645 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 646 return Parent->OrderedRegion.hasValue(); 647 return false; 648 } 649 /// Returns optional parameter for the ordered region. 650 std::pair<const Expr *, OMPOrderedClause *> 651 getParentOrderedRegionParam() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 if (Parent->OrderedRegion.hasValue()) 654 return Parent->OrderedRegion.getValue(); 655 return std::make_pair(nullptr, nullptr); 656 } 657 /// Marks current region as nowait (it has a 'nowait' clause). 658 void setNowaitRegion(bool IsNowait = true) { 659 getTopOfStack().NowaitRegion = IsNowait; 660 } 661 /// Returns true, if parent region is nowait (has associated 662 /// 'nowait' clause), false - otherwise. 663 bool isParentNowaitRegion() const { 664 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 665 return Parent->NowaitRegion; 666 return false; 667 } 668 /// Marks parent region as cancel region. 669 void setParentCancelRegion(bool Cancel = true) { 670 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 671 Parent->CancelRegion |= Cancel; 672 } 673 /// Return true if current region has inner cancel construct. 674 bool isCancelRegion() const { 675 const SharingMapTy *Top = getTopOfStackOrNull(); 676 return Top ? Top->CancelRegion : false; 677 } 678 679 /// Set collapse value for the region. 680 void setAssociatedLoops(unsigned Val) { 681 getTopOfStack().AssociatedLoops = Val; 682 if (Val > 1) 683 getTopOfStack().HasMutipleLoops = true; 684 } 685 /// Return collapse value for region. 686 unsigned getAssociatedLoops() const { 687 const SharingMapTy *Top = getTopOfStackOrNull(); 688 return Top ? Top->AssociatedLoops : 0; 689 } 690 /// Returns true if the construct is associated with multiple loops. 691 bool hasMutipleLoops() const { 692 const SharingMapTy *Top = getTopOfStackOrNull(); 693 return Top ? Top->HasMutipleLoops : false; 694 } 695 696 /// Marks current target region as one with closely nested teams 697 /// region. 698 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 699 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 700 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 701 } 702 /// Returns true, if current region has closely nested teams region. 703 bool hasInnerTeamsRegion() const { 704 return getInnerTeamsRegionLoc().isValid(); 705 } 706 /// Returns location of the nested teams region (if any). 707 SourceLocation getInnerTeamsRegionLoc() const { 708 const SharingMapTy *Top = getTopOfStackOrNull(); 709 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 710 } 711 712 Scope *getCurScope() const { 713 const SharingMapTy *Top = getTopOfStackOrNull(); 714 return Top ? Top->CurScope : nullptr; 715 } 716 SourceLocation getConstructLoc() const { 717 const SharingMapTy *Top = getTopOfStackOrNull(); 718 return Top ? Top->ConstructLoc : SourceLocation(); 719 } 720 721 /// Do the check specified in \a Check to all component lists and return true 722 /// if any issue is found. 723 bool checkMappableExprComponentListsForDecl( 724 const ValueDecl *VD, bool CurrentRegionOnly, 725 const llvm::function_ref< 726 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 727 OpenMPClauseKind)> 728 Check) const { 729 if (isStackEmpty()) 730 return false; 731 auto SI = begin(); 732 auto SE = end(); 733 734 if (SI == SE) 735 return false; 736 737 if (CurrentRegionOnly) 738 SE = std::next(SI); 739 else 740 std::advance(SI, 1); 741 742 for (; SI != SE; ++SI) { 743 auto MI = SI->MappedExprComponents.find(VD); 744 if (MI != SI->MappedExprComponents.end()) 745 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 746 MI->second.Components) 747 if (Check(L, MI->second.Kind)) 748 return true; 749 } 750 return false; 751 } 752 753 /// Do the check specified in \a Check to all component lists at a given level 754 /// and return true if any issue is found. 755 bool checkMappableExprComponentListsForDeclAtLevel( 756 const ValueDecl *VD, unsigned Level, 757 const llvm::function_ref< 758 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 759 OpenMPClauseKind)> 760 Check) const { 761 if (getStackSize() <= Level) 762 return false; 763 764 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 765 auto MI = StackElem.MappedExprComponents.find(VD); 766 if (MI != StackElem.MappedExprComponents.end()) 767 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 768 MI->second.Components) 769 if (Check(L, MI->second.Kind)) 770 return true; 771 return false; 772 } 773 774 /// Create a new mappable expression component list associated with a given 775 /// declaration and initialize it with the provided list of components. 776 void addMappableExpressionComponents( 777 const ValueDecl *VD, 778 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 779 OpenMPClauseKind WhereFoundClauseKind) { 780 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 781 // Create new entry and append the new components there. 782 MEC.Components.resize(MEC.Components.size() + 1); 783 MEC.Components.back().append(Components.begin(), Components.end()); 784 MEC.Kind = WhereFoundClauseKind; 785 } 786 787 unsigned getNestingLevel() const { 788 assert(!isStackEmpty()); 789 return getStackSize() - 1; 790 } 791 void addDoacrossDependClause(OMPDependClause *C, 792 const OperatorOffsetTy &OpsOffs) { 793 SharingMapTy *Parent = getSecondOnStackOrNull(); 794 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 795 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 796 } 797 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 798 getDoacrossDependClauses() const { 799 const SharingMapTy &StackElem = getTopOfStack(); 800 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 801 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 802 return llvm::make_range(Ref.begin(), Ref.end()); 803 } 804 return llvm::make_range(StackElem.DoacrossDepends.end(), 805 StackElem.DoacrossDepends.end()); 806 } 807 808 // Store types of classes which have been explicitly mapped 809 void addMappedClassesQualTypes(QualType QT) { 810 SharingMapTy &StackElem = getTopOfStack(); 811 StackElem.MappedClassesQualTypes.insert(QT); 812 } 813 814 // Return set of mapped classes types 815 bool isClassPreviouslyMapped(QualType QT) const { 816 const SharingMapTy &StackElem = getTopOfStack(); 817 return StackElem.MappedClassesQualTypes.count(QT) != 0; 818 } 819 820 /// Adds global declare target to the parent target region. 821 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 822 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 823 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 824 "Expected declare target link global."); 825 for (auto &Elem : *this) { 826 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 827 Elem.DeclareTargetLinkVarDecls.push_back(E); 828 return; 829 } 830 } 831 } 832 833 /// Returns the list of globals with declare target link if current directive 834 /// is target. 835 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 836 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 837 "Expected target executable directive."); 838 return getTopOfStack().DeclareTargetLinkVarDecls; 839 } 840 }; 841 842 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 843 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 844 } 845 846 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 847 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 848 DKind == OMPD_unknown; 849 } 850 851 } // namespace 852 853 static const Expr *getExprAsWritten(const Expr *E) { 854 if (const auto *FE = dyn_cast<FullExpr>(E)) 855 E = FE->getSubExpr(); 856 857 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 858 E = MTE->GetTemporaryExpr(); 859 860 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 861 E = Binder->getSubExpr(); 862 863 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 864 E = ICE->getSubExprAsWritten(); 865 return E->IgnoreParens(); 866 } 867 868 static Expr *getExprAsWritten(Expr *E) { 869 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 870 } 871 872 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 873 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 874 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 875 D = ME->getMemberDecl(); 876 const auto *VD = dyn_cast<VarDecl>(D); 877 const auto *FD = dyn_cast<FieldDecl>(D); 878 if (VD != nullptr) { 879 VD = VD->getCanonicalDecl(); 880 D = VD; 881 } else { 882 assert(FD); 883 FD = FD->getCanonicalDecl(); 884 D = FD; 885 } 886 return D; 887 } 888 889 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 890 return const_cast<ValueDecl *>( 891 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 892 } 893 894 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 895 ValueDecl *D) const { 896 D = getCanonicalDecl(D); 897 auto *VD = dyn_cast<VarDecl>(D); 898 const auto *FD = dyn_cast<FieldDecl>(D); 899 DSAVarData DVar; 900 if (Iter == end()) { 901 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 902 // in a region but not in construct] 903 // File-scope or namespace-scope variables referenced in called routines 904 // in the region are shared unless they appear in a threadprivate 905 // directive. 906 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 907 DVar.CKind = OMPC_shared; 908 909 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 910 // in a region but not in construct] 911 // Variables with static storage duration that are declared in called 912 // routines in the region are shared. 913 if (VD && VD->hasGlobalStorage()) 914 DVar.CKind = OMPC_shared; 915 916 // Non-static data members are shared by default. 917 if (FD) 918 DVar.CKind = OMPC_shared; 919 920 return DVar; 921 } 922 923 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 924 // in a Construct, C/C++, predetermined, p.1] 925 // Variables with automatic storage duration that are declared in a scope 926 // inside the construct are private. 927 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 928 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 929 DVar.CKind = OMPC_private; 930 return DVar; 931 } 932 933 DVar.DKind = Iter->Directive; 934 // Explicitly specified attributes and local variables with predetermined 935 // attributes. 936 if (Iter->SharingMap.count(D)) { 937 const DSAInfo &Data = Iter->SharingMap.lookup(D); 938 DVar.RefExpr = Data.RefExpr.getPointer(); 939 DVar.PrivateCopy = Data.PrivateCopy; 940 DVar.CKind = Data.Attributes; 941 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 942 return DVar; 943 } 944 945 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 946 // in a Construct, C/C++, implicitly determined, p.1] 947 // In a parallel or task construct, the data-sharing attributes of these 948 // variables are determined by the default clause, if present. 949 switch (Iter->DefaultAttr) { 950 case DSA_shared: 951 DVar.CKind = OMPC_shared; 952 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 953 return DVar; 954 case DSA_none: 955 return DVar; 956 case DSA_unspecified: 957 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 958 // in a Construct, implicitly determined, p.2] 959 // In a parallel construct, if no default clause is present, these 960 // variables are shared. 961 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 962 if (isOpenMPParallelDirective(DVar.DKind) || 963 isOpenMPTeamsDirective(DVar.DKind)) { 964 DVar.CKind = OMPC_shared; 965 return DVar; 966 } 967 968 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 969 // in a Construct, implicitly determined, p.4] 970 // In a task construct, if no default clause is present, a variable that in 971 // the enclosing context is determined to be shared by all implicit tasks 972 // bound to the current team is shared. 973 if (isOpenMPTaskingDirective(DVar.DKind)) { 974 DSAVarData DVarTemp; 975 const_iterator I = Iter, E = end(); 976 do { 977 ++I; 978 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 979 // Referenced in a Construct, implicitly determined, p.6] 980 // In a task construct, if no default clause is present, a variable 981 // whose data-sharing attribute is not determined by the rules above is 982 // firstprivate. 983 DVarTemp = getDSA(I, D); 984 if (DVarTemp.CKind != OMPC_shared) { 985 DVar.RefExpr = nullptr; 986 DVar.CKind = OMPC_firstprivate; 987 return DVar; 988 } 989 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 990 DVar.CKind = 991 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 992 return DVar; 993 } 994 } 995 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 996 // in a Construct, implicitly determined, p.3] 997 // For constructs other than task, if no default clause is present, these 998 // variables inherit their data-sharing attributes from the enclosing 999 // context. 1000 return getDSA(++Iter, D); 1001 } 1002 1003 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1004 const Expr *NewDE) { 1005 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1006 D = getCanonicalDecl(D); 1007 SharingMapTy &StackElem = getTopOfStack(); 1008 auto It = StackElem.AlignedMap.find(D); 1009 if (It == StackElem.AlignedMap.end()) { 1010 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1011 StackElem.AlignedMap[D] = NewDE; 1012 return nullptr; 1013 } 1014 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1015 return It->second; 1016 } 1017 1018 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1019 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1020 D = getCanonicalDecl(D); 1021 SharingMapTy &StackElem = getTopOfStack(); 1022 StackElem.LCVMap.try_emplace( 1023 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1024 } 1025 1026 const DSAStackTy::LCDeclInfo 1027 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1028 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1029 D = getCanonicalDecl(D); 1030 const SharingMapTy &StackElem = getTopOfStack(); 1031 auto It = StackElem.LCVMap.find(D); 1032 if (It != StackElem.LCVMap.end()) 1033 return It->second; 1034 return {0, nullptr}; 1035 } 1036 1037 const DSAStackTy::LCDeclInfo 1038 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1039 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1040 assert(Parent && "Data-sharing attributes stack is empty"); 1041 D = getCanonicalDecl(D); 1042 auto It = Parent->LCVMap.find(D); 1043 if (It != Parent->LCVMap.end()) 1044 return It->second; 1045 return {0, nullptr}; 1046 } 1047 1048 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1049 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1050 assert(Parent && "Data-sharing attributes stack is empty"); 1051 if (Parent->LCVMap.size() < I) 1052 return nullptr; 1053 for (const auto &Pair : Parent->LCVMap) 1054 if (Pair.second.first == I) 1055 return Pair.first; 1056 return nullptr; 1057 } 1058 1059 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1060 DeclRefExpr *PrivateCopy) { 1061 D = getCanonicalDecl(D); 1062 if (A == OMPC_threadprivate) { 1063 DSAInfo &Data = Threadprivates[D]; 1064 Data.Attributes = A; 1065 Data.RefExpr.setPointer(E); 1066 Data.PrivateCopy = nullptr; 1067 } else { 1068 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1069 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1070 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1071 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1072 (isLoopControlVariable(D).first && A == OMPC_private)); 1073 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1074 Data.RefExpr.setInt(/*IntVal=*/true); 1075 return; 1076 } 1077 const bool IsLastprivate = 1078 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1079 Data.Attributes = A; 1080 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1081 Data.PrivateCopy = PrivateCopy; 1082 if (PrivateCopy) { 1083 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1084 Data.Attributes = A; 1085 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1086 Data.PrivateCopy = nullptr; 1087 } 1088 } 1089 } 1090 1091 /// Build a variable declaration for OpenMP loop iteration variable. 1092 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1093 StringRef Name, const AttrVec *Attrs = nullptr, 1094 DeclRefExpr *OrigRef = nullptr) { 1095 DeclContext *DC = SemaRef.CurContext; 1096 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1097 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1098 auto *Decl = 1099 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1100 if (Attrs) { 1101 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1102 I != E; ++I) 1103 Decl->addAttr(*I); 1104 } 1105 Decl->setImplicit(); 1106 if (OrigRef) { 1107 Decl->addAttr( 1108 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1109 } 1110 return Decl; 1111 } 1112 1113 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1114 SourceLocation Loc, 1115 bool RefersToCapture = false) { 1116 D->setReferenced(); 1117 D->markUsed(S.Context); 1118 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1119 SourceLocation(), D, RefersToCapture, Loc, Ty, 1120 VK_LValue); 1121 } 1122 1123 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1124 BinaryOperatorKind BOK) { 1125 D = getCanonicalDecl(D); 1126 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1127 assert( 1128 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1129 "Additional reduction info may be specified only for reduction items."); 1130 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1131 assert(ReductionData.ReductionRange.isInvalid() && 1132 getTopOfStack().Directive == OMPD_taskgroup && 1133 "Additional reduction info may be specified only once for reduction " 1134 "items."); 1135 ReductionData.set(BOK, SR); 1136 Expr *&TaskgroupReductionRef = 1137 getTopOfStack().TaskgroupReductionRef; 1138 if (!TaskgroupReductionRef) { 1139 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1140 SemaRef.Context.VoidPtrTy, ".task_red."); 1141 TaskgroupReductionRef = 1142 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1143 } 1144 } 1145 1146 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1147 const Expr *ReductionRef) { 1148 D = getCanonicalDecl(D); 1149 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1150 assert( 1151 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1152 "Additional reduction info may be specified only for reduction items."); 1153 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1154 assert(ReductionData.ReductionRange.isInvalid() && 1155 getTopOfStack().Directive == OMPD_taskgroup && 1156 "Additional reduction info may be specified only once for reduction " 1157 "items."); 1158 ReductionData.set(ReductionRef, SR); 1159 Expr *&TaskgroupReductionRef = 1160 getTopOfStack().TaskgroupReductionRef; 1161 if (!TaskgroupReductionRef) { 1162 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1163 SemaRef.Context.VoidPtrTy, ".task_red."); 1164 TaskgroupReductionRef = 1165 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1166 } 1167 } 1168 1169 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1170 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1171 Expr *&TaskgroupDescriptor) const { 1172 D = getCanonicalDecl(D); 1173 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1174 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1175 const DSAInfo &Data = I->SharingMap.lookup(D); 1176 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1177 continue; 1178 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1179 if (!ReductionData.ReductionOp || 1180 ReductionData.ReductionOp.is<const Expr *>()) 1181 return DSAVarData(); 1182 SR = ReductionData.ReductionRange; 1183 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1184 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1185 "expression for the descriptor is not " 1186 "set."); 1187 TaskgroupDescriptor = I->TaskgroupReductionRef; 1188 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1189 Data.PrivateCopy, I->DefaultAttrLoc); 1190 } 1191 return DSAVarData(); 1192 } 1193 1194 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1195 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1196 Expr *&TaskgroupDescriptor) const { 1197 D = getCanonicalDecl(D); 1198 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1199 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1200 const DSAInfo &Data = I->SharingMap.lookup(D); 1201 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1202 continue; 1203 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1204 if (!ReductionData.ReductionOp || 1205 !ReductionData.ReductionOp.is<const Expr *>()) 1206 return DSAVarData(); 1207 SR = ReductionData.ReductionRange; 1208 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1209 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1210 "expression for the descriptor is not " 1211 "set."); 1212 TaskgroupDescriptor = I->TaskgroupReductionRef; 1213 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1214 Data.PrivateCopy, I->DefaultAttrLoc); 1215 } 1216 return DSAVarData(); 1217 } 1218 1219 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1220 D = D->getCanonicalDecl(); 1221 for (const_iterator E = end(); I != E; ++I) { 1222 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1223 isOpenMPTargetExecutionDirective(I->Directive)) { 1224 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1225 Scope *CurScope = getCurScope(); 1226 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1227 CurScope = CurScope->getParent(); 1228 return CurScope != TopScope; 1229 } 1230 } 1231 return false; 1232 } 1233 1234 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1235 bool AcceptIfMutable = true, 1236 bool *IsClassType = nullptr) { 1237 ASTContext &Context = SemaRef.getASTContext(); 1238 Type = Type.getNonReferenceType().getCanonicalType(); 1239 bool IsConstant = Type.isConstant(Context); 1240 Type = Context.getBaseElementType(Type); 1241 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1242 ? Type->getAsCXXRecordDecl() 1243 : nullptr; 1244 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1245 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1246 RD = CTD->getTemplatedDecl(); 1247 if (IsClassType) 1248 *IsClassType = RD; 1249 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1250 RD->hasDefinition() && RD->hasMutableFields()); 1251 } 1252 1253 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1254 QualType Type, OpenMPClauseKind CKind, 1255 SourceLocation ELoc, 1256 bool AcceptIfMutable = true, 1257 bool ListItemNotVar = false) { 1258 ASTContext &Context = SemaRef.getASTContext(); 1259 bool IsClassType; 1260 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1261 unsigned Diag = ListItemNotVar 1262 ? diag::err_omp_const_list_item 1263 : IsClassType ? diag::err_omp_const_not_mutable_variable 1264 : diag::err_omp_const_variable; 1265 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1266 if (!ListItemNotVar && D) { 1267 const VarDecl *VD = dyn_cast<VarDecl>(D); 1268 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1269 VarDecl::DeclarationOnly; 1270 SemaRef.Diag(D->getLocation(), 1271 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1272 << D; 1273 } 1274 return true; 1275 } 1276 return false; 1277 } 1278 1279 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1280 bool FromParent) { 1281 D = getCanonicalDecl(D); 1282 DSAVarData DVar; 1283 1284 auto *VD = dyn_cast<VarDecl>(D); 1285 auto TI = Threadprivates.find(D); 1286 if (TI != Threadprivates.end()) { 1287 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1288 DVar.CKind = OMPC_threadprivate; 1289 return DVar; 1290 } 1291 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1292 DVar.RefExpr = buildDeclRefExpr( 1293 SemaRef, VD, D->getType().getNonReferenceType(), 1294 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1295 DVar.CKind = OMPC_threadprivate; 1296 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1297 return DVar; 1298 } 1299 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1300 // in a Construct, C/C++, predetermined, p.1] 1301 // Variables appearing in threadprivate directives are threadprivate. 1302 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1303 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1304 SemaRef.getLangOpts().OpenMPUseTLS && 1305 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1306 (VD && VD->getStorageClass() == SC_Register && 1307 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1308 DVar.RefExpr = buildDeclRefExpr( 1309 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1310 DVar.CKind = OMPC_threadprivate; 1311 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1312 return DVar; 1313 } 1314 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1315 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1316 !isLoopControlVariable(D).first) { 1317 const_iterator IterTarget = 1318 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1319 return isOpenMPTargetExecutionDirective(Data.Directive); 1320 }); 1321 if (IterTarget != end()) { 1322 const_iterator ParentIterTarget = IterTarget + 1; 1323 for (const_iterator Iter = begin(); 1324 Iter != ParentIterTarget; ++Iter) { 1325 if (isOpenMPLocal(VD, Iter)) { 1326 DVar.RefExpr = 1327 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1328 D->getLocation()); 1329 DVar.CKind = OMPC_threadprivate; 1330 return DVar; 1331 } 1332 } 1333 if (!isClauseParsingMode() || IterTarget != begin()) { 1334 auto DSAIter = IterTarget->SharingMap.find(D); 1335 if (DSAIter != IterTarget->SharingMap.end() && 1336 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1337 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1338 DVar.CKind = OMPC_threadprivate; 1339 return DVar; 1340 } 1341 const_iterator End = end(); 1342 if (!SemaRef.isOpenMPCapturedByRef( 1343 D, std::distance(ParentIterTarget, End))) { 1344 DVar.RefExpr = 1345 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1346 IterTarget->ConstructLoc); 1347 DVar.CKind = OMPC_threadprivate; 1348 return DVar; 1349 } 1350 } 1351 } 1352 } 1353 1354 if (isStackEmpty()) 1355 // Not in OpenMP execution region and top scope was already checked. 1356 return DVar; 1357 1358 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1359 // in a Construct, C/C++, predetermined, p.4] 1360 // Static data members are shared. 1361 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1362 // in a Construct, C/C++, predetermined, p.7] 1363 // Variables with static storage duration that are declared in a scope 1364 // inside the construct are shared. 1365 if (VD && VD->isStaticDataMember()) { 1366 // Check for explicitly specified attributes. 1367 const_iterator I = begin(); 1368 const_iterator EndI = end(); 1369 if (FromParent && I != EndI) 1370 ++I; 1371 auto It = I->SharingMap.find(D); 1372 if (It != I->SharingMap.end()) { 1373 const DSAInfo &Data = It->getSecond(); 1374 DVar.RefExpr = Data.RefExpr.getPointer(); 1375 DVar.PrivateCopy = Data.PrivateCopy; 1376 DVar.CKind = Data.Attributes; 1377 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1378 DVar.DKind = I->Directive; 1379 return DVar; 1380 } 1381 1382 DVar.CKind = OMPC_shared; 1383 return DVar; 1384 } 1385 1386 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1387 // The predetermined shared attribute for const-qualified types having no 1388 // mutable members was removed after OpenMP 3.1. 1389 if (SemaRef.LangOpts.OpenMP <= 31) { 1390 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1391 // in a Construct, C/C++, predetermined, p.6] 1392 // Variables with const qualified type having no mutable member are 1393 // shared. 1394 if (isConstNotMutableType(SemaRef, D->getType())) { 1395 // Variables with const-qualified type having no mutable member may be 1396 // listed in a firstprivate clause, even if they are static data members. 1397 DSAVarData DVarTemp = hasInnermostDSA( 1398 D, 1399 [](OpenMPClauseKind C) { 1400 return C == OMPC_firstprivate || C == OMPC_shared; 1401 }, 1402 MatchesAlways, FromParent); 1403 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1404 return DVarTemp; 1405 1406 DVar.CKind = OMPC_shared; 1407 return DVar; 1408 } 1409 } 1410 1411 // Explicitly specified attributes and local variables with predetermined 1412 // attributes. 1413 const_iterator I = begin(); 1414 const_iterator EndI = end(); 1415 if (FromParent && I != EndI) 1416 ++I; 1417 auto It = I->SharingMap.find(D); 1418 if (It != I->SharingMap.end()) { 1419 const DSAInfo &Data = It->getSecond(); 1420 DVar.RefExpr = Data.RefExpr.getPointer(); 1421 DVar.PrivateCopy = Data.PrivateCopy; 1422 DVar.CKind = Data.Attributes; 1423 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1424 DVar.DKind = I->Directive; 1425 } 1426 1427 return DVar; 1428 } 1429 1430 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1431 bool FromParent) const { 1432 if (isStackEmpty()) { 1433 const_iterator I; 1434 return getDSA(I, D); 1435 } 1436 D = getCanonicalDecl(D); 1437 const_iterator StartI = begin(); 1438 const_iterator EndI = end(); 1439 if (FromParent && StartI != EndI) 1440 ++StartI; 1441 return getDSA(StartI, D); 1442 } 1443 1444 const DSAStackTy::DSAVarData 1445 DSAStackTy::hasDSA(ValueDecl *D, 1446 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1447 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1448 bool FromParent) const { 1449 if (isStackEmpty()) 1450 return {}; 1451 D = getCanonicalDecl(D); 1452 const_iterator I = begin(); 1453 const_iterator EndI = end(); 1454 if (FromParent && I != EndI) 1455 ++I; 1456 for (; I != EndI; ++I) { 1457 if (!DPred(I->Directive) && 1458 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1459 continue; 1460 const_iterator NewI = I; 1461 DSAVarData DVar = getDSA(NewI, D); 1462 if (I == NewI && CPred(DVar.CKind)) 1463 return DVar; 1464 } 1465 return {}; 1466 } 1467 1468 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1469 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1470 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1471 bool FromParent) const { 1472 if (isStackEmpty()) 1473 return {}; 1474 D = getCanonicalDecl(D); 1475 const_iterator StartI = begin(); 1476 const_iterator EndI = end(); 1477 if (FromParent && StartI != EndI) 1478 ++StartI; 1479 if (StartI == EndI || !DPred(StartI->Directive)) 1480 return {}; 1481 const_iterator NewI = StartI; 1482 DSAVarData DVar = getDSA(NewI, D); 1483 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1484 } 1485 1486 bool DSAStackTy::hasExplicitDSA( 1487 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1488 unsigned Level, bool NotLastprivate) const { 1489 if (getStackSize() <= Level) 1490 return false; 1491 D = getCanonicalDecl(D); 1492 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1493 auto I = StackElem.SharingMap.find(D); 1494 if (I != StackElem.SharingMap.end() && 1495 I->getSecond().RefExpr.getPointer() && 1496 CPred(I->getSecond().Attributes) && 1497 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1498 return true; 1499 // Check predetermined rules for the loop control variables. 1500 auto LI = StackElem.LCVMap.find(D); 1501 if (LI != StackElem.LCVMap.end()) 1502 return CPred(OMPC_private); 1503 return false; 1504 } 1505 1506 bool DSAStackTy::hasExplicitDirective( 1507 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1508 unsigned Level) const { 1509 if (getStackSize() <= Level) 1510 return false; 1511 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1512 return DPred(StackElem.Directive); 1513 } 1514 1515 bool DSAStackTy::hasDirective( 1516 const llvm::function_ref<bool(OpenMPDirectiveKind, 1517 const DeclarationNameInfo &, SourceLocation)> 1518 DPred, 1519 bool FromParent) const { 1520 // We look only in the enclosing region. 1521 size_t Skip = FromParent ? 2 : 1; 1522 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1523 I != E; ++I) { 1524 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1525 return true; 1526 } 1527 return false; 1528 } 1529 1530 void Sema::InitDataSharingAttributesStack() { 1531 VarDataSharingAttributesStack = new DSAStackTy(*this); 1532 } 1533 1534 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1535 1536 void Sema::pushOpenMPFunctionRegion() { 1537 DSAStack->pushFunction(); 1538 } 1539 1540 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1541 DSAStack->popFunction(OldFSI); 1542 } 1543 1544 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1545 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1546 "Expected OpenMP device compilation."); 1547 return !S.isInOpenMPTargetExecutionDirective() && 1548 !S.isInOpenMPDeclareTargetContext(); 1549 } 1550 1551 /// Do we know that we will eventually codegen the given function? 1552 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1553 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1554 "Expected OpenMP device compilation."); 1555 // Templates are emitted when they're instantiated. 1556 if (FD->isDependentContext()) 1557 return false; 1558 1559 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1560 FD->getCanonicalDecl())) 1561 return true; 1562 1563 // Otherwise, the function is known-emitted if it's in our set of 1564 // known-emitted functions. 1565 return S.DeviceKnownEmittedFns.count(FD) > 0; 1566 } 1567 1568 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1569 unsigned DiagID) { 1570 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1571 "Expected OpenMP device compilation."); 1572 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1573 !isKnownEmitted(*this, getCurFunctionDecl())) 1574 ? DeviceDiagBuilder::K_Deferred 1575 : DeviceDiagBuilder::K_Immediate, 1576 Loc, DiagID, getCurFunctionDecl(), *this); 1577 } 1578 1579 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1580 bool CheckForDelayedContext) { 1581 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1582 "Expected OpenMP device compilation."); 1583 assert(Callee && "Callee may not be null."); 1584 FunctionDecl *Caller = getCurFunctionDecl(); 1585 1586 // If the caller is known-emitted, mark the callee as known-emitted. 1587 // Otherwise, mark the call in our call graph so we can traverse it later. 1588 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1589 (!Caller && !CheckForDelayedContext) || 1590 (Caller && isKnownEmitted(*this, Caller))) 1591 markKnownEmitted(*this, Caller, Callee, Loc, 1592 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1593 return CheckForDelayedContext && isKnownEmitted(S, FD); 1594 }); 1595 else if (Caller) 1596 DeviceCallGraph[Caller].insert({Callee, Loc}); 1597 } 1598 1599 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1600 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1601 "OpenMP device compilation mode is expected."); 1602 QualType Ty = E->getType(); 1603 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1604 ((Ty->isFloat128Type() || 1605 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1606 !Context.getTargetInfo().hasFloat128Type()) || 1607 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1608 !Context.getTargetInfo().hasInt128Type())) 1609 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1610 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1611 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1612 } 1613 1614 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1615 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1616 1617 ASTContext &Ctx = getASTContext(); 1618 bool IsByRef = true; 1619 1620 // Find the directive that is associated with the provided scope. 1621 D = cast<ValueDecl>(D->getCanonicalDecl()); 1622 QualType Ty = D->getType(); 1623 1624 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1625 // This table summarizes how a given variable should be passed to the device 1626 // given its type and the clauses where it appears. This table is based on 1627 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1628 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1629 // 1630 // ========================================================================= 1631 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1632 // | |(tofrom:scalar)| | pvt | | | | 1633 // ========================================================================= 1634 // | scl | | | | - | | bycopy| 1635 // | scl | | - | x | - | - | bycopy| 1636 // | scl | | x | - | - | - | null | 1637 // | scl | x | | | - | | byref | 1638 // | scl | x | - | x | - | - | bycopy| 1639 // | scl | x | x | - | - | - | null | 1640 // | scl | | - | - | - | x | byref | 1641 // | scl | x | - | - | - | x | byref | 1642 // 1643 // | agg | n.a. | | | - | | byref | 1644 // | agg | n.a. | - | x | - | - | byref | 1645 // | agg | n.a. | x | - | - | - | null | 1646 // | agg | n.a. | - | - | - | x | byref | 1647 // | agg | n.a. | - | - | - | x[] | byref | 1648 // 1649 // | ptr | n.a. | | | - | | bycopy| 1650 // | ptr | n.a. | - | x | - | - | bycopy| 1651 // | ptr | n.a. | x | - | - | - | null | 1652 // | ptr | n.a. | - | - | - | x | byref | 1653 // | ptr | n.a. | - | - | - | x[] | bycopy| 1654 // | ptr | n.a. | - | - | x | | bycopy| 1655 // | ptr | n.a. | - | - | x | x | bycopy| 1656 // | ptr | n.a. | - | - | x | x[] | bycopy| 1657 // ========================================================================= 1658 // Legend: 1659 // scl - scalar 1660 // ptr - pointer 1661 // agg - aggregate 1662 // x - applies 1663 // - - invalid in this combination 1664 // [] - mapped with an array section 1665 // byref - should be mapped by reference 1666 // byval - should be mapped by value 1667 // null - initialize a local variable to null on the device 1668 // 1669 // Observations: 1670 // - All scalar declarations that show up in a map clause have to be passed 1671 // by reference, because they may have been mapped in the enclosing data 1672 // environment. 1673 // - If the scalar value does not fit the size of uintptr, it has to be 1674 // passed by reference, regardless the result in the table above. 1675 // - For pointers mapped by value that have either an implicit map or an 1676 // array section, the runtime library may pass the NULL value to the 1677 // device instead of the value passed to it by the compiler. 1678 1679 if (Ty->isReferenceType()) 1680 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1681 1682 // Locate map clauses and see if the variable being captured is referred to 1683 // in any of those clauses. Here we only care about variables, not fields, 1684 // because fields are part of aggregates. 1685 bool IsVariableUsedInMapClause = false; 1686 bool IsVariableAssociatedWithSection = false; 1687 1688 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1689 D, Level, 1690 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1691 OMPClauseMappableExprCommon::MappableExprComponentListRef 1692 MapExprComponents, 1693 OpenMPClauseKind WhereFoundClauseKind) { 1694 // Only the map clause information influences how a variable is 1695 // captured. E.g. is_device_ptr does not require changing the default 1696 // behavior. 1697 if (WhereFoundClauseKind != OMPC_map) 1698 return false; 1699 1700 auto EI = MapExprComponents.rbegin(); 1701 auto EE = MapExprComponents.rend(); 1702 1703 assert(EI != EE && "Invalid map expression!"); 1704 1705 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1706 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1707 1708 ++EI; 1709 if (EI == EE) 1710 return false; 1711 1712 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1713 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1714 isa<MemberExpr>(EI->getAssociatedExpression())) { 1715 IsVariableAssociatedWithSection = true; 1716 // There is nothing more we need to know about this variable. 1717 return true; 1718 } 1719 1720 // Keep looking for more map info. 1721 return false; 1722 }); 1723 1724 if (IsVariableUsedInMapClause) { 1725 // If variable is identified in a map clause it is always captured by 1726 // reference except if it is a pointer that is dereferenced somehow. 1727 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1728 } else { 1729 // By default, all the data that has a scalar type is mapped by copy 1730 // (except for reduction variables). 1731 IsByRef = 1732 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1733 !Ty->isAnyPointerType()) || 1734 !Ty->isScalarType() || 1735 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1736 DSAStack->hasExplicitDSA( 1737 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1738 } 1739 } 1740 1741 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1742 IsByRef = 1743 !DSAStack->hasExplicitDSA( 1744 D, 1745 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1746 Level, /*NotLastprivate=*/true) && 1747 // If the variable is artificial and must be captured by value - try to 1748 // capture by value. 1749 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1750 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1751 } 1752 1753 // When passing data by copy, we need to make sure it fits the uintptr size 1754 // and alignment, because the runtime library only deals with uintptr types. 1755 // If it does not fit the uintptr size, we need to pass the data by reference 1756 // instead. 1757 if (!IsByRef && 1758 (Ctx.getTypeSizeInChars(Ty) > 1759 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1760 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1761 IsByRef = true; 1762 } 1763 1764 return IsByRef; 1765 } 1766 1767 unsigned Sema::getOpenMPNestingLevel() const { 1768 assert(getLangOpts().OpenMP); 1769 return DSAStack->getNestingLevel(); 1770 } 1771 1772 bool Sema::isInOpenMPTargetExecutionDirective() const { 1773 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1774 !DSAStack->isClauseParsingMode()) || 1775 DSAStack->hasDirective( 1776 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1777 SourceLocation) -> bool { 1778 return isOpenMPTargetExecutionDirective(K); 1779 }, 1780 false); 1781 } 1782 1783 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1784 unsigned StopAt) { 1785 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1786 D = getCanonicalDecl(D); 1787 1788 // If we want to determine whether the variable should be captured from the 1789 // perspective of the current capturing scope, and we've already left all the 1790 // capturing scopes of the top directive on the stack, check from the 1791 // perspective of its parent directive (if any) instead. 1792 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1793 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1794 1795 // If we are attempting to capture a global variable in a directive with 1796 // 'target' we return true so that this global is also mapped to the device. 1797 // 1798 auto *VD = dyn_cast<VarDecl>(D); 1799 if (VD && !VD->hasLocalStorage() && 1800 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1801 if (isInOpenMPDeclareTargetContext()) { 1802 // Try to mark variable as declare target if it is used in capturing 1803 // regions. 1804 if (LangOpts.OpenMP <= 45 && 1805 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1806 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1807 return nullptr; 1808 } else if (isInOpenMPTargetExecutionDirective()) { 1809 // If the declaration is enclosed in a 'declare target' directive, 1810 // then it should not be captured. 1811 // 1812 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1813 return nullptr; 1814 return VD; 1815 } 1816 } 1817 1818 if (CheckScopeInfo) { 1819 bool OpenMPFound = false; 1820 for (unsigned I = StopAt + 1; I > 0; --I) { 1821 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1822 if(!isa<CapturingScopeInfo>(FSI)) 1823 return nullptr; 1824 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1825 if (RSI->CapRegionKind == CR_OpenMP) { 1826 OpenMPFound = true; 1827 break; 1828 } 1829 } 1830 if (!OpenMPFound) 1831 return nullptr; 1832 } 1833 1834 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1835 (!DSAStack->isClauseParsingMode() || 1836 DSAStack->getParentDirective() != OMPD_unknown)) { 1837 auto &&Info = DSAStack->isLoopControlVariable(D); 1838 if (Info.first || 1839 (VD && VD->hasLocalStorage() && 1840 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1841 (VD && DSAStack->isForceVarCapturing())) 1842 return VD ? VD : Info.second; 1843 DSAStackTy::DSAVarData DVarPrivate = 1844 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1845 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1846 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1847 // Threadprivate variables must not be captured. 1848 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1849 return nullptr; 1850 // The variable is not private or it is the variable in the directive with 1851 // default(none) clause and not used in any clause. 1852 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1853 [](OpenMPDirectiveKind) { return true; }, 1854 DSAStack->isClauseParsingMode()); 1855 if (DVarPrivate.CKind != OMPC_unknown || 1856 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1857 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1858 } 1859 return nullptr; 1860 } 1861 1862 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1863 unsigned Level) const { 1864 SmallVector<OpenMPDirectiveKind, 4> Regions; 1865 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1866 FunctionScopesIndex -= Regions.size(); 1867 } 1868 1869 void Sema::startOpenMPLoop() { 1870 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1871 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1872 DSAStack->loopInit(); 1873 } 1874 1875 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1876 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1877 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1878 if (DSAStack->getAssociatedLoops() > 0 && 1879 !DSAStack->isLoopStarted()) { 1880 DSAStack->resetPossibleLoopCounter(D); 1881 DSAStack->loopStart(); 1882 return true; 1883 } 1884 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1885 DSAStack->isLoopControlVariable(D).first) && 1886 !DSAStack->hasExplicitDSA( 1887 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1888 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1889 return true; 1890 } 1891 if (const auto *VD = dyn_cast<VarDecl>(D)) { 1892 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 1893 DSAStack->isForceVarCapturing() && 1894 !DSAStack->hasExplicitDSA( 1895 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 1896 return true; 1897 } 1898 return DSAStack->hasExplicitDSA( 1899 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1900 (DSAStack->isClauseParsingMode() && 1901 DSAStack->getClauseParsingMode() == OMPC_private) || 1902 // Consider taskgroup reduction descriptor variable a private to avoid 1903 // possible capture in the region. 1904 (DSAStack->hasExplicitDirective( 1905 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1906 Level) && 1907 DSAStack->isTaskgroupReductionRef(D, Level)); 1908 } 1909 1910 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1911 unsigned Level) { 1912 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1913 D = getCanonicalDecl(D); 1914 OpenMPClauseKind OMPC = OMPC_unknown; 1915 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1916 const unsigned NewLevel = I - 1; 1917 if (DSAStack->hasExplicitDSA(D, 1918 [&OMPC](const OpenMPClauseKind K) { 1919 if (isOpenMPPrivate(K)) { 1920 OMPC = K; 1921 return true; 1922 } 1923 return false; 1924 }, 1925 NewLevel)) 1926 break; 1927 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1928 D, NewLevel, 1929 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1930 OpenMPClauseKind) { return true; })) { 1931 OMPC = OMPC_map; 1932 break; 1933 } 1934 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1935 NewLevel)) { 1936 OMPC = OMPC_map; 1937 if (D->getType()->isScalarType() && 1938 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1939 DefaultMapAttributes::DMA_tofrom_scalar) 1940 OMPC = OMPC_firstprivate; 1941 break; 1942 } 1943 } 1944 if (OMPC != OMPC_unknown) 1945 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1946 } 1947 1948 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1949 unsigned Level) const { 1950 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1951 // Return true if the current level is no longer enclosed in a target region. 1952 1953 const auto *VD = dyn_cast<VarDecl>(D); 1954 return VD && !VD->hasLocalStorage() && 1955 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1956 Level); 1957 } 1958 1959 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1960 1961 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1962 const DeclarationNameInfo &DirName, 1963 Scope *CurScope, SourceLocation Loc) { 1964 DSAStack->push(DKind, DirName, CurScope, Loc); 1965 PushExpressionEvaluationContext( 1966 ExpressionEvaluationContext::PotentiallyEvaluated); 1967 } 1968 1969 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1970 DSAStack->setClauseParsingMode(K); 1971 } 1972 1973 void Sema::EndOpenMPClause() { 1974 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1975 } 1976 1977 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 1978 ArrayRef<OMPClause *> Clauses); 1979 1980 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1981 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1982 // A variable of class type (or array thereof) that appears in a lastprivate 1983 // clause requires an accessible, unambiguous default constructor for the 1984 // class type, unless the list item is also specified in a firstprivate 1985 // clause. 1986 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1987 for (OMPClause *C : D->clauses()) { 1988 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1989 SmallVector<Expr *, 8> PrivateCopies; 1990 for (Expr *DE : Clause->varlists()) { 1991 if (DE->isValueDependent() || DE->isTypeDependent()) { 1992 PrivateCopies.push_back(nullptr); 1993 continue; 1994 } 1995 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1996 auto *VD = cast<VarDecl>(DRE->getDecl()); 1997 QualType Type = VD->getType().getNonReferenceType(); 1998 const DSAStackTy::DSAVarData DVar = 1999 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2000 if (DVar.CKind == OMPC_lastprivate) { 2001 // Generate helper private variable and initialize it with the 2002 // default value. The address of the original variable is replaced 2003 // by the address of the new private variable in CodeGen. This new 2004 // variable is not added to IdResolver, so the code in the OpenMP 2005 // region uses original variable for proper diagnostics. 2006 VarDecl *VDPrivate = buildVarDecl( 2007 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2008 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2009 ActOnUninitializedDecl(VDPrivate); 2010 if (VDPrivate->isInvalidDecl()) { 2011 PrivateCopies.push_back(nullptr); 2012 continue; 2013 } 2014 PrivateCopies.push_back(buildDeclRefExpr( 2015 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2016 } else { 2017 // The variable is also a firstprivate, so initialization sequence 2018 // for private copy is generated already. 2019 PrivateCopies.push_back(nullptr); 2020 } 2021 } 2022 Clause->setPrivateCopies(PrivateCopies); 2023 } 2024 } 2025 // Check allocate clauses. 2026 if (!CurContext->isDependentContext()) 2027 checkAllocateClauses(*this, DSAStack, D->clauses()); 2028 } 2029 2030 DSAStack->pop(); 2031 DiscardCleanupsInEvaluationContext(); 2032 PopExpressionEvaluationContext(); 2033 } 2034 2035 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2036 Expr *NumIterations, Sema &SemaRef, 2037 Scope *S, DSAStackTy *Stack); 2038 2039 namespace { 2040 2041 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2042 private: 2043 Sema &SemaRef; 2044 2045 public: 2046 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2047 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2048 NamedDecl *ND = Candidate.getCorrectionDecl(); 2049 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2050 return VD->hasGlobalStorage() && 2051 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2052 SemaRef.getCurScope()); 2053 } 2054 return false; 2055 } 2056 2057 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2058 return std::make_unique<VarDeclFilterCCC>(*this); 2059 } 2060 2061 }; 2062 2063 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2064 private: 2065 Sema &SemaRef; 2066 2067 public: 2068 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2069 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2070 NamedDecl *ND = Candidate.getCorrectionDecl(); 2071 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2072 isa<FunctionDecl>(ND))) { 2073 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2074 SemaRef.getCurScope()); 2075 } 2076 return false; 2077 } 2078 2079 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2080 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2081 } 2082 }; 2083 2084 } // namespace 2085 2086 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2087 CXXScopeSpec &ScopeSpec, 2088 const DeclarationNameInfo &Id, 2089 OpenMPDirectiveKind Kind) { 2090 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2091 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2092 2093 if (Lookup.isAmbiguous()) 2094 return ExprError(); 2095 2096 VarDecl *VD; 2097 if (!Lookup.isSingleResult()) { 2098 VarDeclFilterCCC CCC(*this); 2099 if (TypoCorrection Corrected = 2100 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2101 CTK_ErrorRecovery)) { 2102 diagnoseTypo(Corrected, 2103 PDiag(Lookup.empty() 2104 ? diag::err_undeclared_var_use_suggest 2105 : diag::err_omp_expected_var_arg_suggest) 2106 << Id.getName()); 2107 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2108 } else { 2109 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2110 : diag::err_omp_expected_var_arg) 2111 << Id.getName(); 2112 return ExprError(); 2113 } 2114 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2115 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2116 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2117 return ExprError(); 2118 } 2119 Lookup.suppressDiagnostics(); 2120 2121 // OpenMP [2.9.2, Syntax, C/C++] 2122 // Variables must be file-scope, namespace-scope, or static block-scope. 2123 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2124 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2125 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2126 bool IsDecl = 2127 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2128 Diag(VD->getLocation(), 2129 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2130 << VD; 2131 return ExprError(); 2132 } 2133 2134 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2135 NamedDecl *ND = CanonicalVD; 2136 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2137 // A threadprivate directive for file-scope variables must appear outside 2138 // any definition or declaration. 2139 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2140 !getCurLexicalContext()->isTranslationUnit()) { 2141 Diag(Id.getLoc(), diag::err_omp_var_scope) 2142 << getOpenMPDirectiveName(Kind) << VD; 2143 bool IsDecl = 2144 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2145 Diag(VD->getLocation(), 2146 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2147 << VD; 2148 return ExprError(); 2149 } 2150 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2151 // A threadprivate directive for static class member variables must appear 2152 // in the class definition, in the same scope in which the member 2153 // variables are declared. 2154 if (CanonicalVD->isStaticDataMember() && 2155 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2156 Diag(Id.getLoc(), diag::err_omp_var_scope) 2157 << getOpenMPDirectiveName(Kind) << VD; 2158 bool IsDecl = 2159 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2160 Diag(VD->getLocation(), 2161 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2162 << VD; 2163 return ExprError(); 2164 } 2165 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2166 // A threadprivate directive for namespace-scope variables must appear 2167 // outside any definition or declaration other than the namespace 2168 // definition itself. 2169 if (CanonicalVD->getDeclContext()->isNamespace() && 2170 (!getCurLexicalContext()->isFileContext() || 2171 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2172 Diag(Id.getLoc(), diag::err_omp_var_scope) 2173 << getOpenMPDirectiveName(Kind) << VD; 2174 bool IsDecl = 2175 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2176 Diag(VD->getLocation(), 2177 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2178 << VD; 2179 return ExprError(); 2180 } 2181 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2182 // A threadprivate directive for static block-scope variables must appear 2183 // in the scope of the variable and not in a nested scope. 2184 if (CanonicalVD->isLocalVarDecl() && CurScope && 2185 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2186 Diag(Id.getLoc(), diag::err_omp_var_scope) 2187 << getOpenMPDirectiveName(Kind) << VD; 2188 bool IsDecl = 2189 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2190 Diag(VD->getLocation(), 2191 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2192 << VD; 2193 return ExprError(); 2194 } 2195 2196 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2197 // A threadprivate directive must lexically precede all references to any 2198 // of the variables in its list. 2199 if (Kind == OMPD_threadprivate && VD->isUsed() && 2200 !DSAStack->isThreadPrivate(VD)) { 2201 Diag(Id.getLoc(), diag::err_omp_var_used) 2202 << getOpenMPDirectiveName(Kind) << VD; 2203 return ExprError(); 2204 } 2205 2206 QualType ExprType = VD->getType().getNonReferenceType(); 2207 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2208 SourceLocation(), VD, 2209 /*RefersToEnclosingVariableOrCapture=*/false, 2210 Id.getLoc(), ExprType, VK_LValue); 2211 } 2212 2213 Sema::DeclGroupPtrTy 2214 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2215 ArrayRef<Expr *> VarList) { 2216 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2217 CurContext->addDecl(D); 2218 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2219 } 2220 return nullptr; 2221 } 2222 2223 namespace { 2224 class LocalVarRefChecker final 2225 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2226 Sema &SemaRef; 2227 2228 public: 2229 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2230 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2231 if (VD->hasLocalStorage()) { 2232 SemaRef.Diag(E->getBeginLoc(), 2233 diag::err_omp_local_var_in_threadprivate_init) 2234 << E->getSourceRange(); 2235 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2236 << VD << VD->getSourceRange(); 2237 return true; 2238 } 2239 } 2240 return false; 2241 } 2242 bool VisitStmt(const Stmt *S) { 2243 for (const Stmt *Child : S->children()) { 2244 if (Child && Visit(Child)) 2245 return true; 2246 } 2247 return false; 2248 } 2249 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2250 }; 2251 } // namespace 2252 2253 OMPThreadPrivateDecl * 2254 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2255 SmallVector<Expr *, 8> Vars; 2256 for (Expr *RefExpr : VarList) { 2257 auto *DE = cast<DeclRefExpr>(RefExpr); 2258 auto *VD = cast<VarDecl>(DE->getDecl()); 2259 SourceLocation ILoc = DE->getExprLoc(); 2260 2261 // Mark variable as used. 2262 VD->setReferenced(); 2263 VD->markUsed(Context); 2264 2265 QualType QType = VD->getType(); 2266 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2267 // It will be analyzed later. 2268 Vars.push_back(DE); 2269 continue; 2270 } 2271 2272 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2273 // A threadprivate variable must not have an incomplete type. 2274 if (RequireCompleteType(ILoc, VD->getType(), 2275 diag::err_omp_threadprivate_incomplete_type)) { 2276 continue; 2277 } 2278 2279 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2280 // A threadprivate variable must not have a reference type. 2281 if (VD->getType()->isReferenceType()) { 2282 Diag(ILoc, diag::err_omp_ref_type_arg) 2283 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2284 bool IsDecl = 2285 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2286 Diag(VD->getLocation(), 2287 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2288 << VD; 2289 continue; 2290 } 2291 2292 // Check if this is a TLS variable. If TLS is not being supported, produce 2293 // the corresponding diagnostic. 2294 if ((VD->getTLSKind() != VarDecl::TLS_None && 2295 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2296 getLangOpts().OpenMPUseTLS && 2297 getASTContext().getTargetInfo().isTLSSupported())) || 2298 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2299 !VD->isLocalVarDecl())) { 2300 Diag(ILoc, diag::err_omp_var_thread_local) 2301 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2302 bool IsDecl = 2303 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2304 Diag(VD->getLocation(), 2305 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2306 << VD; 2307 continue; 2308 } 2309 2310 // Check if initial value of threadprivate variable reference variable with 2311 // local storage (it is not supported by runtime). 2312 if (const Expr *Init = VD->getAnyInitializer()) { 2313 LocalVarRefChecker Checker(*this); 2314 if (Checker.Visit(Init)) 2315 continue; 2316 } 2317 2318 Vars.push_back(RefExpr); 2319 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2320 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2321 Context, SourceRange(Loc, Loc))); 2322 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2323 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2324 } 2325 OMPThreadPrivateDecl *D = nullptr; 2326 if (!Vars.empty()) { 2327 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2328 Vars); 2329 D->setAccess(AS_public); 2330 } 2331 return D; 2332 } 2333 2334 static OMPAllocateDeclAttr::AllocatorTypeTy 2335 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2336 if (!Allocator) 2337 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2338 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2339 Allocator->isInstantiationDependent() || 2340 Allocator->containsUnexpandedParameterPack()) 2341 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2342 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2343 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2344 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2345 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2346 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2347 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2348 llvm::FoldingSetNodeID AEId, DAEId; 2349 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2350 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2351 if (AEId == DAEId) { 2352 AllocatorKindRes = AllocatorKind; 2353 break; 2354 } 2355 } 2356 return AllocatorKindRes; 2357 } 2358 2359 static bool checkPreviousOMPAllocateAttribute( 2360 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2361 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2362 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2363 return false; 2364 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2365 Expr *PrevAllocator = A->getAllocator(); 2366 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2367 getAllocatorKind(S, Stack, PrevAllocator); 2368 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2369 if (AllocatorsMatch && 2370 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2371 Allocator && PrevAllocator) { 2372 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2373 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2374 llvm::FoldingSetNodeID AEId, PAEId; 2375 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2376 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2377 AllocatorsMatch = AEId == PAEId; 2378 } 2379 if (!AllocatorsMatch) { 2380 SmallString<256> AllocatorBuffer; 2381 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2382 if (Allocator) 2383 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2384 SmallString<256> PrevAllocatorBuffer; 2385 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2386 if (PrevAllocator) 2387 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2388 S.getPrintingPolicy()); 2389 2390 SourceLocation AllocatorLoc = 2391 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2392 SourceRange AllocatorRange = 2393 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2394 SourceLocation PrevAllocatorLoc = 2395 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2396 SourceRange PrevAllocatorRange = 2397 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2398 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2399 << (Allocator ? 1 : 0) << AllocatorStream.str() 2400 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2401 << AllocatorRange; 2402 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2403 << PrevAllocatorRange; 2404 return true; 2405 } 2406 return false; 2407 } 2408 2409 static void 2410 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2411 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2412 Expr *Allocator, SourceRange SR) { 2413 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2414 return; 2415 if (Allocator && 2416 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2417 Allocator->isInstantiationDependent() || 2418 Allocator->containsUnexpandedParameterPack())) 2419 return; 2420 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2421 Allocator, SR); 2422 VD->addAttr(A); 2423 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2424 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2425 } 2426 2427 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2428 SourceLocation Loc, ArrayRef<Expr *> VarList, 2429 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2430 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2431 Expr *Allocator = nullptr; 2432 if (Clauses.empty()) { 2433 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2434 // allocate directives that appear in a target region must specify an 2435 // allocator clause unless a requires directive with the dynamic_allocators 2436 // clause is present in the same compilation unit. 2437 if (LangOpts.OpenMPIsDevice && 2438 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2439 targetDiag(Loc, diag::err_expected_allocator_clause); 2440 } else { 2441 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2442 } 2443 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2444 getAllocatorKind(*this, DSAStack, Allocator); 2445 SmallVector<Expr *, 8> Vars; 2446 for (Expr *RefExpr : VarList) { 2447 auto *DE = cast<DeclRefExpr>(RefExpr); 2448 auto *VD = cast<VarDecl>(DE->getDecl()); 2449 2450 // Check if this is a TLS variable or global register. 2451 if (VD->getTLSKind() != VarDecl::TLS_None || 2452 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2453 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2454 !VD->isLocalVarDecl())) 2455 continue; 2456 2457 // If the used several times in the allocate directive, the same allocator 2458 // must be used. 2459 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2460 AllocatorKind, Allocator)) 2461 continue; 2462 2463 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2464 // If a list item has a static storage type, the allocator expression in the 2465 // allocator clause must be a constant expression that evaluates to one of 2466 // the predefined memory allocator values. 2467 if (Allocator && VD->hasGlobalStorage()) { 2468 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2469 Diag(Allocator->getExprLoc(), 2470 diag::err_omp_expected_predefined_allocator) 2471 << Allocator->getSourceRange(); 2472 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2473 VarDecl::DeclarationOnly; 2474 Diag(VD->getLocation(), 2475 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2476 << VD; 2477 continue; 2478 } 2479 } 2480 2481 Vars.push_back(RefExpr); 2482 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2483 DE->getSourceRange()); 2484 } 2485 if (Vars.empty()) 2486 return nullptr; 2487 if (!Owner) 2488 Owner = getCurLexicalContext(); 2489 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2490 D->setAccess(AS_public); 2491 Owner->addDecl(D); 2492 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2493 } 2494 2495 Sema::DeclGroupPtrTy 2496 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2497 ArrayRef<OMPClause *> ClauseList) { 2498 OMPRequiresDecl *D = nullptr; 2499 if (!CurContext->isFileContext()) { 2500 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2501 } else { 2502 D = CheckOMPRequiresDecl(Loc, ClauseList); 2503 if (D) { 2504 CurContext->addDecl(D); 2505 DSAStack->addRequiresDecl(D); 2506 } 2507 } 2508 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2509 } 2510 2511 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2512 ArrayRef<OMPClause *> ClauseList) { 2513 /// For target specific clauses, the requires directive cannot be 2514 /// specified after the handling of any of the target regions in the 2515 /// current compilation unit. 2516 ArrayRef<SourceLocation> TargetLocations = 2517 DSAStack->getEncounteredTargetLocs(); 2518 if (!TargetLocations.empty()) { 2519 for (const OMPClause *CNew : ClauseList) { 2520 // Check if any of the requires clauses affect target regions. 2521 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2522 isa<OMPUnifiedAddressClause>(CNew) || 2523 isa<OMPReverseOffloadClause>(CNew) || 2524 isa<OMPDynamicAllocatorsClause>(CNew)) { 2525 Diag(Loc, diag::err_omp_target_before_requires) 2526 << getOpenMPClauseName(CNew->getClauseKind()); 2527 for (SourceLocation TargetLoc : TargetLocations) { 2528 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2529 } 2530 } 2531 } 2532 } 2533 2534 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2535 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2536 ClauseList); 2537 return nullptr; 2538 } 2539 2540 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2541 const ValueDecl *D, 2542 const DSAStackTy::DSAVarData &DVar, 2543 bool IsLoopIterVar = false) { 2544 if (DVar.RefExpr) { 2545 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2546 << getOpenMPClauseName(DVar.CKind); 2547 return; 2548 } 2549 enum { 2550 PDSA_StaticMemberShared, 2551 PDSA_StaticLocalVarShared, 2552 PDSA_LoopIterVarPrivate, 2553 PDSA_LoopIterVarLinear, 2554 PDSA_LoopIterVarLastprivate, 2555 PDSA_ConstVarShared, 2556 PDSA_GlobalVarShared, 2557 PDSA_TaskVarFirstprivate, 2558 PDSA_LocalVarPrivate, 2559 PDSA_Implicit 2560 } Reason = PDSA_Implicit; 2561 bool ReportHint = false; 2562 auto ReportLoc = D->getLocation(); 2563 auto *VD = dyn_cast<VarDecl>(D); 2564 if (IsLoopIterVar) { 2565 if (DVar.CKind == OMPC_private) 2566 Reason = PDSA_LoopIterVarPrivate; 2567 else if (DVar.CKind == OMPC_lastprivate) 2568 Reason = PDSA_LoopIterVarLastprivate; 2569 else 2570 Reason = PDSA_LoopIterVarLinear; 2571 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2572 DVar.CKind == OMPC_firstprivate) { 2573 Reason = PDSA_TaskVarFirstprivate; 2574 ReportLoc = DVar.ImplicitDSALoc; 2575 } else if (VD && VD->isStaticLocal()) 2576 Reason = PDSA_StaticLocalVarShared; 2577 else if (VD && VD->isStaticDataMember()) 2578 Reason = PDSA_StaticMemberShared; 2579 else if (VD && VD->isFileVarDecl()) 2580 Reason = PDSA_GlobalVarShared; 2581 else if (D->getType().isConstant(SemaRef.getASTContext())) 2582 Reason = PDSA_ConstVarShared; 2583 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2584 ReportHint = true; 2585 Reason = PDSA_LocalVarPrivate; 2586 } 2587 if (Reason != PDSA_Implicit) { 2588 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2589 << Reason << ReportHint 2590 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2591 } else if (DVar.ImplicitDSALoc.isValid()) { 2592 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2593 << getOpenMPClauseName(DVar.CKind); 2594 } 2595 } 2596 2597 namespace { 2598 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2599 DSAStackTy *Stack; 2600 Sema &SemaRef; 2601 bool ErrorFound = false; 2602 CapturedStmt *CS = nullptr; 2603 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2604 llvm::SmallVector<Expr *, 4> ImplicitMap; 2605 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2606 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2607 2608 void VisitSubCaptures(OMPExecutableDirective *S) { 2609 // Check implicitly captured variables. 2610 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2611 return; 2612 visitSubCaptures(S->getInnermostCapturedStmt()); 2613 } 2614 2615 public: 2616 void VisitDeclRefExpr(DeclRefExpr *E) { 2617 if (E->isTypeDependent() || E->isValueDependent() || 2618 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2619 return; 2620 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2621 // Check the datasharing rules for the expressions in the clauses. 2622 if (!CS) { 2623 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2624 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2625 Visit(CED->getInit()); 2626 return; 2627 } 2628 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2629 // Do not analyze internal variables and do not enclose them into 2630 // implicit clauses. 2631 return; 2632 VD = VD->getCanonicalDecl(); 2633 // Skip internally declared variables. 2634 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2635 return; 2636 2637 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2638 // Check if the variable has explicit DSA set and stop analysis if it so. 2639 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2640 return; 2641 2642 // Skip internally declared static variables. 2643 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2644 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2645 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2646 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2647 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2648 return; 2649 2650 SourceLocation ELoc = E->getExprLoc(); 2651 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2652 // The default(none) clause requires that each variable that is referenced 2653 // in the construct, and does not have a predetermined data-sharing 2654 // attribute, must have its data-sharing attribute explicitly determined 2655 // by being listed in a data-sharing attribute clause. 2656 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2657 isImplicitOrExplicitTaskingRegion(DKind) && 2658 VarsWithInheritedDSA.count(VD) == 0) { 2659 VarsWithInheritedDSA[VD] = E; 2660 return; 2661 } 2662 2663 if (isOpenMPTargetExecutionDirective(DKind) && 2664 !Stack->isLoopControlVariable(VD).first) { 2665 if (!Stack->checkMappableExprComponentListsForDecl( 2666 VD, /*CurrentRegionOnly=*/true, 2667 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2668 StackComponents, 2669 OpenMPClauseKind) { 2670 // Variable is used if it has been marked as an array, array 2671 // section or the variable iself. 2672 return StackComponents.size() == 1 || 2673 std::all_of( 2674 std::next(StackComponents.rbegin()), 2675 StackComponents.rend(), 2676 [](const OMPClauseMappableExprCommon:: 2677 MappableComponent &MC) { 2678 return MC.getAssociatedDeclaration() == 2679 nullptr && 2680 (isa<OMPArraySectionExpr>( 2681 MC.getAssociatedExpression()) || 2682 isa<ArraySubscriptExpr>( 2683 MC.getAssociatedExpression())); 2684 }); 2685 })) { 2686 bool IsFirstprivate = false; 2687 // By default lambdas are captured as firstprivates. 2688 if (const auto *RD = 2689 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2690 IsFirstprivate = RD->isLambda(); 2691 IsFirstprivate = 2692 IsFirstprivate || 2693 (VD->getType().getNonReferenceType()->isScalarType() && 2694 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2695 if (IsFirstprivate) 2696 ImplicitFirstprivate.emplace_back(E); 2697 else 2698 ImplicitMap.emplace_back(E); 2699 return; 2700 } 2701 } 2702 2703 // OpenMP [2.9.3.6, Restrictions, p.2] 2704 // A list item that appears in a reduction clause of the innermost 2705 // enclosing worksharing or parallel construct may not be accessed in an 2706 // explicit task. 2707 DVar = Stack->hasInnermostDSA( 2708 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2709 [](OpenMPDirectiveKind K) { 2710 return isOpenMPParallelDirective(K) || 2711 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2712 }, 2713 /*FromParent=*/true); 2714 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2715 ErrorFound = true; 2716 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2717 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2718 return; 2719 } 2720 2721 // Define implicit data-sharing attributes for task. 2722 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2723 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2724 !Stack->isLoopControlVariable(VD).first) { 2725 ImplicitFirstprivate.push_back(E); 2726 return; 2727 } 2728 2729 // Store implicitly used globals with declare target link for parent 2730 // target. 2731 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2732 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2733 Stack->addToParentTargetRegionLinkGlobals(E); 2734 return; 2735 } 2736 } 2737 } 2738 void VisitMemberExpr(MemberExpr *E) { 2739 if (E->isTypeDependent() || E->isValueDependent() || 2740 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2741 return; 2742 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2743 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2744 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2745 if (!FD) 2746 return; 2747 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2748 // Check if the variable has explicit DSA set and stop analysis if it 2749 // so. 2750 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2751 return; 2752 2753 if (isOpenMPTargetExecutionDirective(DKind) && 2754 !Stack->isLoopControlVariable(FD).first && 2755 !Stack->checkMappableExprComponentListsForDecl( 2756 FD, /*CurrentRegionOnly=*/true, 2757 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2758 StackComponents, 2759 OpenMPClauseKind) { 2760 return isa<CXXThisExpr>( 2761 cast<MemberExpr>( 2762 StackComponents.back().getAssociatedExpression()) 2763 ->getBase() 2764 ->IgnoreParens()); 2765 })) { 2766 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2767 // A bit-field cannot appear in a map clause. 2768 // 2769 if (FD->isBitField()) 2770 return; 2771 2772 // Check to see if the member expression is referencing a class that 2773 // has already been explicitly mapped 2774 if (Stack->isClassPreviouslyMapped(TE->getType())) 2775 return; 2776 2777 ImplicitMap.emplace_back(E); 2778 return; 2779 } 2780 2781 SourceLocation ELoc = E->getExprLoc(); 2782 // OpenMP [2.9.3.6, Restrictions, p.2] 2783 // A list item that appears in a reduction clause of the innermost 2784 // enclosing worksharing or parallel construct may not be accessed in 2785 // an explicit task. 2786 DVar = Stack->hasInnermostDSA( 2787 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2788 [](OpenMPDirectiveKind K) { 2789 return isOpenMPParallelDirective(K) || 2790 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2791 }, 2792 /*FromParent=*/true); 2793 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2794 ErrorFound = true; 2795 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2796 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2797 return; 2798 } 2799 2800 // Define implicit data-sharing attributes for task. 2801 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2802 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2803 !Stack->isLoopControlVariable(FD).first) { 2804 // Check if there is a captured expression for the current field in the 2805 // region. Do not mark it as firstprivate unless there is no captured 2806 // expression. 2807 // TODO: try to make it firstprivate. 2808 if (DVar.CKind != OMPC_unknown) 2809 ImplicitFirstprivate.push_back(E); 2810 } 2811 return; 2812 } 2813 if (isOpenMPTargetExecutionDirective(DKind)) { 2814 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2815 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2816 /*NoDiagnose=*/true)) 2817 return; 2818 const auto *VD = cast<ValueDecl>( 2819 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2820 if (!Stack->checkMappableExprComponentListsForDecl( 2821 VD, /*CurrentRegionOnly=*/true, 2822 [&CurComponents]( 2823 OMPClauseMappableExprCommon::MappableExprComponentListRef 2824 StackComponents, 2825 OpenMPClauseKind) { 2826 auto CCI = CurComponents.rbegin(); 2827 auto CCE = CurComponents.rend(); 2828 for (const auto &SC : llvm::reverse(StackComponents)) { 2829 // Do both expressions have the same kind? 2830 if (CCI->getAssociatedExpression()->getStmtClass() != 2831 SC.getAssociatedExpression()->getStmtClass()) 2832 if (!(isa<OMPArraySectionExpr>( 2833 SC.getAssociatedExpression()) && 2834 isa<ArraySubscriptExpr>( 2835 CCI->getAssociatedExpression()))) 2836 return false; 2837 2838 const Decl *CCD = CCI->getAssociatedDeclaration(); 2839 const Decl *SCD = SC.getAssociatedDeclaration(); 2840 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2841 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2842 if (SCD != CCD) 2843 return false; 2844 std::advance(CCI, 1); 2845 if (CCI == CCE) 2846 break; 2847 } 2848 return true; 2849 })) { 2850 Visit(E->getBase()); 2851 } 2852 } else { 2853 Visit(E->getBase()); 2854 } 2855 } 2856 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2857 for (OMPClause *C : S->clauses()) { 2858 // Skip analysis of arguments of implicitly defined firstprivate clause 2859 // for task|target directives. 2860 // Skip analysis of arguments of implicitly defined map clause for target 2861 // directives. 2862 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2863 C->isImplicit())) { 2864 for (Stmt *CC : C->children()) { 2865 if (CC) 2866 Visit(CC); 2867 } 2868 } 2869 } 2870 // Check implicitly captured variables. 2871 VisitSubCaptures(S); 2872 } 2873 void VisitStmt(Stmt *S) { 2874 for (Stmt *C : S->children()) { 2875 if (C) { 2876 // Check implicitly captured variables in the task-based directives to 2877 // check if they must be firstprivatized. 2878 Visit(C); 2879 } 2880 } 2881 } 2882 2883 void visitSubCaptures(CapturedStmt *S) { 2884 for (const CapturedStmt::Capture &Cap : S->captures()) { 2885 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 2886 continue; 2887 VarDecl *VD = Cap.getCapturedVar(); 2888 // Do not try to map the variable if it or its sub-component was mapped 2889 // already. 2890 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2891 Stack->checkMappableExprComponentListsForDecl( 2892 VD, /*CurrentRegionOnly=*/true, 2893 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2894 OpenMPClauseKind) { return true; })) 2895 continue; 2896 DeclRefExpr *DRE = buildDeclRefExpr( 2897 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2898 Cap.getLocation(), /*RefersToCapture=*/true); 2899 Visit(DRE); 2900 } 2901 } 2902 bool isErrorFound() const { return ErrorFound; } 2903 ArrayRef<Expr *> getImplicitFirstprivate() const { 2904 return ImplicitFirstprivate; 2905 } 2906 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2907 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2908 return VarsWithInheritedDSA; 2909 } 2910 2911 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2912 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2913 // Process declare target link variables for the target directives. 2914 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2915 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2916 Visit(E); 2917 } 2918 } 2919 }; 2920 } // namespace 2921 2922 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2923 switch (DKind) { 2924 case OMPD_parallel: 2925 case OMPD_parallel_for: 2926 case OMPD_parallel_for_simd: 2927 case OMPD_parallel_sections: 2928 case OMPD_teams: 2929 case OMPD_teams_distribute: 2930 case OMPD_teams_distribute_simd: { 2931 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2932 QualType KmpInt32PtrTy = 2933 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2934 Sema::CapturedParamNameType Params[] = { 2935 std::make_pair(".global_tid.", KmpInt32PtrTy), 2936 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2937 std::make_pair(StringRef(), QualType()) // __context with shared vars 2938 }; 2939 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2940 Params); 2941 break; 2942 } 2943 case OMPD_target_teams: 2944 case OMPD_target_parallel: 2945 case OMPD_target_parallel_for: 2946 case OMPD_target_parallel_for_simd: 2947 case OMPD_target_teams_distribute: 2948 case OMPD_target_teams_distribute_simd: { 2949 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2950 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2951 QualType KmpInt32PtrTy = 2952 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2953 QualType Args[] = {VoidPtrTy}; 2954 FunctionProtoType::ExtProtoInfo EPI; 2955 EPI.Variadic = true; 2956 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2957 Sema::CapturedParamNameType Params[] = { 2958 std::make_pair(".global_tid.", KmpInt32Ty), 2959 std::make_pair(".part_id.", KmpInt32PtrTy), 2960 std::make_pair(".privates.", VoidPtrTy), 2961 std::make_pair( 2962 ".copy_fn.", 2963 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2964 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2965 std::make_pair(StringRef(), QualType()) // __context with shared vars 2966 }; 2967 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2968 Params); 2969 // Mark this captured region as inlined, because we don't use outlined 2970 // function directly. 2971 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2972 AlwaysInlineAttr::CreateImplicit( 2973 Context, AlwaysInlineAttr::Keyword_forceinline)); 2974 Sema::CapturedParamNameType ParamsTarget[] = { 2975 std::make_pair(StringRef(), QualType()) // __context with shared vars 2976 }; 2977 // Start a captured region for 'target' with no implicit parameters. 2978 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2979 ParamsTarget); 2980 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2981 std::make_pair(".global_tid.", KmpInt32PtrTy), 2982 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2983 std::make_pair(StringRef(), QualType()) // __context with shared vars 2984 }; 2985 // Start a captured region for 'teams' or 'parallel'. Both regions have 2986 // the same implicit parameters. 2987 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2988 ParamsTeamsOrParallel); 2989 break; 2990 } 2991 case OMPD_target: 2992 case OMPD_target_simd: { 2993 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2994 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2995 QualType KmpInt32PtrTy = 2996 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2997 QualType Args[] = {VoidPtrTy}; 2998 FunctionProtoType::ExtProtoInfo EPI; 2999 EPI.Variadic = true; 3000 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3001 Sema::CapturedParamNameType Params[] = { 3002 std::make_pair(".global_tid.", KmpInt32Ty), 3003 std::make_pair(".part_id.", KmpInt32PtrTy), 3004 std::make_pair(".privates.", VoidPtrTy), 3005 std::make_pair( 3006 ".copy_fn.", 3007 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3008 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3009 std::make_pair(StringRef(), QualType()) // __context with shared vars 3010 }; 3011 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3012 Params); 3013 // Mark this captured region as inlined, because we don't use outlined 3014 // function directly. 3015 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3016 AlwaysInlineAttr::CreateImplicit( 3017 Context, AlwaysInlineAttr::Keyword_forceinline)); 3018 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3019 std::make_pair(StringRef(), QualType())); 3020 break; 3021 } 3022 case OMPD_simd: 3023 case OMPD_for: 3024 case OMPD_for_simd: 3025 case OMPD_sections: 3026 case OMPD_section: 3027 case OMPD_single: 3028 case OMPD_master: 3029 case OMPD_critical: 3030 case OMPD_taskgroup: 3031 case OMPD_distribute: 3032 case OMPD_distribute_simd: 3033 case OMPD_ordered: 3034 case OMPD_atomic: 3035 case OMPD_target_data: { 3036 Sema::CapturedParamNameType Params[] = { 3037 std::make_pair(StringRef(), QualType()) // __context with shared vars 3038 }; 3039 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3040 Params); 3041 break; 3042 } 3043 case OMPD_task: { 3044 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3045 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3046 QualType KmpInt32PtrTy = 3047 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3048 QualType Args[] = {VoidPtrTy}; 3049 FunctionProtoType::ExtProtoInfo EPI; 3050 EPI.Variadic = true; 3051 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3052 Sema::CapturedParamNameType Params[] = { 3053 std::make_pair(".global_tid.", KmpInt32Ty), 3054 std::make_pair(".part_id.", KmpInt32PtrTy), 3055 std::make_pair(".privates.", VoidPtrTy), 3056 std::make_pair( 3057 ".copy_fn.", 3058 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3059 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3060 std::make_pair(StringRef(), QualType()) // __context with shared vars 3061 }; 3062 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3063 Params); 3064 // Mark this captured region as inlined, because we don't use outlined 3065 // function directly. 3066 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3067 AlwaysInlineAttr::CreateImplicit( 3068 Context, AlwaysInlineAttr::Keyword_forceinline)); 3069 break; 3070 } 3071 case OMPD_taskloop: 3072 case OMPD_taskloop_simd: { 3073 QualType KmpInt32Ty = 3074 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3075 .withConst(); 3076 QualType KmpUInt64Ty = 3077 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3078 .withConst(); 3079 QualType KmpInt64Ty = 3080 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3081 .withConst(); 3082 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3083 QualType KmpInt32PtrTy = 3084 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3085 QualType Args[] = {VoidPtrTy}; 3086 FunctionProtoType::ExtProtoInfo EPI; 3087 EPI.Variadic = true; 3088 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3089 Sema::CapturedParamNameType Params[] = { 3090 std::make_pair(".global_tid.", KmpInt32Ty), 3091 std::make_pair(".part_id.", KmpInt32PtrTy), 3092 std::make_pair(".privates.", VoidPtrTy), 3093 std::make_pair( 3094 ".copy_fn.", 3095 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3096 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3097 std::make_pair(".lb.", KmpUInt64Ty), 3098 std::make_pair(".ub.", KmpUInt64Ty), 3099 std::make_pair(".st.", KmpInt64Ty), 3100 std::make_pair(".liter.", KmpInt32Ty), 3101 std::make_pair(".reductions.", VoidPtrTy), 3102 std::make_pair(StringRef(), QualType()) // __context with shared vars 3103 }; 3104 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3105 Params); 3106 // Mark this captured region as inlined, because we don't use outlined 3107 // function directly. 3108 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3109 AlwaysInlineAttr::CreateImplicit( 3110 Context, AlwaysInlineAttr::Keyword_forceinline)); 3111 break; 3112 } 3113 case OMPD_distribute_parallel_for_simd: 3114 case OMPD_distribute_parallel_for: { 3115 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3116 QualType KmpInt32PtrTy = 3117 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3118 Sema::CapturedParamNameType Params[] = { 3119 std::make_pair(".global_tid.", KmpInt32PtrTy), 3120 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3121 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3122 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3123 std::make_pair(StringRef(), QualType()) // __context with shared vars 3124 }; 3125 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3126 Params); 3127 break; 3128 } 3129 case OMPD_target_teams_distribute_parallel_for: 3130 case OMPD_target_teams_distribute_parallel_for_simd: { 3131 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3132 QualType KmpInt32PtrTy = 3133 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3134 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3135 3136 QualType Args[] = {VoidPtrTy}; 3137 FunctionProtoType::ExtProtoInfo EPI; 3138 EPI.Variadic = true; 3139 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3140 Sema::CapturedParamNameType Params[] = { 3141 std::make_pair(".global_tid.", KmpInt32Ty), 3142 std::make_pair(".part_id.", KmpInt32PtrTy), 3143 std::make_pair(".privates.", VoidPtrTy), 3144 std::make_pair( 3145 ".copy_fn.", 3146 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3147 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3148 std::make_pair(StringRef(), QualType()) // __context with shared vars 3149 }; 3150 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3151 Params); 3152 // Mark this captured region as inlined, because we don't use outlined 3153 // function directly. 3154 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3155 AlwaysInlineAttr::CreateImplicit( 3156 Context, AlwaysInlineAttr::Keyword_forceinline)); 3157 Sema::CapturedParamNameType ParamsTarget[] = { 3158 std::make_pair(StringRef(), QualType()) // __context with shared vars 3159 }; 3160 // Start a captured region for 'target' with no implicit parameters. 3161 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3162 ParamsTarget); 3163 3164 Sema::CapturedParamNameType ParamsTeams[] = { 3165 std::make_pair(".global_tid.", KmpInt32PtrTy), 3166 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3167 std::make_pair(StringRef(), QualType()) // __context with shared vars 3168 }; 3169 // Start a captured region for 'target' with no implicit parameters. 3170 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3171 ParamsTeams); 3172 3173 Sema::CapturedParamNameType ParamsParallel[] = { 3174 std::make_pair(".global_tid.", KmpInt32PtrTy), 3175 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3176 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3177 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3178 std::make_pair(StringRef(), QualType()) // __context with shared vars 3179 }; 3180 // Start a captured region for 'teams' or 'parallel'. Both regions have 3181 // the same implicit parameters. 3182 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3183 ParamsParallel); 3184 break; 3185 } 3186 3187 case OMPD_teams_distribute_parallel_for: 3188 case OMPD_teams_distribute_parallel_for_simd: { 3189 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3190 QualType KmpInt32PtrTy = 3191 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3192 3193 Sema::CapturedParamNameType ParamsTeams[] = { 3194 std::make_pair(".global_tid.", KmpInt32PtrTy), 3195 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3196 std::make_pair(StringRef(), QualType()) // __context with shared vars 3197 }; 3198 // Start a captured region for 'target' with no implicit parameters. 3199 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3200 ParamsTeams); 3201 3202 Sema::CapturedParamNameType ParamsParallel[] = { 3203 std::make_pair(".global_tid.", KmpInt32PtrTy), 3204 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3205 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3206 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3207 std::make_pair(StringRef(), QualType()) // __context with shared vars 3208 }; 3209 // Start a captured region for 'teams' or 'parallel'. Both regions have 3210 // the same implicit parameters. 3211 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3212 ParamsParallel); 3213 break; 3214 } 3215 case OMPD_target_update: 3216 case OMPD_target_enter_data: 3217 case OMPD_target_exit_data: { 3218 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3219 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3220 QualType KmpInt32PtrTy = 3221 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3222 QualType Args[] = {VoidPtrTy}; 3223 FunctionProtoType::ExtProtoInfo EPI; 3224 EPI.Variadic = true; 3225 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3226 Sema::CapturedParamNameType Params[] = { 3227 std::make_pair(".global_tid.", KmpInt32Ty), 3228 std::make_pair(".part_id.", KmpInt32PtrTy), 3229 std::make_pair(".privates.", VoidPtrTy), 3230 std::make_pair( 3231 ".copy_fn.", 3232 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3233 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3234 std::make_pair(StringRef(), QualType()) // __context with shared vars 3235 }; 3236 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3237 Params); 3238 // Mark this captured region as inlined, because we don't use outlined 3239 // function directly. 3240 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3241 AlwaysInlineAttr::CreateImplicit( 3242 Context, AlwaysInlineAttr::Keyword_forceinline)); 3243 break; 3244 } 3245 case OMPD_threadprivate: 3246 case OMPD_allocate: 3247 case OMPD_taskyield: 3248 case OMPD_barrier: 3249 case OMPD_taskwait: 3250 case OMPD_cancellation_point: 3251 case OMPD_cancel: 3252 case OMPD_flush: 3253 case OMPD_declare_reduction: 3254 case OMPD_declare_mapper: 3255 case OMPD_declare_simd: 3256 case OMPD_declare_target: 3257 case OMPD_end_declare_target: 3258 case OMPD_requires: 3259 llvm_unreachable("OpenMP Directive is not allowed"); 3260 case OMPD_unknown: 3261 llvm_unreachable("Unknown OpenMP directive"); 3262 } 3263 } 3264 3265 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3266 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3267 getOpenMPCaptureRegions(CaptureRegions, DKind); 3268 return CaptureRegions.size(); 3269 } 3270 3271 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3272 Expr *CaptureExpr, bool WithInit, 3273 bool AsExpression) { 3274 assert(CaptureExpr); 3275 ASTContext &C = S.getASTContext(); 3276 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3277 QualType Ty = Init->getType(); 3278 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3279 if (S.getLangOpts().CPlusPlus) { 3280 Ty = C.getLValueReferenceType(Ty); 3281 } else { 3282 Ty = C.getPointerType(Ty); 3283 ExprResult Res = 3284 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3285 if (!Res.isUsable()) 3286 return nullptr; 3287 Init = Res.get(); 3288 } 3289 WithInit = true; 3290 } 3291 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3292 CaptureExpr->getBeginLoc()); 3293 if (!WithInit) 3294 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3295 S.CurContext->addHiddenDecl(CED); 3296 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3297 return CED; 3298 } 3299 3300 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3301 bool WithInit) { 3302 OMPCapturedExprDecl *CD; 3303 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3304 CD = cast<OMPCapturedExprDecl>(VD); 3305 else 3306 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3307 /*AsExpression=*/false); 3308 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3309 CaptureExpr->getExprLoc()); 3310 } 3311 3312 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3313 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3314 if (!Ref) { 3315 OMPCapturedExprDecl *CD = buildCaptureDecl( 3316 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3317 /*WithInit=*/true, /*AsExpression=*/true); 3318 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3319 CaptureExpr->getExprLoc()); 3320 } 3321 ExprResult Res = Ref; 3322 if (!S.getLangOpts().CPlusPlus && 3323 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3324 Ref->getType()->isPointerType()) { 3325 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3326 if (!Res.isUsable()) 3327 return ExprError(); 3328 } 3329 return S.DefaultLvalueConversion(Res.get()); 3330 } 3331 3332 namespace { 3333 // OpenMP directives parsed in this section are represented as a 3334 // CapturedStatement with an associated statement. If a syntax error 3335 // is detected during the parsing of the associated statement, the 3336 // compiler must abort processing and close the CapturedStatement. 3337 // 3338 // Combined directives such as 'target parallel' have more than one 3339 // nested CapturedStatements. This RAII ensures that we unwind out 3340 // of all the nested CapturedStatements when an error is found. 3341 class CaptureRegionUnwinderRAII { 3342 private: 3343 Sema &S; 3344 bool &ErrorFound; 3345 OpenMPDirectiveKind DKind = OMPD_unknown; 3346 3347 public: 3348 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3349 OpenMPDirectiveKind DKind) 3350 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3351 ~CaptureRegionUnwinderRAII() { 3352 if (ErrorFound) { 3353 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3354 while (--ThisCaptureLevel >= 0) 3355 S.ActOnCapturedRegionError(); 3356 } 3357 } 3358 }; 3359 } // namespace 3360 3361 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3362 // Capture variables captured by reference in lambdas for target-based 3363 // directives. 3364 if (!CurContext->isDependentContext() && 3365 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3366 isOpenMPTargetDataManagementDirective( 3367 DSAStack->getCurrentDirective()))) { 3368 QualType Type = V->getType(); 3369 if (const auto *RD = Type.getCanonicalType() 3370 .getNonReferenceType() 3371 ->getAsCXXRecordDecl()) { 3372 bool SavedForceCaptureByReferenceInTargetExecutable = 3373 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3374 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3375 /*V=*/true); 3376 if (RD->isLambda()) { 3377 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3378 FieldDecl *ThisCapture; 3379 RD->getCaptureFields(Captures, ThisCapture); 3380 for (const LambdaCapture &LC : RD->captures()) { 3381 if (LC.getCaptureKind() == LCK_ByRef) { 3382 VarDecl *VD = LC.getCapturedVar(); 3383 DeclContext *VDC = VD->getDeclContext(); 3384 if (!VDC->Encloses(CurContext)) 3385 continue; 3386 MarkVariableReferenced(LC.getLocation(), VD); 3387 } else if (LC.getCaptureKind() == LCK_This) { 3388 QualType ThisTy = getCurrentThisType(); 3389 if (!ThisTy.isNull() && 3390 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3391 CheckCXXThisCapture(LC.getLocation()); 3392 } 3393 } 3394 } 3395 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3396 SavedForceCaptureByReferenceInTargetExecutable); 3397 } 3398 } 3399 } 3400 3401 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3402 ArrayRef<OMPClause *> Clauses) { 3403 bool ErrorFound = false; 3404 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3405 *this, ErrorFound, DSAStack->getCurrentDirective()); 3406 if (!S.isUsable()) { 3407 ErrorFound = true; 3408 return StmtError(); 3409 } 3410 3411 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3412 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3413 OMPOrderedClause *OC = nullptr; 3414 OMPScheduleClause *SC = nullptr; 3415 SmallVector<const OMPLinearClause *, 4> LCs; 3416 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3417 // This is required for proper codegen. 3418 for (OMPClause *Clause : Clauses) { 3419 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3420 Clause->getClauseKind() == OMPC_in_reduction) { 3421 // Capture taskgroup task_reduction descriptors inside the tasking regions 3422 // with the corresponding in_reduction items. 3423 auto *IRC = cast<OMPInReductionClause>(Clause); 3424 for (Expr *E : IRC->taskgroup_descriptors()) 3425 if (E) 3426 MarkDeclarationsReferencedInExpr(E); 3427 } 3428 if (isOpenMPPrivate(Clause->getClauseKind()) || 3429 Clause->getClauseKind() == OMPC_copyprivate || 3430 (getLangOpts().OpenMPUseTLS && 3431 getASTContext().getTargetInfo().isTLSSupported() && 3432 Clause->getClauseKind() == OMPC_copyin)) { 3433 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3434 // Mark all variables in private list clauses as used in inner region. 3435 for (Stmt *VarRef : Clause->children()) { 3436 if (auto *E = cast_or_null<Expr>(VarRef)) { 3437 MarkDeclarationsReferencedInExpr(E); 3438 } 3439 } 3440 DSAStack->setForceVarCapturing(/*V=*/false); 3441 } else if (CaptureRegions.size() > 1 || 3442 CaptureRegions.back() != OMPD_unknown) { 3443 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3444 PICs.push_back(C); 3445 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3446 if (Expr *E = C->getPostUpdateExpr()) 3447 MarkDeclarationsReferencedInExpr(E); 3448 } 3449 } 3450 if (Clause->getClauseKind() == OMPC_schedule) 3451 SC = cast<OMPScheduleClause>(Clause); 3452 else if (Clause->getClauseKind() == OMPC_ordered) 3453 OC = cast<OMPOrderedClause>(Clause); 3454 else if (Clause->getClauseKind() == OMPC_linear) 3455 LCs.push_back(cast<OMPLinearClause>(Clause)); 3456 } 3457 // OpenMP, 2.7.1 Loop Construct, Restrictions 3458 // The nonmonotonic modifier cannot be specified if an ordered clause is 3459 // specified. 3460 if (SC && 3461 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3462 SC->getSecondScheduleModifier() == 3463 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3464 OC) { 3465 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3466 ? SC->getFirstScheduleModifierLoc() 3467 : SC->getSecondScheduleModifierLoc(), 3468 diag::err_omp_schedule_nonmonotonic_ordered) 3469 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3470 ErrorFound = true; 3471 } 3472 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3473 for (const OMPLinearClause *C : LCs) { 3474 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3475 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3476 } 3477 ErrorFound = true; 3478 } 3479 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3480 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3481 OC->getNumForLoops()) { 3482 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3483 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3484 ErrorFound = true; 3485 } 3486 if (ErrorFound) { 3487 return StmtError(); 3488 } 3489 StmtResult SR = S; 3490 unsigned CompletedRegions = 0; 3491 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3492 // Mark all variables in private list clauses as used in inner region. 3493 // Required for proper codegen of combined directives. 3494 // TODO: add processing for other clauses. 3495 if (ThisCaptureRegion != OMPD_unknown) { 3496 for (const clang::OMPClauseWithPreInit *C : PICs) { 3497 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3498 // Find the particular capture region for the clause if the 3499 // directive is a combined one with multiple capture regions. 3500 // If the directive is not a combined one, the capture region 3501 // associated with the clause is OMPD_unknown and is generated 3502 // only once. 3503 if (CaptureRegion == ThisCaptureRegion || 3504 CaptureRegion == OMPD_unknown) { 3505 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3506 for (Decl *D : DS->decls()) 3507 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3508 } 3509 } 3510 } 3511 } 3512 if (++CompletedRegions == CaptureRegions.size()) 3513 DSAStack->setBodyComplete(); 3514 SR = ActOnCapturedRegionEnd(SR.get()); 3515 } 3516 return SR; 3517 } 3518 3519 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3520 OpenMPDirectiveKind CancelRegion, 3521 SourceLocation StartLoc) { 3522 // CancelRegion is only needed for cancel and cancellation_point. 3523 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3524 return false; 3525 3526 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3527 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3528 return false; 3529 3530 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3531 << getOpenMPDirectiveName(CancelRegion); 3532 return true; 3533 } 3534 3535 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3536 OpenMPDirectiveKind CurrentRegion, 3537 const DeclarationNameInfo &CurrentName, 3538 OpenMPDirectiveKind CancelRegion, 3539 SourceLocation StartLoc) { 3540 if (Stack->getCurScope()) { 3541 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3542 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3543 bool NestingProhibited = false; 3544 bool CloseNesting = true; 3545 bool OrphanSeen = false; 3546 enum { 3547 NoRecommend, 3548 ShouldBeInParallelRegion, 3549 ShouldBeInOrderedRegion, 3550 ShouldBeInTargetRegion, 3551 ShouldBeInTeamsRegion 3552 } Recommend = NoRecommend; 3553 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3554 // OpenMP [2.16, Nesting of Regions] 3555 // OpenMP constructs may not be nested inside a simd region. 3556 // OpenMP [2.8.1,simd Construct, Restrictions] 3557 // An ordered construct with the simd clause is the only OpenMP 3558 // construct that can appear in the simd region. 3559 // Allowing a SIMD construct nested in another SIMD construct is an 3560 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3561 // message. 3562 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3563 ? diag::err_omp_prohibited_region_simd 3564 : diag::warn_omp_nesting_simd); 3565 return CurrentRegion != OMPD_simd; 3566 } 3567 if (ParentRegion == OMPD_atomic) { 3568 // OpenMP [2.16, Nesting of Regions] 3569 // OpenMP constructs may not be nested inside an atomic region. 3570 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3571 return true; 3572 } 3573 if (CurrentRegion == OMPD_section) { 3574 // OpenMP [2.7.2, sections Construct, Restrictions] 3575 // Orphaned section directives are prohibited. That is, the section 3576 // directives must appear within the sections construct and must not be 3577 // encountered elsewhere in the sections region. 3578 if (ParentRegion != OMPD_sections && 3579 ParentRegion != OMPD_parallel_sections) { 3580 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3581 << (ParentRegion != OMPD_unknown) 3582 << getOpenMPDirectiveName(ParentRegion); 3583 return true; 3584 } 3585 return false; 3586 } 3587 // Allow some constructs (except teams and cancellation constructs) to be 3588 // orphaned (they could be used in functions, called from OpenMP regions 3589 // with the required preconditions). 3590 if (ParentRegion == OMPD_unknown && 3591 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3592 CurrentRegion != OMPD_cancellation_point && 3593 CurrentRegion != OMPD_cancel) 3594 return false; 3595 if (CurrentRegion == OMPD_cancellation_point || 3596 CurrentRegion == OMPD_cancel) { 3597 // OpenMP [2.16, Nesting of Regions] 3598 // A cancellation point construct for which construct-type-clause is 3599 // taskgroup must be nested inside a task construct. A cancellation 3600 // point construct for which construct-type-clause is not taskgroup must 3601 // be closely nested inside an OpenMP construct that matches the type 3602 // specified in construct-type-clause. 3603 // A cancel construct for which construct-type-clause is taskgroup must be 3604 // nested inside a task construct. A cancel construct for which 3605 // construct-type-clause is not taskgroup must be closely nested inside an 3606 // OpenMP construct that matches the type specified in 3607 // construct-type-clause. 3608 NestingProhibited = 3609 !((CancelRegion == OMPD_parallel && 3610 (ParentRegion == OMPD_parallel || 3611 ParentRegion == OMPD_target_parallel)) || 3612 (CancelRegion == OMPD_for && 3613 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3614 ParentRegion == OMPD_target_parallel_for || 3615 ParentRegion == OMPD_distribute_parallel_for || 3616 ParentRegion == OMPD_teams_distribute_parallel_for || 3617 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3618 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3619 (CancelRegion == OMPD_sections && 3620 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3621 ParentRegion == OMPD_parallel_sections))); 3622 OrphanSeen = ParentRegion == OMPD_unknown; 3623 } else if (CurrentRegion == OMPD_master) { 3624 // OpenMP [2.16, Nesting of Regions] 3625 // A master region may not be closely nested inside a worksharing, 3626 // atomic, or explicit task region. 3627 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3628 isOpenMPTaskingDirective(ParentRegion); 3629 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3630 // OpenMP [2.16, Nesting of Regions] 3631 // A critical region may not be nested (closely or otherwise) inside a 3632 // critical region with the same name. Note that this restriction is not 3633 // sufficient to prevent deadlock. 3634 SourceLocation PreviousCriticalLoc; 3635 bool DeadLock = Stack->hasDirective( 3636 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3637 const DeclarationNameInfo &DNI, 3638 SourceLocation Loc) { 3639 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3640 PreviousCriticalLoc = Loc; 3641 return true; 3642 } 3643 return false; 3644 }, 3645 false /* skip top directive */); 3646 if (DeadLock) { 3647 SemaRef.Diag(StartLoc, 3648 diag::err_omp_prohibited_region_critical_same_name) 3649 << CurrentName.getName(); 3650 if (PreviousCriticalLoc.isValid()) 3651 SemaRef.Diag(PreviousCriticalLoc, 3652 diag::note_omp_previous_critical_region); 3653 return true; 3654 } 3655 } else if (CurrentRegion == OMPD_barrier) { 3656 // OpenMP [2.16, Nesting of Regions] 3657 // A barrier region may not be closely nested inside a worksharing, 3658 // explicit task, critical, ordered, atomic, or master region. 3659 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3660 isOpenMPTaskingDirective(ParentRegion) || 3661 ParentRegion == OMPD_master || 3662 ParentRegion == OMPD_critical || 3663 ParentRegion == OMPD_ordered; 3664 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3665 !isOpenMPParallelDirective(CurrentRegion) && 3666 !isOpenMPTeamsDirective(CurrentRegion)) { 3667 // OpenMP [2.16, Nesting of Regions] 3668 // A worksharing region may not be closely nested inside a worksharing, 3669 // explicit task, critical, ordered, atomic, or master region. 3670 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3671 isOpenMPTaskingDirective(ParentRegion) || 3672 ParentRegion == OMPD_master || 3673 ParentRegion == OMPD_critical || 3674 ParentRegion == OMPD_ordered; 3675 Recommend = ShouldBeInParallelRegion; 3676 } else if (CurrentRegion == OMPD_ordered) { 3677 // OpenMP [2.16, Nesting of Regions] 3678 // An ordered region may not be closely nested inside a critical, 3679 // atomic, or explicit task region. 3680 // An ordered region must be closely nested inside a loop region (or 3681 // parallel loop region) with an ordered clause. 3682 // OpenMP [2.8.1,simd Construct, Restrictions] 3683 // An ordered construct with the simd clause is the only OpenMP construct 3684 // that can appear in the simd region. 3685 NestingProhibited = ParentRegion == OMPD_critical || 3686 isOpenMPTaskingDirective(ParentRegion) || 3687 !(isOpenMPSimdDirective(ParentRegion) || 3688 Stack->isParentOrderedRegion()); 3689 Recommend = ShouldBeInOrderedRegion; 3690 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3691 // OpenMP [2.16, Nesting of Regions] 3692 // If specified, a teams construct must be contained within a target 3693 // construct. 3694 NestingProhibited = ParentRegion != OMPD_target; 3695 OrphanSeen = ParentRegion == OMPD_unknown; 3696 Recommend = ShouldBeInTargetRegion; 3697 } 3698 if (!NestingProhibited && 3699 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3700 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3701 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3702 // OpenMP [2.16, Nesting of Regions] 3703 // distribute, parallel, parallel sections, parallel workshare, and the 3704 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3705 // constructs that can be closely nested in the teams region. 3706 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3707 !isOpenMPDistributeDirective(CurrentRegion); 3708 Recommend = ShouldBeInParallelRegion; 3709 } 3710 if (!NestingProhibited && 3711 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3712 // OpenMP 4.5 [2.17 Nesting of Regions] 3713 // The region associated with the distribute construct must be strictly 3714 // nested inside a teams region 3715 NestingProhibited = 3716 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3717 Recommend = ShouldBeInTeamsRegion; 3718 } 3719 if (!NestingProhibited && 3720 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3721 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3722 // OpenMP 4.5 [2.17 Nesting of Regions] 3723 // If a target, target update, target data, target enter data, or 3724 // target exit data construct is encountered during execution of a 3725 // target region, the behavior is unspecified. 3726 NestingProhibited = Stack->hasDirective( 3727 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3728 SourceLocation) { 3729 if (isOpenMPTargetExecutionDirective(K)) { 3730 OffendingRegion = K; 3731 return true; 3732 } 3733 return false; 3734 }, 3735 false /* don't skip top directive */); 3736 CloseNesting = false; 3737 } 3738 if (NestingProhibited) { 3739 if (OrphanSeen) { 3740 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3741 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3742 } else { 3743 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3744 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3745 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3746 } 3747 return true; 3748 } 3749 } 3750 return false; 3751 } 3752 3753 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3754 ArrayRef<OMPClause *> Clauses, 3755 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3756 bool ErrorFound = false; 3757 unsigned NamedModifiersNumber = 0; 3758 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3759 OMPD_unknown + 1); 3760 SmallVector<SourceLocation, 4> NameModifierLoc; 3761 for (const OMPClause *C : Clauses) { 3762 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3763 // At most one if clause without a directive-name-modifier can appear on 3764 // the directive. 3765 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3766 if (FoundNameModifiers[CurNM]) { 3767 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3768 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3769 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3770 ErrorFound = true; 3771 } else if (CurNM != OMPD_unknown) { 3772 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3773 ++NamedModifiersNumber; 3774 } 3775 FoundNameModifiers[CurNM] = IC; 3776 if (CurNM == OMPD_unknown) 3777 continue; 3778 // Check if the specified name modifier is allowed for the current 3779 // directive. 3780 // At most one if clause with the particular directive-name-modifier can 3781 // appear on the directive. 3782 bool MatchFound = false; 3783 for (auto NM : AllowedNameModifiers) { 3784 if (CurNM == NM) { 3785 MatchFound = true; 3786 break; 3787 } 3788 } 3789 if (!MatchFound) { 3790 S.Diag(IC->getNameModifierLoc(), 3791 diag::err_omp_wrong_if_directive_name_modifier) 3792 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3793 ErrorFound = true; 3794 } 3795 } 3796 } 3797 // If any if clause on the directive includes a directive-name-modifier then 3798 // all if clauses on the directive must include a directive-name-modifier. 3799 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3800 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3801 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3802 diag::err_omp_no_more_if_clause); 3803 } else { 3804 std::string Values; 3805 std::string Sep(", "); 3806 unsigned AllowedCnt = 0; 3807 unsigned TotalAllowedNum = 3808 AllowedNameModifiers.size() - NamedModifiersNumber; 3809 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3810 ++Cnt) { 3811 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3812 if (!FoundNameModifiers[NM]) { 3813 Values += "'"; 3814 Values += getOpenMPDirectiveName(NM); 3815 Values += "'"; 3816 if (AllowedCnt + 2 == TotalAllowedNum) 3817 Values += " or "; 3818 else if (AllowedCnt + 1 != TotalAllowedNum) 3819 Values += Sep; 3820 ++AllowedCnt; 3821 } 3822 } 3823 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3824 diag::err_omp_unnamed_if_clause) 3825 << (TotalAllowedNum > 1) << Values; 3826 } 3827 for (SourceLocation Loc : NameModifierLoc) { 3828 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3829 } 3830 ErrorFound = true; 3831 } 3832 return ErrorFound; 3833 } 3834 3835 static std::pair<ValueDecl *, bool> 3836 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 3837 SourceRange &ERange, bool AllowArraySection = false) { 3838 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 3839 RefExpr->containsUnexpandedParameterPack()) 3840 return std::make_pair(nullptr, true); 3841 3842 // OpenMP [3.1, C/C++] 3843 // A list item is a variable name. 3844 // OpenMP [2.9.3.3, Restrictions, p.1] 3845 // A variable that is part of another variable (as an array or 3846 // structure element) cannot appear in a private clause. 3847 RefExpr = RefExpr->IgnoreParens(); 3848 enum { 3849 NoArrayExpr = -1, 3850 ArraySubscript = 0, 3851 OMPArraySection = 1 3852 } IsArrayExpr = NoArrayExpr; 3853 if (AllowArraySection) { 3854 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 3855 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 3856 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3857 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3858 RefExpr = Base; 3859 IsArrayExpr = ArraySubscript; 3860 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 3861 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 3862 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 3863 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 3864 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3865 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3866 RefExpr = Base; 3867 IsArrayExpr = OMPArraySection; 3868 } 3869 } 3870 ELoc = RefExpr->getExprLoc(); 3871 ERange = RefExpr->getSourceRange(); 3872 RefExpr = RefExpr->IgnoreParenImpCasts(); 3873 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 3874 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 3875 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 3876 (S.getCurrentThisType().isNull() || !ME || 3877 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 3878 !isa<FieldDecl>(ME->getMemberDecl()))) { 3879 if (IsArrayExpr != NoArrayExpr) { 3880 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 3881 << ERange; 3882 } else { 3883 S.Diag(ELoc, 3884 AllowArraySection 3885 ? diag::err_omp_expected_var_name_member_expr_or_array_item 3886 : diag::err_omp_expected_var_name_member_expr) 3887 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 3888 } 3889 return std::make_pair(nullptr, false); 3890 } 3891 return std::make_pair( 3892 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 3893 } 3894 3895 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 3896 ArrayRef<OMPClause *> Clauses) { 3897 assert(!S.CurContext->isDependentContext() && 3898 "Expected non-dependent context."); 3899 auto AllocateRange = 3900 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 3901 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 3902 DeclToCopy; 3903 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 3904 return isOpenMPPrivate(C->getClauseKind()); 3905 }); 3906 for (OMPClause *Cl : PrivateRange) { 3907 MutableArrayRef<Expr *>::iterator I, It, Et; 3908 if (Cl->getClauseKind() == OMPC_private) { 3909 auto *PC = cast<OMPPrivateClause>(Cl); 3910 I = PC->private_copies().begin(); 3911 It = PC->varlist_begin(); 3912 Et = PC->varlist_end(); 3913 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 3914 auto *PC = cast<OMPFirstprivateClause>(Cl); 3915 I = PC->private_copies().begin(); 3916 It = PC->varlist_begin(); 3917 Et = PC->varlist_end(); 3918 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 3919 auto *PC = cast<OMPLastprivateClause>(Cl); 3920 I = PC->private_copies().begin(); 3921 It = PC->varlist_begin(); 3922 Et = PC->varlist_end(); 3923 } else if (Cl->getClauseKind() == OMPC_linear) { 3924 auto *PC = cast<OMPLinearClause>(Cl); 3925 I = PC->privates().begin(); 3926 It = PC->varlist_begin(); 3927 Et = PC->varlist_end(); 3928 } else if (Cl->getClauseKind() == OMPC_reduction) { 3929 auto *PC = cast<OMPReductionClause>(Cl); 3930 I = PC->privates().begin(); 3931 It = PC->varlist_begin(); 3932 Et = PC->varlist_end(); 3933 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 3934 auto *PC = cast<OMPTaskReductionClause>(Cl); 3935 I = PC->privates().begin(); 3936 It = PC->varlist_begin(); 3937 Et = PC->varlist_end(); 3938 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 3939 auto *PC = cast<OMPInReductionClause>(Cl); 3940 I = PC->privates().begin(); 3941 It = PC->varlist_begin(); 3942 Et = PC->varlist_end(); 3943 } else { 3944 llvm_unreachable("Expected private clause."); 3945 } 3946 for (Expr *E : llvm::make_range(It, Et)) { 3947 if (!*I) { 3948 ++I; 3949 continue; 3950 } 3951 SourceLocation ELoc; 3952 SourceRange ERange; 3953 Expr *SimpleRefExpr = E; 3954 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 3955 /*AllowArraySection=*/true); 3956 DeclToCopy.try_emplace(Res.first, 3957 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 3958 ++I; 3959 } 3960 } 3961 for (OMPClause *C : AllocateRange) { 3962 auto *AC = cast<OMPAllocateClause>(C); 3963 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3964 getAllocatorKind(S, Stack, AC->getAllocator()); 3965 // OpenMP, 2.11.4 allocate Clause, Restrictions. 3966 // For task, taskloop or target directives, allocation requests to memory 3967 // allocators with the trait access set to thread result in unspecified 3968 // behavior. 3969 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 3970 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 3971 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 3972 S.Diag(AC->getAllocator()->getExprLoc(), 3973 diag::warn_omp_allocate_thread_on_task_target_directive) 3974 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3975 } 3976 for (Expr *E : AC->varlists()) { 3977 SourceLocation ELoc; 3978 SourceRange ERange; 3979 Expr *SimpleRefExpr = E; 3980 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 3981 ValueDecl *VD = Res.first; 3982 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 3983 if (!isOpenMPPrivate(Data.CKind)) { 3984 S.Diag(E->getExprLoc(), 3985 diag::err_omp_expected_private_copy_for_allocate); 3986 continue; 3987 } 3988 VarDecl *PrivateVD = DeclToCopy[VD]; 3989 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 3990 AllocatorKind, AC->getAllocator())) 3991 continue; 3992 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 3993 E->getSourceRange()); 3994 } 3995 } 3996 } 3997 3998 StmtResult Sema::ActOnOpenMPExecutableDirective( 3999 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4000 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4001 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4002 StmtResult Res = StmtError(); 4003 // First check CancelRegion which is then used in checkNestingOfRegions. 4004 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4005 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4006 StartLoc)) 4007 return StmtError(); 4008 4009 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4010 VarsWithInheritedDSAType VarsWithInheritedDSA; 4011 bool ErrorFound = false; 4012 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4013 if (AStmt && !CurContext->isDependentContext()) { 4014 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4015 4016 // Check default data sharing attributes for referenced variables. 4017 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4018 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4019 Stmt *S = AStmt; 4020 while (--ThisCaptureLevel >= 0) 4021 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4022 DSAChecker.Visit(S); 4023 if (!isOpenMPTargetDataManagementDirective(Kind) && 4024 !isOpenMPTaskingDirective(Kind)) { 4025 // Visit subcaptures to generate implicit clauses for captured vars. 4026 auto *CS = cast<CapturedStmt>(AStmt); 4027 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4028 getOpenMPCaptureRegions(CaptureRegions, Kind); 4029 // Ignore outer tasking regions for target directives. 4030 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4031 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4032 DSAChecker.visitSubCaptures(CS); 4033 } 4034 if (DSAChecker.isErrorFound()) 4035 return StmtError(); 4036 // Generate list of implicitly defined firstprivate variables. 4037 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4038 4039 SmallVector<Expr *, 4> ImplicitFirstprivates( 4040 DSAChecker.getImplicitFirstprivate().begin(), 4041 DSAChecker.getImplicitFirstprivate().end()); 4042 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4043 DSAChecker.getImplicitMap().end()); 4044 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4045 for (OMPClause *C : Clauses) { 4046 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4047 for (Expr *E : IRC->taskgroup_descriptors()) 4048 if (E) 4049 ImplicitFirstprivates.emplace_back(E); 4050 } 4051 } 4052 if (!ImplicitFirstprivates.empty()) { 4053 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4054 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4055 SourceLocation())) { 4056 ClausesWithImplicit.push_back(Implicit); 4057 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4058 ImplicitFirstprivates.size(); 4059 } else { 4060 ErrorFound = true; 4061 } 4062 } 4063 if (!ImplicitMaps.empty()) { 4064 CXXScopeSpec MapperIdScopeSpec; 4065 DeclarationNameInfo MapperId; 4066 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4067 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4068 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4069 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4070 ClausesWithImplicit.emplace_back(Implicit); 4071 ErrorFound |= 4072 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4073 } else { 4074 ErrorFound = true; 4075 } 4076 } 4077 } 4078 4079 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4080 switch (Kind) { 4081 case OMPD_parallel: 4082 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4083 EndLoc); 4084 AllowedNameModifiers.push_back(OMPD_parallel); 4085 break; 4086 case OMPD_simd: 4087 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4088 VarsWithInheritedDSA); 4089 break; 4090 case OMPD_for: 4091 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4092 VarsWithInheritedDSA); 4093 break; 4094 case OMPD_for_simd: 4095 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4096 EndLoc, VarsWithInheritedDSA); 4097 break; 4098 case OMPD_sections: 4099 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4100 EndLoc); 4101 break; 4102 case OMPD_section: 4103 assert(ClausesWithImplicit.empty() && 4104 "No clauses are allowed for 'omp section' directive"); 4105 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4106 break; 4107 case OMPD_single: 4108 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4109 EndLoc); 4110 break; 4111 case OMPD_master: 4112 assert(ClausesWithImplicit.empty() && 4113 "No clauses are allowed for 'omp master' directive"); 4114 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4115 break; 4116 case OMPD_critical: 4117 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4118 StartLoc, EndLoc); 4119 break; 4120 case OMPD_parallel_for: 4121 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4122 EndLoc, VarsWithInheritedDSA); 4123 AllowedNameModifiers.push_back(OMPD_parallel); 4124 break; 4125 case OMPD_parallel_for_simd: 4126 Res = ActOnOpenMPParallelForSimdDirective( 4127 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4128 AllowedNameModifiers.push_back(OMPD_parallel); 4129 break; 4130 case OMPD_parallel_sections: 4131 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4132 StartLoc, EndLoc); 4133 AllowedNameModifiers.push_back(OMPD_parallel); 4134 break; 4135 case OMPD_task: 4136 Res = 4137 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4138 AllowedNameModifiers.push_back(OMPD_task); 4139 break; 4140 case OMPD_taskyield: 4141 assert(ClausesWithImplicit.empty() && 4142 "No clauses are allowed for 'omp taskyield' directive"); 4143 assert(AStmt == nullptr && 4144 "No associated statement allowed for 'omp taskyield' directive"); 4145 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4146 break; 4147 case OMPD_barrier: 4148 assert(ClausesWithImplicit.empty() && 4149 "No clauses are allowed for 'omp barrier' directive"); 4150 assert(AStmt == nullptr && 4151 "No associated statement allowed for 'omp barrier' directive"); 4152 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4153 break; 4154 case OMPD_taskwait: 4155 assert(ClausesWithImplicit.empty() && 4156 "No clauses are allowed for 'omp taskwait' directive"); 4157 assert(AStmt == nullptr && 4158 "No associated statement allowed for 'omp taskwait' directive"); 4159 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4160 break; 4161 case OMPD_taskgroup: 4162 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4163 EndLoc); 4164 break; 4165 case OMPD_flush: 4166 assert(AStmt == nullptr && 4167 "No associated statement allowed for 'omp flush' directive"); 4168 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4169 break; 4170 case OMPD_ordered: 4171 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4172 EndLoc); 4173 break; 4174 case OMPD_atomic: 4175 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4176 EndLoc); 4177 break; 4178 case OMPD_teams: 4179 Res = 4180 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4181 break; 4182 case OMPD_target: 4183 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4184 EndLoc); 4185 AllowedNameModifiers.push_back(OMPD_target); 4186 break; 4187 case OMPD_target_parallel: 4188 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4189 StartLoc, EndLoc); 4190 AllowedNameModifiers.push_back(OMPD_target); 4191 AllowedNameModifiers.push_back(OMPD_parallel); 4192 break; 4193 case OMPD_target_parallel_for: 4194 Res = ActOnOpenMPTargetParallelForDirective( 4195 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4196 AllowedNameModifiers.push_back(OMPD_target); 4197 AllowedNameModifiers.push_back(OMPD_parallel); 4198 break; 4199 case OMPD_cancellation_point: 4200 assert(ClausesWithImplicit.empty() && 4201 "No clauses are allowed for 'omp cancellation point' directive"); 4202 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4203 "cancellation point' directive"); 4204 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4205 break; 4206 case OMPD_cancel: 4207 assert(AStmt == nullptr && 4208 "No associated statement allowed for 'omp cancel' directive"); 4209 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4210 CancelRegion); 4211 AllowedNameModifiers.push_back(OMPD_cancel); 4212 break; 4213 case OMPD_target_data: 4214 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4215 EndLoc); 4216 AllowedNameModifiers.push_back(OMPD_target_data); 4217 break; 4218 case OMPD_target_enter_data: 4219 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4220 EndLoc, AStmt); 4221 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4222 break; 4223 case OMPD_target_exit_data: 4224 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4225 EndLoc, AStmt); 4226 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4227 break; 4228 case OMPD_taskloop: 4229 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4230 EndLoc, VarsWithInheritedDSA); 4231 AllowedNameModifiers.push_back(OMPD_taskloop); 4232 break; 4233 case OMPD_taskloop_simd: 4234 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4235 EndLoc, VarsWithInheritedDSA); 4236 AllowedNameModifiers.push_back(OMPD_taskloop); 4237 break; 4238 case OMPD_distribute: 4239 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4240 EndLoc, VarsWithInheritedDSA); 4241 break; 4242 case OMPD_target_update: 4243 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4244 EndLoc, AStmt); 4245 AllowedNameModifiers.push_back(OMPD_target_update); 4246 break; 4247 case OMPD_distribute_parallel_for: 4248 Res = ActOnOpenMPDistributeParallelForDirective( 4249 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4250 AllowedNameModifiers.push_back(OMPD_parallel); 4251 break; 4252 case OMPD_distribute_parallel_for_simd: 4253 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4254 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4255 AllowedNameModifiers.push_back(OMPD_parallel); 4256 break; 4257 case OMPD_distribute_simd: 4258 Res = ActOnOpenMPDistributeSimdDirective( 4259 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4260 break; 4261 case OMPD_target_parallel_for_simd: 4262 Res = ActOnOpenMPTargetParallelForSimdDirective( 4263 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4264 AllowedNameModifiers.push_back(OMPD_target); 4265 AllowedNameModifiers.push_back(OMPD_parallel); 4266 break; 4267 case OMPD_target_simd: 4268 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4269 EndLoc, VarsWithInheritedDSA); 4270 AllowedNameModifiers.push_back(OMPD_target); 4271 break; 4272 case OMPD_teams_distribute: 4273 Res = ActOnOpenMPTeamsDistributeDirective( 4274 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4275 break; 4276 case OMPD_teams_distribute_simd: 4277 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4278 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4279 break; 4280 case OMPD_teams_distribute_parallel_for_simd: 4281 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4282 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4283 AllowedNameModifiers.push_back(OMPD_parallel); 4284 break; 4285 case OMPD_teams_distribute_parallel_for: 4286 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4287 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4288 AllowedNameModifiers.push_back(OMPD_parallel); 4289 break; 4290 case OMPD_target_teams: 4291 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4292 EndLoc); 4293 AllowedNameModifiers.push_back(OMPD_target); 4294 break; 4295 case OMPD_target_teams_distribute: 4296 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4297 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4298 AllowedNameModifiers.push_back(OMPD_target); 4299 break; 4300 case OMPD_target_teams_distribute_parallel_for: 4301 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4302 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4303 AllowedNameModifiers.push_back(OMPD_target); 4304 AllowedNameModifiers.push_back(OMPD_parallel); 4305 break; 4306 case OMPD_target_teams_distribute_parallel_for_simd: 4307 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4308 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4309 AllowedNameModifiers.push_back(OMPD_target); 4310 AllowedNameModifiers.push_back(OMPD_parallel); 4311 break; 4312 case OMPD_target_teams_distribute_simd: 4313 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4314 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4315 AllowedNameModifiers.push_back(OMPD_target); 4316 break; 4317 case OMPD_declare_target: 4318 case OMPD_end_declare_target: 4319 case OMPD_threadprivate: 4320 case OMPD_allocate: 4321 case OMPD_declare_reduction: 4322 case OMPD_declare_mapper: 4323 case OMPD_declare_simd: 4324 case OMPD_requires: 4325 llvm_unreachable("OpenMP Directive is not allowed"); 4326 case OMPD_unknown: 4327 llvm_unreachable("Unknown OpenMP directive"); 4328 } 4329 4330 ErrorFound = Res.isInvalid() || ErrorFound; 4331 4332 // Check variables in the clauses if default(none) was specified. 4333 if (DSAStack->getDefaultDSA() == DSA_none) { 4334 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4335 for (OMPClause *C : Clauses) { 4336 switch (C->getClauseKind()) { 4337 case OMPC_num_threads: 4338 case OMPC_dist_schedule: 4339 // Do not analyse if no parent teams directive. 4340 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4341 break; 4342 continue; 4343 case OMPC_if: 4344 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4345 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4346 break; 4347 continue; 4348 case OMPC_schedule: 4349 break; 4350 case OMPC_ordered: 4351 case OMPC_device: 4352 case OMPC_num_teams: 4353 case OMPC_thread_limit: 4354 case OMPC_priority: 4355 case OMPC_grainsize: 4356 case OMPC_num_tasks: 4357 case OMPC_hint: 4358 case OMPC_collapse: 4359 case OMPC_safelen: 4360 case OMPC_simdlen: 4361 case OMPC_final: 4362 case OMPC_default: 4363 case OMPC_proc_bind: 4364 case OMPC_private: 4365 case OMPC_firstprivate: 4366 case OMPC_lastprivate: 4367 case OMPC_shared: 4368 case OMPC_reduction: 4369 case OMPC_task_reduction: 4370 case OMPC_in_reduction: 4371 case OMPC_linear: 4372 case OMPC_aligned: 4373 case OMPC_copyin: 4374 case OMPC_copyprivate: 4375 case OMPC_nowait: 4376 case OMPC_untied: 4377 case OMPC_mergeable: 4378 case OMPC_allocate: 4379 case OMPC_read: 4380 case OMPC_write: 4381 case OMPC_update: 4382 case OMPC_capture: 4383 case OMPC_seq_cst: 4384 case OMPC_depend: 4385 case OMPC_threads: 4386 case OMPC_simd: 4387 case OMPC_map: 4388 case OMPC_nogroup: 4389 case OMPC_defaultmap: 4390 case OMPC_to: 4391 case OMPC_from: 4392 case OMPC_use_device_ptr: 4393 case OMPC_is_device_ptr: 4394 continue; 4395 case OMPC_allocator: 4396 case OMPC_flush: 4397 case OMPC_threadprivate: 4398 case OMPC_uniform: 4399 case OMPC_unknown: 4400 case OMPC_unified_address: 4401 case OMPC_unified_shared_memory: 4402 case OMPC_reverse_offload: 4403 case OMPC_dynamic_allocators: 4404 case OMPC_atomic_default_mem_order: 4405 llvm_unreachable("Unexpected clause"); 4406 } 4407 for (Stmt *CC : C->children()) { 4408 if (CC) 4409 DSAChecker.Visit(CC); 4410 } 4411 } 4412 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4413 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4414 } 4415 for (const auto &P : VarsWithInheritedDSA) { 4416 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4417 continue; 4418 ErrorFound = true; 4419 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4420 << P.first << P.second->getSourceRange(); 4421 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4422 } 4423 4424 if (!AllowedNameModifiers.empty()) 4425 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4426 ErrorFound; 4427 4428 if (ErrorFound) 4429 return StmtError(); 4430 4431 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4432 Res.getAs<OMPExecutableDirective>() 4433 ->getStructuredBlock() 4434 ->setIsOMPStructuredBlock(true); 4435 } 4436 4437 if (!CurContext->isDependentContext() && 4438 isOpenMPTargetExecutionDirective(Kind) && 4439 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4440 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4441 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4442 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4443 // Register target to DSA Stack. 4444 DSAStack->addTargetDirLocation(StartLoc); 4445 } 4446 4447 return Res; 4448 } 4449 4450 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4451 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4452 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4453 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4454 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4455 assert(Aligneds.size() == Alignments.size()); 4456 assert(Linears.size() == LinModifiers.size()); 4457 assert(Linears.size() == Steps.size()); 4458 if (!DG || DG.get().isNull()) 4459 return DeclGroupPtrTy(); 4460 4461 if (!DG.get().isSingleDecl()) { 4462 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4463 return DG; 4464 } 4465 Decl *ADecl = DG.get().getSingleDecl(); 4466 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4467 ADecl = FTD->getTemplatedDecl(); 4468 4469 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4470 if (!FD) { 4471 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4472 return DeclGroupPtrTy(); 4473 } 4474 4475 // OpenMP [2.8.2, declare simd construct, Description] 4476 // The parameter of the simdlen clause must be a constant positive integer 4477 // expression. 4478 ExprResult SL; 4479 if (Simdlen) 4480 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4481 // OpenMP [2.8.2, declare simd construct, Description] 4482 // The special this pointer can be used as if was one of the arguments to the 4483 // function in any of the linear, aligned, or uniform clauses. 4484 // The uniform clause declares one or more arguments to have an invariant 4485 // value for all concurrent invocations of the function in the execution of a 4486 // single SIMD loop. 4487 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4488 const Expr *UniformedLinearThis = nullptr; 4489 for (const Expr *E : Uniforms) { 4490 E = E->IgnoreParenImpCasts(); 4491 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4492 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4493 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4494 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4495 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4496 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4497 continue; 4498 } 4499 if (isa<CXXThisExpr>(E)) { 4500 UniformedLinearThis = E; 4501 continue; 4502 } 4503 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4504 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4505 } 4506 // OpenMP [2.8.2, declare simd construct, Description] 4507 // The aligned clause declares that the object to which each list item points 4508 // is aligned to the number of bytes expressed in the optional parameter of 4509 // the aligned clause. 4510 // The special this pointer can be used as if was one of the arguments to the 4511 // function in any of the linear, aligned, or uniform clauses. 4512 // The type of list items appearing in the aligned clause must be array, 4513 // pointer, reference to array, or reference to pointer. 4514 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4515 const Expr *AlignedThis = nullptr; 4516 for (const Expr *E : Aligneds) { 4517 E = E->IgnoreParenImpCasts(); 4518 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4519 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4520 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4521 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4522 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4523 ->getCanonicalDecl() == CanonPVD) { 4524 // OpenMP [2.8.1, simd construct, Restrictions] 4525 // A list-item cannot appear in more than one aligned clause. 4526 if (AlignedArgs.count(CanonPVD) > 0) { 4527 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4528 << 1 << E->getSourceRange(); 4529 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4530 diag::note_omp_explicit_dsa) 4531 << getOpenMPClauseName(OMPC_aligned); 4532 continue; 4533 } 4534 AlignedArgs[CanonPVD] = E; 4535 QualType QTy = PVD->getType() 4536 .getNonReferenceType() 4537 .getUnqualifiedType() 4538 .getCanonicalType(); 4539 const Type *Ty = QTy.getTypePtrOrNull(); 4540 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4541 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4542 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4543 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4544 } 4545 continue; 4546 } 4547 } 4548 if (isa<CXXThisExpr>(E)) { 4549 if (AlignedThis) { 4550 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4551 << 2 << E->getSourceRange(); 4552 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4553 << getOpenMPClauseName(OMPC_aligned); 4554 } 4555 AlignedThis = E; 4556 continue; 4557 } 4558 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4559 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4560 } 4561 // The optional parameter of the aligned clause, alignment, must be a constant 4562 // positive integer expression. If no optional parameter is specified, 4563 // implementation-defined default alignments for SIMD instructions on the 4564 // target platforms are assumed. 4565 SmallVector<const Expr *, 4> NewAligns; 4566 for (Expr *E : Alignments) { 4567 ExprResult Align; 4568 if (E) 4569 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4570 NewAligns.push_back(Align.get()); 4571 } 4572 // OpenMP [2.8.2, declare simd construct, Description] 4573 // The linear clause declares one or more list items to be private to a SIMD 4574 // lane and to have a linear relationship with respect to the iteration space 4575 // of a loop. 4576 // The special this pointer can be used as if was one of the arguments to the 4577 // function in any of the linear, aligned, or uniform clauses. 4578 // When a linear-step expression is specified in a linear clause it must be 4579 // either a constant integer expression or an integer-typed parameter that is 4580 // specified in a uniform clause on the directive. 4581 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4582 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4583 auto MI = LinModifiers.begin(); 4584 for (const Expr *E : Linears) { 4585 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4586 ++MI; 4587 E = E->IgnoreParenImpCasts(); 4588 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4589 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4590 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4591 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4592 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4593 ->getCanonicalDecl() == CanonPVD) { 4594 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4595 // A list-item cannot appear in more than one linear clause. 4596 if (LinearArgs.count(CanonPVD) > 0) { 4597 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4598 << getOpenMPClauseName(OMPC_linear) 4599 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4600 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4601 diag::note_omp_explicit_dsa) 4602 << getOpenMPClauseName(OMPC_linear); 4603 continue; 4604 } 4605 // Each argument can appear in at most one uniform or linear clause. 4606 if (UniformedArgs.count(CanonPVD) > 0) { 4607 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4608 << getOpenMPClauseName(OMPC_linear) 4609 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4610 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4611 diag::note_omp_explicit_dsa) 4612 << getOpenMPClauseName(OMPC_uniform); 4613 continue; 4614 } 4615 LinearArgs[CanonPVD] = E; 4616 if (E->isValueDependent() || E->isTypeDependent() || 4617 E->isInstantiationDependent() || 4618 E->containsUnexpandedParameterPack()) 4619 continue; 4620 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4621 PVD->getOriginalType()); 4622 continue; 4623 } 4624 } 4625 if (isa<CXXThisExpr>(E)) { 4626 if (UniformedLinearThis) { 4627 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4628 << getOpenMPClauseName(OMPC_linear) 4629 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4630 << E->getSourceRange(); 4631 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4632 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4633 : OMPC_linear); 4634 continue; 4635 } 4636 UniformedLinearThis = E; 4637 if (E->isValueDependent() || E->isTypeDependent() || 4638 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4639 continue; 4640 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4641 E->getType()); 4642 continue; 4643 } 4644 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4645 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4646 } 4647 Expr *Step = nullptr; 4648 Expr *NewStep = nullptr; 4649 SmallVector<Expr *, 4> NewSteps; 4650 for (Expr *E : Steps) { 4651 // Skip the same step expression, it was checked already. 4652 if (Step == E || !E) { 4653 NewSteps.push_back(E ? NewStep : nullptr); 4654 continue; 4655 } 4656 Step = E; 4657 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4658 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4659 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4660 if (UniformedArgs.count(CanonPVD) == 0) { 4661 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4662 << Step->getSourceRange(); 4663 } else if (E->isValueDependent() || E->isTypeDependent() || 4664 E->isInstantiationDependent() || 4665 E->containsUnexpandedParameterPack() || 4666 CanonPVD->getType()->hasIntegerRepresentation()) { 4667 NewSteps.push_back(Step); 4668 } else { 4669 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4670 << Step->getSourceRange(); 4671 } 4672 continue; 4673 } 4674 NewStep = Step; 4675 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4676 !Step->isInstantiationDependent() && 4677 !Step->containsUnexpandedParameterPack()) { 4678 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4679 .get(); 4680 if (NewStep) 4681 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4682 } 4683 NewSteps.push_back(NewStep); 4684 } 4685 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4686 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4687 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4688 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4689 const_cast<Expr **>(Linears.data()), Linears.size(), 4690 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4691 NewSteps.data(), NewSteps.size(), SR); 4692 ADecl->addAttr(NewAttr); 4693 return ConvertDeclToDeclGroup(ADecl); 4694 } 4695 4696 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4697 Stmt *AStmt, 4698 SourceLocation StartLoc, 4699 SourceLocation EndLoc) { 4700 if (!AStmt) 4701 return StmtError(); 4702 4703 auto *CS = cast<CapturedStmt>(AStmt); 4704 // 1.2.2 OpenMP Language Terminology 4705 // Structured block - An executable statement with a single entry at the 4706 // top and a single exit at the bottom. 4707 // The point of exit cannot be a branch out of the structured block. 4708 // longjmp() and throw() must not violate the entry/exit criteria. 4709 CS->getCapturedDecl()->setNothrow(); 4710 4711 setFunctionHasBranchProtectedScope(); 4712 4713 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4714 DSAStack->isCancelRegion()); 4715 } 4716 4717 namespace { 4718 /// Iteration space of a single for loop. 4719 struct LoopIterationSpace final { 4720 /// True if the condition operator is the strict compare operator (<, > or 4721 /// !=). 4722 bool IsStrictCompare = false; 4723 /// Condition of the loop. 4724 Expr *PreCond = nullptr; 4725 /// This expression calculates the number of iterations in the loop. 4726 /// It is always possible to calculate it before starting the loop. 4727 Expr *NumIterations = nullptr; 4728 /// The loop counter variable. 4729 Expr *CounterVar = nullptr; 4730 /// Private loop counter variable. 4731 Expr *PrivateCounterVar = nullptr; 4732 /// This is initializer for the initial value of #CounterVar. 4733 Expr *CounterInit = nullptr; 4734 /// This is step for the #CounterVar used to generate its update: 4735 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4736 Expr *CounterStep = nullptr; 4737 /// Should step be subtracted? 4738 bool Subtract = false; 4739 /// Source range of the loop init. 4740 SourceRange InitSrcRange; 4741 /// Source range of the loop condition. 4742 SourceRange CondSrcRange; 4743 /// Source range of the loop increment. 4744 SourceRange IncSrcRange; 4745 /// Minimum value that can have the loop control variable. Used to support 4746 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 4747 /// since only such variables can be used in non-loop invariant expressions. 4748 Expr *MinValue = nullptr; 4749 /// Maximum value that can have the loop control variable. Used to support 4750 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 4751 /// since only such variables can be used in non-loop invariant expressions. 4752 Expr *MaxValue = nullptr; 4753 /// true, if the lower bound depends on the outer loop control var. 4754 bool IsNonRectangularLB = false; 4755 /// true, if the upper bound depends on the outer loop control var. 4756 bool IsNonRectangularUB = false; 4757 /// Index of the loop this loop depends on and forms non-rectangular loop 4758 /// nest. 4759 unsigned LoopDependentIdx = 0; 4760 /// Final condition for the non-rectangular loop nest support. It is used to 4761 /// check that the number of iterations for this particular counter must be 4762 /// finished. 4763 Expr *FinalCondition = nullptr; 4764 }; 4765 4766 /// Helper class for checking canonical form of the OpenMP loops and 4767 /// extracting iteration space of each loop in the loop nest, that will be used 4768 /// for IR generation. 4769 class OpenMPIterationSpaceChecker { 4770 /// Reference to Sema. 4771 Sema &SemaRef; 4772 /// Data-sharing stack. 4773 DSAStackTy &Stack; 4774 /// A location for diagnostics (when there is no some better location). 4775 SourceLocation DefaultLoc; 4776 /// A location for diagnostics (when increment is not compatible). 4777 SourceLocation ConditionLoc; 4778 /// A source location for referring to loop init later. 4779 SourceRange InitSrcRange; 4780 /// A source location for referring to condition later. 4781 SourceRange ConditionSrcRange; 4782 /// A source location for referring to increment later. 4783 SourceRange IncrementSrcRange; 4784 /// Loop variable. 4785 ValueDecl *LCDecl = nullptr; 4786 /// Reference to loop variable. 4787 Expr *LCRef = nullptr; 4788 /// Lower bound (initializer for the var). 4789 Expr *LB = nullptr; 4790 /// Upper bound. 4791 Expr *UB = nullptr; 4792 /// Loop step (increment). 4793 Expr *Step = nullptr; 4794 /// This flag is true when condition is one of: 4795 /// Var < UB 4796 /// Var <= UB 4797 /// UB > Var 4798 /// UB >= Var 4799 /// This will have no value when the condition is != 4800 llvm::Optional<bool> TestIsLessOp; 4801 /// This flag is true when condition is strict ( < or > ). 4802 bool TestIsStrictOp = false; 4803 /// This flag is true when step is subtracted on each iteration. 4804 bool SubtractStep = false; 4805 /// The outer loop counter this loop depends on (if any). 4806 const ValueDecl *DepDecl = nullptr; 4807 /// Contains number of loop (starts from 1) on which loop counter init 4808 /// expression of this loop depends on. 4809 Optional<unsigned> InitDependOnLC; 4810 /// Contains number of loop (starts from 1) on which loop counter condition 4811 /// expression of this loop depends on. 4812 Optional<unsigned> CondDependOnLC; 4813 /// Checks if the provide statement depends on the loop counter. 4814 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 4815 /// Original condition required for checking of the exit condition for 4816 /// non-rectangular loop. 4817 Expr *Condition = nullptr; 4818 4819 public: 4820 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 4821 SourceLocation DefaultLoc) 4822 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 4823 ConditionLoc(DefaultLoc) {} 4824 /// Check init-expr for canonical loop form and save loop counter 4825 /// variable - #Var and its initialization value - #LB. 4826 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4827 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4828 /// for less/greater and for strict/non-strict comparison. 4829 bool checkAndSetCond(Expr *S); 4830 /// Check incr-expr for canonical loop form and return true if it 4831 /// does not conform, otherwise save loop step (#Step). 4832 bool checkAndSetInc(Expr *S); 4833 /// Return the loop counter variable. 4834 ValueDecl *getLoopDecl() const { return LCDecl; } 4835 /// Return the reference expression to loop counter variable. 4836 Expr *getLoopDeclRefExpr() const { return LCRef; } 4837 /// Source range of the loop init. 4838 SourceRange getInitSrcRange() const { return InitSrcRange; } 4839 /// Source range of the loop condition. 4840 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4841 /// Source range of the loop increment. 4842 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4843 /// True if the step should be subtracted. 4844 bool shouldSubtractStep() const { return SubtractStep; } 4845 /// True, if the compare operator is strict (<, > or !=). 4846 bool isStrictTestOp() const { return TestIsStrictOp; } 4847 /// Build the expression to calculate the number of iterations. 4848 Expr *buildNumIterations( 4849 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 4850 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4851 /// Build the precondition expression for the loops. 4852 Expr * 4853 buildPreCond(Scope *S, Expr *Cond, 4854 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4855 /// Build reference expression to the counter be used for codegen. 4856 DeclRefExpr * 4857 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4858 DSAStackTy &DSA) const; 4859 /// Build reference expression to the private counter be used for 4860 /// codegen. 4861 Expr *buildPrivateCounterVar() const; 4862 /// Build initialization of the counter be used for codegen. 4863 Expr *buildCounterInit() const; 4864 /// Build step of the counter be used for codegen. 4865 Expr *buildCounterStep() const; 4866 /// Build loop data with counter value for depend clauses in ordered 4867 /// directives. 4868 Expr * 4869 buildOrderedLoopData(Scope *S, Expr *Counter, 4870 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4871 SourceLocation Loc, Expr *Inc = nullptr, 4872 OverloadedOperatorKind OOK = OO_Amp); 4873 /// Builds the minimum value for the loop counter. 4874 std::pair<Expr *, Expr *> buildMinMaxValues( 4875 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4876 /// Builds final condition for the non-rectangular loops. 4877 Expr *buildFinalCondition(Scope *S) const; 4878 /// Return true if any expression is dependent. 4879 bool dependent() const; 4880 /// Returns true if the initializer forms non-rectangular loop. 4881 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 4882 /// Returns true if the condition forms non-rectangular loop. 4883 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 4884 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 4885 unsigned getLoopDependentIdx() const { 4886 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 4887 } 4888 4889 private: 4890 /// Check the right-hand side of an assignment in the increment 4891 /// expression. 4892 bool checkAndSetIncRHS(Expr *RHS); 4893 /// Helper to set loop counter variable and its initializer. 4894 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 4895 bool EmitDiags); 4896 /// Helper to set upper bound. 4897 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4898 SourceRange SR, SourceLocation SL); 4899 /// Helper to set loop increment. 4900 bool setStep(Expr *NewStep, bool Subtract); 4901 }; 4902 4903 bool OpenMPIterationSpaceChecker::dependent() const { 4904 if (!LCDecl) { 4905 assert(!LB && !UB && !Step); 4906 return false; 4907 } 4908 return LCDecl->getType()->isDependentType() || 4909 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4910 (Step && Step->isValueDependent()); 4911 } 4912 4913 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4914 Expr *NewLCRefExpr, 4915 Expr *NewLB, bool EmitDiags) { 4916 // State consistency checking to ensure correct usage. 4917 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4918 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4919 if (!NewLCDecl || !NewLB) 4920 return true; 4921 LCDecl = getCanonicalDecl(NewLCDecl); 4922 LCRef = NewLCRefExpr; 4923 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4924 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4925 if ((Ctor->isCopyOrMoveConstructor() || 4926 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4927 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4928 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4929 LB = NewLB; 4930 if (EmitDiags) 4931 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 4932 return false; 4933 } 4934 4935 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4936 llvm::Optional<bool> LessOp, 4937 bool StrictOp, SourceRange SR, 4938 SourceLocation SL) { 4939 // State consistency checking to ensure correct usage. 4940 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4941 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4942 if (!NewUB) 4943 return true; 4944 UB = NewUB; 4945 if (LessOp) 4946 TestIsLessOp = LessOp; 4947 TestIsStrictOp = StrictOp; 4948 ConditionSrcRange = SR; 4949 ConditionLoc = SL; 4950 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 4951 return false; 4952 } 4953 4954 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4955 // State consistency checking to ensure correct usage. 4956 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4957 if (!NewStep) 4958 return true; 4959 if (!NewStep->isValueDependent()) { 4960 // Check that the step is integer expression. 4961 SourceLocation StepLoc = NewStep->getBeginLoc(); 4962 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4963 StepLoc, getExprAsWritten(NewStep)); 4964 if (Val.isInvalid()) 4965 return true; 4966 NewStep = Val.get(); 4967 4968 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4969 // If test-expr is of form var relational-op b and relational-op is < or 4970 // <= then incr-expr must cause var to increase on each iteration of the 4971 // loop. If test-expr is of form var relational-op b and relational-op is 4972 // > or >= then incr-expr must cause var to decrease on each iteration of 4973 // the loop. 4974 // If test-expr is of form b relational-op var and relational-op is < or 4975 // <= then incr-expr must cause var to decrease on each iteration of the 4976 // loop. If test-expr is of form b relational-op var and relational-op is 4977 // > or >= then incr-expr must cause var to increase on each iteration of 4978 // the loop. 4979 llvm::APSInt Result; 4980 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4981 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4982 bool IsConstNeg = 4983 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4984 bool IsConstPos = 4985 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4986 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4987 4988 // != with increment is treated as <; != with decrement is treated as > 4989 if (!TestIsLessOp.hasValue()) 4990 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4991 if (UB && (IsConstZero || 4992 (TestIsLessOp.getValue() ? 4993 (IsConstNeg || (IsUnsigned && Subtract)) : 4994 (IsConstPos || (IsUnsigned && !Subtract))))) { 4995 SemaRef.Diag(NewStep->getExprLoc(), 4996 diag::err_omp_loop_incr_not_compatible) 4997 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4998 SemaRef.Diag(ConditionLoc, 4999 diag::note_omp_loop_cond_requres_compatible_incr) 5000 << TestIsLessOp.getValue() << ConditionSrcRange; 5001 return true; 5002 } 5003 if (TestIsLessOp.getValue() == Subtract) { 5004 NewStep = 5005 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5006 .get(); 5007 Subtract = !Subtract; 5008 } 5009 } 5010 5011 Step = NewStep; 5012 SubtractStep = Subtract; 5013 return false; 5014 } 5015 5016 namespace { 5017 /// Checker for the non-rectangular loops. Checks if the initializer or 5018 /// condition expression references loop counter variable. 5019 class LoopCounterRefChecker final 5020 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5021 Sema &SemaRef; 5022 DSAStackTy &Stack; 5023 const ValueDecl *CurLCDecl = nullptr; 5024 const ValueDecl *DepDecl = nullptr; 5025 const ValueDecl *PrevDepDecl = nullptr; 5026 bool IsInitializer = true; 5027 unsigned BaseLoopId = 0; 5028 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5029 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5030 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5031 << (IsInitializer ? 0 : 1); 5032 return false; 5033 } 5034 const auto &&Data = Stack.isLoopControlVariable(VD); 5035 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5036 // The type of the loop iterator on which we depend may not have a random 5037 // access iterator type. 5038 if (Data.first && VD->getType()->isRecordType()) { 5039 SmallString<128> Name; 5040 llvm::raw_svector_ostream OS(Name); 5041 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5042 /*Qualified=*/true); 5043 SemaRef.Diag(E->getExprLoc(), 5044 diag::err_omp_wrong_dependency_iterator_type) 5045 << OS.str(); 5046 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5047 return false; 5048 } 5049 if (Data.first && 5050 (DepDecl || (PrevDepDecl && 5051 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5052 if (!DepDecl && PrevDepDecl) 5053 DepDecl = PrevDepDecl; 5054 SmallString<128> Name; 5055 llvm::raw_svector_ostream OS(Name); 5056 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5057 /*Qualified=*/true); 5058 SemaRef.Diag(E->getExprLoc(), 5059 diag::err_omp_invariant_or_linear_dependency) 5060 << OS.str(); 5061 return false; 5062 } 5063 if (Data.first) { 5064 DepDecl = VD; 5065 BaseLoopId = Data.first; 5066 } 5067 return Data.first; 5068 } 5069 5070 public: 5071 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5072 const ValueDecl *VD = E->getDecl(); 5073 if (isa<VarDecl>(VD)) 5074 return checkDecl(E, VD); 5075 return false; 5076 } 5077 bool VisitMemberExpr(const MemberExpr *E) { 5078 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5079 const ValueDecl *VD = E->getMemberDecl(); 5080 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5081 return checkDecl(E, VD); 5082 } 5083 return false; 5084 } 5085 bool VisitStmt(const Stmt *S) { 5086 bool Res = false; 5087 for (const Stmt *Child : S->children()) 5088 Res = (Child && Visit(Child)) || Res; 5089 return Res; 5090 } 5091 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5092 const ValueDecl *CurLCDecl, bool IsInitializer, 5093 const ValueDecl *PrevDepDecl = nullptr) 5094 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5095 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5096 unsigned getBaseLoopId() const { 5097 assert(CurLCDecl && "Expected loop dependency."); 5098 return BaseLoopId; 5099 } 5100 const ValueDecl *getDepDecl() const { 5101 assert(CurLCDecl && "Expected loop dependency."); 5102 return DepDecl; 5103 } 5104 }; 5105 } // namespace 5106 5107 Optional<unsigned> 5108 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5109 bool IsInitializer) { 5110 // Check for the non-rectangular loops. 5111 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5112 DepDecl); 5113 if (LoopStmtChecker.Visit(S)) { 5114 DepDecl = LoopStmtChecker.getDepDecl(); 5115 return LoopStmtChecker.getBaseLoopId(); 5116 } 5117 return llvm::None; 5118 } 5119 5120 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5121 // Check init-expr for canonical loop form and save loop counter 5122 // variable - #Var and its initialization value - #LB. 5123 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5124 // var = lb 5125 // integer-type var = lb 5126 // random-access-iterator-type var = lb 5127 // pointer-type var = lb 5128 // 5129 if (!S) { 5130 if (EmitDiags) { 5131 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5132 } 5133 return true; 5134 } 5135 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5136 if (!ExprTemp->cleanupsHaveSideEffects()) 5137 S = ExprTemp->getSubExpr(); 5138 5139 InitSrcRange = S->getSourceRange(); 5140 if (Expr *E = dyn_cast<Expr>(S)) 5141 S = E->IgnoreParens(); 5142 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5143 if (BO->getOpcode() == BO_Assign) { 5144 Expr *LHS = BO->getLHS()->IgnoreParens(); 5145 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5146 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5147 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5148 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5149 EmitDiags); 5150 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5151 } 5152 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5153 if (ME->isArrow() && 5154 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5155 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5156 EmitDiags); 5157 } 5158 } 5159 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5160 if (DS->isSingleDecl()) { 5161 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5162 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5163 // Accept non-canonical init form here but emit ext. warning. 5164 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5165 SemaRef.Diag(S->getBeginLoc(), 5166 diag::ext_omp_loop_not_canonical_init) 5167 << S->getSourceRange(); 5168 return setLCDeclAndLB( 5169 Var, 5170 buildDeclRefExpr(SemaRef, Var, 5171 Var->getType().getNonReferenceType(), 5172 DS->getBeginLoc()), 5173 Var->getInit(), EmitDiags); 5174 } 5175 } 5176 } 5177 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5178 if (CE->getOperator() == OO_Equal) { 5179 Expr *LHS = CE->getArg(0); 5180 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5181 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5182 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5183 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5184 EmitDiags); 5185 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5186 } 5187 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5188 if (ME->isArrow() && 5189 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5190 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5191 EmitDiags); 5192 } 5193 } 5194 } 5195 5196 if (dependent() || SemaRef.CurContext->isDependentContext()) 5197 return false; 5198 if (EmitDiags) { 5199 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5200 << S->getSourceRange(); 5201 } 5202 return true; 5203 } 5204 5205 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5206 /// variable (which may be the loop variable) if possible. 5207 static const ValueDecl *getInitLCDecl(const Expr *E) { 5208 if (!E) 5209 return nullptr; 5210 E = getExprAsWritten(E); 5211 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5212 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5213 if ((Ctor->isCopyOrMoveConstructor() || 5214 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5215 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5216 E = CE->getArg(0)->IgnoreParenImpCasts(); 5217 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5218 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5219 return getCanonicalDecl(VD); 5220 } 5221 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5222 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5223 return getCanonicalDecl(ME->getMemberDecl()); 5224 return nullptr; 5225 } 5226 5227 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5228 // Check test-expr for canonical form, save upper-bound UB, flags for 5229 // less/greater and for strict/non-strict comparison. 5230 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5231 // var relational-op b 5232 // b relational-op var 5233 // 5234 if (!S) { 5235 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 5236 return true; 5237 } 5238 Condition = S; 5239 S = getExprAsWritten(S); 5240 SourceLocation CondLoc = S->getBeginLoc(); 5241 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5242 if (BO->isRelationalOp()) { 5243 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5244 return setUB(BO->getRHS(), 5245 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5246 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5247 BO->getSourceRange(), BO->getOperatorLoc()); 5248 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5249 return setUB(BO->getLHS(), 5250 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5251 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5252 BO->getSourceRange(), BO->getOperatorLoc()); 5253 } else if (BO->getOpcode() == BO_NE) 5254 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 5255 BO->getRHS() : BO->getLHS(), 5256 /*LessOp=*/llvm::None, 5257 /*StrictOp=*/true, 5258 BO->getSourceRange(), BO->getOperatorLoc()); 5259 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5260 if (CE->getNumArgs() == 2) { 5261 auto Op = CE->getOperator(); 5262 switch (Op) { 5263 case OO_Greater: 5264 case OO_GreaterEqual: 5265 case OO_Less: 5266 case OO_LessEqual: 5267 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5268 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5269 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5270 CE->getOperatorLoc()); 5271 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5272 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5273 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5274 CE->getOperatorLoc()); 5275 break; 5276 case OO_ExclaimEqual: 5277 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 5278 CE->getArg(1) : CE->getArg(0), 5279 /*LessOp=*/llvm::None, 5280 /*StrictOp=*/true, 5281 CE->getSourceRange(), 5282 CE->getOperatorLoc()); 5283 break; 5284 default: 5285 break; 5286 } 5287 } 5288 } 5289 if (dependent() || SemaRef.CurContext->isDependentContext()) 5290 return false; 5291 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5292 << S->getSourceRange() << LCDecl; 5293 return true; 5294 } 5295 5296 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5297 // RHS of canonical loop form increment can be: 5298 // var + incr 5299 // incr + var 5300 // var - incr 5301 // 5302 RHS = RHS->IgnoreParenImpCasts(); 5303 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5304 if (BO->isAdditiveOp()) { 5305 bool IsAdd = BO->getOpcode() == BO_Add; 5306 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5307 return setStep(BO->getRHS(), !IsAdd); 5308 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5309 return setStep(BO->getLHS(), /*Subtract=*/false); 5310 } 5311 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5312 bool IsAdd = CE->getOperator() == OO_Plus; 5313 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5314 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5315 return setStep(CE->getArg(1), !IsAdd); 5316 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5317 return setStep(CE->getArg(0), /*Subtract=*/false); 5318 } 5319 } 5320 if (dependent() || SemaRef.CurContext->isDependentContext()) 5321 return false; 5322 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5323 << RHS->getSourceRange() << LCDecl; 5324 return true; 5325 } 5326 5327 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5328 // Check incr-expr for canonical loop form and return true if it 5329 // does not conform. 5330 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5331 // ++var 5332 // var++ 5333 // --var 5334 // var-- 5335 // var += incr 5336 // var -= incr 5337 // var = var + incr 5338 // var = incr + var 5339 // var = var - incr 5340 // 5341 if (!S) { 5342 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5343 return true; 5344 } 5345 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5346 if (!ExprTemp->cleanupsHaveSideEffects()) 5347 S = ExprTemp->getSubExpr(); 5348 5349 IncrementSrcRange = S->getSourceRange(); 5350 S = S->IgnoreParens(); 5351 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5352 if (UO->isIncrementDecrementOp() && 5353 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5354 return setStep(SemaRef 5355 .ActOnIntegerConstant(UO->getBeginLoc(), 5356 (UO->isDecrementOp() ? -1 : 1)) 5357 .get(), 5358 /*Subtract=*/false); 5359 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5360 switch (BO->getOpcode()) { 5361 case BO_AddAssign: 5362 case BO_SubAssign: 5363 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5364 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5365 break; 5366 case BO_Assign: 5367 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5368 return checkAndSetIncRHS(BO->getRHS()); 5369 break; 5370 default: 5371 break; 5372 } 5373 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5374 switch (CE->getOperator()) { 5375 case OO_PlusPlus: 5376 case OO_MinusMinus: 5377 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5378 return setStep(SemaRef 5379 .ActOnIntegerConstant( 5380 CE->getBeginLoc(), 5381 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5382 .get(), 5383 /*Subtract=*/false); 5384 break; 5385 case OO_PlusEqual: 5386 case OO_MinusEqual: 5387 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5388 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5389 break; 5390 case OO_Equal: 5391 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5392 return checkAndSetIncRHS(CE->getArg(1)); 5393 break; 5394 default: 5395 break; 5396 } 5397 } 5398 if (dependent() || SemaRef.CurContext->isDependentContext()) 5399 return false; 5400 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5401 << S->getSourceRange() << LCDecl; 5402 return true; 5403 } 5404 5405 static ExprResult 5406 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5407 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5408 if (SemaRef.CurContext->isDependentContext()) 5409 return ExprResult(Capture); 5410 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5411 return SemaRef.PerformImplicitConversion( 5412 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5413 /*AllowExplicit=*/true); 5414 auto I = Captures.find(Capture); 5415 if (I != Captures.end()) 5416 return buildCapture(SemaRef, Capture, I->second); 5417 DeclRefExpr *Ref = nullptr; 5418 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5419 Captures[Capture] = Ref; 5420 return Res; 5421 } 5422 5423 /// Build the expression to calculate the number of iterations. 5424 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5425 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5426 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5427 ExprResult Diff; 5428 QualType VarType = LCDecl->getType().getNonReferenceType(); 5429 if (VarType->isIntegerType() || VarType->isPointerType() || 5430 SemaRef.getLangOpts().CPlusPlus) { 5431 Expr *LBVal = LB; 5432 Expr *UBVal = UB; 5433 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5434 // max(LB(MinVal), LB(MaxVal)) 5435 if (InitDependOnLC) { 5436 const LoopIterationSpace &IS = 5437 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5438 InitDependOnLC.getValueOr( 5439 CondDependOnLC.getValueOr(0))]; 5440 if (!IS.MinValue || !IS.MaxValue) 5441 return nullptr; 5442 // OuterVar = Min 5443 ExprResult MinValue = 5444 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5445 if (!MinValue.isUsable()) 5446 return nullptr; 5447 5448 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5449 IS.CounterVar, MinValue.get()); 5450 if (!LBMinVal.isUsable()) 5451 return nullptr; 5452 // OuterVar = Min, LBVal 5453 LBMinVal = 5454 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5455 if (!LBMinVal.isUsable()) 5456 return nullptr; 5457 // (OuterVar = Min, LBVal) 5458 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5459 if (!LBMinVal.isUsable()) 5460 return nullptr; 5461 5462 // OuterVar = Max 5463 ExprResult MaxValue = 5464 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5465 if (!MaxValue.isUsable()) 5466 return nullptr; 5467 5468 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5469 IS.CounterVar, MaxValue.get()); 5470 if (!LBMaxVal.isUsable()) 5471 return nullptr; 5472 // OuterVar = Max, LBVal 5473 LBMaxVal = 5474 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5475 if (!LBMaxVal.isUsable()) 5476 return nullptr; 5477 // (OuterVar = Max, LBVal) 5478 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5479 if (!LBMaxVal.isUsable()) 5480 return nullptr; 5481 5482 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5483 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5484 if (!LBMin || !LBMax) 5485 return nullptr; 5486 // LB(MinVal) < LB(MaxVal) 5487 ExprResult MinLessMaxRes = 5488 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 5489 if (!MinLessMaxRes.isUsable()) 5490 return nullptr; 5491 Expr *MinLessMax = 5492 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 5493 if (!MinLessMax) 5494 return nullptr; 5495 if (TestIsLessOp.getValue()) { 5496 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 5497 // LB(MaxVal)) 5498 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5499 MinLessMax, LBMin, LBMax); 5500 if (!MinLB.isUsable()) 5501 return nullptr; 5502 LBVal = MinLB.get(); 5503 } else { 5504 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 5505 // LB(MaxVal)) 5506 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5507 MinLessMax, LBMax, LBMin); 5508 if (!MaxLB.isUsable()) 5509 return nullptr; 5510 LBVal = MaxLB.get(); 5511 } 5512 } 5513 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 5514 // min(UB(MinVal), UB(MaxVal)) 5515 if (CondDependOnLC) { 5516 const LoopIterationSpace &IS = 5517 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5518 InitDependOnLC.getValueOr( 5519 CondDependOnLC.getValueOr(0))]; 5520 if (!IS.MinValue || !IS.MaxValue) 5521 return nullptr; 5522 // OuterVar = Min 5523 ExprResult MinValue = 5524 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5525 if (!MinValue.isUsable()) 5526 return nullptr; 5527 5528 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5529 IS.CounterVar, MinValue.get()); 5530 if (!UBMinVal.isUsable()) 5531 return nullptr; 5532 // OuterVar = Min, UBVal 5533 UBMinVal = 5534 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 5535 if (!UBMinVal.isUsable()) 5536 return nullptr; 5537 // (OuterVar = Min, UBVal) 5538 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 5539 if (!UBMinVal.isUsable()) 5540 return nullptr; 5541 5542 // OuterVar = Max 5543 ExprResult MaxValue = 5544 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5545 if (!MaxValue.isUsable()) 5546 return nullptr; 5547 5548 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5549 IS.CounterVar, MaxValue.get()); 5550 if (!UBMaxVal.isUsable()) 5551 return nullptr; 5552 // OuterVar = Max, UBVal 5553 UBMaxVal = 5554 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 5555 if (!UBMaxVal.isUsable()) 5556 return nullptr; 5557 // (OuterVar = Max, UBVal) 5558 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 5559 if (!UBMaxVal.isUsable()) 5560 return nullptr; 5561 5562 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 5563 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 5564 if (!UBMin || !UBMax) 5565 return nullptr; 5566 // UB(MinVal) > UB(MaxVal) 5567 ExprResult MinGreaterMaxRes = 5568 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 5569 if (!MinGreaterMaxRes.isUsable()) 5570 return nullptr; 5571 Expr *MinGreaterMax = 5572 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 5573 if (!MinGreaterMax) 5574 return nullptr; 5575 if (TestIsLessOp.getValue()) { 5576 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 5577 // UB(MaxVal)) 5578 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 5579 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 5580 if (!MaxUB.isUsable()) 5581 return nullptr; 5582 UBVal = MaxUB.get(); 5583 } else { 5584 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 5585 // UB(MaxVal)) 5586 ExprResult MinUB = SemaRef.ActOnConditionalOp( 5587 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 5588 if (!MinUB.isUsable()) 5589 return nullptr; 5590 UBVal = MinUB.get(); 5591 } 5592 } 5593 // Upper - Lower 5594 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 5595 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 5596 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5597 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5598 if (!Upper || !Lower) 5599 return nullptr; 5600 5601 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5602 5603 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5604 // BuildBinOp already emitted error, this one is to point user to upper 5605 // and lower bound, and to tell what is passed to 'operator-'. 5606 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5607 << Upper->getSourceRange() << Lower->getSourceRange(); 5608 return nullptr; 5609 } 5610 } 5611 5612 if (!Diff.isUsable()) 5613 return nullptr; 5614 5615 // Upper - Lower [- 1] 5616 if (TestIsStrictOp) 5617 Diff = SemaRef.BuildBinOp( 5618 S, DefaultLoc, BO_Sub, Diff.get(), 5619 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5620 if (!Diff.isUsable()) 5621 return nullptr; 5622 5623 // Upper - Lower [- 1] + Step 5624 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5625 if (!NewStep.isUsable()) 5626 return nullptr; 5627 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5628 if (!Diff.isUsable()) 5629 return nullptr; 5630 5631 // Parentheses (for dumping/debugging purposes only). 5632 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5633 if (!Diff.isUsable()) 5634 return nullptr; 5635 5636 // (Upper - Lower [- 1] + Step) / Step 5637 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5638 if (!Diff.isUsable()) 5639 return nullptr; 5640 5641 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5642 QualType Type = Diff.get()->getType(); 5643 ASTContext &C = SemaRef.Context; 5644 bool UseVarType = VarType->hasIntegerRepresentation() && 5645 C.getTypeSize(Type) > C.getTypeSize(VarType); 5646 if (!Type->isIntegerType() || UseVarType) { 5647 unsigned NewSize = 5648 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5649 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5650 : Type->hasSignedIntegerRepresentation(); 5651 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5652 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5653 Diff = SemaRef.PerformImplicitConversion( 5654 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5655 if (!Diff.isUsable()) 5656 return nullptr; 5657 } 5658 } 5659 if (LimitedType) { 5660 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5661 if (NewSize != C.getTypeSize(Type)) { 5662 if (NewSize < C.getTypeSize(Type)) { 5663 assert(NewSize == 64 && "incorrect loop var size"); 5664 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5665 << InitSrcRange << ConditionSrcRange; 5666 } 5667 QualType NewType = C.getIntTypeForBitwidth( 5668 NewSize, Type->hasSignedIntegerRepresentation() || 5669 C.getTypeSize(Type) < NewSize); 5670 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5671 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5672 Sema::AA_Converting, true); 5673 if (!Diff.isUsable()) 5674 return nullptr; 5675 } 5676 } 5677 } 5678 5679 return Diff.get(); 5680 } 5681 5682 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 5683 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5684 // Do not build for iterators, they cannot be used in non-rectangular loop 5685 // nests. 5686 if (LCDecl->getType()->isRecordType()) 5687 return std::make_pair(nullptr, nullptr); 5688 // If we subtract, the min is in the condition, otherwise the min is in the 5689 // init value. 5690 Expr *MinExpr = nullptr; 5691 Expr *MaxExpr = nullptr; 5692 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5693 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5694 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 5695 : CondDependOnLC.hasValue(); 5696 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 5697 : InitDependOnLC.hasValue(); 5698 Expr *Lower = 5699 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5700 Expr *Upper = 5701 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5702 if (!Upper || !Lower) 5703 return std::make_pair(nullptr, nullptr); 5704 5705 if (TestIsLessOp.getValue()) 5706 MinExpr = Lower; 5707 else 5708 MaxExpr = Upper; 5709 5710 // Build minimum/maximum value based on number of iterations. 5711 ExprResult Diff; 5712 QualType VarType = LCDecl->getType().getNonReferenceType(); 5713 5714 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5715 if (!Diff.isUsable()) 5716 return std::make_pair(nullptr, nullptr); 5717 5718 // Upper - Lower [- 1] 5719 if (TestIsStrictOp) 5720 Diff = SemaRef.BuildBinOp( 5721 S, DefaultLoc, BO_Sub, Diff.get(), 5722 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5723 if (!Diff.isUsable()) 5724 return std::make_pair(nullptr, nullptr); 5725 5726 // Upper - Lower [- 1] + Step 5727 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5728 if (!NewStep.isUsable()) 5729 return std::make_pair(nullptr, nullptr); 5730 5731 // Parentheses (for dumping/debugging purposes only). 5732 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5733 if (!Diff.isUsable()) 5734 return std::make_pair(nullptr, nullptr); 5735 5736 // (Upper - Lower [- 1]) / Step 5737 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5738 if (!Diff.isUsable()) 5739 return std::make_pair(nullptr, nullptr); 5740 5741 // ((Upper - Lower [- 1]) / Step) * Step 5742 // Parentheses (for dumping/debugging purposes only). 5743 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5744 if (!Diff.isUsable()) 5745 return std::make_pair(nullptr, nullptr); 5746 5747 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 5748 if (!Diff.isUsable()) 5749 return std::make_pair(nullptr, nullptr); 5750 5751 // Convert to the original type or ptrdiff_t, if original type is pointer. 5752 if (!VarType->isAnyPointerType() && 5753 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 5754 Diff = SemaRef.PerformImplicitConversion( 5755 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 5756 } else if (VarType->isAnyPointerType() && 5757 !SemaRef.Context.hasSameType( 5758 Diff.get()->getType(), 5759 SemaRef.Context.getUnsignedPointerDiffType())) { 5760 Diff = SemaRef.PerformImplicitConversion( 5761 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 5762 Sema::AA_Converting, /*AllowExplicit=*/true); 5763 } 5764 if (!Diff.isUsable()) 5765 return std::make_pair(nullptr, nullptr); 5766 5767 // Parentheses (for dumping/debugging purposes only). 5768 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5769 if (!Diff.isUsable()) 5770 return std::make_pair(nullptr, nullptr); 5771 5772 if (TestIsLessOp.getValue()) { 5773 // MinExpr = Lower; 5774 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 5775 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 5776 if (!Diff.isUsable()) 5777 return std::make_pair(nullptr, nullptr); 5778 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5779 if (!Diff.isUsable()) 5780 return std::make_pair(nullptr, nullptr); 5781 MaxExpr = Diff.get(); 5782 } else { 5783 // MaxExpr = Upper; 5784 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 5785 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 5786 if (!Diff.isUsable()) 5787 return std::make_pair(nullptr, nullptr); 5788 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5789 if (!Diff.isUsable()) 5790 return std::make_pair(nullptr, nullptr); 5791 MinExpr = Diff.get(); 5792 } 5793 5794 return std::make_pair(MinExpr, MaxExpr); 5795 } 5796 5797 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 5798 if (InitDependOnLC || CondDependOnLC) 5799 return Condition; 5800 return nullptr; 5801 } 5802 5803 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5804 Scope *S, Expr *Cond, 5805 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5806 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5807 Sema::TentativeAnalysisScope Trap(SemaRef); 5808 5809 ExprResult NewLB = 5810 InitDependOnLC ? LB : tryBuildCapture(SemaRef, LB, Captures); 5811 ExprResult NewUB = 5812 CondDependOnLC ? UB : tryBuildCapture(SemaRef, UB, Captures); 5813 if (!NewLB.isUsable() || !NewUB.isUsable()) 5814 return nullptr; 5815 5816 ExprResult CondExpr = 5817 SemaRef.BuildBinOp(S, DefaultLoc, 5818 TestIsLessOp.getValue() ? 5819 (TestIsStrictOp ? BO_LT : BO_LE) : 5820 (TestIsStrictOp ? BO_GT : BO_GE), 5821 NewLB.get(), NewUB.get()); 5822 if (CondExpr.isUsable()) { 5823 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 5824 SemaRef.Context.BoolTy)) 5825 CondExpr = SemaRef.PerformImplicitConversion( 5826 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 5827 /*AllowExplicit=*/true); 5828 } 5829 5830 // Otherwise use original loop condition and evaluate it in runtime. 5831 return CondExpr.isUsable() ? CondExpr.get() : Cond; 5832 } 5833 5834 /// Build reference expression to the counter be used for codegen. 5835 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 5836 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5837 DSAStackTy &DSA) const { 5838 auto *VD = dyn_cast<VarDecl>(LCDecl); 5839 if (!VD) { 5840 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 5841 DeclRefExpr *Ref = buildDeclRefExpr( 5842 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 5843 const DSAStackTy::DSAVarData Data = 5844 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 5845 // If the loop control decl is explicitly marked as private, do not mark it 5846 // as captured again. 5847 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 5848 Captures.insert(std::make_pair(LCRef, Ref)); 5849 return Ref; 5850 } 5851 return cast<DeclRefExpr>(LCRef); 5852 } 5853 5854 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 5855 if (LCDecl && !LCDecl->isInvalidDecl()) { 5856 QualType Type = LCDecl->getType().getNonReferenceType(); 5857 VarDecl *PrivateVar = buildVarDecl( 5858 SemaRef, DefaultLoc, Type, LCDecl->getName(), 5859 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 5860 isa<VarDecl>(LCDecl) 5861 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 5862 : nullptr); 5863 if (PrivateVar->isInvalidDecl()) 5864 return nullptr; 5865 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 5866 } 5867 return nullptr; 5868 } 5869 5870 /// Build initialization of the counter to be used for codegen. 5871 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 5872 5873 /// Build step of the counter be used for codegen. 5874 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 5875 5876 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 5877 Scope *S, Expr *Counter, 5878 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 5879 Expr *Inc, OverloadedOperatorKind OOK) { 5880 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 5881 if (!Cnt) 5882 return nullptr; 5883 if (Inc) { 5884 assert((OOK == OO_Plus || OOK == OO_Minus) && 5885 "Expected only + or - operations for depend clauses."); 5886 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 5887 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 5888 if (!Cnt) 5889 return nullptr; 5890 } 5891 ExprResult Diff; 5892 QualType VarType = LCDecl->getType().getNonReferenceType(); 5893 if (VarType->isIntegerType() || VarType->isPointerType() || 5894 SemaRef.getLangOpts().CPlusPlus) { 5895 // Upper - Lower 5896 Expr *Upper = TestIsLessOp.getValue() 5897 ? Cnt 5898 : tryBuildCapture(SemaRef, UB, Captures).get(); 5899 Expr *Lower = TestIsLessOp.getValue() 5900 ? tryBuildCapture(SemaRef, LB, Captures).get() 5901 : Cnt; 5902 if (!Upper || !Lower) 5903 return nullptr; 5904 5905 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5906 5907 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5908 // BuildBinOp already emitted error, this one is to point user to upper 5909 // and lower bound, and to tell what is passed to 'operator-'. 5910 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5911 << Upper->getSourceRange() << Lower->getSourceRange(); 5912 return nullptr; 5913 } 5914 } 5915 5916 if (!Diff.isUsable()) 5917 return nullptr; 5918 5919 // Parentheses (for dumping/debugging purposes only). 5920 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5921 if (!Diff.isUsable()) 5922 return nullptr; 5923 5924 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5925 if (!NewStep.isUsable()) 5926 return nullptr; 5927 // (Upper - Lower) / Step 5928 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5929 if (!Diff.isUsable()) 5930 return nullptr; 5931 5932 return Diff.get(); 5933 } 5934 } // namespace 5935 5936 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5937 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5938 assert(Init && "Expected loop in canonical form."); 5939 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5940 if (AssociatedLoops > 0 && 5941 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5942 DSAStack->loopStart(); 5943 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 5944 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5945 if (ValueDecl *D = ISC.getLoopDecl()) { 5946 auto *VD = dyn_cast<VarDecl>(D); 5947 DeclRefExpr *PrivateRef = nullptr; 5948 if (!VD) { 5949 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5950 VD = Private; 5951 } else { 5952 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5953 /*WithInit=*/false); 5954 VD = cast<VarDecl>(PrivateRef->getDecl()); 5955 } 5956 } 5957 DSAStack->addLoopControlVariable(D, VD); 5958 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5959 if (LD != D->getCanonicalDecl()) { 5960 DSAStack->resetPossibleLoopCounter(); 5961 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5962 MarkDeclarationsReferencedInExpr( 5963 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5964 Var->getType().getNonLValueExprType(Context), 5965 ForLoc, /*RefersToCapture=*/true)); 5966 } 5967 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 5968 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 5969 // Referenced in a Construct, C/C++]. The loop iteration variable in the 5970 // associated for-loop of a simd construct with just one associated 5971 // for-loop may be listed in a linear clause with a constant-linear-step 5972 // that is the increment of the associated for-loop. The loop iteration 5973 // variable(s) in the associated for-loop(s) of a for or parallel for 5974 // construct may be listed in a private or lastprivate clause. 5975 DSAStackTy::DSAVarData DVar = 5976 DSAStack->getTopDSA(D, /*FromParent=*/false); 5977 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 5978 // is declared in the loop and it is predetermined as a private. 5979 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5980 OpenMPClauseKind PredeterminedCKind = 5981 isOpenMPSimdDirective(DKind) 5982 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 5983 : OMPC_private; 5984 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5985 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 5986 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 5987 DVar.CKind != OMPC_private))) || 5988 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5989 isOpenMPDistributeDirective(DKind)) && 5990 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5991 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5992 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 5993 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5994 << getOpenMPClauseName(DVar.CKind) 5995 << getOpenMPDirectiveName(DKind) 5996 << getOpenMPClauseName(PredeterminedCKind); 5997 if (DVar.RefExpr == nullptr) 5998 DVar.CKind = PredeterminedCKind; 5999 reportOriginalDsa(*this, DSAStack, D, DVar, 6000 /*IsLoopIterVar=*/true); 6001 } else if (LoopDeclRefExpr) { 6002 // Make the loop iteration variable private (for worksharing 6003 // constructs), linear (for simd directives with the only one 6004 // associated loop) or lastprivate (for simd directives with several 6005 // collapsed or ordered loops). 6006 if (DVar.CKind == OMPC_unknown) 6007 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6008 PrivateRef); 6009 } 6010 } 6011 } 6012 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6013 } 6014 } 6015 6016 /// Called on a for stmt to check and extract its iteration space 6017 /// for further processing (such as collapsing). 6018 static bool checkOpenMPIterationSpace( 6019 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6020 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6021 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6022 Expr *OrderedLoopCountExpr, 6023 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6024 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6025 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6026 // OpenMP [2.6, Canonical Loop Form] 6027 // for (init-expr; test-expr; incr-expr) structured-block 6028 auto *For = dyn_cast_or_null<ForStmt>(S); 6029 if (!For) { 6030 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6031 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6032 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6033 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6034 if (TotalNestedLoopCount > 1) { 6035 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6036 SemaRef.Diag(DSA.getConstructLoc(), 6037 diag::note_omp_collapse_ordered_expr) 6038 << 2 << CollapseLoopCountExpr->getSourceRange() 6039 << OrderedLoopCountExpr->getSourceRange(); 6040 else if (CollapseLoopCountExpr) 6041 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6042 diag::note_omp_collapse_ordered_expr) 6043 << 0 << CollapseLoopCountExpr->getSourceRange(); 6044 else 6045 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6046 diag::note_omp_collapse_ordered_expr) 6047 << 1 << OrderedLoopCountExpr->getSourceRange(); 6048 } 6049 return true; 6050 } 6051 assert(For->getBody()); 6052 6053 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 6054 6055 // Check init. 6056 Stmt *Init = For->getInit(); 6057 if (ISC.checkAndSetInit(Init)) 6058 return true; 6059 6060 bool HasErrors = false; 6061 6062 // Check loop variable's type. 6063 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6064 // OpenMP [2.6, Canonical Loop Form] 6065 // Var is one of the following: 6066 // A variable of signed or unsigned integer type. 6067 // For C++, a variable of a random access iterator type. 6068 // For C, a variable of a pointer type. 6069 QualType VarType = LCDecl->getType().getNonReferenceType(); 6070 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6071 !VarType->isPointerType() && 6072 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6073 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6074 << SemaRef.getLangOpts().CPlusPlus; 6075 HasErrors = true; 6076 } 6077 6078 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6079 // a Construct 6080 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6081 // parallel for construct is (are) private. 6082 // The loop iteration variable in the associated for-loop of a simd 6083 // construct with just one associated for-loop is linear with a 6084 // constant-linear-step that is the increment of the associated for-loop. 6085 // Exclude loop var from the list of variables with implicitly defined data 6086 // sharing attributes. 6087 VarsWithImplicitDSA.erase(LCDecl); 6088 6089 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6090 6091 // Check test-expr. 6092 HasErrors |= ISC.checkAndSetCond(For->getCond()); 6093 6094 // Check incr-expr. 6095 HasErrors |= ISC.checkAndSetInc(For->getInc()); 6096 } 6097 6098 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6099 return HasErrors; 6100 6101 // Build the loop's iteration space representation. 6102 ResultIterSpaces[CurrentNestedLoopCount].PreCond = 6103 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 6104 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6105 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6106 (isOpenMPWorksharingDirective(DKind) || 6107 isOpenMPTaskLoopDirective(DKind) || 6108 isOpenMPDistributeDirective(DKind)), 6109 Captures); 6110 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6111 ISC.buildCounterVar(Captures, DSA); 6112 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6113 ISC.buildPrivateCounterVar(); 6114 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6115 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6116 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6117 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6118 ISC.getConditionSrcRange(); 6119 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6120 ISC.getIncrementSrcRange(); 6121 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6122 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6123 ISC.isStrictTestOp(); 6124 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6125 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6126 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6127 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6128 ISC.buildFinalCondition(DSA.getCurScope()); 6129 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6130 ISC.doesInitDependOnLC(); 6131 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6132 ISC.doesCondDependOnLC(); 6133 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6134 ISC.getLoopDependentIdx(); 6135 6136 HasErrors |= 6137 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6138 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6139 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6140 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6141 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6142 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6143 if (!HasErrors && DSA.isOrderedRegion()) { 6144 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6145 if (CurrentNestedLoopCount < 6146 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6147 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6148 CurrentNestedLoopCount, 6149 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6150 DSA.getOrderedRegionParam().second->setLoopCounter( 6151 CurrentNestedLoopCount, 6152 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6153 } 6154 } 6155 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6156 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6157 // Erroneous case - clause has some problems. 6158 continue; 6159 } 6160 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6161 Pair.second.size() <= CurrentNestedLoopCount) { 6162 // Erroneous case - clause has some problems. 6163 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6164 continue; 6165 } 6166 Expr *CntValue; 6167 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6168 CntValue = ISC.buildOrderedLoopData( 6169 DSA.getCurScope(), 6170 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6171 Pair.first->getDependencyLoc()); 6172 else 6173 CntValue = ISC.buildOrderedLoopData( 6174 DSA.getCurScope(), 6175 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6176 Pair.first->getDependencyLoc(), 6177 Pair.second[CurrentNestedLoopCount].first, 6178 Pair.second[CurrentNestedLoopCount].second); 6179 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6180 } 6181 } 6182 6183 return HasErrors; 6184 } 6185 6186 /// Build 'VarRef = Start. 6187 static ExprResult 6188 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6189 ExprResult Start, bool IsNonRectangularLB, 6190 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6191 // Build 'VarRef = Start. 6192 ExprResult NewStart = IsNonRectangularLB 6193 ? Start.get() 6194 : tryBuildCapture(SemaRef, Start.get(), Captures); 6195 if (!NewStart.isUsable()) 6196 return ExprError(); 6197 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6198 VarRef.get()->getType())) { 6199 NewStart = SemaRef.PerformImplicitConversion( 6200 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6201 /*AllowExplicit=*/true); 6202 if (!NewStart.isUsable()) 6203 return ExprError(); 6204 } 6205 6206 ExprResult Init = 6207 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6208 return Init; 6209 } 6210 6211 /// Build 'VarRef = Start + Iter * Step'. 6212 static ExprResult buildCounterUpdate( 6213 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6214 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6215 bool IsNonRectangularLB, 6216 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6217 // Add parentheses (for debugging purposes only). 6218 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6219 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6220 !Step.isUsable()) 6221 return ExprError(); 6222 6223 ExprResult NewStep = Step; 6224 if (Captures) 6225 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6226 if (NewStep.isInvalid()) 6227 return ExprError(); 6228 ExprResult Update = 6229 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6230 if (!Update.isUsable()) 6231 return ExprError(); 6232 6233 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6234 // 'VarRef = Start (+|-) Iter * Step'. 6235 if (!Start.isUsable()) 6236 return ExprError(); 6237 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6238 if (!NewStart.isUsable()) 6239 return ExprError(); 6240 if (Captures && !IsNonRectangularLB) 6241 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6242 if (NewStart.isInvalid()) 6243 return ExprError(); 6244 6245 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6246 ExprResult SavedUpdate = Update; 6247 ExprResult UpdateVal; 6248 if (VarRef.get()->getType()->isOverloadableType() || 6249 NewStart.get()->getType()->isOverloadableType() || 6250 Update.get()->getType()->isOverloadableType()) { 6251 Sema::TentativeAnalysisScope Trap(SemaRef); 6252 6253 Update = 6254 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6255 if (Update.isUsable()) { 6256 UpdateVal = 6257 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6258 VarRef.get(), SavedUpdate.get()); 6259 if (UpdateVal.isUsable()) { 6260 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6261 UpdateVal.get()); 6262 } 6263 } 6264 } 6265 6266 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6267 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6268 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6269 NewStart.get(), SavedUpdate.get()); 6270 if (!Update.isUsable()) 6271 return ExprError(); 6272 6273 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6274 VarRef.get()->getType())) { 6275 Update = SemaRef.PerformImplicitConversion( 6276 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6277 if (!Update.isUsable()) 6278 return ExprError(); 6279 } 6280 6281 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6282 } 6283 return Update; 6284 } 6285 6286 /// Convert integer expression \a E to make it have at least \a Bits 6287 /// bits. 6288 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6289 if (E == nullptr) 6290 return ExprError(); 6291 ASTContext &C = SemaRef.Context; 6292 QualType OldType = E->getType(); 6293 unsigned HasBits = C.getTypeSize(OldType); 6294 if (HasBits >= Bits) 6295 return ExprResult(E); 6296 // OK to convert to signed, because new type has more bits than old. 6297 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6298 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6299 true); 6300 } 6301 6302 /// Check if the given expression \a E is a constant integer that fits 6303 /// into \a Bits bits. 6304 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6305 if (E == nullptr) 6306 return false; 6307 llvm::APSInt Result; 6308 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6309 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6310 return false; 6311 } 6312 6313 /// Build preinits statement for the given declarations. 6314 static Stmt *buildPreInits(ASTContext &Context, 6315 MutableArrayRef<Decl *> PreInits) { 6316 if (!PreInits.empty()) { 6317 return new (Context) DeclStmt( 6318 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6319 SourceLocation(), SourceLocation()); 6320 } 6321 return nullptr; 6322 } 6323 6324 /// Build preinits statement for the given declarations. 6325 static Stmt * 6326 buildPreInits(ASTContext &Context, 6327 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6328 if (!Captures.empty()) { 6329 SmallVector<Decl *, 16> PreInits; 6330 for (const auto &Pair : Captures) 6331 PreInits.push_back(Pair.second->getDecl()); 6332 return buildPreInits(Context, PreInits); 6333 } 6334 return nullptr; 6335 } 6336 6337 /// Build postupdate expression for the given list of postupdates expressions. 6338 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6339 Expr *PostUpdate = nullptr; 6340 if (!PostUpdates.empty()) { 6341 for (Expr *E : PostUpdates) { 6342 Expr *ConvE = S.BuildCStyleCastExpr( 6343 E->getExprLoc(), 6344 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6345 E->getExprLoc(), E) 6346 .get(); 6347 PostUpdate = PostUpdate 6348 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6349 PostUpdate, ConvE) 6350 .get() 6351 : ConvE; 6352 } 6353 } 6354 return PostUpdate; 6355 } 6356 6357 /// Called on a for stmt to check itself and nested loops (if any). 6358 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6359 /// number of collapsed loops otherwise. 6360 static unsigned 6361 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6362 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6363 DSAStackTy &DSA, 6364 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6365 OMPLoopDirective::HelperExprs &Built) { 6366 unsigned NestedLoopCount = 1; 6367 if (CollapseLoopCountExpr) { 6368 // Found 'collapse' clause - calculate collapse number. 6369 Expr::EvalResult Result; 6370 if (!CollapseLoopCountExpr->isValueDependent() && 6371 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6372 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6373 } else { 6374 Built.clear(/*Size=*/1); 6375 return 1; 6376 } 6377 } 6378 unsigned OrderedLoopCount = 1; 6379 if (OrderedLoopCountExpr) { 6380 // Found 'ordered' clause - calculate collapse number. 6381 Expr::EvalResult EVResult; 6382 if (!OrderedLoopCountExpr->isValueDependent() && 6383 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6384 SemaRef.getASTContext())) { 6385 llvm::APSInt Result = EVResult.Val.getInt(); 6386 if (Result.getLimitedValue() < NestedLoopCount) { 6387 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6388 diag::err_omp_wrong_ordered_loop_count) 6389 << OrderedLoopCountExpr->getSourceRange(); 6390 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6391 diag::note_collapse_loop_count) 6392 << CollapseLoopCountExpr->getSourceRange(); 6393 } 6394 OrderedLoopCount = Result.getLimitedValue(); 6395 } else { 6396 Built.clear(/*Size=*/1); 6397 return 1; 6398 } 6399 } 6400 // This is helper routine for loop directives (e.g., 'for', 'simd', 6401 // 'for simd', etc.). 6402 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6403 SmallVector<LoopIterationSpace, 4> IterSpaces( 6404 std::max(OrderedLoopCount, NestedLoopCount)); 6405 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6406 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6407 if (checkOpenMPIterationSpace( 6408 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6409 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6410 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6411 return 0; 6412 // Move on to the next nested for loop, or to the loop body. 6413 // OpenMP [2.8.1, simd construct, Restrictions] 6414 // All loops associated with the construct must be perfectly nested; that 6415 // is, there must be no intervening code nor any OpenMP directive between 6416 // any two loops. 6417 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6418 } 6419 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6420 if (checkOpenMPIterationSpace( 6421 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6422 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6423 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6424 return 0; 6425 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6426 // Handle initialization of captured loop iterator variables. 6427 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6428 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6429 Captures[DRE] = DRE; 6430 } 6431 } 6432 // Move on to the next nested for loop, or to the loop body. 6433 // OpenMP [2.8.1, simd construct, Restrictions] 6434 // All loops associated with the construct must be perfectly nested; that 6435 // is, there must be no intervening code nor any OpenMP directive between 6436 // any two loops. 6437 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6438 } 6439 6440 Built.clear(/* size */ NestedLoopCount); 6441 6442 if (SemaRef.CurContext->isDependentContext()) 6443 return NestedLoopCount; 6444 6445 // An example of what is generated for the following code: 6446 // 6447 // #pragma omp simd collapse(2) ordered(2) 6448 // for (i = 0; i < NI; ++i) 6449 // for (k = 0; k < NK; ++k) 6450 // for (j = J0; j < NJ; j+=2) { 6451 // <loop body> 6452 // } 6453 // 6454 // We generate the code below. 6455 // Note: the loop body may be outlined in CodeGen. 6456 // Note: some counters may be C++ classes, operator- is used to find number of 6457 // iterations and operator+= to calculate counter value. 6458 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6459 // or i64 is currently supported). 6460 // 6461 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6462 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6463 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6464 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6465 // // similar updates for vars in clauses (e.g. 'linear') 6466 // <loop body (using local i and j)> 6467 // } 6468 // i = NI; // assign final values of counters 6469 // j = NJ; 6470 // 6471 6472 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6473 // the iteration counts of the collapsed for loops. 6474 // Precondition tests if there is at least one iteration (all conditions are 6475 // true). 6476 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6477 Expr *N0 = IterSpaces[0].NumIterations; 6478 ExprResult LastIteration32 = 6479 widenIterationCount(/*Bits=*/32, 6480 SemaRef 6481 .PerformImplicitConversion( 6482 N0->IgnoreImpCasts(), N0->getType(), 6483 Sema::AA_Converting, /*AllowExplicit=*/true) 6484 .get(), 6485 SemaRef); 6486 ExprResult LastIteration64 = widenIterationCount( 6487 /*Bits=*/64, 6488 SemaRef 6489 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6490 Sema::AA_Converting, 6491 /*AllowExplicit=*/true) 6492 .get(), 6493 SemaRef); 6494 6495 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6496 return NestedLoopCount; 6497 6498 ASTContext &C = SemaRef.Context; 6499 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6500 6501 Scope *CurScope = DSA.getCurScope(); 6502 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6503 if (PreCond.isUsable()) { 6504 PreCond = 6505 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6506 PreCond.get(), IterSpaces[Cnt].PreCond); 6507 } 6508 Expr *N = IterSpaces[Cnt].NumIterations; 6509 SourceLocation Loc = N->getExprLoc(); 6510 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6511 if (LastIteration32.isUsable()) 6512 LastIteration32 = SemaRef.BuildBinOp( 6513 CurScope, Loc, BO_Mul, LastIteration32.get(), 6514 SemaRef 6515 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6516 Sema::AA_Converting, 6517 /*AllowExplicit=*/true) 6518 .get()); 6519 if (LastIteration64.isUsable()) 6520 LastIteration64 = SemaRef.BuildBinOp( 6521 CurScope, Loc, BO_Mul, LastIteration64.get(), 6522 SemaRef 6523 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6524 Sema::AA_Converting, 6525 /*AllowExplicit=*/true) 6526 .get()); 6527 } 6528 6529 // Choose either the 32-bit or 64-bit version. 6530 ExprResult LastIteration = LastIteration64; 6531 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6532 (LastIteration32.isUsable() && 6533 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6534 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6535 fitsInto( 6536 /*Bits=*/32, 6537 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6538 LastIteration64.get(), SemaRef)))) 6539 LastIteration = LastIteration32; 6540 QualType VType = LastIteration.get()->getType(); 6541 QualType RealVType = VType; 6542 QualType StrideVType = VType; 6543 if (isOpenMPTaskLoopDirective(DKind)) { 6544 VType = 6545 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6546 StrideVType = 6547 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6548 } 6549 6550 if (!LastIteration.isUsable()) 6551 return 0; 6552 6553 // Save the number of iterations. 6554 ExprResult NumIterations = LastIteration; 6555 { 6556 LastIteration = SemaRef.BuildBinOp( 6557 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6558 LastIteration.get(), 6559 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6560 if (!LastIteration.isUsable()) 6561 return 0; 6562 } 6563 6564 // Calculate the last iteration number beforehand instead of doing this on 6565 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6566 llvm::APSInt Result; 6567 bool IsConstant = 6568 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6569 ExprResult CalcLastIteration; 6570 if (!IsConstant) { 6571 ExprResult SaveRef = 6572 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6573 LastIteration = SaveRef; 6574 6575 // Prepare SaveRef + 1. 6576 NumIterations = SemaRef.BuildBinOp( 6577 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6578 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6579 if (!NumIterations.isUsable()) 6580 return 0; 6581 } 6582 6583 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6584 6585 // Build variables passed into runtime, necessary for worksharing directives. 6586 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6587 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6588 isOpenMPDistributeDirective(DKind)) { 6589 // Lower bound variable, initialized with zero. 6590 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6591 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6592 SemaRef.AddInitializerToDecl(LBDecl, 6593 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6594 /*DirectInit*/ false); 6595 6596 // Upper bound variable, initialized with last iteration number. 6597 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6598 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6599 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6600 /*DirectInit*/ false); 6601 6602 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6603 // This will be used to implement clause 'lastprivate'. 6604 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6605 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6606 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6607 SemaRef.AddInitializerToDecl(ILDecl, 6608 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6609 /*DirectInit*/ false); 6610 6611 // Stride variable returned by runtime (we initialize it to 1 by default). 6612 VarDecl *STDecl = 6613 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6614 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6615 SemaRef.AddInitializerToDecl(STDecl, 6616 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6617 /*DirectInit*/ false); 6618 6619 // Build expression: UB = min(UB, LastIteration) 6620 // It is necessary for CodeGen of directives with static scheduling. 6621 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6622 UB.get(), LastIteration.get()); 6623 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6624 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6625 LastIteration.get(), UB.get()); 6626 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6627 CondOp.get()); 6628 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6629 6630 // If we have a combined directive that combines 'distribute', 'for' or 6631 // 'simd' we need to be able to access the bounds of the schedule of the 6632 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6633 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6634 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6635 // Lower bound variable, initialized with zero. 6636 VarDecl *CombLBDecl = 6637 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6638 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6639 SemaRef.AddInitializerToDecl( 6640 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6641 /*DirectInit*/ false); 6642 6643 // Upper bound variable, initialized with last iteration number. 6644 VarDecl *CombUBDecl = 6645 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6646 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6647 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6648 /*DirectInit*/ false); 6649 6650 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6651 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6652 ExprResult CombCondOp = 6653 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6654 LastIteration.get(), CombUB.get()); 6655 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6656 CombCondOp.get()); 6657 CombEUB = 6658 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6659 6660 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6661 // We expect to have at least 2 more parameters than the 'parallel' 6662 // directive does - the lower and upper bounds of the previous schedule. 6663 assert(CD->getNumParams() >= 4 && 6664 "Unexpected number of parameters in loop combined directive"); 6665 6666 // Set the proper type for the bounds given what we learned from the 6667 // enclosed loops. 6668 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6669 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6670 6671 // Previous lower and upper bounds are obtained from the region 6672 // parameters. 6673 PrevLB = 6674 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6675 PrevUB = 6676 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6677 } 6678 } 6679 6680 // Build the iteration variable and its initialization before loop. 6681 ExprResult IV; 6682 ExprResult Init, CombInit; 6683 { 6684 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6685 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6686 Expr *RHS = 6687 (isOpenMPWorksharingDirective(DKind) || 6688 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6689 ? LB.get() 6690 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6691 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6692 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6693 6694 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6695 Expr *CombRHS = 6696 (isOpenMPWorksharingDirective(DKind) || 6697 isOpenMPTaskLoopDirective(DKind) || 6698 isOpenMPDistributeDirective(DKind)) 6699 ? CombLB.get() 6700 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6701 CombInit = 6702 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6703 CombInit = 6704 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6705 } 6706 } 6707 6708 bool UseStrictCompare = 6709 RealVType->hasUnsignedIntegerRepresentation() && 6710 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6711 return LIS.IsStrictCompare; 6712 }); 6713 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6714 // unsigned IV)) for worksharing loops. 6715 SourceLocation CondLoc = AStmt->getBeginLoc(); 6716 Expr *BoundUB = UB.get(); 6717 if (UseStrictCompare) { 6718 BoundUB = 6719 SemaRef 6720 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6721 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6722 .get(); 6723 BoundUB = 6724 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6725 } 6726 ExprResult Cond = 6727 (isOpenMPWorksharingDirective(DKind) || 6728 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6729 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6730 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6731 BoundUB) 6732 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6733 NumIterations.get()); 6734 ExprResult CombDistCond; 6735 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6736 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6737 NumIterations.get()); 6738 } 6739 6740 ExprResult CombCond; 6741 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6742 Expr *BoundCombUB = CombUB.get(); 6743 if (UseStrictCompare) { 6744 BoundCombUB = 6745 SemaRef 6746 .BuildBinOp( 6747 CurScope, CondLoc, BO_Add, BoundCombUB, 6748 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6749 .get(); 6750 BoundCombUB = 6751 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6752 .get(); 6753 } 6754 CombCond = 6755 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6756 IV.get(), BoundCombUB); 6757 } 6758 // Loop increment (IV = IV + 1) 6759 SourceLocation IncLoc = AStmt->getBeginLoc(); 6760 ExprResult Inc = 6761 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6762 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6763 if (!Inc.isUsable()) 6764 return 0; 6765 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6766 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6767 if (!Inc.isUsable()) 6768 return 0; 6769 6770 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6771 // Used for directives with static scheduling. 6772 // In combined construct, add combined version that use CombLB and CombUB 6773 // base variables for the update 6774 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6775 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6776 isOpenMPDistributeDirective(DKind)) { 6777 // LB + ST 6778 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6779 if (!NextLB.isUsable()) 6780 return 0; 6781 // LB = LB + ST 6782 NextLB = 6783 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6784 NextLB = 6785 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6786 if (!NextLB.isUsable()) 6787 return 0; 6788 // UB + ST 6789 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6790 if (!NextUB.isUsable()) 6791 return 0; 6792 // UB = UB + ST 6793 NextUB = 6794 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6795 NextUB = 6796 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6797 if (!NextUB.isUsable()) 6798 return 0; 6799 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6800 CombNextLB = 6801 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6802 if (!NextLB.isUsable()) 6803 return 0; 6804 // LB = LB + ST 6805 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6806 CombNextLB.get()); 6807 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6808 /*DiscardedValue*/ false); 6809 if (!CombNextLB.isUsable()) 6810 return 0; 6811 // UB + ST 6812 CombNextUB = 6813 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 6814 if (!CombNextUB.isUsable()) 6815 return 0; 6816 // UB = UB + ST 6817 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 6818 CombNextUB.get()); 6819 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 6820 /*DiscardedValue*/ false); 6821 if (!CombNextUB.isUsable()) 6822 return 0; 6823 } 6824 } 6825 6826 // Create increment expression for distribute loop when combined in a same 6827 // directive with for as IV = IV + ST; ensure upper bound expression based 6828 // on PrevUB instead of NumIterations - used to implement 'for' when found 6829 // in combination with 'distribute', like in 'distribute parallel for' 6830 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 6831 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 6832 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6833 DistCond = SemaRef.BuildBinOp( 6834 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 6835 assert(DistCond.isUsable() && "distribute cond expr was not built"); 6836 6837 DistInc = 6838 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 6839 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6840 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 6841 DistInc.get()); 6842 DistInc = 6843 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 6844 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6845 6846 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 6847 // construct 6848 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 6849 ExprResult IsUBGreater = 6850 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 6851 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6852 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 6853 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 6854 CondOp.get()); 6855 PrevEUB = 6856 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 6857 6858 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 6859 // parallel for is in combination with a distribute directive with 6860 // schedule(static, 1) 6861 Expr *BoundPrevUB = PrevUB.get(); 6862 if (UseStrictCompare) { 6863 BoundPrevUB = 6864 SemaRef 6865 .BuildBinOp( 6866 CurScope, CondLoc, BO_Add, BoundPrevUB, 6867 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6868 .get(); 6869 BoundPrevUB = 6870 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 6871 .get(); 6872 } 6873 ParForInDistCond = 6874 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6875 IV.get(), BoundPrevUB); 6876 } 6877 6878 // Build updates and final values of the loop counters. 6879 bool HasErrors = false; 6880 Built.Counters.resize(NestedLoopCount); 6881 Built.Inits.resize(NestedLoopCount); 6882 Built.Updates.resize(NestedLoopCount); 6883 Built.Finals.resize(NestedLoopCount); 6884 Built.DependentCounters.resize(NestedLoopCount); 6885 Built.DependentInits.resize(NestedLoopCount); 6886 Built.FinalsConditions.resize(NestedLoopCount); 6887 { 6888 // We implement the following algorithm for obtaining the 6889 // original loop iteration variable values based on the 6890 // value of the collapsed loop iteration variable IV. 6891 // 6892 // Let n+1 be the number of collapsed loops in the nest. 6893 // Iteration variables (I0, I1, .... In) 6894 // Iteration counts (N0, N1, ... Nn) 6895 // 6896 // Acc = IV; 6897 // 6898 // To compute Ik for loop k, 0 <= k <= n, generate: 6899 // Prod = N(k+1) * N(k+2) * ... * Nn; 6900 // Ik = Acc / Prod; 6901 // Acc -= Ik * Prod; 6902 // 6903 ExprResult Acc = IV; 6904 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6905 LoopIterationSpace &IS = IterSpaces[Cnt]; 6906 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 6907 ExprResult Iter; 6908 6909 // Compute prod 6910 ExprResult Prod = 6911 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6912 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 6913 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 6914 IterSpaces[K].NumIterations); 6915 6916 // Iter = Acc / Prod 6917 // If there is at least one more inner loop to avoid 6918 // multiplication by 1. 6919 if (Cnt + 1 < NestedLoopCount) 6920 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 6921 Acc.get(), Prod.get()); 6922 else 6923 Iter = Acc; 6924 if (!Iter.isUsable()) { 6925 HasErrors = true; 6926 break; 6927 } 6928 6929 // Update Acc: 6930 // Acc -= Iter * Prod 6931 // Check if there is at least one more inner loop to avoid 6932 // multiplication by 1. 6933 if (Cnt + 1 < NestedLoopCount) 6934 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 6935 Iter.get(), Prod.get()); 6936 else 6937 Prod = Iter; 6938 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 6939 Acc.get(), Prod.get()); 6940 6941 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 6942 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 6943 DeclRefExpr *CounterVar = buildDeclRefExpr( 6944 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 6945 /*RefersToCapture=*/true); 6946 ExprResult Init = 6947 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 6948 IS.CounterInit, IS.IsNonRectangularLB, Captures); 6949 if (!Init.isUsable()) { 6950 HasErrors = true; 6951 break; 6952 } 6953 ExprResult Update = buildCounterUpdate( 6954 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 6955 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 6956 if (!Update.isUsable()) { 6957 HasErrors = true; 6958 break; 6959 } 6960 6961 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6962 ExprResult Final = 6963 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 6964 IS.CounterInit, IS.NumIterations, IS.CounterStep, 6965 IS.Subtract, IS.IsNonRectangularLB, &Captures); 6966 if (!Final.isUsable()) { 6967 HasErrors = true; 6968 break; 6969 } 6970 6971 if (!Update.isUsable() || !Final.isUsable()) { 6972 HasErrors = true; 6973 break; 6974 } 6975 // Save results 6976 Built.Counters[Cnt] = IS.CounterVar; 6977 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6978 Built.Inits[Cnt] = Init.get(); 6979 Built.Updates[Cnt] = Update.get(); 6980 Built.Finals[Cnt] = Final.get(); 6981 Built.DependentCounters[Cnt] = nullptr; 6982 Built.DependentInits[Cnt] = nullptr; 6983 Built.FinalsConditions[Cnt] = nullptr; 6984 if (IS.IsNonRectangularLB) { 6985 Built.DependentCounters[Cnt] = 6986 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 6987 Built.DependentInits[Cnt] = 6988 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 6989 Built.FinalsConditions[Cnt] = IS.FinalCondition; 6990 } 6991 } 6992 } 6993 6994 if (HasErrors) 6995 return 0; 6996 6997 // Save results 6998 Built.IterationVarRef = IV.get(); 6999 Built.LastIteration = LastIteration.get(); 7000 Built.NumIterations = NumIterations.get(); 7001 Built.CalcLastIteration = SemaRef 7002 .ActOnFinishFullExpr(CalcLastIteration.get(), 7003 /*DiscardedValue=*/false) 7004 .get(); 7005 Built.PreCond = PreCond.get(); 7006 Built.PreInits = buildPreInits(C, Captures); 7007 Built.Cond = Cond.get(); 7008 Built.Init = Init.get(); 7009 Built.Inc = Inc.get(); 7010 Built.LB = LB.get(); 7011 Built.UB = UB.get(); 7012 Built.IL = IL.get(); 7013 Built.ST = ST.get(); 7014 Built.EUB = EUB.get(); 7015 Built.NLB = NextLB.get(); 7016 Built.NUB = NextUB.get(); 7017 Built.PrevLB = PrevLB.get(); 7018 Built.PrevUB = PrevUB.get(); 7019 Built.DistInc = DistInc.get(); 7020 Built.PrevEUB = PrevEUB.get(); 7021 Built.DistCombinedFields.LB = CombLB.get(); 7022 Built.DistCombinedFields.UB = CombUB.get(); 7023 Built.DistCombinedFields.EUB = CombEUB.get(); 7024 Built.DistCombinedFields.Init = CombInit.get(); 7025 Built.DistCombinedFields.Cond = CombCond.get(); 7026 Built.DistCombinedFields.NLB = CombNextLB.get(); 7027 Built.DistCombinedFields.NUB = CombNextUB.get(); 7028 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7029 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7030 7031 return NestedLoopCount; 7032 } 7033 7034 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7035 auto CollapseClauses = 7036 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7037 if (CollapseClauses.begin() != CollapseClauses.end()) 7038 return (*CollapseClauses.begin())->getNumForLoops(); 7039 return nullptr; 7040 } 7041 7042 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7043 auto OrderedClauses = 7044 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7045 if (OrderedClauses.begin() != OrderedClauses.end()) 7046 return (*OrderedClauses.begin())->getNumForLoops(); 7047 return nullptr; 7048 } 7049 7050 static bool checkSimdlenSafelenSpecified(Sema &S, 7051 const ArrayRef<OMPClause *> Clauses) { 7052 const OMPSafelenClause *Safelen = nullptr; 7053 const OMPSimdlenClause *Simdlen = nullptr; 7054 7055 for (const OMPClause *Clause : Clauses) { 7056 if (Clause->getClauseKind() == OMPC_safelen) 7057 Safelen = cast<OMPSafelenClause>(Clause); 7058 else if (Clause->getClauseKind() == OMPC_simdlen) 7059 Simdlen = cast<OMPSimdlenClause>(Clause); 7060 if (Safelen && Simdlen) 7061 break; 7062 } 7063 7064 if (Simdlen && Safelen) { 7065 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7066 const Expr *SafelenLength = Safelen->getSafelen(); 7067 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7068 SimdlenLength->isInstantiationDependent() || 7069 SimdlenLength->containsUnexpandedParameterPack()) 7070 return false; 7071 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7072 SafelenLength->isInstantiationDependent() || 7073 SafelenLength->containsUnexpandedParameterPack()) 7074 return false; 7075 Expr::EvalResult SimdlenResult, SafelenResult; 7076 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7077 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7078 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7079 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7080 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7081 // If both simdlen and safelen clauses are specified, the value of the 7082 // simdlen parameter must be less than or equal to the value of the safelen 7083 // parameter. 7084 if (SimdlenRes > SafelenRes) { 7085 S.Diag(SimdlenLength->getExprLoc(), 7086 diag::err_omp_wrong_simdlen_safelen_values) 7087 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7088 return true; 7089 } 7090 } 7091 return false; 7092 } 7093 7094 StmtResult 7095 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7096 SourceLocation StartLoc, SourceLocation EndLoc, 7097 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7098 if (!AStmt) 7099 return StmtError(); 7100 7101 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7102 OMPLoopDirective::HelperExprs B; 7103 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7104 // define the nested loops number. 7105 unsigned NestedLoopCount = checkOpenMPLoop( 7106 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7107 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7108 if (NestedLoopCount == 0) 7109 return StmtError(); 7110 7111 assert((CurContext->isDependentContext() || B.builtAll()) && 7112 "omp simd loop exprs were not built"); 7113 7114 if (!CurContext->isDependentContext()) { 7115 // Finalize the clauses that need pre-built expressions for CodeGen. 7116 for (OMPClause *C : Clauses) { 7117 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7118 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7119 B.NumIterations, *this, CurScope, 7120 DSAStack)) 7121 return StmtError(); 7122 } 7123 } 7124 7125 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7126 return StmtError(); 7127 7128 setFunctionHasBranchProtectedScope(); 7129 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7130 Clauses, AStmt, B); 7131 } 7132 7133 StmtResult 7134 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7135 SourceLocation StartLoc, SourceLocation EndLoc, 7136 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7137 if (!AStmt) 7138 return StmtError(); 7139 7140 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7141 OMPLoopDirective::HelperExprs B; 7142 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7143 // define the nested loops number. 7144 unsigned NestedLoopCount = checkOpenMPLoop( 7145 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7146 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7147 if (NestedLoopCount == 0) 7148 return StmtError(); 7149 7150 assert((CurContext->isDependentContext() || B.builtAll()) && 7151 "omp for loop exprs were not built"); 7152 7153 if (!CurContext->isDependentContext()) { 7154 // Finalize the clauses that need pre-built expressions for CodeGen. 7155 for (OMPClause *C : Clauses) { 7156 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7157 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7158 B.NumIterations, *this, CurScope, 7159 DSAStack)) 7160 return StmtError(); 7161 } 7162 } 7163 7164 setFunctionHasBranchProtectedScope(); 7165 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7166 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7167 } 7168 7169 StmtResult Sema::ActOnOpenMPForSimdDirective( 7170 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7171 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7172 if (!AStmt) 7173 return StmtError(); 7174 7175 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7176 OMPLoopDirective::HelperExprs B; 7177 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7178 // define the nested loops number. 7179 unsigned NestedLoopCount = 7180 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7181 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7182 VarsWithImplicitDSA, B); 7183 if (NestedLoopCount == 0) 7184 return StmtError(); 7185 7186 assert((CurContext->isDependentContext() || B.builtAll()) && 7187 "omp for simd loop exprs were not built"); 7188 7189 if (!CurContext->isDependentContext()) { 7190 // Finalize the clauses that need pre-built expressions for CodeGen. 7191 for (OMPClause *C : Clauses) { 7192 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7193 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7194 B.NumIterations, *this, CurScope, 7195 DSAStack)) 7196 return StmtError(); 7197 } 7198 } 7199 7200 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7201 return StmtError(); 7202 7203 setFunctionHasBranchProtectedScope(); 7204 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7205 Clauses, AStmt, B); 7206 } 7207 7208 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7209 Stmt *AStmt, 7210 SourceLocation StartLoc, 7211 SourceLocation EndLoc) { 7212 if (!AStmt) 7213 return StmtError(); 7214 7215 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7216 auto BaseStmt = AStmt; 7217 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7218 BaseStmt = CS->getCapturedStmt(); 7219 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7220 auto S = C->children(); 7221 if (S.begin() == S.end()) 7222 return StmtError(); 7223 // All associated statements must be '#pragma omp section' except for 7224 // the first one. 7225 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7226 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7227 if (SectionStmt) 7228 Diag(SectionStmt->getBeginLoc(), 7229 diag::err_omp_sections_substmt_not_section); 7230 return StmtError(); 7231 } 7232 cast<OMPSectionDirective>(SectionStmt) 7233 ->setHasCancel(DSAStack->isCancelRegion()); 7234 } 7235 } else { 7236 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7237 return StmtError(); 7238 } 7239 7240 setFunctionHasBranchProtectedScope(); 7241 7242 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7243 DSAStack->isCancelRegion()); 7244 } 7245 7246 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7247 SourceLocation StartLoc, 7248 SourceLocation EndLoc) { 7249 if (!AStmt) 7250 return StmtError(); 7251 7252 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7253 7254 setFunctionHasBranchProtectedScope(); 7255 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7256 7257 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7258 DSAStack->isCancelRegion()); 7259 } 7260 7261 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7262 Stmt *AStmt, 7263 SourceLocation StartLoc, 7264 SourceLocation EndLoc) { 7265 if (!AStmt) 7266 return StmtError(); 7267 7268 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7269 7270 setFunctionHasBranchProtectedScope(); 7271 7272 // OpenMP [2.7.3, single Construct, Restrictions] 7273 // The copyprivate clause must not be used with the nowait clause. 7274 const OMPClause *Nowait = nullptr; 7275 const OMPClause *Copyprivate = nullptr; 7276 for (const OMPClause *Clause : Clauses) { 7277 if (Clause->getClauseKind() == OMPC_nowait) 7278 Nowait = Clause; 7279 else if (Clause->getClauseKind() == OMPC_copyprivate) 7280 Copyprivate = Clause; 7281 if (Copyprivate && Nowait) { 7282 Diag(Copyprivate->getBeginLoc(), 7283 diag::err_omp_single_copyprivate_with_nowait); 7284 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7285 return StmtError(); 7286 } 7287 } 7288 7289 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7290 } 7291 7292 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7293 SourceLocation StartLoc, 7294 SourceLocation EndLoc) { 7295 if (!AStmt) 7296 return StmtError(); 7297 7298 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7299 7300 setFunctionHasBranchProtectedScope(); 7301 7302 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7303 } 7304 7305 StmtResult Sema::ActOnOpenMPCriticalDirective( 7306 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7307 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7308 if (!AStmt) 7309 return StmtError(); 7310 7311 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7312 7313 bool ErrorFound = false; 7314 llvm::APSInt Hint; 7315 SourceLocation HintLoc; 7316 bool DependentHint = false; 7317 for (const OMPClause *C : Clauses) { 7318 if (C->getClauseKind() == OMPC_hint) { 7319 if (!DirName.getName()) { 7320 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7321 ErrorFound = true; 7322 } 7323 Expr *E = cast<OMPHintClause>(C)->getHint(); 7324 if (E->isTypeDependent() || E->isValueDependent() || 7325 E->isInstantiationDependent()) { 7326 DependentHint = true; 7327 } else { 7328 Hint = E->EvaluateKnownConstInt(Context); 7329 HintLoc = C->getBeginLoc(); 7330 } 7331 } 7332 } 7333 if (ErrorFound) 7334 return StmtError(); 7335 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7336 if (Pair.first && DirName.getName() && !DependentHint) { 7337 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7338 Diag(StartLoc, diag::err_omp_critical_with_hint); 7339 if (HintLoc.isValid()) 7340 Diag(HintLoc, diag::note_omp_critical_hint_here) 7341 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7342 else 7343 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7344 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7345 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7346 << 1 7347 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7348 /*Radix=*/10, /*Signed=*/false); 7349 } else { 7350 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7351 } 7352 } 7353 } 7354 7355 setFunctionHasBranchProtectedScope(); 7356 7357 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7358 Clauses, AStmt); 7359 if (!Pair.first && DirName.getName() && !DependentHint) 7360 DSAStack->addCriticalWithHint(Dir, Hint); 7361 return Dir; 7362 } 7363 7364 StmtResult Sema::ActOnOpenMPParallelForDirective( 7365 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7366 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7367 if (!AStmt) 7368 return StmtError(); 7369 7370 auto *CS = cast<CapturedStmt>(AStmt); 7371 // 1.2.2 OpenMP Language Terminology 7372 // Structured block - An executable statement with a single entry at the 7373 // top and a single exit at the bottom. 7374 // The point of exit cannot be a branch out of the structured block. 7375 // longjmp() and throw() must not violate the entry/exit criteria. 7376 CS->getCapturedDecl()->setNothrow(); 7377 7378 OMPLoopDirective::HelperExprs B; 7379 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7380 // define the nested loops number. 7381 unsigned NestedLoopCount = 7382 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7383 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7384 VarsWithImplicitDSA, B); 7385 if (NestedLoopCount == 0) 7386 return StmtError(); 7387 7388 assert((CurContext->isDependentContext() || B.builtAll()) && 7389 "omp parallel for loop exprs were not built"); 7390 7391 if (!CurContext->isDependentContext()) { 7392 // Finalize the clauses that need pre-built expressions for CodeGen. 7393 for (OMPClause *C : Clauses) { 7394 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7395 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7396 B.NumIterations, *this, CurScope, 7397 DSAStack)) 7398 return StmtError(); 7399 } 7400 } 7401 7402 setFunctionHasBranchProtectedScope(); 7403 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7404 NestedLoopCount, Clauses, AStmt, B, 7405 DSAStack->isCancelRegion()); 7406 } 7407 7408 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7409 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7410 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7411 if (!AStmt) 7412 return StmtError(); 7413 7414 auto *CS = cast<CapturedStmt>(AStmt); 7415 // 1.2.2 OpenMP Language Terminology 7416 // Structured block - An executable statement with a single entry at the 7417 // top and a single exit at the bottom. 7418 // The point of exit cannot be a branch out of the structured block. 7419 // longjmp() and throw() must not violate the entry/exit criteria. 7420 CS->getCapturedDecl()->setNothrow(); 7421 7422 OMPLoopDirective::HelperExprs B; 7423 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7424 // define the nested loops number. 7425 unsigned NestedLoopCount = 7426 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7427 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7428 VarsWithImplicitDSA, B); 7429 if (NestedLoopCount == 0) 7430 return StmtError(); 7431 7432 if (!CurContext->isDependentContext()) { 7433 // Finalize the clauses that need pre-built expressions for CodeGen. 7434 for (OMPClause *C : Clauses) { 7435 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7436 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7437 B.NumIterations, *this, CurScope, 7438 DSAStack)) 7439 return StmtError(); 7440 } 7441 } 7442 7443 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7444 return StmtError(); 7445 7446 setFunctionHasBranchProtectedScope(); 7447 return OMPParallelForSimdDirective::Create( 7448 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7449 } 7450 7451 StmtResult 7452 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7453 Stmt *AStmt, SourceLocation StartLoc, 7454 SourceLocation EndLoc) { 7455 if (!AStmt) 7456 return StmtError(); 7457 7458 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7459 auto BaseStmt = AStmt; 7460 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7461 BaseStmt = CS->getCapturedStmt(); 7462 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7463 auto S = C->children(); 7464 if (S.begin() == S.end()) 7465 return StmtError(); 7466 // All associated statements must be '#pragma omp section' except for 7467 // the first one. 7468 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7469 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7470 if (SectionStmt) 7471 Diag(SectionStmt->getBeginLoc(), 7472 diag::err_omp_parallel_sections_substmt_not_section); 7473 return StmtError(); 7474 } 7475 cast<OMPSectionDirective>(SectionStmt) 7476 ->setHasCancel(DSAStack->isCancelRegion()); 7477 } 7478 } else { 7479 Diag(AStmt->getBeginLoc(), 7480 diag::err_omp_parallel_sections_not_compound_stmt); 7481 return StmtError(); 7482 } 7483 7484 setFunctionHasBranchProtectedScope(); 7485 7486 return OMPParallelSectionsDirective::Create( 7487 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7488 } 7489 7490 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7491 Stmt *AStmt, SourceLocation StartLoc, 7492 SourceLocation EndLoc) { 7493 if (!AStmt) 7494 return StmtError(); 7495 7496 auto *CS = cast<CapturedStmt>(AStmt); 7497 // 1.2.2 OpenMP Language Terminology 7498 // Structured block - An executable statement with a single entry at the 7499 // top and a single exit at the bottom. 7500 // The point of exit cannot be a branch out of the structured block. 7501 // longjmp() and throw() must not violate the entry/exit criteria. 7502 CS->getCapturedDecl()->setNothrow(); 7503 7504 setFunctionHasBranchProtectedScope(); 7505 7506 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7507 DSAStack->isCancelRegion()); 7508 } 7509 7510 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7511 SourceLocation EndLoc) { 7512 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7513 } 7514 7515 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7516 SourceLocation EndLoc) { 7517 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7518 } 7519 7520 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7521 SourceLocation EndLoc) { 7522 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7523 } 7524 7525 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7526 Stmt *AStmt, 7527 SourceLocation StartLoc, 7528 SourceLocation EndLoc) { 7529 if (!AStmt) 7530 return StmtError(); 7531 7532 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7533 7534 setFunctionHasBranchProtectedScope(); 7535 7536 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7537 AStmt, 7538 DSAStack->getTaskgroupReductionRef()); 7539 } 7540 7541 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7542 SourceLocation StartLoc, 7543 SourceLocation EndLoc) { 7544 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7545 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7546 } 7547 7548 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7549 Stmt *AStmt, 7550 SourceLocation StartLoc, 7551 SourceLocation EndLoc) { 7552 const OMPClause *DependFound = nullptr; 7553 const OMPClause *DependSourceClause = nullptr; 7554 const OMPClause *DependSinkClause = nullptr; 7555 bool ErrorFound = false; 7556 const OMPThreadsClause *TC = nullptr; 7557 const OMPSIMDClause *SC = nullptr; 7558 for (const OMPClause *C : Clauses) { 7559 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7560 DependFound = C; 7561 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7562 if (DependSourceClause) { 7563 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7564 << getOpenMPDirectiveName(OMPD_ordered) 7565 << getOpenMPClauseName(OMPC_depend) << 2; 7566 ErrorFound = true; 7567 } else { 7568 DependSourceClause = C; 7569 } 7570 if (DependSinkClause) { 7571 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7572 << 0; 7573 ErrorFound = true; 7574 } 7575 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7576 if (DependSourceClause) { 7577 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7578 << 1; 7579 ErrorFound = true; 7580 } 7581 DependSinkClause = C; 7582 } 7583 } else if (C->getClauseKind() == OMPC_threads) { 7584 TC = cast<OMPThreadsClause>(C); 7585 } else if (C->getClauseKind() == OMPC_simd) { 7586 SC = cast<OMPSIMDClause>(C); 7587 } 7588 } 7589 if (!ErrorFound && !SC && 7590 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7591 // OpenMP [2.8.1,simd Construct, Restrictions] 7592 // An ordered construct with the simd clause is the only OpenMP construct 7593 // that can appear in the simd region. 7594 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7595 ErrorFound = true; 7596 } else if (DependFound && (TC || SC)) { 7597 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7598 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7599 ErrorFound = true; 7600 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7601 Diag(DependFound->getBeginLoc(), 7602 diag::err_omp_ordered_directive_without_param); 7603 ErrorFound = true; 7604 } else if (TC || Clauses.empty()) { 7605 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7606 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7607 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7608 << (TC != nullptr); 7609 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7610 ErrorFound = true; 7611 } 7612 } 7613 if ((!AStmt && !DependFound) || ErrorFound) 7614 return StmtError(); 7615 7616 if (AStmt) { 7617 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7618 7619 setFunctionHasBranchProtectedScope(); 7620 } 7621 7622 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7623 } 7624 7625 namespace { 7626 /// Helper class for checking expression in 'omp atomic [update]' 7627 /// construct. 7628 class OpenMPAtomicUpdateChecker { 7629 /// Error results for atomic update expressions. 7630 enum ExprAnalysisErrorCode { 7631 /// A statement is not an expression statement. 7632 NotAnExpression, 7633 /// Expression is not builtin binary or unary operation. 7634 NotABinaryOrUnaryExpression, 7635 /// Unary operation is not post-/pre- increment/decrement operation. 7636 NotAnUnaryIncDecExpression, 7637 /// An expression is not of scalar type. 7638 NotAScalarType, 7639 /// A binary operation is not an assignment operation. 7640 NotAnAssignmentOp, 7641 /// RHS part of the binary operation is not a binary expression. 7642 NotABinaryExpression, 7643 /// RHS part is not additive/multiplicative/shift/biwise binary 7644 /// expression. 7645 NotABinaryOperator, 7646 /// RHS binary operation does not have reference to the updated LHS 7647 /// part. 7648 NotAnUpdateExpression, 7649 /// No errors is found. 7650 NoError 7651 }; 7652 /// Reference to Sema. 7653 Sema &SemaRef; 7654 /// A location for note diagnostics (when error is found). 7655 SourceLocation NoteLoc; 7656 /// 'x' lvalue part of the source atomic expression. 7657 Expr *X; 7658 /// 'expr' rvalue part of the source atomic expression. 7659 Expr *E; 7660 /// Helper expression of the form 7661 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7662 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7663 Expr *UpdateExpr; 7664 /// Is 'x' a LHS in a RHS part of full update expression. It is 7665 /// important for non-associative operations. 7666 bool IsXLHSInRHSPart; 7667 BinaryOperatorKind Op; 7668 SourceLocation OpLoc; 7669 /// true if the source expression is a postfix unary operation, false 7670 /// if it is a prefix unary operation. 7671 bool IsPostfixUpdate; 7672 7673 public: 7674 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7675 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7676 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7677 /// Check specified statement that it is suitable for 'atomic update' 7678 /// constructs and extract 'x', 'expr' and Operation from the original 7679 /// expression. If DiagId and NoteId == 0, then only check is performed 7680 /// without error notification. 7681 /// \param DiagId Diagnostic which should be emitted if error is found. 7682 /// \param NoteId Diagnostic note for the main error message. 7683 /// \return true if statement is not an update expression, false otherwise. 7684 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7685 /// Return the 'x' lvalue part of the source atomic expression. 7686 Expr *getX() const { return X; } 7687 /// Return the 'expr' rvalue part of the source atomic expression. 7688 Expr *getExpr() const { return E; } 7689 /// Return the update expression used in calculation of the updated 7690 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7691 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7692 Expr *getUpdateExpr() const { return UpdateExpr; } 7693 /// Return true if 'x' is LHS in RHS part of full update expression, 7694 /// false otherwise. 7695 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7696 7697 /// true if the source expression is a postfix unary operation, false 7698 /// if it is a prefix unary operation. 7699 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7700 7701 private: 7702 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7703 unsigned NoteId = 0); 7704 }; 7705 } // namespace 7706 7707 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7708 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7709 ExprAnalysisErrorCode ErrorFound = NoError; 7710 SourceLocation ErrorLoc, NoteLoc; 7711 SourceRange ErrorRange, NoteRange; 7712 // Allowed constructs are: 7713 // x = x binop expr; 7714 // x = expr binop x; 7715 if (AtomicBinOp->getOpcode() == BO_Assign) { 7716 X = AtomicBinOp->getLHS(); 7717 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7718 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7719 if (AtomicInnerBinOp->isMultiplicativeOp() || 7720 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7721 AtomicInnerBinOp->isBitwiseOp()) { 7722 Op = AtomicInnerBinOp->getOpcode(); 7723 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7724 Expr *LHS = AtomicInnerBinOp->getLHS(); 7725 Expr *RHS = AtomicInnerBinOp->getRHS(); 7726 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7727 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7728 /*Canonical=*/true); 7729 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7730 /*Canonical=*/true); 7731 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7732 /*Canonical=*/true); 7733 if (XId == LHSId) { 7734 E = RHS; 7735 IsXLHSInRHSPart = true; 7736 } else if (XId == RHSId) { 7737 E = LHS; 7738 IsXLHSInRHSPart = false; 7739 } else { 7740 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7741 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7742 NoteLoc = X->getExprLoc(); 7743 NoteRange = X->getSourceRange(); 7744 ErrorFound = NotAnUpdateExpression; 7745 } 7746 } else { 7747 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7748 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7749 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7750 NoteRange = SourceRange(NoteLoc, NoteLoc); 7751 ErrorFound = NotABinaryOperator; 7752 } 7753 } else { 7754 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7755 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7756 ErrorFound = NotABinaryExpression; 7757 } 7758 } else { 7759 ErrorLoc = AtomicBinOp->getExprLoc(); 7760 ErrorRange = AtomicBinOp->getSourceRange(); 7761 NoteLoc = AtomicBinOp->getOperatorLoc(); 7762 NoteRange = SourceRange(NoteLoc, NoteLoc); 7763 ErrorFound = NotAnAssignmentOp; 7764 } 7765 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7766 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7767 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7768 return true; 7769 } 7770 if (SemaRef.CurContext->isDependentContext()) 7771 E = X = UpdateExpr = nullptr; 7772 return ErrorFound != NoError; 7773 } 7774 7775 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7776 unsigned NoteId) { 7777 ExprAnalysisErrorCode ErrorFound = NoError; 7778 SourceLocation ErrorLoc, NoteLoc; 7779 SourceRange ErrorRange, NoteRange; 7780 // Allowed constructs are: 7781 // x++; 7782 // x--; 7783 // ++x; 7784 // --x; 7785 // x binop= expr; 7786 // x = x binop expr; 7787 // x = expr binop x; 7788 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7789 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7790 if (AtomicBody->getType()->isScalarType() || 7791 AtomicBody->isInstantiationDependent()) { 7792 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7793 AtomicBody->IgnoreParenImpCasts())) { 7794 // Check for Compound Assignment Operation 7795 Op = BinaryOperator::getOpForCompoundAssignment( 7796 AtomicCompAssignOp->getOpcode()); 7797 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7798 E = AtomicCompAssignOp->getRHS(); 7799 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7800 IsXLHSInRHSPart = true; 7801 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7802 AtomicBody->IgnoreParenImpCasts())) { 7803 // Check for Binary Operation 7804 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7805 return true; 7806 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7807 AtomicBody->IgnoreParenImpCasts())) { 7808 // Check for Unary Operation 7809 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7810 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7811 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7812 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7813 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 7814 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 7815 IsXLHSInRHSPart = true; 7816 } else { 7817 ErrorFound = NotAnUnaryIncDecExpression; 7818 ErrorLoc = AtomicUnaryOp->getExprLoc(); 7819 ErrorRange = AtomicUnaryOp->getSourceRange(); 7820 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 7821 NoteRange = SourceRange(NoteLoc, NoteLoc); 7822 } 7823 } else if (!AtomicBody->isInstantiationDependent()) { 7824 ErrorFound = NotABinaryOrUnaryExpression; 7825 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 7826 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 7827 } 7828 } else { 7829 ErrorFound = NotAScalarType; 7830 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 7831 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7832 } 7833 } else { 7834 ErrorFound = NotAnExpression; 7835 NoteLoc = ErrorLoc = S->getBeginLoc(); 7836 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7837 } 7838 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7839 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7840 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7841 return true; 7842 } 7843 if (SemaRef.CurContext->isDependentContext()) 7844 E = X = UpdateExpr = nullptr; 7845 if (ErrorFound == NoError && E && X) { 7846 // Build an update expression of form 'OpaqueValueExpr(x) binop 7847 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 7848 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 7849 auto *OVEX = new (SemaRef.getASTContext()) 7850 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 7851 auto *OVEExpr = new (SemaRef.getASTContext()) 7852 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 7853 ExprResult Update = 7854 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 7855 IsXLHSInRHSPart ? OVEExpr : OVEX); 7856 if (Update.isInvalid()) 7857 return true; 7858 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 7859 Sema::AA_Casting); 7860 if (Update.isInvalid()) 7861 return true; 7862 UpdateExpr = Update.get(); 7863 } 7864 return ErrorFound != NoError; 7865 } 7866 7867 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 7868 Stmt *AStmt, 7869 SourceLocation StartLoc, 7870 SourceLocation EndLoc) { 7871 if (!AStmt) 7872 return StmtError(); 7873 7874 auto *CS = cast<CapturedStmt>(AStmt); 7875 // 1.2.2 OpenMP Language Terminology 7876 // Structured block - An executable statement with a single entry at the 7877 // top and a single exit at the bottom. 7878 // The point of exit cannot be a branch out of the structured block. 7879 // longjmp() and throw() must not violate the entry/exit criteria. 7880 OpenMPClauseKind AtomicKind = OMPC_unknown; 7881 SourceLocation AtomicKindLoc; 7882 for (const OMPClause *C : Clauses) { 7883 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 7884 C->getClauseKind() == OMPC_update || 7885 C->getClauseKind() == OMPC_capture) { 7886 if (AtomicKind != OMPC_unknown) { 7887 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 7888 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 7889 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 7890 << getOpenMPClauseName(AtomicKind); 7891 } else { 7892 AtomicKind = C->getClauseKind(); 7893 AtomicKindLoc = C->getBeginLoc(); 7894 } 7895 } 7896 } 7897 7898 Stmt *Body = CS->getCapturedStmt(); 7899 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 7900 Body = EWC->getSubExpr(); 7901 7902 Expr *X = nullptr; 7903 Expr *V = nullptr; 7904 Expr *E = nullptr; 7905 Expr *UE = nullptr; 7906 bool IsXLHSInRHSPart = false; 7907 bool IsPostfixUpdate = false; 7908 // OpenMP [2.12.6, atomic Construct] 7909 // In the next expressions: 7910 // * x and v (as applicable) are both l-value expressions with scalar type. 7911 // * During the execution of an atomic region, multiple syntactic 7912 // occurrences of x must designate the same storage location. 7913 // * Neither of v and expr (as applicable) may access the storage location 7914 // designated by x. 7915 // * Neither of x and expr (as applicable) may access the storage location 7916 // designated by v. 7917 // * expr is an expression with scalar type. 7918 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 7919 // * binop, binop=, ++, and -- are not overloaded operators. 7920 // * The expression x binop expr must be numerically equivalent to x binop 7921 // (expr). This requirement is satisfied if the operators in expr have 7922 // precedence greater than binop, or by using parentheses around expr or 7923 // subexpressions of expr. 7924 // * The expression expr binop x must be numerically equivalent to (expr) 7925 // binop x. This requirement is satisfied if the operators in expr have 7926 // precedence equal to or greater than binop, or by using parentheses around 7927 // expr or subexpressions of expr. 7928 // * For forms that allow multiple occurrences of x, the number of times 7929 // that x is evaluated is unspecified. 7930 if (AtomicKind == OMPC_read) { 7931 enum { 7932 NotAnExpression, 7933 NotAnAssignmentOp, 7934 NotAScalarType, 7935 NotAnLValue, 7936 NoError 7937 } ErrorFound = NoError; 7938 SourceLocation ErrorLoc, NoteLoc; 7939 SourceRange ErrorRange, NoteRange; 7940 // If clause is read: 7941 // v = x; 7942 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7943 const auto *AtomicBinOp = 7944 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7945 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7946 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7947 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 7948 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7949 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 7950 if (!X->isLValue() || !V->isLValue()) { 7951 const Expr *NotLValueExpr = X->isLValue() ? V : X; 7952 ErrorFound = NotAnLValue; 7953 ErrorLoc = AtomicBinOp->getExprLoc(); 7954 ErrorRange = AtomicBinOp->getSourceRange(); 7955 NoteLoc = NotLValueExpr->getExprLoc(); 7956 NoteRange = NotLValueExpr->getSourceRange(); 7957 } 7958 } else if (!X->isInstantiationDependent() || 7959 !V->isInstantiationDependent()) { 7960 const Expr *NotScalarExpr = 7961 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7962 ? V 7963 : X; 7964 ErrorFound = NotAScalarType; 7965 ErrorLoc = AtomicBinOp->getExprLoc(); 7966 ErrorRange = AtomicBinOp->getSourceRange(); 7967 NoteLoc = NotScalarExpr->getExprLoc(); 7968 NoteRange = NotScalarExpr->getSourceRange(); 7969 } 7970 } else if (!AtomicBody->isInstantiationDependent()) { 7971 ErrorFound = NotAnAssignmentOp; 7972 ErrorLoc = AtomicBody->getExprLoc(); 7973 ErrorRange = AtomicBody->getSourceRange(); 7974 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7975 : AtomicBody->getExprLoc(); 7976 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7977 : AtomicBody->getSourceRange(); 7978 } 7979 } else { 7980 ErrorFound = NotAnExpression; 7981 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7982 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7983 } 7984 if (ErrorFound != NoError) { 7985 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7986 << ErrorRange; 7987 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7988 << NoteRange; 7989 return StmtError(); 7990 } 7991 if (CurContext->isDependentContext()) 7992 V = X = nullptr; 7993 } else if (AtomicKind == OMPC_write) { 7994 enum { 7995 NotAnExpression, 7996 NotAnAssignmentOp, 7997 NotAScalarType, 7998 NotAnLValue, 7999 NoError 8000 } ErrorFound = NoError; 8001 SourceLocation ErrorLoc, NoteLoc; 8002 SourceRange ErrorRange, NoteRange; 8003 // If clause is write: 8004 // x = expr; 8005 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8006 const auto *AtomicBinOp = 8007 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8008 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8009 X = AtomicBinOp->getLHS(); 8010 E = AtomicBinOp->getRHS(); 8011 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8012 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8013 if (!X->isLValue()) { 8014 ErrorFound = NotAnLValue; 8015 ErrorLoc = AtomicBinOp->getExprLoc(); 8016 ErrorRange = AtomicBinOp->getSourceRange(); 8017 NoteLoc = X->getExprLoc(); 8018 NoteRange = X->getSourceRange(); 8019 } 8020 } else if (!X->isInstantiationDependent() || 8021 !E->isInstantiationDependent()) { 8022 const Expr *NotScalarExpr = 8023 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8024 ? E 8025 : X; 8026 ErrorFound = NotAScalarType; 8027 ErrorLoc = AtomicBinOp->getExprLoc(); 8028 ErrorRange = AtomicBinOp->getSourceRange(); 8029 NoteLoc = NotScalarExpr->getExprLoc(); 8030 NoteRange = NotScalarExpr->getSourceRange(); 8031 } 8032 } else if (!AtomicBody->isInstantiationDependent()) { 8033 ErrorFound = NotAnAssignmentOp; 8034 ErrorLoc = AtomicBody->getExprLoc(); 8035 ErrorRange = AtomicBody->getSourceRange(); 8036 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8037 : AtomicBody->getExprLoc(); 8038 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8039 : AtomicBody->getSourceRange(); 8040 } 8041 } else { 8042 ErrorFound = NotAnExpression; 8043 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8044 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8045 } 8046 if (ErrorFound != NoError) { 8047 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8048 << ErrorRange; 8049 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8050 << NoteRange; 8051 return StmtError(); 8052 } 8053 if (CurContext->isDependentContext()) 8054 E = X = nullptr; 8055 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8056 // If clause is update: 8057 // x++; 8058 // x--; 8059 // ++x; 8060 // --x; 8061 // x binop= expr; 8062 // x = x binop expr; 8063 // x = expr binop x; 8064 OpenMPAtomicUpdateChecker Checker(*this); 8065 if (Checker.checkStatement( 8066 Body, (AtomicKind == OMPC_update) 8067 ? diag::err_omp_atomic_update_not_expression_statement 8068 : diag::err_omp_atomic_not_expression_statement, 8069 diag::note_omp_atomic_update)) 8070 return StmtError(); 8071 if (!CurContext->isDependentContext()) { 8072 E = Checker.getExpr(); 8073 X = Checker.getX(); 8074 UE = Checker.getUpdateExpr(); 8075 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8076 } 8077 } else if (AtomicKind == OMPC_capture) { 8078 enum { 8079 NotAnAssignmentOp, 8080 NotACompoundStatement, 8081 NotTwoSubstatements, 8082 NotASpecificExpression, 8083 NoError 8084 } ErrorFound = NoError; 8085 SourceLocation ErrorLoc, NoteLoc; 8086 SourceRange ErrorRange, NoteRange; 8087 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8088 // If clause is a capture: 8089 // v = x++; 8090 // v = x--; 8091 // v = ++x; 8092 // v = --x; 8093 // v = x binop= expr; 8094 // v = x = x binop expr; 8095 // v = x = expr binop x; 8096 const auto *AtomicBinOp = 8097 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8098 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8099 V = AtomicBinOp->getLHS(); 8100 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8101 OpenMPAtomicUpdateChecker Checker(*this); 8102 if (Checker.checkStatement( 8103 Body, diag::err_omp_atomic_capture_not_expression_statement, 8104 diag::note_omp_atomic_update)) 8105 return StmtError(); 8106 E = Checker.getExpr(); 8107 X = Checker.getX(); 8108 UE = Checker.getUpdateExpr(); 8109 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8110 IsPostfixUpdate = Checker.isPostfixUpdate(); 8111 } else if (!AtomicBody->isInstantiationDependent()) { 8112 ErrorLoc = AtomicBody->getExprLoc(); 8113 ErrorRange = AtomicBody->getSourceRange(); 8114 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8115 : AtomicBody->getExprLoc(); 8116 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8117 : AtomicBody->getSourceRange(); 8118 ErrorFound = NotAnAssignmentOp; 8119 } 8120 if (ErrorFound != NoError) { 8121 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8122 << ErrorRange; 8123 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8124 return StmtError(); 8125 } 8126 if (CurContext->isDependentContext()) 8127 UE = V = E = X = nullptr; 8128 } else { 8129 // If clause is a capture: 8130 // { v = x; x = expr; } 8131 // { v = x; x++; } 8132 // { v = x; x--; } 8133 // { v = x; ++x; } 8134 // { v = x; --x; } 8135 // { v = x; x binop= expr; } 8136 // { v = x; x = x binop expr; } 8137 // { v = x; x = expr binop x; } 8138 // { x++; v = x; } 8139 // { x--; v = x; } 8140 // { ++x; v = x; } 8141 // { --x; v = x; } 8142 // { x binop= expr; v = x; } 8143 // { x = x binop expr; v = x; } 8144 // { x = expr binop x; v = x; } 8145 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8146 // Check that this is { expr1; expr2; } 8147 if (CS->size() == 2) { 8148 Stmt *First = CS->body_front(); 8149 Stmt *Second = CS->body_back(); 8150 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8151 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8152 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8153 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8154 // Need to find what subexpression is 'v' and what is 'x'. 8155 OpenMPAtomicUpdateChecker Checker(*this); 8156 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8157 BinaryOperator *BinOp = nullptr; 8158 if (IsUpdateExprFound) { 8159 BinOp = dyn_cast<BinaryOperator>(First); 8160 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8161 } 8162 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8163 // { v = x; x++; } 8164 // { v = x; x--; } 8165 // { v = x; ++x; } 8166 // { v = x; --x; } 8167 // { v = x; x binop= expr; } 8168 // { v = x; x = x binop expr; } 8169 // { v = x; x = expr binop x; } 8170 // Check that the first expression has form v = x. 8171 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8172 llvm::FoldingSetNodeID XId, PossibleXId; 8173 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8174 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8175 IsUpdateExprFound = XId == PossibleXId; 8176 if (IsUpdateExprFound) { 8177 V = BinOp->getLHS(); 8178 X = Checker.getX(); 8179 E = Checker.getExpr(); 8180 UE = Checker.getUpdateExpr(); 8181 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8182 IsPostfixUpdate = true; 8183 } 8184 } 8185 if (!IsUpdateExprFound) { 8186 IsUpdateExprFound = !Checker.checkStatement(First); 8187 BinOp = nullptr; 8188 if (IsUpdateExprFound) { 8189 BinOp = dyn_cast<BinaryOperator>(Second); 8190 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8191 } 8192 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8193 // { x++; v = x; } 8194 // { x--; v = x; } 8195 // { ++x; v = x; } 8196 // { --x; v = x; } 8197 // { x binop= expr; v = x; } 8198 // { x = x binop expr; v = x; } 8199 // { x = expr binop x; v = x; } 8200 // Check that the second expression has form v = x. 8201 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8202 llvm::FoldingSetNodeID XId, PossibleXId; 8203 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8204 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8205 IsUpdateExprFound = XId == PossibleXId; 8206 if (IsUpdateExprFound) { 8207 V = BinOp->getLHS(); 8208 X = Checker.getX(); 8209 E = Checker.getExpr(); 8210 UE = Checker.getUpdateExpr(); 8211 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8212 IsPostfixUpdate = false; 8213 } 8214 } 8215 } 8216 if (!IsUpdateExprFound) { 8217 // { v = x; x = expr; } 8218 auto *FirstExpr = dyn_cast<Expr>(First); 8219 auto *SecondExpr = dyn_cast<Expr>(Second); 8220 if (!FirstExpr || !SecondExpr || 8221 !(FirstExpr->isInstantiationDependent() || 8222 SecondExpr->isInstantiationDependent())) { 8223 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8224 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8225 ErrorFound = NotAnAssignmentOp; 8226 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8227 : First->getBeginLoc(); 8228 NoteRange = ErrorRange = FirstBinOp 8229 ? FirstBinOp->getSourceRange() 8230 : SourceRange(ErrorLoc, ErrorLoc); 8231 } else { 8232 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8233 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8234 ErrorFound = NotAnAssignmentOp; 8235 NoteLoc = ErrorLoc = SecondBinOp 8236 ? SecondBinOp->getOperatorLoc() 8237 : Second->getBeginLoc(); 8238 NoteRange = ErrorRange = 8239 SecondBinOp ? SecondBinOp->getSourceRange() 8240 : SourceRange(ErrorLoc, ErrorLoc); 8241 } else { 8242 Expr *PossibleXRHSInFirst = 8243 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8244 Expr *PossibleXLHSInSecond = 8245 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8246 llvm::FoldingSetNodeID X1Id, X2Id; 8247 PossibleXRHSInFirst->Profile(X1Id, Context, 8248 /*Canonical=*/true); 8249 PossibleXLHSInSecond->Profile(X2Id, Context, 8250 /*Canonical=*/true); 8251 IsUpdateExprFound = X1Id == X2Id; 8252 if (IsUpdateExprFound) { 8253 V = FirstBinOp->getLHS(); 8254 X = SecondBinOp->getLHS(); 8255 E = SecondBinOp->getRHS(); 8256 UE = nullptr; 8257 IsXLHSInRHSPart = false; 8258 IsPostfixUpdate = true; 8259 } else { 8260 ErrorFound = NotASpecificExpression; 8261 ErrorLoc = FirstBinOp->getExprLoc(); 8262 ErrorRange = FirstBinOp->getSourceRange(); 8263 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8264 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8265 } 8266 } 8267 } 8268 } 8269 } 8270 } else { 8271 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8272 NoteRange = ErrorRange = 8273 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8274 ErrorFound = NotTwoSubstatements; 8275 } 8276 } else { 8277 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8278 NoteRange = ErrorRange = 8279 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8280 ErrorFound = NotACompoundStatement; 8281 } 8282 if (ErrorFound != NoError) { 8283 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8284 << ErrorRange; 8285 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8286 return StmtError(); 8287 } 8288 if (CurContext->isDependentContext()) 8289 UE = V = E = X = nullptr; 8290 } 8291 } 8292 8293 setFunctionHasBranchProtectedScope(); 8294 8295 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8296 X, V, E, UE, IsXLHSInRHSPart, 8297 IsPostfixUpdate); 8298 } 8299 8300 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8301 Stmt *AStmt, 8302 SourceLocation StartLoc, 8303 SourceLocation EndLoc) { 8304 if (!AStmt) 8305 return StmtError(); 8306 8307 auto *CS = cast<CapturedStmt>(AStmt); 8308 // 1.2.2 OpenMP Language Terminology 8309 // Structured block - An executable statement with a single entry at the 8310 // top and a single exit at the bottom. 8311 // The point of exit cannot be a branch out of the structured block. 8312 // longjmp() and throw() must not violate the entry/exit criteria. 8313 CS->getCapturedDecl()->setNothrow(); 8314 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8315 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8316 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8317 // 1.2.2 OpenMP Language Terminology 8318 // Structured block - An executable statement with a single entry at the 8319 // top and a single exit at the bottom. 8320 // The point of exit cannot be a branch out of the structured block. 8321 // longjmp() and throw() must not violate the entry/exit criteria. 8322 CS->getCapturedDecl()->setNothrow(); 8323 } 8324 8325 // OpenMP [2.16, Nesting of Regions] 8326 // If specified, a teams construct must be contained within a target 8327 // construct. That target construct must contain no statements or directives 8328 // outside of the teams construct. 8329 if (DSAStack->hasInnerTeamsRegion()) { 8330 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8331 bool OMPTeamsFound = true; 8332 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8333 auto I = CS->body_begin(); 8334 while (I != CS->body_end()) { 8335 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8336 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8337 OMPTeamsFound) { 8338 8339 OMPTeamsFound = false; 8340 break; 8341 } 8342 ++I; 8343 } 8344 assert(I != CS->body_end() && "Not found statement"); 8345 S = *I; 8346 } else { 8347 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8348 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8349 } 8350 if (!OMPTeamsFound) { 8351 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8352 Diag(DSAStack->getInnerTeamsRegionLoc(), 8353 diag::note_omp_nested_teams_construct_here); 8354 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8355 << isa<OMPExecutableDirective>(S); 8356 return StmtError(); 8357 } 8358 } 8359 8360 setFunctionHasBranchProtectedScope(); 8361 8362 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8363 } 8364 8365 StmtResult 8366 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8367 Stmt *AStmt, SourceLocation StartLoc, 8368 SourceLocation EndLoc) { 8369 if (!AStmt) 8370 return StmtError(); 8371 8372 auto *CS = cast<CapturedStmt>(AStmt); 8373 // 1.2.2 OpenMP Language Terminology 8374 // Structured block - An executable statement with a single entry at the 8375 // top and a single exit at the bottom. 8376 // The point of exit cannot be a branch out of the structured block. 8377 // longjmp() and throw() must not violate the entry/exit criteria. 8378 CS->getCapturedDecl()->setNothrow(); 8379 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8380 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8381 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8382 // 1.2.2 OpenMP Language Terminology 8383 // Structured block - An executable statement with a single entry at the 8384 // top and a single exit at the bottom. 8385 // The point of exit cannot be a branch out of the structured block. 8386 // longjmp() and throw() must not violate the entry/exit criteria. 8387 CS->getCapturedDecl()->setNothrow(); 8388 } 8389 8390 setFunctionHasBranchProtectedScope(); 8391 8392 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8393 AStmt); 8394 } 8395 8396 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8397 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8398 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8399 if (!AStmt) 8400 return StmtError(); 8401 8402 auto *CS = cast<CapturedStmt>(AStmt); 8403 // 1.2.2 OpenMP Language Terminology 8404 // Structured block - An executable statement with a single entry at the 8405 // top and a single exit at the bottom. 8406 // The point of exit cannot be a branch out of the structured block. 8407 // longjmp() and throw() must not violate the entry/exit criteria. 8408 CS->getCapturedDecl()->setNothrow(); 8409 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8410 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8411 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 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 8420 OMPLoopDirective::HelperExprs B; 8421 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8422 // define the nested loops number. 8423 unsigned NestedLoopCount = 8424 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8425 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8426 VarsWithImplicitDSA, B); 8427 if (NestedLoopCount == 0) 8428 return StmtError(); 8429 8430 assert((CurContext->isDependentContext() || B.builtAll()) && 8431 "omp target parallel for loop exprs were not built"); 8432 8433 if (!CurContext->isDependentContext()) { 8434 // Finalize the clauses that need pre-built expressions for CodeGen. 8435 for (OMPClause *C : Clauses) { 8436 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8437 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8438 B.NumIterations, *this, CurScope, 8439 DSAStack)) 8440 return StmtError(); 8441 } 8442 } 8443 8444 setFunctionHasBranchProtectedScope(); 8445 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8446 NestedLoopCount, Clauses, AStmt, 8447 B, DSAStack->isCancelRegion()); 8448 } 8449 8450 /// Check for existence of a map clause in the list of clauses. 8451 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8452 const OpenMPClauseKind K) { 8453 return llvm::any_of( 8454 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8455 } 8456 8457 template <typename... Params> 8458 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8459 const Params... ClauseTypes) { 8460 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8461 } 8462 8463 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8464 Stmt *AStmt, 8465 SourceLocation StartLoc, 8466 SourceLocation EndLoc) { 8467 if (!AStmt) 8468 return StmtError(); 8469 8470 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8471 8472 // OpenMP [2.10.1, Restrictions, p. 97] 8473 // At least one map clause must appear on the directive. 8474 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8475 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8476 << "'map' or 'use_device_ptr'" 8477 << getOpenMPDirectiveName(OMPD_target_data); 8478 return StmtError(); 8479 } 8480 8481 setFunctionHasBranchProtectedScope(); 8482 8483 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8484 AStmt); 8485 } 8486 8487 StmtResult 8488 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8489 SourceLocation StartLoc, 8490 SourceLocation EndLoc, Stmt *AStmt) { 8491 if (!AStmt) 8492 return StmtError(); 8493 8494 auto *CS = cast<CapturedStmt>(AStmt); 8495 // 1.2.2 OpenMP Language Terminology 8496 // Structured block - An executable statement with a single entry at the 8497 // top and a single exit at the bottom. 8498 // The point of exit cannot be a branch out of the structured block. 8499 // longjmp() and throw() must not violate the entry/exit criteria. 8500 CS->getCapturedDecl()->setNothrow(); 8501 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8502 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8503 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8504 // 1.2.2 OpenMP Language Terminology 8505 // Structured block - An executable statement with a single entry at the 8506 // top and a single exit at the bottom. 8507 // The point of exit cannot be a branch out of the structured block. 8508 // longjmp() and throw() must not violate the entry/exit criteria. 8509 CS->getCapturedDecl()->setNothrow(); 8510 } 8511 8512 // OpenMP [2.10.2, Restrictions, p. 99] 8513 // At least one map clause must appear on the directive. 8514 if (!hasClauses(Clauses, OMPC_map)) { 8515 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8516 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8517 return StmtError(); 8518 } 8519 8520 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8521 AStmt); 8522 } 8523 8524 StmtResult 8525 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8526 SourceLocation StartLoc, 8527 SourceLocation EndLoc, Stmt *AStmt) { 8528 if (!AStmt) 8529 return StmtError(); 8530 8531 auto *CS = cast<CapturedStmt>(AStmt); 8532 // 1.2.2 OpenMP Language Terminology 8533 // Structured block - An executable statement with a single entry at the 8534 // top and a single exit at the bottom. 8535 // The point of exit cannot be a branch out of the structured block. 8536 // longjmp() and throw() must not violate the entry/exit criteria. 8537 CS->getCapturedDecl()->setNothrow(); 8538 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8539 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8540 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8541 // 1.2.2 OpenMP Language Terminology 8542 // Structured block - An executable statement with a single entry at the 8543 // top and a single exit at the bottom. 8544 // The point of exit cannot be a branch out of the structured block. 8545 // longjmp() and throw() must not violate the entry/exit criteria. 8546 CS->getCapturedDecl()->setNothrow(); 8547 } 8548 8549 // OpenMP [2.10.3, Restrictions, p. 102] 8550 // At least one map clause must appear on the directive. 8551 if (!hasClauses(Clauses, OMPC_map)) { 8552 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8553 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8554 return StmtError(); 8555 } 8556 8557 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8558 AStmt); 8559 } 8560 8561 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8562 SourceLocation StartLoc, 8563 SourceLocation EndLoc, 8564 Stmt *AStmt) { 8565 if (!AStmt) 8566 return StmtError(); 8567 8568 auto *CS = cast<CapturedStmt>(AStmt); 8569 // 1.2.2 OpenMP Language Terminology 8570 // Structured block - An executable statement with a single entry at the 8571 // top and a single exit at the bottom. 8572 // The point of exit cannot be a branch out of the structured block. 8573 // longjmp() and throw() must not violate the entry/exit criteria. 8574 CS->getCapturedDecl()->setNothrow(); 8575 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8576 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8577 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8578 // 1.2.2 OpenMP Language Terminology 8579 // Structured block - An executable statement with a single entry at the 8580 // top and a single exit at the bottom. 8581 // The point of exit cannot be a branch out of the structured block. 8582 // longjmp() and throw() must not violate the entry/exit criteria. 8583 CS->getCapturedDecl()->setNothrow(); 8584 } 8585 8586 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8587 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8588 return StmtError(); 8589 } 8590 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8591 AStmt); 8592 } 8593 8594 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8595 Stmt *AStmt, SourceLocation StartLoc, 8596 SourceLocation EndLoc) { 8597 if (!AStmt) 8598 return StmtError(); 8599 8600 auto *CS = cast<CapturedStmt>(AStmt); 8601 // 1.2.2 OpenMP Language Terminology 8602 // Structured block - An executable statement with a single entry at the 8603 // top and a single exit at the bottom. 8604 // The point of exit cannot be a branch out of the structured block. 8605 // longjmp() and throw() must not violate the entry/exit criteria. 8606 CS->getCapturedDecl()->setNothrow(); 8607 8608 setFunctionHasBranchProtectedScope(); 8609 8610 DSAStack->setParentTeamsRegionLoc(StartLoc); 8611 8612 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8613 } 8614 8615 StmtResult 8616 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8617 SourceLocation EndLoc, 8618 OpenMPDirectiveKind CancelRegion) { 8619 if (DSAStack->isParentNowaitRegion()) { 8620 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8621 return StmtError(); 8622 } 8623 if (DSAStack->isParentOrderedRegion()) { 8624 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8625 return StmtError(); 8626 } 8627 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8628 CancelRegion); 8629 } 8630 8631 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8632 SourceLocation StartLoc, 8633 SourceLocation EndLoc, 8634 OpenMPDirectiveKind CancelRegion) { 8635 if (DSAStack->isParentNowaitRegion()) { 8636 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8637 return StmtError(); 8638 } 8639 if (DSAStack->isParentOrderedRegion()) { 8640 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8641 return StmtError(); 8642 } 8643 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8644 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8645 CancelRegion); 8646 } 8647 8648 static bool checkGrainsizeNumTasksClauses(Sema &S, 8649 ArrayRef<OMPClause *> Clauses) { 8650 const OMPClause *PrevClause = nullptr; 8651 bool ErrorFound = false; 8652 for (const OMPClause *C : Clauses) { 8653 if (C->getClauseKind() == OMPC_grainsize || 8654 C->getClauseKind() == OMPC_num_tasks) { 8655 if (!PrevClause) 8656 PrevClause = C; 8657 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8658 S.Diag(C->getBeginLoc(), 8659 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8660 << getOpenMPClauseName(C->getClauseKind()) 8661 << getOpenMPClauseName(PrevClause->getClauseKind()); 8662 S.Diag(PrevClause->getBeginLoc(), 8663 diag::note_omp_previous_grainsize_num_tasks) 8664 << getOpenMPClauseName(PrevClause->getClauseKind()); 8665 ErrorFound = true; 8666 } 8667 } 8668 } 8669 return ErrorFound; 8670 } 8671 8672 static bool checkReductionClauseWithNogroup(Sema &S, 8673 ArrayRef<OMPClause *> Clauses) { 8674 const OMPClause *ReductionClause = nullptr; 8675 const OMPClause *NogroupClause = nullptr; 8676 for (const OMPClause *C : Clauses) { 8677 if (C->getClauseKind() == OMPC_reduction) { 8678 ReductionClause = C; 8679 if (NogroupClause) 8680 break; 8681 continue; 8682 } 8683 if (C->getClauseKind() == OMPC_nogroup) { 8684 NogroupClause = C; 8685 if (ReductionClause) 8686 break; 8687 continue; 8688 } 8689 } 8690 if (ReductionClause && NogroupClause) { 8691 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8692 << SourceRange(NogroupClause->getBeginLoc(), 8693 NogroupClause->getEndLoc()); 8694 return true; 8695 } 8696 return false; 8697 } 8698 8699 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8700 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8701 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8702 if (!AStmt) 8703 return StmtError(); 8704 8705 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8706 OMPLoopDirective::HelperExprs B; 8707 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8708 // define the nested loops number. 8709 unsigned NestedLoopCount = 8710 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8711 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8712 VarsWithImplicitDSA, B); 8713 if (NestedLoopCount == 0) 8714 return StmtError(); 8715 8716 assert((CurContext->isDependentContext() || B.builtAll()) && 8717 "omp for loop exprs were not built"); 8718 8719 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8720 // The grainsize clause and num_tasks clause are mutually exclusive and may 8721 // not appear on the same taskloop directive. 8722 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8723 return StmtError(); 8724 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8725 // If a reduction clause is present on the taskloop directive, the nogroup 8726 // clause must not be specified. 8727 if (checkReductionClauseWithNogroup(*this, Clauses)) 8728 return StmtError(); 8729 8730 setFunctionHasBranchProtectedScope(); 8731 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8732 NestedLoopCount, Clauses, AStmt, B); 8733 } 8734 8735 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8736 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8737 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8738 if (!AStmt) 8739 return StmtError(); 8740 8741 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8742 OMPLoopDirective::HelperExprs B; 8743 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8744 // define the nested loops number. 8745 unsigned NestedLoopCount = 8746 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8747 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8748 VarsWithImplicitDSA, B); 8749 if (NestedLoopCount == 0) 8750 return StmtError(); 8751 8752 assert((CurContext->isDependentContext() || B.builtAll()) && 8753 "omp for loop exprs were not built"); 8754 8755 if (!CurContext->isDependentContext()) { 8756 // Finalize the clauses that need pre-built expressions for CodeGen. 8757 for (OMPClause *C : Clauses) { 8758 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8759 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8760 B.NumIterations, *this, CurScope, 8761 DSAStack)) 8762 return StmtError(); 8763 } 8764 } 8765 8766 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8767 // The grainsize clause and num_tasks clause are mutually exclusive and may 8768 // not appear on the same taskloop directive. 8769 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8770 return StmtError(); 8771 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8772 // If a reduction clause is present on the taskloop directive, the nogroup 8773 // clause must not be specified. 8774 if (checkReductionClauseWithNogroup(*this, Clauses)) 8775 return StmtError(); 8776 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8777 return StmtError(); 8778 8779 setFunctionHasBranchProtectedScope(); 8780 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8781 NestedLoopCount, Clauses, AStmt, B); 8782 } 8783 8784 StmtResult Sema::ActOnOpenMPDistributeDirective( 8785 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8786 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8787 if (!AStmt) 8788 return StmtError(); 8789 8790 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8791 OMPLoopDirective::HelperExprs B; 8792 // In presence of clause 'collapse' with number of loops, it will 8793 // define the nested loops number. 8794 unsigned NestedLoopCount = 8795 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8796 nullptr /*ordered not a clause on distribute*/, AStmt, 8797 *this, *DSAStack, VarsWithImplicitDSA, B); 8798 if (NestedLoopCount == 0) 8799 return StmtError(); 8800 8801 assert((CurContext->isDependentContext() || B.builtAll()) && 8802 "omp for loop exprs were not built"); 8803 8804 setFunctionHasBranchProtectedScope(); 8805 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8806 NestedLoopCount, Clauses, AStmt, B); 8807 } 8808 8809 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8810 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8811 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8812 if (!AStmt) 8813 return StmtError(); 8814 8815 auto *CS = cast<CapturedStmt>(AStmt); 8816 // 1.2.2 OpenMP Language Terminology 8817 // Structured block - An executable statement with a single entry at the 8818 // top and a single exit at the bottom. 8819 // The point of exit cannot be a branch out of the structured block. 8820 // longjmp() and throw() must not violate the entry/exit criteria. 8821 CS->getCapturedDecl()->setNothrow(); 8822 for (int ThisCaptureLevel = 8823 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 8824 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8825 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8826 // 1.2.2 OpenMP Language Terminology 8827 // Structured block - An executable statement with a single entry at the 8828 // top and a single exit at the bottom. 8829 // The point of exit cannot be a branch out of the structured block. 8830 // longjmp() and throw() must not violate the entry/exit criteria. 8831 CS->getCapturedDecl()->setNothrow(); 8832 } 8833 8834 OMPLoopDirective::HelperExprs B; 8835 // In presence of clause 'collapse' with number of loops, it will 8836 // define the nested loops number. 8837 unsigned NestedLoopCount = checkOpenMPLoop( 8838 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8839 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8840 VarsWithImplicitDSA, B); 8841 if (NestedLoopCount == 0) 8842 return StmtError(); 8843 8844 assert((CurContext->isDependentContext() || B.builtAll()) && 8845 "omp for loop exprs were not built"); 8846 8847 setFunctionHasBranchProtectedScope(); 8848 return OMPDistributeParallelForDirective::Create( 8849 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8850 DSAStack->isCancelRegion()); 8851 } 8852 8853 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 8854 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8855 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8856 if (!AStmt) 8857 return StmtError(); 8858 8859 auto *CS = cast<CapturedStmt>(AStmt); 8860 // 1.2.2 OpenMP Language Terminology 8861 // Structured block - An executable statement with a single entry at the 8862 // top and a single exit at the bottom. 8863 // The point of exit cannot be a branch out of the structured block. 8864 // longjmp() and throw() must not violate the entry/exit criteria. 8865 CS->getCapturedDecl()->setNothrow(); 8866 for (int ThisCaptureLevel = 8867 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 8868 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8869 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8870 // 1.2.2 OpenMP Language Terminology 8871 // Structured block - An executable statement with a single entry at the 8872 // top and a single exit at the bottom. 8873 // The point of exit cannot be a branch out of the structured block. 8874 // longjmp() and throw() must not violate the entry/exit criteria. 8875 CS->getCapturedDecl()->setNothrow(); 8876 } 8877 8878 OMPLoopDirective::HelperExprs B; 8879 // In presence of clause 'collapse' with number of loops, it will 8880 // define the nested loops number. 8881 unsigned NestedLoopCount = checkOpenMPLoop( 8882 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8883 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8884 VarsWithImplicitDSA, B); 8885 if (NestedLoopCount == 0) 8886 return StmtError(); 8887 8888 assert((CurContext->isDependentContext() || B.builtAll()) && 8889 "omp for loop exprs were not built"); 8890 8891 if (!CurContext->isDependentContext()) { 8892 // Finalize the clauses that need pre-built expressions for CodeGen. 8893 for (OMPClause *C : Clauses) { 8894 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8895 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8896 B.NumIterations, *this, CurScope, 8897 DSAStack)) 8898 return StmtError(); 8899 } 8900 } 8901 8902 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8903 return StmtError(); 8904 8905 setFunctionHasBranchProtectedScope(); 8906 return OMPDistributeParallelForSimdDirective::Create( 8907 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8908 } 8909 8910 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 8911 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8912 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8913 if (!AStmt) 8914 return StmtError(); 8915 8916 auto *CS = cast<CapturedStmt>(AStmt); 8917 // 1.2.2 OpenMP Language Terminology 8918 // Structured block - An executable statement with a single entry at the 8919 // top and a single exit at the bottom. 8920 // The point of exit cannot be a branch out of the structured block. 8921 // longjmp() and throw() must not violate the entry/exit criteria. 8922 CS->getCapturedDecl()->setNothrow(); 8923 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 8924 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8925 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8926 // 1.2.2 OpenMP Language Terminology 8927 // Structured block - An executable statement with a single entry at the 8928 // top and a single exit at the bottom. 8929 // The point of exit cannot be a branch out of the structured block. 8930 // longjmp() and throw() must not violate the entry/exit criteria. 8931 CS->getCapturedDecl()->setNothrow(); 8932 } 8933 8934 OMPLoopDirective::HelperExprs B; 8935 // In presence of clause 'collapse' with number of loops, it will 8936 // define the nested loops number. 8937 unsigned NestedLoopCount = 8938 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 8939 nullptr /*ordered not a clause on distribute*/, CS, *this, 8940 *DSAStack, VarsWithImplicitDSA, B); 8941 if (NestedLoopCount == 0) 8942 return StmtError(); 8943 8944 assert((CurContext->isDependentContext() || B.builtAll()) && 8945 "omp for loop exprs were not built"); 8946 8947 if (!CurContext->isDependentContext()) { 8948 // Finalize the clauses that need pre-built expressions for CodeGen. 8949 for (OMPClause *C : Clauses) { 8950 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8951 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8952 B.NumIterations, *this, CurScope, 8953 DSAStack)) 8954 return StmtError(); 8955 } 8956 } 8957 8958 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8959 return StmtError(); 8960 8961 setFunctionHasBranchProtectedScope(); 8962 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 8963 NestedLoopCount, Clauses, AStmt, B); 8964 } 8965 8966 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 8967 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8968 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8969 if (!AStmt) 8970 return StmtError(); 8971 8972 auto *CS = cast<CapturedStmt>(AStmt); 8973 // 1.2.2 OpenMP Language Terminology 8974 // Structured block - An executable statement with a single entry at the 8975 // top and a single exit at the bottom. 8976 // The point of exit cannot be a branch out of the structured block. 8977 // longjmp() and throw() must not violate the entry/exit criteria. 8978 CS->getCapturedDecl()->setNothrow(); 8979 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8980 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8981 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8982 // 1.2.2 OpenMP Language Terminology 8983 // Structured block - An executable statement with a single entry at the 8984 // top and a single exit at the bottom. 8985 // The point of exit cannot be a branch out of the structured block. 8986 // longjmp() and throw() must not violate the entry/exit criteria. 8987 CS->getCapturedDecl()->setNothrow(); 8988 } 8989 8990 OMPLoopDirective::HelperExprs B; 8991 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8992 // define the nested loops number. 8993 unsigned NestedLoopCount = checkOpenMPLoop( 8994 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8995 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8996 VarsWithImplicitDSA, B); 8997 if (NestedLoopCount == 0) 8998 return StmtError(); 8999 9000 assert((CurContext->isDependentContext() || B.builtAll()) && 9001 "omp target parallel for simd loop exprs were not built"); 9002 9003 if (!CurContext->isDependentContext()) { 9004 // Finalize the clauses that need pre-built expressions for CodeGen. 9005 for (OMPClause *C : Clauses) { 9006 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9007 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9008 B.NumIterations, *this, CurScope, 9009 DSAStack)) 9010 return StmtError(); 9011 } 9012 } 9013 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9014 return StmtError(); 9015 9016 setFunctionHasBranchProtectedScope(); 9017 return OMPTargetParallelForSimdDirective::Create( 9018 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9019 } 9020 9021 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9022 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9023 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9024 if (!AStmt) 9025 return StmtError(); 9026 9027 auto *CS = cast<CapturedStmt>(AStmt); 9028 // 1.2.2 OpenMP Language Terminology 9029 // Structured block - An executable statement with a single entry at the 9030 // top and a single exit at the bottom. 9031 // The point of exit cannot be a branch out of the structured block. 9032 // longjmp() and throw() must not violate the entry/exit criteria. 9033 CS->getCapturedDecl()->setNothrow(); 9034 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9035 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9036 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9037 // 1.2.2 OpenMP Language Terminology 9038 // Structured block - An executable statement with a single entry at the 9039 // top and a single exit at the bottom. 9040 // The point of exit cannot be a branch out of the structured block. 9041 // longjmp() and throw() must not violate the entry/exit criteria. 9042 CS->getCapturedDecl()->setNothrow(); 9043 } 9044 9045 OMPLoopDirective::HelperExprs B; 9046 // In presence of clause 'collapse' with number of loops, it will define the 9047 // nested loops number. 9048 unsigned NestedLoopCount = 9049 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9050 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9051 VarsWithImplicitDSA, B); 9052 if (NestedLoopCount == 0) 9053 return StmtError(); 9054 9055 assert((CurContext->isDependentContext() || B.builtAll()) && 9056 "omp target simd loop exprs were not built"); 9057 9058 if (!CurContext->isDependentContext()) { 9059 // Finalize the clauses that need pre-built expressions for CodeGen. 9060 for (OMPClause *C : Clauses) { 9061 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9062 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9063 B.NumIterations, *this, CurScope, 9064 DSAStack)) 9065 return StmtError(); 9066 } 9067 } 9068 9069 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9070 return StmtError(); 9071 9072 setFunctionHasBranchProtectedScope(); 9073 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9074 NestedLoopCount, Clauses, AStmt, B); 9075 } 9076 9077 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9078 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9079 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9080 if (!AStmt) 9081 return StmtError(); 9082 9083 auto *CS = cast<CapturedStmt>(AStmt); 9084 // 1.2.2 OpenMP Language Terminology 9085 // Structured block - An executable statement with a single entry at the 9086 // top and a single exit at the bottom. 9087 // The point of exit cannot be a branch out of the structured block. 9088 // longjmp() and throw() must not violate the entry/exit criteria. 9089 CS->getCapturedDecl()->setNothrow(); 9090 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9091 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9092 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9093 // 1.2.2 OpenMP Language Terminology 9094 // Structured block - An executable statement with a single entry at the 9095 // top and a single exit at the bottom. 9096 // The point of exit cannot be a branch out of the structured block. 9097 // longjmp() and throw() must not violate the entry/exit criteria. 9098 CS->getCapturedDecl()->setNothrow(); 9099 } 9100 9101 OMPLoopDirective::HelperExprs B; 9102 // In presence of clause 'collapse' with number of loops, it will 9103 // define the nested loops number. 9104 unsigned NestedLoopCount = 9105 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9106 nullptr /*ordered not a clause on distribute*/, CS, *this, 9107 *DSAStack, VarsWithImplicitDSA, B); 9108 if (NestedLoopCount == 0) 9109 return StmtError(); 9110 9111 assert((CurContext->isDependentContext() || B.builtAll()) && 9112 "omp teams distribute loop exprs were not built"); 9113 9114 setFunctionHasBranchProtectedScope(); 9115 9116 DSAStack->setParentTeamsRegionLoc(StartLoc); 9117 9118 return OMPTeamsDistributeDirective::Create( 9119 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9120 } 9121 9122 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9123 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9124 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9125 if (!AStmt) 9126 return StmtError(); 9127 9128 auto *CS = cast<CapturedStmt>(AStmt); 9129 // 1.2.2 OpenMP Language Terminology 9130 // Structured block - An executable statement with a single entry at the 9131 // top and a single exit at the bottom. 9132 // The point of exit cannot be a branch out of the structured block. 9133 // longjmp() and throw() must not violate the entry/exit criteria. 9134 CS->getCapturedDecl()->setNothrow(); 9135 for (int ThisCaptureLevel = 9136 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9137 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9138 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9139 // 1.2.2 OpenMP Language Terminology 9140 // Structured block - An executable statement with a single entry at the 9141 // top and a single exit at the bottom. 9142 // The point of exit cannot be a branch out of the structured block. 9143 // longjmp() and throw() must not violate the entry/exit criteria. 9144 CS->getCapturedDecl()->setNothrow(); 9145 } 9146 9147 9148 OMPLoopDirective::HelperExprs B; 9149 // In presence of clause 'collapse' with number of loops, it will 9150 // define the nested loops number. 9151 unsigned NestedLoopCount = checkOpenMPLoop( 9152 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9153 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9154 VarsWithImplicitDSA, B); 9155 9156 if (NestedLoopCount == 0) 9157 return StmtError(); 9158 9159 assert((CurContext->isDependentContext() || B.builtAll()) && 9160 "omp teams distribute simd loop exprs were not built"); 9161 9162 if (!CurContext->isDependentContext()) { 9163 // Finalize the clauses that need pre-built expressions for CodeGen. 9164 for (OMPClause *C : Clauses) { 9165 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9166 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9167 B.NumIterations, *this, CurScope, 9168 DSAStack)) 9169 return StmtError(); 9170 } 9171 } 9172 9173 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9174 return StmtError(); 9175 9176 setFunctionHasBranchProtectedScope(); 9177 9178 DSAStack->setParentTeamsRegionLoc(StartLoc); 9179 9180 return OMPTeamsDistributeSimdDirective::Create( 9181 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9182 } 9183 9184 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9185 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9186 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9187 if (!AStmt) 9188 return StmtError(); 9189 9190 auto *CS = cast<CapturedStmt>(AStmt); 9191 // 1.2.2 OpenMP Language Terminology 9192 // Structured block - An executable statement with a single entry at the 9193 // top and a single exit at the bottom. 9194 // The point of exit cannot be a branch out of the structured block. 9195 // longjmp() and throw() must not violate the entry/exit criteria. 9196 CS->getCapturedDecl()->setNothrow(); 9197 9198 for (int ThisCaptureLevel = 9199 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9200 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9201 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9202 // 1.2.2 OpenMP Language Terminology 9203 // Structured block - An executable statement with a single entry at the 9204 // top and a single exit at the bottom. 9205 // The point of exit cannot be a branch out of the structured block. 9206 // longjmp() and throw() must not violate the entry/exit criteria. 9207 CS->getCapturedDecl()->setNothrow(); 9208 } 9209 9210 OMPLoopDirective::HelperExprs B; 9211 // In presence of clause 'collapse' with number of loops, it will 9212 // define the nested loops number. 9213 unsigned NestedLoopCount = checkOpenMPLoop( 9214 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9215 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9216 VarsWithImplicitDSA, B); 9217 9218 if (NestedLoopCount == 0) 9219 return StmtError(); 9220 9221 assert((CurContext->isDependentContext() || B.builtAll()) && 9222 "omp for loop exprs were not built"); 9223 9224 if (!CurContext->isDependentContext()) { 9225 // Finalize the clauses that need pre-built expressions for CodeGen. 9226 for (OMPClause *C : Clauses) { 9227 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9228 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9229 B.NumIterations, *this, CurScope, 9230 DSAStack)) 9231 return StmtError(); 9232 } 9233 } 9234 9235 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9236 return StmtError(); 9237 9238 setFunctionHasBranchProtectedScope(); 9239 9240 DSAStack->setParentTeamsRegionLoc(StartLoc); 9241 9242 return OMPTeamsDistributeParallelForSimdDirective::Create( 9243 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9244 } 9245 9246 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9247 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9248 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9249 if (!AStmt) 9250 return StmtError(); 9251 9252 auto *CS = cast<CapturedStmt>(AStmt); 9253 // 1.2.2 OpenMP Language Terminology 9254 // Structured block - An executable statement with a single entry at the 9255 // top and a single exit at the bottom. 9256 // The point of exit cannot be a branch out of the structured block. 9257 // longjmp() and throw() must not violate the entry/exit criteria. 9258 CS->getCapturedDecl()->setNothrow(); 9259 9260 for (int ThisCaptureLevel = 9261 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9262 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9263 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9264 // 1.2.2 OpenMP Language Terminology 9265 // Structured block - An executable statement with a single entry at the 9266 // top and a single exit at the bottom. 9267 // The point of exit cannot be a branch out of the structured block. 9268 // longjmp() and throw() must not violate the entry/exit criteria. 9269 CS->getCapturedDecl()->setNothrow(); 9270 } 9271 9272 OMPLoopDirective::HelperExprs B; 9273 // In presence of clause 'collapse' with number of loops, it will 9274 // define the nested loops number. 9275 unsigned NestedLoopCount = checkOpenMPLoop( 9276 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9277 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9278 VarsWithImplicitDSA, B); 9279 9280 if (NestedLoopCount == 0) 9281 return StmtError(); 9282 9283 assert((CurContext->isDependentContext() || B.builtAll()) && 9284 "omp for loop exprs were not built"); 9285 9286 setFunctionHasBranchProtectedScope(); 9287 9288 DSAStack->setParentTeamsRegionLoc(StartLoc); 9289 9290 return OMPTeamsDistributeParallelForDirective::Create( 9291 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9292 DSAStack->isCancelRegion()); 9293 } 9294 9295 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9296 Stmt *AStmt, 9297 SourceLocation StartLoc, 9298 SourceLocation EndLoc) { 9299 if (!AStmt) 9300 return StmtError(); 9301 9302 auto *CS = cast<CapturedStmt>(AStmt); 9303 // 1.2.2 OpenMP Language Terminology 9304 // Structured block - An executable statement with a single entry at the 9305 // top and a single exit at the bottom. 9306 // The point of exit cannot be a branch out of the structured block. 9307 // longjmp() and throw() must not violate the entry/exit criteria. 9308 CS->getCapturedDecl()->setNothrow(); 9309 9310 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9311 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9312 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9313 // 1.2.2 OpenMP Language Terminology 9314 // Structured block - An executable statement with a single entry at the 9315 // top and a single exit at the bottom. 9316 // The point of exit cannot be a branch out of the structured block. 9317 // longjmp() and throw() must not violate the entry/exit criteria. 9318 CS->getCapturedDecl()->setNothrow(); 9319 } 9320 setFunctionHasBranchProtectedScope(); 9321 9322 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9323 AStmt); 9324 } 9325 9326 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9327 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9328 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9329 if (!AStmt) 9330 return StmtError(); 9331 9332 auto *CS = cast<CapturedStmt>(AStmt); 9333 // 1.2.2 OpenMP Language Terminology 9334 // Structured block - An executable statement with a single entry at the 9335 // top and a single exit at the bottom. 9336 // The point of exit cannot be a branch out of the structured block. 9337 // longjmp() and throw() must not violate the entry/exit criteria. 9338 CS->getCapturedDecl()->setNothrow(); 9339 for (int ThisCaptureLevel = 9340 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9341 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9342 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9343 // 1.2.2 OpenMP Language Terminology 9344 // Structured block - An executable statement with a single entry at the 9345 // top and a single exit at the bottom. 9346 // The point of exit cannot be a branch out of the structured block. 9347 // longjmp() and throw() must not violate the entry/exit criteria. 9348 CS->getCapturedDecl()->setNothrow(); 9349 } 9350 9351 OMPLoopDirective::HelperExprs B; 9352 // In presence of clause 'collapse' with number of loops, it will 9353 // define the nested loops number. 9354 unsigned NestedLoopCount = checkOpenMPLoop( 9355 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9356 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9357 VarsWithImplicitDSA, B); 9358 if (NestedLoopCount == 0) 9359 return StmtError(); 9360 9361 assert((CurContext->isDependentContext() || B.builtAll()) && 9362 "omp target teams distribute loop exprs were not built"); 9363 9364 setFunctionHasBranchProtectedScope(); 9365 return OMPTargetTeamsDistributeDirective::Create( 9366 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9367 } 9368 9369 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9370 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9371 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9372 if (!AStmt) 9373 return StmtError(); 9374 9375 auto *CS = cast<CapturedStmt>(AStmt); 9376 // 1.2.2 OpenMP Language Terminology 9377 // Structured block - An executable statement with a single entry at the 9378 // top and a single exit at the bottom. 9379 // The point of exit cannot be a branch out of the structured block. 9380 // longjmp() and throw() must not violate the entry/exit criteria. 9381 CS->getCapturedDecl()->setNothrow(); 9382 for (int ThisCaptureLevel = 9383 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9384 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9385 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9386 // 1.2.2 OpenMP Language Terminology 9387 // Structured block - An executable statement with a single entry at the 9388 // top and a single exit at the bottom. 9389 // The point of exit cannot be a branch out of the structured block. 9390 // longjmp() and throw() must not violate the entry/exit criteria. 9391 CS->getCapturedDecl()->setNothrow(); 9392 } 9393 9394 OMPLoopDirective::HelperExprs B; 9395 // In presence of clause 'collapse' with number of loops, it will 9396 // define the nested loops number. 9397 unsigned NestedLoopCount = checkOpenMPLoop( 9398 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9399 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9400 VarsWithImplicitDSA, B); 9401 if (NestedLoopCount == 0) 9402 return StmtError(); 9403 9404 assert((CurContext->isDependentContext() || B.builtAll()) && 9405 "omp target teams distribute parallel for loop exprs were not built"); 9406 9407 if (!CurContext->isDependentContext()) { 9408 // Finalize the clauses that need pre-built expressions for CodeGen. 9409 for (OMPClause *C : Clauses) { 9410 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9411 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9412 B.NumIterations, *this, CurScope, 9413 DSAStack)) 9414 return StmtError(); 9415 } 9416 } 9417 9418 setFunctionHasBranchProtectedScope(); 9419 return OMPTargetTeamsDistributeParallelForDirective::Create( 9420 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9421 DSAStack->isCancelRegion()); 9422 } 9423 9424 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9425 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9426 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9427 if (!AStmt) 9428 return StmtError(); 9429 9430 auto *CS = cast<CapturedStmt>(AStmt); 9431 // 1.2.2 OpenMP Language Terminology 9432 // Structured block - An executable statement with a single entry at the 9433 // top and a single exit at the bottom. 9434 // The point of exit cannot be a branch out of the structured block. 9435 // longjmp() and throw() must not violate the entry/exit criteria. 9436 CS->getCapturedDecl()->setNothrow(); 9437 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9438 OMPD_target_teams_distribute_parallel_for_simd); 9439 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9440 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9441 // 1.2.2 OpenMP Language Terminology 9442 // Structured block - An executable statement with a single entry at the 9443 // top and a single exit at the bottom. 9444 // The point of exit cannot be a branch out of the structured block. 9445 // longjmp() and throw() must not violate the entry/exit criteria. 9446 CS->getCapturedDecl()->setNothrow(); 9447 } 9448 9449 OMPLoopDirective::HelperExprs B; 9450 // In presence of clause 'collapse' with number of loops, it will 9451 // define the nested loops number. 9452 unsigned NestedLoopCount = 9453 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9454 getCollapseNumberExpr(Clauses), 9455 nullptr /*ordered not a clause on distribute*/, CS, *this, 9456 *DSAStack, VarsWithImplicitDSA, B); 9457 if (NestedLoopCount == 0) 9458 return StmtError(); 9459 9460 assert((CurContext->isDependentContext() || B.builtAll()) && 9461 "omp target teams distribute parallel for simd loop exprs were not " 9462 "built"); 9463 9464 if (!CurContext->isDependentContext()) { 9465 // Finalize the clauses that need pre-built expressions for CodeGen. 9466 for (OMPClause *C : Clauses) { 9467 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9468 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9469 B.NumIterations, *this, CurScope, 9470 DSAStack)) 9471 return StmtError(); 9472 } 9473 } 9474 9475 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9476 return StmtError(); 9477 9478 setFunctionHasBranchProtectedScope(); 9479 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9480 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9481 } 9482 9483 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9484 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9485 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9486 if (!AStmt) 9487 return StmtError(); 9488 9489 auto *CS = cast<CapturedStmt>(AStmt); 9490 // 1.2.2 OpenMP Language Terminology 9491 // Structured block - An executable statement with a single entry at the 9492 // top and a single exit at the bottom. 9493 // The point of exit cannot be a branch out of the structured block. 9494 // longjmp() and throw() must not violate the entry/exit criteria. 9495 CS->getCapturedDecl()->setNothrow(); 9496 for (int ThisCaptureLevel = 9497 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9498 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9499 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9500 // 1.2.2 OpenMP Language Terminology 9501 // Structured block - An executable statement with a single entry at the 9502 // top and a single exit at the bottom. 9503 // The point of exit cannot be a branch out of the structured block. 9504 // longjmp() and throw() must not violate the entry/exit criteria. 9505 CS->getCapturedDecl()->setNothrow(); 9506 } 9507 9508 OMPLoopDirective::HelperExprs B; 9509 // In presence of clause 'collapse' with number of loops, it will 9510 // define the nested loops number. 9511 unsigned NestedLoopCount = checkOpenMPLoop( 9512 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9513 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9514 VarsWithImplicitDSA, B); 9515 if (NestedLoopCount == 0) 9516 return StmtError(); 9517 9518 assert((CurContext->isDependentContext() || B.builtAll()) && 9519 "omp target teams distribute simd loop exprs were not built"); 9520 9521 if (!CurContext->isDependentContext()) { 9522 // Finalize the clauses that need pre-built expressions for CodeGen. 9523 for (OMPClause *C : Clauses) { 9524 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9525 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9526 B.NumIterations, *this, CurScope, 9527 DSAStack)) 9528 return StmtError(); 9529 } 9530 } 9531 9532 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9533 return StmtError(); 9534 9535 setFunctionHasBranchProtectedScope(); 9536 return OMPTargetTeamsDistributeSimdDirective::Create( 9537 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9538 } 9539 9540 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9541 SourceLocation StartLoc, 9542 SourceLocation LParenLoc, 9543 SourceLocation EndLoc) { 9544 OMPClause *Res = nullptr; 9545 switch (Kind) { 9546 case OMPC_final: 9547 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9548 break; 9549 case OMPC_num_threads: 9550 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9551 break; 9552 case OMPC_safelen: 9553 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9554 break; 9555 case OMPC_simdlen: 9556 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9557 break; 9558 case OMPC_allocator: 9559 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9560 break; 9561 case OMPC_collapse: 9562 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9563 break; 9564 case OMPC_ordered: 9565 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9566 break; 9567 case OMPC_device: 9568 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9569 break; 9570 case OMPC_num_teams: 9571 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9572 break; 9573 case OMPC_thread_limit: 9574 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9575 break; 9576 case OMPC_priority: 9577 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9578 break; 9579 case OMPC_grainsize: 9580 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9581 break; 9582 case OMPC_num_tasks: 9583 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9584 break; 9585 case OMPC_hint: 9586 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9587 break; 9588 case OMPC_if: 9589 case OMPC_default: 9590 case OMPC_proc_bind: 9591 case OMPC_schedule: 9592 case OMPC_private: 9593 case OMPC_firstprivate: 9594 case OMPC_lastprivate: 9595 case OMPC_shared: 9596 case OMPC_reduction: 9597 case OMPC_task_reduction: 9598 case OMPC_in_reduction: 9599 case OMPC_linear: 9600 case OMPC_aligned: 9601 case OMPC_copyin: 9602 case OMPC_copyprivate: 9603 case OMPC_nowait: 9604 case OMPC_untied: 9605 case OMPC_mergeable: 9606 case OMPC_threadprivate: 9607 case OMPC_allocate: 9608 case OMPC_flush: 9609 case OMPC_read: 9610 case OMPC_write: 9611 case OMPC_update: 9612 case OMPC_capture: 9613 case OMPC_seq_cst: 9614 case OMPC_depend: 9615 case OMPC_threads: 9616 case OMPC_simd: 9617 case OMPC_map: 9618 case OMPC_nogroup: 9619 case OMPC_dist_schedule: 9620 case OMPC_defaultmap: 9621 case OMPC_unknown: 9622 case OMPC_uniform: 9623 case OMPC_to: 9624 case OMPC_from: 9625 case OMPC_use_device_ptr: 9626 case OMPC_is_device_ptr: 9627 case OMPC_unified_address: 9628 case OMPC_unified_shared_memory: 9629 case OMPC_reverse_offload: 9630 case OMPC_dynamic_allocators: 9631 case OMPC_atomic_default_mem_order: 9632 llvm_unreachable("Clause is not allowed."); 9633 } 9634 return Res; 9635 } 9636 9637 // An OpenMP directive such as 'target parallel' has two captured regions: 9638 // for the 'target' and 'parallel' respectively. This function returns 9639 // the region in which to capture expressions associated with a clause. 9640 // A return value of OMPD_unknown signifies that the expression should not 9641 // be captured. 9642 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9643 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9644 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9645 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9646 switch (CKind) { 9647 case OMPC_if: 9648 switch (DKind) { 9649 case OMPD_target_parallel: 9650 case OMPD_target_parallel_for: 9651 case OMPD_target_parallel_for_simd: 9652 // If this clause applies to the nested 'parallel' region, capture within 9653 // the 'target' region, otherwise do not capture. 9654 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9655 CaptureRegion = OMPD_target; 9656 break; 9657 case OMPD_target_teams_distribute_parallel_for: 9658 case OMPD_target_teams_distribute_parallel_for_simd: 9659 // If this clause applies to the nested 'parallel' region, capture within 9660 // the 'teams' region, otherwise do not capture. 9661 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9662 CaptureRegion = OMPD_teams; 9663 break; 9664 case OMPD_teams_distribute_parallel_for: 9665 case OMPD_teams_distribute_parallel_for_simd: 9666 CaptureRegion = OMPD_teams; 9667 break; 9668 case OMPD_target_update: 9669 case OMPD_target_enter_data: 9670 case OMPD_target_exit_data: 9671 CaptureRegion = OMPD_task; 9672 break; 9673 case OMPD_cancel: 9674 case OMPD_parallel: 9675 case OMPD_parallel_sections: 9676 case OMPD_parallel_for: 9677 case OMPD_parallel_for_simd: 9678 case OMPD_target: 9679 case OMPD_target_simd: 9680 case OMPD_target_teams: 9681 case OMPD_target_teams_distribute: 9682 case OMPD_target_teams_distribute_simd: 9683 case OMPD_distribute_parallel_for: 9684 case OMPD_distribute_parallel_for_simd: 9685 case OMPD_task: 9686 case OMPD_taskloop: 9687 case OMPD_taskloop_simd: 9688 case OMPD_target_data: 9689 // Do not capture if-clause expressions. 9690 break; 9691 case OMPD_threadprivate: 9692 case OMPD_allocate: 9693 case OMPD_taskyield: 9694 case OMPD_barrier: 9695 case OMPD_taskwait: 9696 case OMPD_cancellation_point: 9697 case OMPD_flush: 9698 case OMPD_declare_reduction: 9699 case OMPD_declare_mapper: 9700 case OMPD_declare_simd: 9701 case OMPD_declare_target: 9702 case OMPD_end_declare_target: 9703 case OMPD_teams: 9704 case OMPD_simd: 9705 case OMPD_for: 9706 case OMPD_for_simd: 9707 case OMPD_sections: 9708 case OMPD_section: 9709 case OMPD_single: 9710 case OMPD_master: 9711 case OMPD_critical: 9712 case OMPD_taskgroup: 9713 case OMPD_distribute: 9714 case OMPD_ordered: 9715 case OMPD_atomic: 9716 case OMPD_distribute_simd: 9717 case OMPD_teams_distribute: 9718 case OMPD_teams_distribute_simd: 9719 case OMPD_requires: 9720 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9721 case OMPD_unknown: 9722 llvm_unreachable("Unknown OpenMP directive"); 9723 } 9724 break; 9725 case OMPC_num_threads: 9726 switch (DKind) { 9727 case OMPD_target_parallel: 9728 case OMPD_target_parallel_for: 9729 case OMPD_target_parallel_for_simd: 9730 CaptureRegion = OMPD_target; 9731 break; 9732 case OMPD_teams_distribute_parallel_for: 9733 case OMPD_teams_distribute_parallel_for_simd: 9734 case OMPD_target_teams_distribute_parallel_for: 9735 case OMPD_target_teams_distribute_parallel_for_simd: 9736 CaptureRegion = OMPD_teams; 9737 break; 9738 case OMPD_parallel: 9739 case OMPD_parallel_sections: 9740 case OMPD_parallel_for: 9741 case OMPD_parallel_for_simd: 9742 case OMPD_distribute_parallel_for: 9743 case OMPD_distribute_parallel_for_simd: 9744 // Do not capture num_threads-clause expressions. 9745 break; 9746 case OMPD_target_data: 9747 case OMPD_target_enter_data: 9748 case OMPD_target_exit_data: 9749 case OMPD_target_update: 9750 case OMPD_target: 9751 case OMPD_target_simd: 9752 case OMPD_target_teams: 9753 case OMPD_target_teams_distribute: 9754 case OMPD_target_teams_distribute_simd: 9755 case OMPD_cancel: 9756 case OMPD_task: 9757 case OMPD_taskloop: 9758 case OMPD_taskloop_simd: 9759 case OMPD_threadprivate: 9760 case OMPD_allocate: 9761 case OMPD_taskyield: 9762 case OMPD_barrier: 9763 case OMPD_taskwait: 9764 case OMPD_cancellation_point: 9765 case OMPD_flush: 9766 case OMPD_declare_reduction: 9767 case OMPD_declare_mapper: 9768 case OMPD_declare_simd: 9769 case OMPD_declare_target: 9770 case OMPD_end_declare_target: 9771 case OMPD_teams: 9772 case OMPD_simd: 9773 case OMPD_for: 9774 case OMPD_for_simd: 9775 case OMPD_sections: 9776 case OMPD_section: 9777 case OMPD_single: 9778 case OMPD_master: 9779 case OMPD_critical: 9780 case OMPD_taskgroup: 9781 case OMPD_distribute: 9782 case OMPD_ordered: 9783 case OMPD_atomic: 9784 case OMPD_distribute_simd: 9785 case OMPD_teams_distribute: 9786 case OMPD_teams_distribute_simd: 9787 case OMPD_requires: 9788 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9789 case OMPD_unknown: 9790 llvm_unreachable("Unknown OpenMP directive"); 9791 } 9792 break; 9793 case OMPC_num_teams: 9794 switch (DKind) { 9795 case OMPD_target_teams: 9796 case OMPD_target_teams_distribute: 9797 case OMPD_target_teams_distribute_simd: 9798 case OMPD_target_teams_distribute_parallel_for: 9799 case OMPD_target_teams_distribute_parallel_for_simd: 9800 CaptureRegion = OMPD_target; 9801 break; 9802 case OMPD_teams_distribute_parallel_for: 9803 case OMPD_teams_distribute_parallel_for_simd: 9804 case OMPD_teams: 9805 case OMPD_teams_distribute: 9806 case OMPD_teams_distribute_simd: 9807 // Do not capture num_teams-clause expressions. 9808 break; 9809 case OMPD_distribute_parallel_for: 9810 case OMPD_distribute_parallel_for_simd: 9811 case OMPD_task: 9812 case OMPD_taskloop: 9813 case OMPD_taskloop_simd: 9814 case OMPD_target_data: 9815 case OMPD_target_enter_data: 9816 case OMPD_target_exit_data: 9817 case OMPD_target_update: 9818 case OMPD_cancel: 9819 case OMPD_parallel: 9820 case OMPD_parallel_sections: 9821 case OMPD_parallel_for: 9822 case OMPD_parallel_for_simd: 9823 case OMPD_target: 9824 case OMPD_target_simd: 9825 case OMPD_target_parallel: 9826 case OMPD_target_parallel_for: 9827 case OMPD_target_parallel_for_simd: 9828 case OMPD_threadprivate: 9829 case OMPD_allocate: 9830 case OMPD_taskyield: 9831 case OMPD_barrier: 9832 case OMPD_taskwait: 9833 case OMPD_cancellation_point: 9834 case OMPD_flush: 9835 case OMPD_declare_reduction: 9836 case OMPD_declare_mapper: 9837 case OMPD_declare_simd: 9838 case OMPD_declare_target: 9839 case OMPD_end_declare_target: 9840 case OMPD_simd: 9841 case OMPD_for: 9842 case OMPD_for_simd: 9843 case OMPD_sections: 9844 case OMPD_section: 9845 case OMPD_single: 9846 case OMPD_master: 9847 case OMPD_critical: 9848 case OMPD_taskgroup: 9849 case OMPD_distribute: 9850 case OMPD_ordered: 9851 case OMPD_atomic: 9852 case OMPD_distribute_simd: 9853 case OMPD_requires: 9854 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9855 case OMPD_unknown: 9856 llvm_unreachable("Unknown OpenMP directive"); 9857 } 9858 break; 9859 case OMPC_thread_limit: 9860 switch (DKind) { 9861 case OMPD_target_teams: 9862 case OMPD_target_teams_distribute: 9863 case OMPD_target_teams_distribute_simd: 9864 case OMPD_target_teams_distribute_parallel_for: 9865 case OMPD_target_teams_distribute_parallel_for_simd: 9866 CaptureRegion = OMPD_target; 9867 break; 9868 case OMPD_teams_distribute_parallel_for: 9869 case OMPD_teams_distribute_parallel_for_simd: 9870 case OMPD_teams: 9871 case OMPD_teams_distribute: 9872 case OMPD_teams_distribute_simd: 9873 // Do not capture thread_limit-clause expressions. 9874 break; 9875 case OMPD_distribute_parallel_for: 9876 case OMPD_distribute_parallel_for_simd: 9877 case OMPD_task: 9878 case OMPD_taskloop: 9879 case OMPD_taskloop_simd: 9880 case OMPD_target_data: 9881 case OMPD_target_enter_data: 9882 case OMPD_target_exit_data: 9883 case OMPD_target_update: 9884 case OMPD_cancel: 9885 case OMPD_parallel: 9886 case OMPD_parallel_sections: 9887 case OMPD_parallel_for: 9888 case OMPD_parallel_for_simd: 9889 case OMPD_target: 9890 case OMPD_target_simd: 9891 case OMPD_target_parallel: 9892 case OMPD_target_parallel_for: 9893 case OMPD_target_parallel_for_simd: 9894 case OMPD_threadprivate: 9895 case OMPD_allocate: 9896 case OMPD_taskyield: 9897 case OMPD_barrier: 9898 case OMPD_taskwait: 9899 case OMPD_cancellation_point: 9900 case OMPD_flush: 9901 case OMPD_declare_reduction: 9902 case OMPD_declare_mapper: 9903 case OMPD_declare_simd: 9904 case OMPD_declare_target: 9905 case OMPD_end_declare_target: 9906 case OMPD_simd: 9907 case OMPD_for: 9908 case OMPD_for_simd: 9909 case OMPD_sections: 9910 case OMPD_section: 9911 case OMPD_single: 9912 case OMPD_master: 9913 case OMPD_critical: 9914 case OMPD_taskgroup: 9915 case OMPD_distribute: 9916 case OMPD_ordered: 9917 case OMPD_atomic: 9918 case OMPD_distribute_simd: 9919 case OMPD_requires: 9920 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 9921 case OMPD_unknown: 9922 llvm_unreachable("Unknown OpenMP directive"); 9923 } 9924 break; 9925 case OMPC_schedule: 9926 switch (DKind) { 9927 case OMPD_parallel_for: 9928 case OMPD_parallel_for_simd: 9929 case OMPD_distribute_parallel_for: 9930 case OMPD_distribute_parallel_for_simd: 9931 case OMPD_teams_distribute_parallel_for: 9932 case OMPD_teams_distribute_parallel_for_simd: 9933 case OMPD_target_parallel_for: 9934 case OMPD_target_parallel_for_simd: 9935 case OMPD_target_teams_distribute_parallel_for: 9936 case OMPD_target_teams_distribute_parallel_for_simd: 9937 CaptureRegion = OMPD_parallel; 9938 break; 9939 case OMPD_for: 9940 case OMPD_for_simd: 9941 // Do not capture schedule-clause expressions. 9942 break; 9943 case OMPD_task: 9944 case OMPD_taskloop: 9945 case OMPD_taskloop_simd: 9946 case OMPD_target_data: 9947 case OMPD_target_enter_data: 9948 case OMPD_target_exit_data: 9949 case OMPD_target_update: 9950 case OMPD_teams: 9951 case OMPD_teams_distribute: 9952 case OMPD_teams_distribute_simd: 9953 case OMPD_target_teams_distribute: 9954 case OMPD_target_teams_distribute_simd: 9955 case OMPD_target: 9956 case OMPD_target_simd: 9957 case OMPD_target_parallel: 9958 case OMPD_cancel: 9959 case OMPD_parallel: 9960 case OMPD_parallel_sections: 9961 case OMPD_threadprivate: 9962 case OMPD_allocate: 9963 case OMPD_taskyield: 9964 case OMPD_barrier: 9965 case OMPD_taskwait: 9966 case OMPD_cancellation_point: 9967 case OMPD_flush: 9968 case OMPD_declare_reduction: 9969 case OMPD_declare_mapper: 9970 case OMPD_declare_simd: 9971 case OMPD_declare_target: 9972 case OMPD_end_declare_target: 9973 case OMPD_simd: 9974 case OMPD_sections: 9975 case OMPD_section: 9976 case OMPD_single: 9977 case OMPD_master: 9978 case OMPD_critical: 9979 case OMPD_taskgroup: 9980 case OMPD_distribute: 9981 case OMPD_ordered: 9982 case OMPD_atomic: 9983 case OMPD_distribute_simd: 9984 case OMPD_target_teams: 9985 case OMPD_requires: 9986 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9987 case OMPD_unknown: 9988 llvm_unreachable("Unknown OpenMP directive"); 9989 } 9990 break; 9991 case OMPC_dist_schedule: 9992 switch (DKind) { 9993 case OMPD_teams_distribute_parallel_for: 9994 case OMPD_teams_distribute_parallel_for_simd: 9995 case OMPD_teams_distribute: 9996 case OMPD_teams_distribute_simd: 9997 case OMPD_target_teams_distribute_parallel_for: 9998 case OMPD_target_teams_distribute_parallel_for_simd: 9999 case OMPD_target_teams_distribute: 10000 case OMPD_target_teams_distribute_simd: 10001 CaptureRegion = OMPD_teams; 10002 break; 10003 case OMPD_distribute_parallel_for: 10004 case OMPD_distribute_parallel_for_simd: 10005 case OMPD_distribute: 10006 case OMPD_distribute_simd: 10007 // Do not capture thread_limit-clause expressions. 10008 break; 10009 case OMPD_parallel_for: 10010 case OMPD_parallel_for_simd: 10011 case OMPD_target_parallel_for_simd: 10012 case OMPD_target_parallel_for: 10013 case OMPD_task: 10014 case OMPD_taskloop: 10015 case OMPD_taskloop_simd: 10016 case OMPD_target_data: 10017 case OMPD_target_enter_data: 10018 case OMPD_target_exit_data: 10019 case OMPD_target_update: 10020 case OMPD_teams: 10021 case OMPD_target: 10022 case OMPD_target_simd: 10023 case OMPD_target_parallel: 10024 case OMPD_cancel: 10025 case OMPD_parallel: 10026 case OMPD_parallel_sections: 10027 case OMPD_threadprivate: 10028 case OMPD_allocate: 10029 case OMPD_taskyield: 10030 case OMPD_barrier: 10031 case OMPD_taskwait: 10032 case OMPD_cancellation_point: 10033 case OMPD_flush: 10034 case OMPD_declare_reduction: 10035 case OMPD_declare_mapper: 10036 case OMPD_declare_simd: 10037 case OMPD_declare_target: 10038 case OMPD_end_declare_target: 10039 case OMPD_simd: 10040 case OMPD_for: 10041 case OMPD_for_simd: 10042 case OMPD_sections: 10043 case OMPD_section: 10044 case OMPD_single: 10045 case OMPD_master: 10046 case OMPD_critical: 10047 case OMPD_taskgroup: 10048 case OMPD_ordered: 10049 case OMPD_atomic: 10050 case OMPD_target_teams: 10051 case OMPD_requires: 10052 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10053 case OMPD_unknown: 10054 llvm_unreachable("Unknown OpenMP directive"); 10055 } 10056 break; 10057 case OMPC_device: 10058 switch (DKind) { 10059 case OMPD_target_update: 10060 case OMPD_target_enter_data: 10061 case OMPD_target_exit_data: 10062 case OMPD_target: 10063 case OMPD_target_simd: 10064 case OMPD_target_teams: 10065 case OMPD_target_parallel: 10066 case OMPD_target_teams_distribute: 10067 case OMPD_target_teams_distribute_simd: 10068 case OMPD_target_parallel_for: 10069 case OMPD_target_parallel_for_simd: 10070 case OMPD_target_teams_distribute_parallel_for: 10071 case OMPD_target_teams_distribute_parallel_for_simd: 10072 CaptureRegion = OMPD_task; 10073 break; 10074 case OMPD_target_data: 10075 // Do not capture device-clause expressions. 10076 break; 10077 case OMPD_teams_distribute_parallel_for: 10078 case OMPD_teams_distribute_parallel_for_simd: 10079 case OMPD_teams: 10080 case OMPD_teams_distribute: 10081 case OMPD_teams_distribute_simd: 10082 case OMPD_distribute_parallel_for: 10083 case OMPD_distribute_parallel_for_simd: 10084 case OMPD_task: 10085 case OMPD_taskloop: 10086 case OMPD_taskloop_simd: 10087 case OMPD_cancel: 10088 case OMPD_parallel: 10089 case OMPD_parallel_sections: 10090 case OMPD_parallel_for: 10091 case OMPD_parallel_for_simd: 10092 case OMPD_threadprivate: 10093 case OMPD_allocate: 10094 case OMPD_taskyield: 10095 case OMPD_barrier: 10096 case OMPD_taskwait: 10097 case OMPD_cancellation_point: 10098 case OMPD_flush: 10099 case OMPD_declare_reduction: 10100 case OMPD_declare_mapper: 10101 case OMPD_declare_simd: 10102 case OMPD_declare_target: 10103 case OMPD_end_declare_target: 10104 case OMPD_simd: 10105 case OMPD_for: 10106 case OMPD_for_simd: 10107 case OMPD_sections: 10108 case OMPD_section: 10109 case OMPD_single: 10110 case OMPD_master: 10111 case OMPD_critical: 10112 case OMPD_taskgroup: 10113 case OMPD_distribute: 10114 case OMPD_ordered: 10115 case OMPD_atomic: 10116 case OMPD_distribute_simd: 10117 case OMPD_requires: 10118 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10119 case OMPD_unknown: 10120 llvm_unreachable("Unknown OpenMP directive"); 10121 } 10122 break; 10123 case OMPC_firstprivate: 10124 case OMPC_lastprivate: 10125 case OMPC_reduction: 10126 case OMPC_task_reduction: 10127 case OMPC_in_reduction: 10128 case OMPC_linear: 10129 case OMPC_default: 10130 case OMPC_proc_bind: 10131 case OMPC_final: 10132 case OMPC_safelen: 10133 case OMPC_simdlen: 10134 case OMPC_allocator: 10135 case OMPC_collapse: 10136 case OMPC_private: 10137 case OMPC_shared: 10138 case OMPC_aligned: 10139 case OMPC_copyin: 10140 case OMPC_copyprivate: 10141 case OMPC_ordered: 10142 case OMPC_nowait: 10143 case OMPC_untied: 10144 case OMPC_mergeable: 10145 case OMPC_threadprivate: 10146 case OMPC_allocate: 10147 case OMPC_flush: 10148 case OMPC_read: 10149 case OMPC_write: 10150 case OMPC_update: 10151 case OMPC_capture: 10152 case OMPC_seq_cst: 10153 case OMPC_depend: 10154 case OMPC_threads: 10155 case OMPC_simd: 10156 case OMPC_map: 10157 case OMPC_priority: 10158 case OMPC_grainsize: 10159 case OMPC_nogroup: 10160 case OMPC_num_tasks: 10161 case OMPC_hint: 10162 case OMPC_defaultmap: 10163 case OMPC_unknown: 10164 case OMPC_uniform: 10165 case OMPC_to: 10166 case OMPC_from: 10167 case OMPC_use_device_ptr: 10168 case OMPC_is_device_ptr: 10169 case OMPC_unified_address: 10170 case OMPC_unified_shared_memory: 10171 case OMPC_reverse_offload: 10172 case OMPC_dynamic_allocators: 10173 case OMPC_atomic_default_mem_order: 10174 llvm_unreachable("Unexpected OpenMP clause."); 10175 } 10176 return CaptureRegion; 10177 } 10178 10179 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10180 Expr *Condition, SourceLocation StartLoc, 10181 SourceLocation LParenLoc, 10182 SourceLocation NameModifierLoc, 10183 SourceLocation ColonLoc, 10184 SourceLocation EndLoc) { 10185 Expr *ValExpr = Condition; 10186 Stmt *HelperValStmt = nullptr; 10187 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10188 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10189 !Condition->isInstantiationDependent() && 10190 !Condition->containsUnexpandedParameterPack()) { 10191 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10192 if (Val.isInvalid()) 10193 return nullptr; 10194 10195 ValExpr = Val.get(); 10196 10197 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10198 CaptureRegion = 10199 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10200 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10201 ValExpr = MakeFullExpr(ValExpr).get(); 10202 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10203 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10204 HelperValStmt = buildPreInits(Context, Captures); 10205 } 10206 } 10207 10208 return new (Context) 10209 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10210 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10211 } 10212 10213 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10214 SourceLocation StartLoc, 10215 SourceLocation LParenLoc, 10216 SourceLocation EndLoc) { 10217 Expr *ValExpr = Condition; 10218 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10219 !Condition->isInstantiationDependent() && 10220 !Condition->containsUnexpandedParameterPack()) { 10221 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10222 if (Val.isInvalid()) 10223 return nullptr; 10224 10225 ValExpr = MakeFullExpr(Val.get()).get(); 10226 } 10227 10228 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10229 } 10230 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10231 Expr *Op) { 10232 if (!Op) 10233 return ExprError(); 10234 10235 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10236 public: 10237 IntConvertDiagnoser() 10238 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10239 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10240 QualType T) override { 10241 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10242 } 10243 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10244 QualType T) override { 10245 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10246 } 10247 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10248 QualType T, 10249 QualType ConvTy) override { 10250 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10251 } 10252 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10253 QualType ConvTy) override { 10254 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10255 << ConvTy->isEnumeralType() << ConvTy; 10256 } 10257 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10258 QualType T) override { 10259 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10260 } 10261 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 10262 QualType ConvTy) override { 10263 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10264 << ConvTy->isEnumeralType() << ConvTy; 10265 } 10266 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 10267 QualType) override { 10268 llvm_unreachable("conversion functions are permitted"); 10269 } 10270 } ConvertDiagnoser; 10271 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 10272 } 10273 10274 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 10275 OpenMPClauseKind CKind, 10276 bool StrictlyPositive) { 10277 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 10278 !ValExpr->isInstantiationDependent()) { 10279 SourceLocation Loc = ValExpr->getExprLoc(); 10280 ExprResult Value = 10281 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 10282 if (Value.isInvalid()) 10283 return false; 10284 10285 ValExpr = Value.get(); 10286 // The expression must evaluate to a non-negative integer value. 10287 llvm::APSInt Result; 10288 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 10289 Result.isSigned() && 10290 !((!StrictlyPositive && Result.isNonNegative()) || 10291 (StrictlyPositive && Result.isStrictlyPositive()))) { 10292 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 10293 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10294 << ValExpr->getSourceRange(); 10295 return false; 10296 } 10297 } 10298 return true; 10299 } 10300 10301 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 10302 SourceLocation StartLoc, 10303 SourceLocation LParenLoc, 10304 SourceLocation EndLoc) { 10305 Expr *ValExpr = NumThreads; 10306 Stmt *HelperValStmt = nullptr; 10307 10308 // OpenMP [2.5, Restrictions] 10309 // The num_threads expression must evaluate to a positive integer value. 10310 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 10311 /*StrictlyPositive=*/true)) 10312 return nullptr; 10313 10314 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10315 OpenMPDirectiveKind CaptureRegion = 10316 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 10317 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10318 ValExpr = MakeFullExpr(ValExpr).get(); 10319 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10320 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10321 HelperValStmt = buildPreInits(Context, Captures); 10322 } 10323 10324 return new (Context) OMPNumThreadsClause( 10325 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 10326 } 10327 10328 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 10329 OpenMPClauseKind CKind, 10330 bool StrictlyPositive) { 10331 if (!E) 10332 return ExprError(); 10333 if (E->isValueDependent() || E->isTypeDependent() || 10334 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 10335 return E; 10336 llvm::APSInt Result; 10337 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 10338 if (ICE.isInvalid()) 10339 return ExprError(); 10340 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 10341 (!StrictlyPositive && !Result.isNonNegative())) { 10342 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 10343 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10344 << E->getSourceRange(); 10345 return ExprError(); 10346 } 10347 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 10348 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 10349 << E->getSourceRange(); 10350 return ExprError(); 10351 } 10352 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 10353 DSAStack->setAssociatedLoops(Result.getExtValue()); 10354 else if (CKind == OMPC_ordered) 10355 DSAStack->setAssociatedLoops(Result.getExtValue()); 10356 return ICE; 10357 } 10358 10359 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 10360 SourceLocation LParenLoc, 10361 SourceLocation EndLoc) { 10362 // OpenMP [2.8.1, simd construct, Description] 10363 // The parameter of the safelen clause must be a constant 10364 // positive integer expression. 10365 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10366 if (Safelen.isInvalid()) 10367 return nullptr; 10368 return new (Context) 10369 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10370 } 10371 10372 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10373 SourceLocation LParenLoc, 10374 SourceLocation EndLoc) { 10375 // OpenMP [2.8.1, simd construct, Description] 10376 // The parameter of the simdlen clause must be a constant 10377 // positive integer expression. 10378 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10379 if (Simdlen.isInvalid()) 10380 return nullptr; 10381 return new (Context) 10382 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10383 } 10384 10385 /// Tries to find omp_allocator_handle_t type. 10386 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10387 DSAStackTy *Stack) { 10388 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10389 if (!OMPAllocatorHandleT.isNull()) 10390 return true; 10391 // Build the predefined allocator expressions. 10392 bool ErrorFound = false; 10393 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10394 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10395 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10396 StringRef Allocator = 10397 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10398 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10399 auto *VD = dyn_cast_or_null<ValueDecl>( 10400 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10401 if (!VD) { 10402 ErrorFound = true; 10403 break; 10404 } 10405 QualType AllocatorType = 10406 VD->getType().getNonLValueExprType(S.getASTContext()); 10407 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10408 if (!Res.isUsable()) { 10409 ErrorFound = true; 10410 break; 10411 } 10412 if (OMPAllocatorHandleT.isNull()) 10413 OMPAllocatorHandleT = AllocatorType; 10414 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10415 ErrorFound = true; 10416 break; 10417 } 10418 Stack->setAllocator(AllocatorKind, Res.get()); 10419 } 10420 if (ErrorFound) { 10421 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10422 return false; 10423 } 10424 OMPAllocatorHandleT.addConst(); 10425 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10426 return true; 10427 } 10428 10429 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10430 SourceLocation LParenLoc, 10431 SourceLocation EndLoc) { 10432 // OpenMP [2.11.3, allocate Directive, Description] 10433 // allocator is an expression of omp_allocator_handle_t type. 10434 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10435 return nullptr; 10436 10437 ExprResult Allocator = DefaultLvalueConversion(A); 10438 if (Allocator.isInvalid()) 10439 return nullptr; 10440 Allocator = PerformImplicitConversion(Allocator.get(), 10441 DSAStack->getOMPAllocatorHandleT(), 10442 Sema::AA_Initializing, 10443 /*AllowExplicit=*/true); 10444 if (Allocator.isInvalid()) 10445 return nullptr; 10446 return new (Context) 10447 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10448 } 10449 10450 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10451 SourceLocation StartLoc, 10452 SourceLocation LParenLoc, 10453 SourceLocation EndLoc) { 10454 // OpenMP [2.7.1, loop construct, Description] 10455 // OpenMP [2.8.1, simd construct, Description] 10456 // OpenMP [2.9.6, distribute construct, Description] 10457 // The parameter of the collapse clause must be a constant 10458 // positive integer expression. 10459 ExprResult NumForLoopsResult = 10460 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10461 if (NumForLoopsResult.isInvalid()) 10462 return nullptr; 10463 return new (Context) 10464 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10465 } 10466 10467 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10468 SourceLocation EndLoc, 10469 SourceLocation LParenLoc, 10470 Expr *NumForLoops) { 10471 // OpenMP [2.7.1, loop construct, Description] 10472 // OpenMP [2.8.1, simd construct, Description] 10473 // OpenMP [2.9.6, distribute construct, Description] 10474 // The parameter of the ordered clause must be a constant 10475 // positive integer expression if any. 10476 if (NumForLoops && LParenLoc.isValid()) { 10477 ExprResult NumForLoopsResult = 10478 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10479 if (NumForLoopsResult.isInvalid()) 10480 return nullptr; 10481 NumForLoops = NumForLoopsResult.get(); 10482 } else { 10483 NumForLoops = nullptr; 10484 } 10485 auto *Clause = OMPOrderedClause::Create( 10486 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10487 StartLoc, LParenLoc, EndLoc); 10488 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10489 return Clause; 10490 } 10491 10492 OMPClause *Sema::ActOnOpenMPSimpleClause( 10493 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10494 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10495 OMPClause *Res = nullptr; 10496 switch (Kind) { 10497 case OMPC_default: 10498 Res = 10499 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10500 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10501 break; 10502 case OMPC_proc_bind: 10503 Res = ActOnOpenMPProcBindClause( 10504 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10505 LParenLoc, EndLoc); 10506 break; 10507 case OMPC_atomic_default_mem_order: 10508 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10509 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10510 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10511 break; 10512 case OMPC_if: 10513 case OMPC_final: 10514 case OMPC_num_threads: 10515 case OMPC_safelen: 10516 case OMPC_simdlen: 10517 case OMPC_allocator: 10518 case OMPC_collapse: 10519 case OMPC_schedule: 10520 case OMPC_private: 10521 case OMPC_firstprivate: 10522 case OMPC_lastprivate: 10523 case OMPC_shared: 10524 case OMPC_reduction: 10525 case OMPC_task_reduction: 10526 case OMPC_in_reduction: 10527 case OMPC_linear: 10528 case OMPC_aligned: 10529 case OMPC_copyin: 10530 case OMPC_copyprivate: 10531 case OMPC_ordered: 10532 case OMPC_nowait: 10533 case OMPC_untied: 10534 case OMPC_mergeable: 10535 case OMPC_threadprivate: 10536 case OMPC_allocate: 10537 case OMPC_flush: 10538 case OMPC_read: 10539 case OMPC_write: 10540 case OMPC_update: 10541 case OMPC_capture: 10542 case OMPC_seq_cst: 10543 case OMPC_depend: 10544 case OMPC_device: 10545 case OMPC_threads: 10546 case OMPC_simd: 10547 case OMPC_map: 10548 case OMPC_num_teams: 10549 case OMPC_thread_limit: 10550 case OMPC_priority: 10551 case OMPC_grainsize: 10552 case OMPC_nogroup: 10553 case OMPC_num_tasks: 10554 case OMPC_hint: 10555 case OMPC_dist_schedule: 10556 case OMPC_defaultmap: 10557 case OMPC_unknown: 10558 case OMPC_uniform: 10559 case OMPC_to: 10560 case OMPC_from: 10561 case OMPC_use_device_ptr: 10562 case OMPC_is_device_ptr: 10563 case OMPC_unified_address: 10564 case OMPC_unified_shared_memory: 10565 case OMPC_reverse_offload: 10566 case OMPC_dynamic_allocators: 10567 llvm_unreachable("Clause is not allowed."); 10568 } 10569 return Res; 10570 } 10571 10572 static std::string 10573 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10574 ArrayRef<unsigned> Exclude = llvm::None) { 10575 SmallString<256> Buffer; 10576 llvm::raw_svector_ostream Out(Buffer); 10577 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10578 unsigned Skipped = Exclude.size(); 10579 auto S = Exclude.begin(), E = Exclude.end(); 10580 for (unsigned I = First; I < Last; ++I) { 10581 if (std::find(S, E, I) != E) { 10582 --Skipped; 10583 continue; 10584 } 10585 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10586 if (I == Bound - Skipped) 10587 Out << " or "; 10588 else if (I != Bound + 1 - Skipped) 10589 Out << ", "; 10590 } 10591 return Out.str(); 10592 } 10593 10594 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10595 SourceLocation KindKwLoc, 10596 SourceLocation StartLoc, 10597 SourceLocation LParenLoc, 10598 SourceLocation EndLoc) { 10599 if (Kind == OMPC_DEFAULT_unknown) { 10600 static_assert(OMPC_DEFAULT_unknown > 0, 10601 "OMPC_DEFAULT_unknown not greater than 0"); 10602 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10603 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10604 /*Last=*/OMPC_DEFAULT_unknown) 10605 << getOpenMPClauseName(OMPC_default); 10606 return nullptr; 10607 } 10608 switch (Kind) { 10609 case OMPC_DEFAULT_none: 10610 DSAStack->setDefaultDSANone(KindKwLoc); 10611 break; 10612 case OMPC_DEFAULT_shared: 10613 DSAStack->setDefaultDSAShared(KindKwLoc); 10614 break; 10615 case OMPC_DEFAULT_unknown: 10616 llvm_unreachable("Clause kind is not allowed."); 10617 break; 10618 } 10619 return new (Context) 10620 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10621 } 10622 10623 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10624 SourceLocation KindKwLoc, 10625 SourceLocation StartLoc, 10626 SourceLocation LParenLoc, 10627 SourceLocation EndLoc) { 10628 if (Kind == OMPC_PROC_BIND_unknown) { 10629 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10630 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10631 /*Last=*/OMPC_PROC_BIND_unknown) 10632 << getOpenMPClauseName(OMPC_proc_bind); 10633 return nullptr; 10634 } 10635 return new (Context) 10636 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10637 } 10638 10639 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10640 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10641 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10642 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10643 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10644 << getListOfPossibleValues( 10645 OMPC_atomic_default_mem_order, /*First=*/0, 10646 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10647 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10648 return nullptr; 10649 } 10650 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10651 LParenLoc, EndLoc); 10652 } 10653 10654 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10655 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10656 SourceLocation StartLoc, SourceLocation LParenLoc, 10657 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10658 SourceLocation EndLoc) { 10659 OMPClause *Res = nullptr; 10660 switch (Kind) { 10661 case OMPC_schedule: 10662 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10663 assert(Argument.size() == NumberOfElements && 10664 ArgumentLoc.size() == NumberOfElements); 10665 Res = ActOnOpenMPScheduleClause( 10666 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10667 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10668 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10669 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10670 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10671 break; 10672 case OMPC_if: 10673 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10674 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10675 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10676 DelimLoc, EndLoc); 10677 break; 10678 case OMPC_dist_schedule: 10679 Res = ActOnOpenMPDistScheduleClause( 10680 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10681 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10682 break; 10683 case OMPC_defaultmap: 10684 enum { Modifier, DefaultmapKind }; 10685 Res = ActOnOpenMPDefaultmapClause( 10686 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10687 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10688 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10689 EndLoc); 10690 break; 10691 case OMPC_final: 10692 case OMPC_num_threads: 10693 case OMPC_safelen: 10694 case OMPC_simdlen: 10695 case OMPC_allocator: 10696 case OMPC_collapse: 10697 case OMPC_default: 10698 case OMPC_proc_bind: 10699 case OMPC_private: 10700 case OMPC_firstprivate: 10701 case OMPC_lastprivate: 10702 case OMPC_shared: 10703 case OMPC_reduction: 10704 case OMPC_task_reduction: 10705 case OMPC_in_reduction: 10706 case OMPC_linear: 10707 case OMPC_aligned: 10708 case OMPC_copyin: 10709 case OMPC_copyprivate: 10710 case OMPC_ordered: 10711 case OMPC_nowait: 10712 case OMPC_untied: 10713 case OMPC_mergeable: 10714 case OMPC_threadprivate: 10715 case OMPC_allocate: 10716 case OMPC_flush: 10717 case OMPC_read: 10718 case OMPC_write: 10719 case OMPC_update: 10720 case OMPC_capture: 10721 case OMPC_seq_cst: 10722 case OMPC_depend: 10723 case OMPC_device: 10724 case OMPC_threads: 10725 case OMPC_simd: 10726 case OMPC_map: 10727 case OMPC_num_teams: 10728 case OMPC_thread_limit: 10729 case OMPC_priority: 10730 case OMPC_grainsize: 10731 case OMPC_nogroup: 10732 case OMPC_num_tasks: 10733 case OMPC_hint: 10734 case OMPC_unknown: 10735 case OMPC_uniform: 10736 case OMPC_to: 10737 case OMPC_from: 10738 case OMPC_use_device_ptr: 10739 case OMPC_is_device_ptr: 10740 case OMPC_unified_address: 10741 case OMPC_unified_shared_memory: 10742 case OMPC_reverse_offload: 10743 case OMPC_dynamic_allocators: 10744 case OMPC_atomic_default_mem_order: 10745 llvm_unreachable("Clause is not allowed."); 10746 } 10747 return Res; 10748 } 10749 10750 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10751 OpenMPScheduleClauseModifier M2, 10752 SourceLocation M1Loc, SourceLocation M2Loc) { 10753 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10754 SmallVector<unsigned, 2> Excluded; 10755 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10756 Excluded.push_back(M2); 10757 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10758 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10759 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10760 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10761 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10762 << getListOfPossibleValues(OMPC_schedule, 10763 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10764 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10765 Excluded) 10766 << getOpenMPClauseName(OMPC_schedule); 10767 return true; 10768 } 10769 return false; 10770 } 10771 10772 OMPClause *Sema::ActOnOpenMPScheduleClause( 10773 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10774 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10775 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10776 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10777 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10778 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10779 return nullptr; 10780 // OpenMP, 2.7.1, Loop Construct, Restrictions 10781 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10782 // but not both. 10783 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10784 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10785 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10786 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10787 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10788 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10789 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10790 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10791 return nullptr; 10792 } 10793 if (Kind == OMPC_SCHEDULE_unknown) { 10794 std::string Values; 10795 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10796 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10797 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10798 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10799 Exclude); 10800 } else { 10801 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10802 /*Last=*/OMPC_SCHEDULE_unknown); 10803 } 10804 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10805 << Values << getOpenMPClauseName(OMPC_schedule); 10806 return nullptr; 10807 } 10808 // OpenMP, 2.7.1, Loop Construct, Restrictions 10809 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 10810 // schedule(guided). 10811 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 10812 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 10813 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 10814 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 10815 diag::err_omp_schedule_nonmonotonic_static); 10816 return nullptr; 10817 } 10818 Expr *ValExpr = ChunkSize; 10819 Stmt *HelperValStmt = nullptr; 10820 if (ChunkSize) { 10821 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10822 !ChunkSize->isInstantiationDependent() && 10823 !ChunkSize->containsUnexpandedParameterPack()) { 10824 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 10825 ExprResult Val = 10826 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10827 if (Val.isInvalid()) 10828 return nullptr; 10829 10830 ValExpr = Val.get(); 10831 10832 // OpenMP [2.7.1, Restrictions] 10833 // chunk_size must be a loop invariant integer expression with a positive 10834 // value. 10835 llvm::APSInt Result; 10836 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10837 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10838 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10839 << "schedule" << 1 << ChunkSize->getSourceRange(); 10840 return nullptr; 10841 } 10842 } else if (getOpenMPCaptureRegionForClause( 10843 DSAStack->getCurrentDirective(), OMPC_schedule) != 10844 OMPD_unknown && 10845 !CurContext->isDependentContext()) { 10846 ValExpr = MakeFullExpr(ValExpr).get(); 10847 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10848 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10849 HelperValStmt = buildPreInits(Context, Captures); 10850 } 10851 } 10852 } 10853 10854 return new (Context) 10855 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 10856 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 10857 } 10858 10859 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 10860 SourceLocation StartLoc, 10861 SourceLocation EndLoc) { 10862 OMPClause *Res = nullptr; 10863 switch (Kind) { 10864 case OMPC_ordered: 10865 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 10866 break; 10867 case OMPC_nowait: 10868 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 10869 break; 10870 case OMPC_untied: 10871 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 10872 break; 10873 case OMPC_mergeable: 10874 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 10875 break; 10876 case OMPC_read: 10877 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 10878 break; 10879 case OMPC_write: 10880 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 10881 break; 10882 case OMPC_update: 10883 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 10884 break; 10885 case OMPC_capture: 10886 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 10887 break; 10888 case OMPC_seq_cst: 10889 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 10890 break; 10891 case OMPC_threads: 10892 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 10893 break; 10894 case OMPC_simd: 10895 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 10896 break; 10897 case OMPC_nogroup: 10898 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 10899 break; 10900 case OMPC_unified_address: 10901 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 10902 break; 10903 case OMPC_unified_shared_memory: 10904 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10905 break; 10906 case OMPC_reverse_offload: 10907 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 10908 break; 10909 case OMPC_dynamic_allocators: 10910 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 10911 break; 10912 case OMPC_if: 10913 case OMPC_final: 10914 case OMPC_num_threads: 10915 case OMPC_safelen: 10916 case OMPC_simdlen: 10917 case OMPC_allocator: 10918 case OMPC_collapse: 10919 case OMPC_schedule: 10920 case OMPC_private: 10921 case OMPC_firstprivate: 10922 case OMPC_lastprivate: 10923 case OMPC_shared: 10924 case OMPC_reduction: 10925 case OMPC_task_reduction: 10926 case OMPC_in_reduction: 10927 case OMPC_linear: 10928 case OMPC_aligned: 10929 case OMPC_copyin: 10930 case OMPC_copyprivate: 10931 case OMPC_default: 10932 case OMPC_proc_bind: 10933 case OMPC_threadprivate: 10934 case OMPC_allocate: 10935 case OMPC_flush: 10936 case OMPC_depend: 10937 case OMPC_device: 10938 case OMPC_map: 10939 case OMPC_num_teams: 10940 case OMPC_thread_limit: 10941 case OMPC_priority: 10942 case OMPC_grainsize: 10943 case OMPC_num_tasks: 10944 case OMPC_hint: 10945 case OMPC_dist_schedule: 10946 case OMPC_defaultmap: 10947 case OMPC_unknown: 10948 case OMPC_uniform: 10949 case OMPC_to: 10950 case OMPC_from: 10951 case OMPC_use_device_ptr: 10952 case OMPC_is_device_ptr: 10953 case OMPC_atomic_default_mem_order: 10954 llvm_unreachable("Clause is not allowed."); 10955 } 10956 return Res; 10957 } 10958 10959 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 10960 SourceLocation EndLoc) { 10961 DSAStack->setNowaitRegion(); 10962 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 10963 } 10964 10965 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 10966 SourceLocation EndLoc) { 10967 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 10968 } 10969 10970 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 10971 SourceLocation EndLoc) { 10972 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10973 } 10974 10975 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10976 SourceLocation EndLoc) { 10977 return new (Context) OMPReadClause(StartLoc, EndLoc); 10978 } 10979 10980 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10981 SourceLocation EndLoc) { 10982 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10983 } 10984 10985 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10986 SourceLocation EndLoc) { 10987 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10988 } 10989 10990 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10991 SourceLocation EndLoc) { 10992 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10993 } 10994 10995 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10996 SourceLocation EndLoc) { 10997 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10998 } 10999 11000 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11001 SourceLocation EndLoc) { 11002 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11003 } 11004 11005 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11006 SourceLocation EndLoc) { 11007 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11008 } 11009 11010 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11011 SourceLocation EndLoc) { 11012 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11013 } 11014 11015 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11016 SourceLocation EndLoc) { 11017 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11018 } 11019 11020 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11021 SourceLocation EndLoc) { 11022 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11023 } 11024 11025 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11026 SourceLocation EndLoc) { 11027 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11028 } 11029 11030 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11031 SourceLocation EndLoc) { 11032 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11033 } 11034 11035 OMPClause *Sema::ActOnOpenMPVarListClause( 11036 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11037 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11038 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11039 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11040 OpenMPLinearClauseKind LinKind, 11041 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11042 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11043 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11044 SourceLocation StartLoc = Locs.StartLoc; 11045 SourceLocation LParenLoc = Locs.LParenLoc; 11046 SourceLocation EndLoc = Locs.EndLoc; 11047 OMPClause *Res = nullptr; 11048 switch (Kind) { 11049 case OMPC_private: 11050 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11051 break; 11052 case OMPC_firstprivate: 11053 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11054 break; 11055 case OMPC_lastprivate: 11056 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11057 break; 11058 case OMPC_shared: 11059 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11060 break; 11061 case OMPC_reduction: 11062 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11063 EndLoc, ReductionOrMapperIdScopeSpec, 11064 ReductionOrMapperId); 11065 break; 11066 case OMPC_task_reduction: 11067 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11068 EndLoc, ReductionOrMapperIdScopeSpec, 11069 ReductionOrMapperId); 11070 break; 11071 case OMPC_in_reduction: 11072 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11073 EndLoc, ReductionOrMapperIdScopeSpec, 11074 ReductionOrMapperId); 11075 break; 11076 case OMPC_linear: 11077 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11078 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11079 break; 11080 case OMPC_aligned: 11081 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11082 ColonLoc, EndLoc); 11083 break; 11084 case OMPC_copyin: 11085 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11086 break; 11087 case OMPC_copyprivate: 11088 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11089 break; 11090 case OMPC_flush: 11091 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11092 break; 11093 case OMPC_depend: 11094 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11095 StartLoc, LParenLoc, EndLoc); 11096 break; 11097 case OMPC_map: 11098 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11099 ReductionOrMapperIdScopeSpec, 11100 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11101 DepLinMapLoc, ColonLoc, VarList, Locs); 11102 break; 11103 case OMPC_to: 11104 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11105 ReductionOrMapperId, Locs); 11106 break; 11107 case OMPC_from: 11108 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11109 ReductionOrMapperId, Locs); 11110 break; 11111 case OMPC_use_device_ptr: 11112 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11113 break; 11114 case OMPC_is_device_ptr: 11115 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11116 break; 11117 case OMPC_allocate: 11118 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11119 ColonLoc, EndLoc); 11120 break; 11121 case OMPC_if: 11122 case OMPC_final: 11123 case OMPC_num_threads: 11124 case OMPC_safelen: 11125 case OMPC_simdlen: 11126 case OMPC_allocator: 11127 case OMPC_collapse: 11128 case OMPC_default: 11129 case OMPC_proc_bind: 11130 case OMPC_schedule: 11131 case OMPC_ordered: 11132 case OMPC_nowait: 11133 case OMPC_untied: 11134 case OMPC_mergeable: 11135 case OMPC_threadprivate: 11136 case OMPC_read: 11137 case OMPC_write: 11138 case OMPC_update: 11139 case OMPC_capture: 11140 case OMPC_seq_cst: 11141 case OMPC_device: 11142 case OMPC_threads: 11143 case OMPC_simd: 11144 case OMPC_num_teams: 11145 case OMPC_thread_limit: 11146 case OMPC_priority: 11147 case OMPC_grainsize: 11148 case OMPC_nogroup: 11149 case OMPC_num_tasks: 11150 case OMPC_hint: 11151 case OMPC_dist_schedule: 11152 case OMPC_defaultmap: 11153 case OMPC_unknown: 11154 case OMPC_uniform: 11155 case OMPC_unified_address: 11156 case OMPC_unified_shared_memory: 11157 case OMPC_reverse_offload: 11158 case OMPC_dynamic_allocators: 11159 case OMPC_atomic_default_mem_order: 11160 llvm_unreachable("Clause is not allowed."); 11161 } 11162 return Res; 11163 } 11164 11165 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11166 ExprObjectKind OK, SourceLocation Loc) { 11167 ExprResult Res = BuildDeclRefExpr( 11168 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11169 if (!Res.isUsable()) 11170 return ExprError(); 11171 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11172 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11173 if (!Res.isUsable()) 11174 return ExprError(); 11175 } 11176 if (VK != VK_LValue && Res.get()->isGLValue()) { 11177 Res = DefaultLvalueConversion(Res.get()); 11178 if (!Res.isUsable()) 11179 return ExprError(); 11180 } 11181 return Res; 11182 } 11183 11184 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11185 SourceLocation StartLoc, 11186 SourceLocation LParenLoc, 11187 SourceLocation EndLoc) { 11188 SmallVector<Expr *, 8> Vars; 11189 SmallVector<Expr *, 8> PrivateCopies; 11190 for (Expr *RefExpr : VarList) { 11191 assert(RefExpr && "NULL expr in OpenMP private clause."); 11192 SourceLocation ELoc; 11193 SourceRange ERange; 11194 Expr *SimpleRefExpr = RefExpr; 11195 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11196 if (Res.second) { 11197 // It will be analyzed later. 11198 Vars.push_back(RefExpr); 11199 PrivateCopies.push_back(nullptr); 11200 } 11201 ValueDecl *D = Res.first; 11202 if (!D) 11203 continue; 11204 11205 QualType Type = D->getType(); 11206 auto *VD = dyn_cast<VarDecl>(D); 11207 11208 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11209 // A variable that appears in a private clause must not have an incomplete 11210 // type or a reference type. 11211 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11212 continue; 11213 Type = Type.getNonReferenceType(); 11214 11215 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11216 // A variable that is privatized must not have a const-qualified type 11217 // unless it is of class type with a mutable member. This restriction does 11218 // not apply to the firstprivate clause. 11219 // 11220 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11221 // A variable that appears in a private clause must not have a 11222 // const-qualified type unless it is of class type with a mutable member. 11223 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11224 continue; 11225 11226 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11227 // in a Construct] 11228 // Variables with the predetermined data-sharing attributes may not be 11229 // listed in data-sharing attributes clauses, except for the cases 11230 // listed below. For these exceptions only, listing a predetermined 11231 // variable in a data-sharing attribute clause is allowed and overrides 11232 // the variable's predetermined data-sharing attributes. 11233 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11234 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11235 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11236 << getOpenMPClauseName(OMPC_private); 11237 reportOriginalDsa(*this, DSAStack, D, DVar); 11238 continue; 11239 } 11240 11241 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11242 // Variably modified types are not supported for tasks. 11243 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11244 isOpenMPTaskingDirective(CurrDir)) { 11245 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11246 << getOpenMPClauseName(OMPC_private) << Type 11247 << getOpenMPDirectiveName(CurrDir); 11248 bool IsDecl = 11249 !VD || 11250 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11251 Diag(D->getLocation(), 11252 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11253 << D; 11254 continue; 11255 } 11256 11257 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11258 // A list item cannot appear in both a map clause and a data-sharing 11259 // attribute clause on the same construct 11260 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11261 OpenMPClauseKind ConflictKind; 11262 if (DSAStack->checkMappableExprComponentListsForDecl( 11263 VD, /*CurrentRegionOnly=*/true, 11264 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 11265 OpenMPClauseKind WhereFoundClauseKind) -> bool { 11266 ConflictKind = WhereFoundClauseKind; 11267 return true; 11268 })) { 11269 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11270 << getOpenMPClauseName(OMPC_private) 11271 << getOpenMPClauseName(ConflictKind) 11272 << getOpenMPDirectiveName(CurrDir); 11273 reportOriginalDsa(*this, DSAStack, D, DVar); 11274 continue; 11275 } 11276 } 11277 11278 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 11279 // A variable of class type (or array thereof) that appears in a private 11280 // clause requires an accessible, unambiguous default constructor for the 11281 // class type. 11282 // Generate helper private variable and initialize it with the default 11283 // value. The address of the original variable is replaced by the address of 11284 // the new private variable in CodeGen. This new variable is not added to 11285 // IdResolver, so the code in the OpenMP region uses original variable for 11286 // proper diagnostics. 11287 Type = Type.getUnqualifiedType(); 11288 VarDecl *VDPrivate = 11289 buildVarDecl(*this, ELoc, Type, D->getName(), 11290 D->hasAttrs() ? &D->getAttrs() : nullptr, 11291 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11292 ActOnUninitializedDecl(VDPrivate); 11293 if (VDPrivate->isInvalidDecl()) 11294 continue; 11295 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11296 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11297 11298 DeclRefExpr *Ref = nullptr; 11299 if (!VD && !CurContext->isDependentContext()) 11300 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11301 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 11302 Vars.push_back((VD || CurContext->isDependentContext()) 11303 ? RefExpr->IgnoreParens() 11304 : Ref); 11305 PrivateCopies.push_back(VDPrivateRefExpr); 11306 } 11307 11308 if (Vars.empty()) 11309 return nullptr; 11310 11311 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11312 PrivateCopies); 11313 } 11314 11315 namespace { 11316 class DiagsUninitializedSeveretyRAII { 11317 private: 11318 DiagnosticsEngine &Diags; 11319 SourceLocation SavedLoc; 11320 bool IsIgnored = false; 11321 11322 public: 11323 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 11324 bool IsIgnored) 11325 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 11326 if (!IsIgnored) { 11327 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 11328 /*Map*/ diag::Severity::Ignored, Loc); 11329 } 11330 } 11331 ~DiagsUninitializedSeveretyRAII() { 11332 if (!IsIgnored) 11333 Diags.popMappings(SavedLoc); 11334 } 11335 }; 11336 } 11337 11338 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 11339 SourceLocation StartLoc, 11340 SourceLocation LParenLoc, 11341 SourceLocation EndLoc) { 11342 SmallVector<Expr *, 8> Vars; 11343 SmallVector<Expr *, 8> PrivateCopies; 11344 SmallVector<Expr *, 8> Inits; 11345 SmallVector<Decl *, 4> ExprCaptures; 11346 bool IsImplicitClause = 11347 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 11348 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 11349 11350 for (Expr *RefExpr : VarList) { 11351 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 11352 SourceLocation ELoc; 11353 SourceRange ERange; 11354 Expr *SimpleRefExpr = RefExpr; 11355 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11356 if (Res.second) { 11357 // It will be analyzed later. 11358 Vars.push_back(RefExpr); 11359 PrivateCopies.push_back(nullptr); 11360 Inits.push_back(nullptr); 11361 } 11362 ValueDecl *D = Res.first; 11363 if (!D) 11364 continue; 11365 11366 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11367 QualType Type = D->getType(); 11368 auto *VD = dyn_cast<VarDecl>(D); 11369 11370 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11371 // A variable that appears in a private clause must not have an incomplete 11372 // type or a reference type. 11373 if (RequireCompleteType(ELoc, Type, 11374 diag::err_omp_firstprivate_incomplete_type)) 11375 continue; 11376 Type = Type.getNonReferenceType(); 11377 11378 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11379 // A variable of class type (or array thereof) that appears in a private 11380 // clause requires an accessible, unambiguous copy constructor for the 11381 // class type. 11382 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11383 11384 // If an implicit firstprivate variable found it was checked already. 11385 DSAStackTy::DSAVarData TopDVar; 11386 if (!IsImplicitClause) { 11387 DSAStackTy::DSAVarData DVar = 11388 DSAStack->getTopDSA(D, /*FromParent=*/false); 11389 TopDVar = DVar; 11390 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11391 bool IsConstant = ElemType.isConstant(Context); 11392 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11393 // A list item that specifies a given variable may not appear in more 11394 // than one clause on the same directive, except that a variable may be 11395 // specified in both firstprivate and lastprivate clauses. 11396 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11397 // A list item may appear in a firstprivate or lastprivate clause but not 11398 // both. 11399 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11400 (isOpenMPDistributeDirective(CurrDir) || 11401 DVar.CKind != OMPC_lastprivate) && 11402 DVar.RefExpr) { 11403 Diag(ELoc, diag::err_omp_wrong_dsa) 11404 << getOpenMPClauseName(DVar.CKind) 11405 << getOpenMPClauseName(OMPC_firstprivate); 11406 reportOriginalDsa(*this, DSAStack, D, DVar); 11407 continue; 11408 } 11409 11410 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11411 // in a Construct] 11412 // Variables with the predetermined data-sharing attributes may not be 11413 // listed in data-sharing attributes clauses, except for the cases 11414 // listed below. For these exceptions only, listing a predetermined 11415 // variable in a data-sharing attribute clause is allowed and overrides 11416 // the variable's predetermined data-sharing attributes. 11417 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11418 // in a Construct, C/C++, p.2] 11419 // Variables with const-qualified type having no mutable member may be 11420 // listed in a firstprivate clause, even if they are static data members. 11421 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11422 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11423 Diag(ELoc, diag::err_omp_wrong_dsa) 11424 << getOpenMPClauseName(DVar.CKind) 11425 << getOpenMPClauseName(OMPC_firstprivate); 11426 reportOriginalDsa(*this, DSAStack, D, DVar); 11427 continue; 11428 } 11429 11430 // OpenMP [2.9.3.4, Restrictions, p.2] 11431 // A list item that is private within a parallel region must not appear 11432 // in a firstprivate clause on a worksharing construct if any of the 11433 // worksharing regions arising from the worksharing construct ever bind 11434 // to any of the parallel regions arising from the parallel construct. 11435 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11436 // A list item that is private within a teams region must not appear in a 11437 // firstprivate clause on a distribute construct if any of the distribute 11438 // regions arising from the distribute construct ever bind to any of the 11439 // teams regions arising from the teams construct. 11440 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11441 // A list item that appears in a reduction clause of a teams construct 11442 // must not appear in a firstprivate clause on a distribute construct if 11443 // any of the distribute regions arising from the distribute construct 11444 // ever bind to any of the teams regions arising from the teams construct. 11445 if ((isOpenMPWorksharingDirective(CurrDir) || 11446 isOpenMPDistributeDirective(CurrDir)) && 11447 !isOpenMPParallelDirective(CurrDir) && 11448 !isOpenMPTeamsDirective(CurrDir)) { 11449 DVar = DSAStack->getImplicitDSA(D, true); 11450 if (DVar.CKind != OMPC_shared && 11451 (isOpenMPParallelDirective(DVar.DKind) || 11452 isOpenMPTeamsDirective(DVar.DKind) || 11453 DVar.DKind == OMPD_unknown)) { 11454 Diag(ELoc, diag::err_omp_required_access) 11455 << getOpenMPClauseName(OMPC_firstprivate) 11456 << getOpenMPClauseName(OMPC_shared); 11457 reportOriginalDsa(*this, DSAStack, D, DVar); 11458 continue; 11459 } 11460 } 11461 // OpenMP [2.9.3.4, Restrictions, p.3] 11462 // A list item that appears in a reduction clause of a parallel construct 11463 // must not appear in a firstprivate clause on a worksharing or task 11464 // construct if any of the worksharing or task regions arising from the 11465 // worksharing or task construct ever bind to any of the parallel regions 11466 // arising from the parallel construct. 11467 // OpenMP [2.9.3.4, Restrictions, p.4] 11468 // A list item that appears in a reduction clause in worksharing 11469 // construct must not appear in a firstprivate clause in a task construct 11470 // encountered during execution of any of the worksharing regions arising 11471 // from the worksharing construct. 11472 if (isOpenMPTaskingDirective(CurrDir)) { 11473 DVar = DSAStack->hasInnermostDSA( 11474 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11475 [](OpenMPDirectiveKind K) { 11476 return isOpenMPParallelDirective(K) || 11477 isOpenMPWorksharingDirective(K) || 11478 isOpenMPTeamsDirective(K); 11479 }, 11480 /*FromParent=*/true); 11481 if (DVar.CKind == OMPC_reduction && 11482 (isOpenMPParallelDirective(DVar.DKind) || 11483 isOpenMPWorksharingDirective(DVar.DKind) || 11484 isOpenMPTeamsDirective(DVar.DKind))) { 11485 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11486 << getOpenMPDirectiveName(DVar.DKind); 11487 reportOriginalDsa(*this, DSAStack, D, DVar); 11488 continue; 11489 } 11490 } 11491 11492 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11493 // A list item cannot appear in both a map clause and a data-sharing 11494 // attribute clause on the same construct 11495 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11496 OpenMPClauseKind ConflictKind; 11497 if (DSAStack->checkMappableExprComponentListsForDecl( 11498 VD, /*CurrentRegionOnly=*/true, 11499 [&ConflictKind]( 11500 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11501 OpenMPClauseKind WhereFoundClauseKind) { 11502 ConflictKind = WhereFoundClauseKind; 11503 return true; 11504 })) { 11505 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11506 << getOpenMPClauseName(OMPC_firstprivate) 11507 << getOpenMPClauseName(ConflictKind) 11508 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11509 reportOriginalDsa(*this, DSAStack, D, DVar); 11510 continue; 11511 } 11512 } 11513 } 11514 11515 // Variably modified types are not supported for tasks. 11516 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11517 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11518 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11519 << getOpenMPClauseName(OMPC_firstprivate) << Type 11520 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11521 bool IsDecl = 11522 !VD || 11523 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11524 Diag(D->getLocation(), 11525 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11526 << D; 11527 continue; 11528 } 11529 11530 Type = Type.getUnqualifiedType(); 11531 VarDecl *VDPrivate = 11532 buildVarDecl(*this, ELoc, Type, D->getName(), 11533 D->hasAttrs() ? &D->getAttrs() : nullptr, 11534 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11535 // Generate helper private variable and initialize it with the value of the 11536 // original variable. The address of the original variable is replaced by 11537 // the address of the new private variable in the CodeGen. This new variable 11538 // is not added to IdResolver, so the code in the OpenMP region uses 11539 // original variable for proper diagnostics and variable capturing. 11540 Expr *VDInitRefExpr = nullptr; 11541 // For arrays generate initializer for single element and replace it by the 11542 // original array element in CodeGen. 11543 if (Type->isArrayType()) { 11544 VarDecl *VDInit = 11545 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11546 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11547 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11548 ElemType = ElemType.getUnqualifiedType(); 11549 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11550 ".firstprivate.temp"); 11551 InitializedEntity Entity = 11552 InitializedEntity::InitializeVariable(VDInitTemp); 11553 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11554 11555 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11556 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11557 if (Result.isInvalid()) 11558 VDPrivate->setInvalidDecl(); 11559 else 11560 VDPrivate->setInit(Result.getAs<Expr>()); 11561 // Remove temp variable declaration. 11562 Context.Deallocate(VDInitTemp); 11563 } else { 11564 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11565 ".firstprivate.temp"); 11566 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11567 RefExpr->getExprLoc()); 11568 AddInitializerToDecl(VDPrivate, 11569 DefaultLvalueConversion(VDInitRefExpr).get(), 11570 /*DirectInit=*/false); 11571 } 11572 if (VDPrivate->isInvalidDecl()) { 11573 if (IsImplicitClause) { 11574 Diag(RefExpr->getExprLoc(), 11575 diag::note_omp_task_predetermined_firstprivate_here); 11576 } 11577 continue; 11578 } 11579 CurContext->addDecl(VDPrivate); 11580 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11581 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11582 RefExpr->getExprLoc()); 11583 DeclRefExpr *Ref = nullptr; 11584 if (!VD && !CurContext->isDependentContext()) { 11585 if (TopDVar.CKind == OMPC_lastprivate) { 11586 Ref = TopDVar.PrivateCopy; 11587 } else { 11588 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11589 if (!isOpenMPCapturedDecl(D)) 11590 ExprCaptures.push_back(Ref->getDecl()); 11591 } 11592 } 11593 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11594 Vars.push_back((VD || CurContext->isDependentContext()) 11595 ? RefExpr->IgnoreParens() 11596 : Ref); 11597 PrivateCopies.push_back(VDPrivateRefExpr); 11598 Inits.push_back(VDInitRefExpr); 11599 } 11600 11601 if (Vars.empty()) 11602 return nullptr; 11603 11604 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11605 Vars, PrivateCopies, Inits, 11606 buildPreInits(Context, ExprCaptures)); 11607 } 11608 11609 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11610 SourceLocation StartLoc, 11611 SourceLocation LParenLoc, 11612 SourceLocation EndLoc) { 11613 SmallVector<Expr *, 8> Vars; 11614 SmallVector<Expr *, 8> SrcExprs; 11615 SmallVector<Expr *, 8> DstExprs; 11616 SmallVector<Expr *, 8> AssignmentOps; 11617 SmallVector<Decl *, 4> ExprCaptures; 11618 SmallVector<Expr *, 4> ExprPostUpdates; 11619 for (Expr *RefExpr : VarList) { 11620 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11621 SourceLocation ELoc; 11622 SourceRange ERange; 11623 Expr *SimpleRefExpr = RefExpr; 11624 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11625 if (Res.second) { 11626 // It will be analyzed later. 11627 Vars.push_back(RefExpr); 11628 SrcExprs.push_back(nullptr); 11629 DstExprs.push_back(nullptr); 11630 AssignmentOps.push_back(nullptr); 11631 } 11632 ValueDecl *D = Res.first; 11633 if (!D) 11634 continue; 11635 11636 QualType Type = D->getType(); 11637 auto *VD = dyn_cast<VarDecl>(D); 11638 11639 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11640 // A variable that appears in a lastprivate clause must not have an 11641 // incomplete type or a reference type. 11642 if (RequireCompleteType(ELoc, Type, 11643 diag::err_omp_lastprivate_incomplete_type)) 11644 continue; 11645 Type = Type.getNonReferenceType(); 11646 11647 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11648 // A variable that is privatized must not have a const-qualified type 11649 // unless it is of class type with a mutable member. This restriction does 11650 // not apply to the firstprivate clause. 11651 // 11652 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11653 // A variable that appears in a lastprivate clause must not have a 11654 // const-qualified type unless it is of class type with a mutable member. 11655 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11656 continue; 11657 11658 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11659 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11660 // in a Construct] 11661 // Variables with the predetermined data-sharing attributes may not be 11662 // listed in data-sharing attributes clauses, except for the cases 11663 // listed below. 11664 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11665 // A list item may appear in a firstprivate or lastprivate clause but not 11666 // both. 11667 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11668 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11669 (isOpenMPDistributeDirective(CurrDir) || 11670 DVar.CKind != OMPC_firstprivate) && 11671 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11672 Diag(ELoc, diag::err_omp_wrong_dsa) 11673 << getOpenMPClauseName(DVar.CKind) 11674 << getOpenMPClauseName(OMPC_lastprivate); 11675 reportOriginalDsa(*this, DSAStack, D, DVar); 11676 continue; 11677 } 11678 11679 // OpenMP [2.14.3.5, Restrictions, p.2] 11680 // A list item that is private within a parallel region, or that appears in 11681 // the reduction clause of a parallel construct, must not appear in a 11682 // lastprivate clause on a worksharing construct if any of the corresponding 11683 // worksharing regions ever binds to any of the corresponding parallel 11684 // regions. 11685 DSAStackTy::DSAVarData TopDVar = DVar; 11686 if (isOpenMPWorksharingDirective(CurrDir) && 11687 !isOpenMPParallelDirective(CurrDir) && 11688 !isOpenMPTeamsDirective(CurrDir)) { 11689 DVar = DSAStack->getImplicitDSA(D, true); 11690 if (DVar.CKind != OMPC_shared) { 11691 Diag(ELoc, diag::err_omp_required_access) 11692 << getOpenMPClauseName(OMPC_lastprivate) 11693 << getOpenMPClauseName(OMPC_shared); 11694 reportOriginalDsa(*this, DSAStack, D, DVar); 11695 continue; 11696 } 11697 } 11698 11699 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11700 // A variable of class type (or array thereof) that appears in a 11701 // lastprivate clause requires an accessible, unambiguous default 11702 // constructor for the class type, unless the list item is also specified 11703 // in a firstprivate clause. 11704 // A variable of class type (or array thereof) that appears in a 11705 // lastprivate clause requires an accessible, unambiguous copy assignment 11706 // operator for the class type. 11707 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11708 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11709 Type.getUnqualifiedType(), ".lastprivate.src", 11710 D->hasAttrs() ? &D->getAttrs() : nullptr); 11711 DeclRefExpr *PseudoSrcExpr = 11712 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11713 VarDecl *DstVD = 11714 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11715 D->hasAttrs() ? &D->getAttrs() : nullptr); 11716 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11717 // For arrays generate assignment operation for single element and replace 11718 // it by the original array element in CodeGen. 11719 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11720 PseudoDstExpr, PseudoSrcExpr); 11721 if (AssignmentOp.isInvalid()) 11722 continue; 11723 AssignmentOp = 11724 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11725 if (AssignmentOp.isInvalid()) 11726 continue; 11727 11728 DeclRefExpr *Ref = nullptr; 11729 if (!VD && !CurContext->isDependentContext()) { 11730 if (TopDVar.CKind == OMPC_firstprivate) { 11731 Ref = TopDVar.PrivateCopy; 11732 } else { 11733 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11734 if (!isOpenMPCapturedDecl(D)) 11735 ExprCaptures.push_back(Ref->getDecl()); 11736 } 11737 if (TopDVar.CKind == OMPC_firstprivate || 11738 (!isOpenMPCapturedDecl(D) && 11739 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11740 ExprResult RefRes = DefaultLvalueConversion(Ref); 11741 if (!RefRes.isUsable()) 11742 continue; 11743 ExprResult PostUpdateRes = 11744 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11745 RefRes.get()); 11746 if (!PostUpdateRes.isUsable()) 11747 continue; 11748 ExprPostUpdates.push_back( 11749 IgnoredValueConversions(PostUpdateRes.get()).get()); 11750 } 11751 } 11752 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11753 Vars.push_back((VD || CurContext->isDependentContext()) 11754 ? RefExpr->IgnoreParens() 11755 : Ref); 11756 SrcExprs.push_back(PseudoSrcExpr); 11757 DstExprs.push_back(PseudoDstExpr); 11758 AssignmentOps.push_back(AssignmentOp.get()); 11759 } 11760 11761 if (Vars.empty()) 11762 return nullptr; 11763 11764 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11765 Vars, SrcExprs, DstExprs, AssignmentOps, 11766 buildPreInits(Context, ExprCaptures), 11767 buildPostUpdate(*this, ExprPostUpdates)); 11768 } 11769 11770 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11771 SourceLocation StartLoc, 11772 SourceLocation LParenLoc, 11773 SourceLocation EndLoc) { 11774 SmallVector<Expr *, 8> Vars; 11775 for (Expr *RefExpr : VarList) { 11776 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11777 SourceLocation ELoc; 11778 SourceRange ERange; 11779 Expr *SimpleRefExpr = RefExpr; 11780 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11781 if (Res.second) { 11782 // It will be analyzed later. 11783 Vars.push_back(RefExpr); 11784 } 11785 ValueDecl *D = Res.first; 11786 if (!D) 11787 continue; 11788 11789 auto *VD = dyn_cast<VarDecl>(D); 11790 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11791 // in a Construct] 11792 // Variables with the predetermined data-sharing attributes may not be 11793 // listed in data-sharing attributes clauses, except for the cases 11794 // listed below. For these exceptions only, listing a predetermined 11795 // variable in a data-sharing attribute clause is allowed and overrides 11796 // the variable's predetermined data-sharing attributes. 11797 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11798 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 11799 DVar.RefExpr) { 11800 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11801 << getOpenMPClauseName(OMPC_shared); 11802 reportOriginalDsa(*this, DSAStack, D, DVar); 11803 continue; 11804 } 11805 11806 DeclRefExpr *Ref = nullptr; 11807 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 11808 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11809 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 11810 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 11811 ? RefExpr->IgnoreParens() 11812 : Ref); 11813 } 11814 11815 if (Vars.empty()) 11816 return nullptr; 11817 11818 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 11819 } 11820 11821 namespace { 11822 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 11823 DSAStackTy *Stack; 11824 11825 public: 11826 bool VisitDeclRefExpr(DeclRefExpr *E) { 11827 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 11828 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 11829 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 11830 return false; 11831 if (DVar.CKind != OMPC_unknown) 11832 return true; 11833 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 11834 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 11835 /*FromParent=*/true); 11836 return DVarPrivate.CKind != OMPC_unknown; 11837 } 11838 return false; 11839 } 11840 bool VisitStmt(Stmt *S) { 11841 for (Stmt *Child : S->children()) { 11842 if (Child && Visit(Child)) 11843 return true; 11844 } 11845 return false; 11846 } 11847 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 11848 }; 11849 } // namespace 11850 11851 namespace { 11852 // Transform MemberExpression for specified FieldDecl of current class to 11853 // DeclRefExpr to specified OMPCapturedExprDecl. 11854 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 11855 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 11856 ValueDecl *Field = nullptr; 11857 DeclRefExpr *CapturedExpr = nullptr; 11858 11859 public: 11860 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 11861 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 11862 11863 ExprResult TransformMemberExpr(MemberExpr *E) { 11864 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 11865 E->getMemberDecl() == Field) { 11866 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 11867 return CapturedExpr; 11868 } 11869 return BaseTransform::TransformMemberExpr(E); 11870 } 11871 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 11872 }; 11873 } // namespace 11874 11875 template <typename T, typename U> 11876 static T filterLookupForUDReductionAndMapper( 11877 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 11878 for (U &Set : Lookups) { 11879 for (auto *D : Set) { 11880 if (T Res = Gen(cast<ValueDecl>(D))) 11881 return Res; 11882 } 11883 } 11884 return T(); 11885 } 11886 11887 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 11888 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 11889 11890 for (auto RD : D->redecls()) { 11891 // Don't bother with extra checks if we already know this one isn't visible. 11892 if (RD == D) 11893 continue; 11894 11895 auto ND = cast<NamedDecl>(RD); 11896 if (LookupResult::isVisible(SemaRef, ND)) 11897 return ND; 11898 } 11899 11900 return nullptr; 11901 } 11902 11903 static void 11904 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 11905 SourceLocation Loc, QualType Ty, 11906 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 11907 // Find all of the associated namespaces and classes based on the 11908 // arguments we have. 11909 Sema::AssociatedNamespaceSet AssociatedNamespaces; 11910 Sema::AssociatedClassSet AssociatedClasses; 11911 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 11912 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 11913 AssociatedClasses); 11914 11915 // C++ [basic.lookup.argdep]p3: 11916 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11917 // and let Y be the lookup set produced by argument dependent 11918 // lookup (defined as follows). If X contains [...] then Y is 11919 // empty. Otherwise Y is the set of declarations found in the 11920 // namespaces associated with the argument types as described 11921 // below. The set of declarations found by the lookup of the name 11922 // is the union of X and Y. 11923 // 11924 // Here, we compute Y and add its members to the overloaded 11925 // candidate set. 11926 for (auto *NS : AssociatedNamespaces) { 11927 // When considering an associated namespace, the lookup is the 11928 // same as the lookup performed when the associated namespace is 11929 // used as a qualifier (3.4.3.2) except that: 11930 // 11931 // -- Any using-directives in the associated namespace are 11932 // ignored. 11933 // 11934 // -- Any namespace-scope friend functions declared in 11935 // associated classes are visible within their respective 11936 // namespaces even if they are not visible during an ordinary 11937 // lookup (11.4). 11938 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11939 for (auto *D : R) { 11940 auto *Underlying = D; 11941 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11942 Underlying = USD->getTargetDecl(); 11943 11944 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11945 !isa<OMPDeclareMapperDecl>(Underlying)) 11946 continue; 11947 11948 if (!SemaRef.isVisible(D)) { 11949 D = findAcceptableDecl(SemaRef, D); 11950 if (!D) 11951 continue; 11952 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11953 Underlying = USD->getTargetDecl(); 11954 } 11955 Lookups.emplace_back(); 11956 Lookups.back().addDecl(Underlying); 11957 } 11958 } 11959 } 11960 11961 static ExprResult 11962 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11963 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11964 const DeclarationNameInfo &ReductionId, QualType Ty, 11965 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11966 if (ReductionIdScopeSpec.isInvalid()) 11967 return ExprError(); 11968 SmallVector<UnresolvedSet<8>, 4> Lookups; 11969 if (S) { 11970 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11971 Lookup.suppressDiagnostics(); 11972 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11973 NamedDecl *D = Lookup.getRepresentativeDecl(); 11974 do { 11975 S = S->getParent(); 11976 } while (S && !S->isDeclScope(D)); 11977 if (S) 11978 S = S->getParent(); 11979 Lookups.emplace_back(); 11980 Lookups.back().append(Lookup.begin(), Lookup.end()); 11981 Lookup.clear(); 11982 } 11983 } else if (auto *ULE = 11984 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11985 Lookups.push_back(UnresolvedSet<8>()); 11986 Decl *PrevD = nullptr; 11987 for (NamedDecl *D : ULE->decls()) { 11988 if (D == PrevD) 11989 Lookups.push_back(UnresolvedSet<8>()); 11990 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11991 Lookups.back().addDecl(DRD); 11992 PrevD = D; 11993 } 11994 } 11995 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11996 Ty->isInstantiationDependentType() || 11997 Ty->containsUnexpandedParameterPack() || 11998 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11999 return !D->isInvalidDecl() && 12000 (D->getType()->isDependentType() || 12001 D->getType()->isInstantiationDependentType() || 12002 D->getType()->containsUnexpandedParameterPack()); 12003 })) { 12004 UnresolvedSet<8> ResSet; 12005 for (const UnresolvedSet<8> &Set : Lookups) { 12006 if (Set.empty()) 12007 continue; 12008 ResSet.append(Set.begin(), Set.end()); 12009 // The last item marks the end of all declarations at the specified scope. 12010 ResSet.addDecl(Set[Set.size() - 1]); 12011 } 12012 return UnresolvedLookupExpr::Create( 12013 SemaRef.Context, /*NamingClass=*/nullptr, 12014 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12015 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12016 } 12017 // Lookup inside the classes. 12018 // C++ [over.match.oper]p3: 12019 // For a unary operator @ with an operand of a type whose 12020 // cv-unqualified version is T1, and for a binary operator @ with 12021 // a left operand of a type whose cv-unqualified version is T1 and 12022 // a right operand of a type whose cv-unqualified version is T2, 12023 // three sets of candidate functions, designated member 12024 // candidates, non-member candidates and built-in candidates, are 12025 // constructed as follows: 12026 // -- If T1 is a complete class type or a class currently being 12027 // defined, the set of member candidates is the result of the 12028 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12029 // the set of member candidates is empty. 12030 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12031 Lookup.suppressDiagnostics(); 12032 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12033 // Complete the type if it can be completed. 12034 // If the type is neither complete nor being defined, bail out now. 12035 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12036 TyRec->getDecl()->getDefinition()) { 12037 Lookup.clear(); 12038 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12039 if (Lookup.empty()) { 12040 Lookups.emplace_back(); 12041 Lookups.back().append(Lookup.begin(), Lookup.end()); 12042 } 12043 } 12044 } 12045 // Perform ADL. 12046 if (SemaRef.getLangOpts().CPlusPlus) 12047 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12048 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12049 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12050 if (!D->isInvalidDecl() && 12051 SemaRef.Context.hasSameType(D->getType(), Ty)) 12052 return D; 12053 return nullptr; 12054 })) 12055 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12056 VK_LValue, Loc); 12057 if (SemaRef.getLangOpts().CPlusPlus) { 12058 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12059 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12060 if (!D->isInvalidDecl() && 12061 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12062 !Ty.isMoreQualifiedThan(D->getType())) 12063 return D; 12064 return nullptr; 12065 })) { 12066 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12067 /*DetectVirtual=*/false); 12068 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12069 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12070 VD->getType().getUnqualifiedType()))) { 12071 if (SemaRef.CheckBaseClassAccess( 12072 Loc, VD->getType(), Ty, Paths.front(), 12073 /*DiagID=*/0) != Sema::AR_inaccessible) { 12074 SemaRef.BuildBasePathArray(Paths, BasePath); 12075 return SemaRef.BuildDeclRefExpr( 12076 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12077 } 12078 } 12079 } 12080 } 12081 } 12082 if (ReductionIdScopeSpec.isSet()) { 12083 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12084 return ExprError(); 12085 } 12086 return ExprEmpty(); 12087 } 12088 12089 namespace { 12090 /// Data for the reduction-based clauses. 12091 struct ReductionData { 12092 /// List of original reduction items. 12093 SmallVector<Expr *, 8> Vars; 12094 /// List of private copies of the reduction items. 12095 SmallVector<Expr *, 8> Privates; 12096 /// LHS expressions for the reduction_op expressions. 12097 SmallVector<Expr *, 8> LHSs; 12098 /// RHS expressions for the reduction_op expressions. 12099 SmallVector<Expr *, 8> RHSs; 12100 /// Reduction operation expression. 12101 SmallVector<Expr *, 8> ReductionOps; 12102 /// Taskgroup descriptors for the corresponding reduction items in 12103 /// in_reduction clauses. 12104 SmallVector<Expr *, 8> TaskgroupDescriptors; 12105 /// List of captures for clause. 12106 SmallVector<Decl *, 4> ExprCaptures; 12107 /// List of postupdate expressions. 12108 SmallVector<Expr *, 4> ExprPostUpdates; 12109 ReductionData() = delete; 12110 /// Reserves required memory for the reduction data. 12111 ReductionData(unsigned Size) { 12112 Vars.reserve(Size); 12113 Privates.reserve(Size); 12114 LHSs.reserve(Size); 12115 RHSs.reserve(Size); 12116 ReductionOps.reserve(Size); 12117 TaskgroupDescriptors.reserve(Size); 12118 ExprCaptures.reserve(Size); 12119 ExprPostUpdates.reserve(Size); 12120 } 12121 /// Stores reduction item and reduction operation only (required for dependent 12122 /// reduction item). 12123 void push(Expr *Item, Expr *ReductionOp) { 12124 Vars.emplace_back(Item); 12125 Privates.emplace_back(nullptr); 12126 LHSs.emplace_back(nullptr); 12127 RHSs.emplace_back(nullptr); 12128 ReductionOps.emplace_back(ReductionOp); 12129 TaskgroupDescriptors.emplace_back(nullptr); 12130 } 12131 /// Stores reduction data. 12132 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12133 Expr *TaskgroupDescriptor) { 12134 Vars.emplace_back(Item); 12135 Privates.emplace_back(Private); 12136 LHSs.emplace_back(LHS); 12137 RHSs.emplace_back(RHS); 12138 ReductionOps.emplace_back(ReductionOp); 12139 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12140 } 12141 }; 12142 } // namespace 12143 12144 static bool checkOMPArraySectionConstantForReduction( 12145 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12146 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12147 const Expr *Length = OASE->getLength(); 12148 if (Length == nullptr) { 12149 // For array sections of the form [1:] or [:], we would need to analyze 12150 // the lower bound... 12151 if (OASE->getColonLoc().isValid()) 12152 return false; 12153 12154 // This is an array subscript which has implicit length 1! 12155 SingleElement = true; 12156 ArraySizes.push_back(llvm::APSInt::get(1)); 12157 } else { 12158 Expr::EvalResult Result; 12159 if (!Length->EvaluateAsInt(Result, Context)) 12160 return false; 12161 12162 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12163 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12164 ArraySizes.push_back(ConstantLengthValue); 12165 } 12166 12167 // Get the base of this array section and walk up from there. 12168 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12169 12170 // We require length = 1 for all array sections except the right-most to 12171 // guarantee that the memory region is contiguous and has no holes in it. 12172 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12173 Length = TempOASE->getLength(); 12174 if (Length == nullptr) { 12175 // For array sections of the form [1:] or [:], we would need to analyze 12176 // the lower bound... 12177 if (OASE->getColonLoc().isValid()) 12178 return false; 12179 12180 // This is an array subscript which has implicit length 1! 12181 ArraySizes.push_back(llvm::APSInt::get(1)); 12182 } else { 12183 Expr::EvalResult Result; 12184 if (!Length->EvaluateAsInt(Result, Context)) 12185 return false; 12186 12187 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12188 if (ConstantLengthValue.getSExtValue() != 1) 12189 return false; 12190 12191 ArraySizes.push_back(ConstantLengthValue); 12192 } 12193 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12194 } 12195 12196 // If we have a single element, we don't need to add the implicit lengths. 12197 if (!SingleElement) { 12198 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12199 // Has implicit length 1! 12200 ArraySizes.push_back(llvm::APSInt::get(1)); 12201 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12202 } 12203 } 12204 12205 // This array section can be privatized as a single value or as a constant 12206 // sized array. 12207 return true; 12208 } 12209 12210 static bool actOnOMPReductionKindClause( 12211 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12212 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12213 SourceLocation ColonLoc, SourceLocation EndLoc, 12214 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12215 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12216 DeclarationName DN = ReductionId.getName(); 12217 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12218 BinaryOperatorKind BOK = BO_Comma; 12219 12220 ASTContext &Context = S.Context; 12221 // OpenMP [2.14.3.6, reduction clause] 12222 // C 12223 // reduction-identifier is either an identifier or one of the following 12224 // operators: +, -, *, &, |, ^, && and || 12225 // C++ 12226 // reduction-identifier is either an id-expression or one of the following 12227 // operators: +, -, *, &, |, ^, && and || 12228 switch (OOK) { 12229 case OO_Plus: 12230 case OO_Minus: 12231 BOK = BO_Add; 12232 break; 12233 case OO_Star: 12234 BOK = BO_Mul; 12235 break; 12236 case OO_Amp: 12237 BOK = BO_And; 12238 break; 12239 case OO_Pipe: 12240 BOK = BO_Or; 12241 break; 12242 case OO_Caret: 12243 BOK = BO_Xor; 12244 break; 12245 case OO_AmpAmp: 12246 BOK = BO_LAnd; 12247 break; 12248 case OO_PipePipe: 12249 BOK = BO_LOr; 12250 break; 12251 case OO_New: 12252 case OO_Delete: 12253 case OO_Array_New: 12254 case OO_Array_Delete: 12255 case OO_Slash: 12256 case OO_Percent: 12257 case OO_Tilde: 12258 case OO_Exclaim: 12259 case OO_Equal: 12260 case OO_Less: 12261 case OO_Greater: 12262 case OO_LessEqual: 12263 case OO_GreaterEqual: 12264 case OO_PlusEqual: 12265 case OO_MinusEqual: 12266 case OO_StarEqual: 12267 case OO_SlashEqual: 12268 case OO_PercentEqual: 12269 case OO_CaretEqual: 12270 case OO_AmpEqual: 12271 case OO_PipeEqual: 12272 case OO_LessLess: 12273 case OO_GreaterGreater: 12274 case OO_LessLessEqual: 12275 case OO_GreaterGreaterEqual: 12276 case OO_EqualEqual: 12277 case OO_ExclaimEqual: 12278 case OO_Spaceship: 12279 case OO_PlusPlus: 12280 case OO_MinusMinus: 12281 case OO_Comma: 12282 case OO_ArrowStar: 12283 case OO_Arrow: 12284 case OO_Call: 12285 case OO_Subscript: 12286 case OO_Conditional: 12287 case OO_Coawait: 12288 case NUM_OVERLOADED_OPERATORS: 12289 llvm_unreachable("Unexpected reduction identifier"); 12290 case OO_None: 12291 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 12292 if (II->isStr("max")) 12293 BOK = BO_GT; 12294 else if (II->isStr("min")) 12295 BOK = BO_LT; 12296 } 12297 break; 12298 } 12299 SourceRange ReductionIdRange; 12300 if (ReductionIdScopeSpec.isValid()) 12301 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 12302 else 12303 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 12304 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 12305 12306 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 12307 bool FirstIter = true; 12308 for (Expr *RefExpr : VarList) { 12309 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 12310 // OpenMP [2.1, C/C++] 12311 // A list item is a variable or array section, subject to the restrictions 12312 // specified in Section 2.4 on page 42 and in each of the sections 12313 // describing clauses and directives for which a list appears. 12314 // OpenMP [2.14.3.3, Restrictions, p.1] 12315 // A variable that is part of another variable (as an array or 12316 // structure element) cannot appear in a private clause. 12317 if (!FirstIter && IR != ER) 12318 ++IR; 12319 FirstIter = false; 12320 SourceLocation ELoc; 12321 SourceRange ERange; 12322 Expr *SimpleRefExpr = RefExpr; 12323 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 12324 /*AllowArraySection=*/true); 12325 if (Res.second) { 12326 // Try to find 'declare reduction' corresponding construct before using 12327 // builtin/overloaded operators. 12328 QualType Type = Context.DependentTy; 12329 CXXCastPath BasePath; 12330 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12331 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12332 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12333 Expr *ReductionOp = nullptr; 12334 if (S.CurContext->isDependentContext() && 12335 (DeclareReductionRef.isUnset() || 12336 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 12337 ReductionOp = DeclareReductionRef.get(); 12338 // It will be analyzed later. 12339 RD.push(RefExpr, ReductionOp); 12340 } 12341 ValueDecl *D = Res.first; 12342 if (!D) 12343 continue; 12344 12345 Expr *TaskgroupDescriptor = nullptr; 12346 QualType Type; 12347 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 12348 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 12349 if (ASE) { 12350 Type = ASE->getType().getNonReferenceType(); 12351 } else if (OASE) { 12352 QualType BaseType = 12353 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 12354 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 12355 Type = ATy->getElementType(); 12356 else 12357 Type = BaseType->getPointeeType(); 12358 Type = Type.getNonReferenceType(); 12359 } else { 12360 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 12361 } 12362 auto *VD = dyn_cast<VarDecl>(D); 12363 12364 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12365 // A variable that appears in a private clause must not have an incomplete 12366 // type or a reference type. 12367 if (S.RequireCompleteType(ELoc, D->getType(), 12368 diag::err_omp_reduction_incomplete_type)) 12369 continue; 12370 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12371 // A list item that appears in a reduction clause must not be 12372 // const-qualified. 12373 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12374 /*AcceptIfMutable*/ false, ASE || OASE)) 12375 continue; 12376 12377 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12378 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12379 // If a list-item is a reference type then it must bind to the same object 12380 // for all threads of the team. 12381 if (!ASE && !OASE) { 12382 if (VD) { 12383 VarDecl *VDDef = VD->getDefinition(); 12384 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12385 DSARefChecker Check(Stack); 12386 if (Check.Visit(VDDef->getInit())) { 12387 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12388 << getOpenMPClauseName(ClauseKind) << ERange; 12389 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12390 continue; 12391 } 12392 } 12393 } 12394 12395 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12396 // in a Construct] 12397 // Variables with the predetermined data-sharing attributes may not be 12398 // listed in data-sharing attributes clauses, except for the cases 12399 // listed below. For these exceptions only, listing a predetermined 12400 // variable in a data-sharing attribute clause is allowed and overrides 12401 // the variable's predetermined data-sharing attributes. 12402 // OpenMP [2.14.3.6, Restrictions, p.3] 12403 // Any number of reduction clauses can be specified on the directive, 12404 // but a list item can appear only once in the reduction clauses for that 12405 // directive. 12406 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12407 if (DVar.CKind == OMPC_reduction) { 12408 S.Diag(ELoc, diag::err_omp_once_referenced) 12409 << getOpenMPClauseName(ClauseKind); 12410 if (DVar.RefExpr) 12411 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12412 continue; 12413 } 12414 if (DVar.CKind != OMPC_unknown) { 12415 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12416 << getOpenMPClauseName(DVar.CKind) 12417 << getOpenMPClauseName(OMPC_reduction); 12418 reportOriginalDsa(S, Stack, D, DVar); 12419 continue; 12420 } 12421 12422 // OpenMP [2.14.3.6, Restrictions, p.1] 12423 // A list item that appears in a reduction clause of a worksharing 12424 // construct must be shared in the parallel regions to which any of the 12425 // worksharing regions arising from the worksharing construct bind. 12426 if (isOpenMPWorksharingDirective(CurrDir) && 12427 !isOpenMPParallelDirective(CurrDir) && 12428 !isOpenMPTeamsDirective(CurrDir)) { 12429 DVar = Stack->getImplicitDSA(D, true); 12430 if (DVar.CKind != OMPC_shared) { 12431 S.Diag(ELoc, diag::err_omp_required_access) 12432 << getOpenMPClauseName(OMPC_reduction) 12433 << getOpenMPClauseName(OMPC_shared); 12434 reportOriginalDsa(S, Stack, D, DVar); 12435 continue; 12436 } 12437 } 12438 } 12439 12440 // Try to find 'declare reduction' corresponding construct before using 12441 // builtin/overloaded operators. 12442 CXXCastPath BasePath; 12443 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12444 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12445 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12446 if (DeclareReductionRef.isInvalid()) 12447 continue; 12448 if (S.CurContext->isDependentContext() && 12449 (DeclareReductionRef.isUnset() || 12450 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12451 RD.push(RefExpr, DeclareReductionRef.get()); 12452 continue; 12453 } 12454 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12455 // Not allowed reduction identifier is found. 12456 S.Diag(ReductionId.getBeginLoc(), 12457 diag::err_omp_unknown_reduction_identifier) 12458 << Type << ReductionIdRange; 12459 continue; 12460 } 12461 12462 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12463 // The type of a list item that appears in a reduction clause must be valid 12464 // for the reduction-identifier. For a max or min reduction in C, the type 12465 // of the list item must be an allowed arithmetic data type: char, int, 12466 // float, double, or _Bool, possibly modified with long, short, signed, or 12467 // unsigned. For a max or min reduction in C++, the type of the list item 12468 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12469 // double, or bool, possibly modified with long, short, signed, or unsigned. 12470 if (DeclareReductionRef.isUnset()) { 12471 if ((BOK == BO_GT || BOK == BO_LT) && 12472 !(Type->isScalarType() || 12473 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12474 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12475 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12476 if (!ASE && !OASE) { 12477 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12478 VarDecl::DeclarationOnly; 12479 S.Diag(D->getLocation(), 12480 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12481 << D; 12482 } 12483 continue; 12484 } 12485 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12486 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12487 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12488 << getOpenMPClauseName(ClauseKind); 12489 if (!ASE && !OASE) { 12490 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12491 VarDecl::DeclarationOnly; 12492 S.Diag(D->getLocation(), 12493 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12494 << D; 12495 } 12496 continue; 12497 } 12498 } 12499 12500 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12501 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12502 D->hasAttrs() ? &D->getAttrs() : nullptr); 12503 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12504 D->hasAttrs() ? &D->getAttrs() : nullptr); 12505 QualType PrivateTy = Type; 12506 12507 // Try if we can determine constant lengths for all array sections and avoid 12508 // the VLA. 12509 bool ConstantLengthOASE = false; 12510 if (OASE) { 12511 bool SingleElement; 12512 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12513 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12514 Context, OASE, SingleElement, ArraySizes); 12515 12516 // If we don't have a single element, we must emit a constant array type. 12517 if (ConstantLengthOASE && !SingleElement) { 12518 for (llvm::APSInt &Size : ArraySizes) 12519 PrivateTy = Context.getConstantArrayType( 12520 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12521 } 12522 } 12523 12524 if ((OASE && !ConstantLengthOASE) || 12525 (!OASE && !ASE && 12526 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12527 if (!Context.getTargetInfo().isVLASupported()) { 12528 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 12529 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12530 S.Diag(ELoc, diag::note_vla_unsupported); 12531 } else { 12532 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12533 S.targetDiag(ELoc, diag::note_vla_unsupported); 12534 } 12535 continue; 12536 } 12537 // For arrays/array sections only: 12538 // Create pseudo array type for private copy. The size for this array will 12539 // be generated during codegen. 12540 // For array subscripts or single variables Private Ty is the same as Type 12541 // (type of the variable or single array element). 12542 PrivateTy = Context.getVariableArrayType( 12543 Type, 12544 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12545 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12546 } else if (!ASE && !OASE && 12547 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12548 PrivateTy = D->getType().getNonReferenceType(); 12549 } 12550 // Private copy. 12551 VarDecl *PrivateVD = 12552 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12553 D->hasAttrs() ? &D->getAttrs() : nullptr, 12554 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12555 // Add initializer for private variable. 12556 Expr *Init = nullptr; 12557 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12558 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12559 if (DeclareReductionRef.isUsable()) { 12560 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12561 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12562 if (DRD->getInitializer()) { 12563 Init = DRDRef; 12564 RHSVD->setInit(DRDRef); 12565 RHSVD->setInitStyle(VarDecl::CallInit); 12566 } 12567 } else { 12568 switch (BOK) { 12569 case BO_Add: 12570 case BO_Xor: 12571 case BO_Or: 12572 case BO_LOr: 12573 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12574 if (Type->isScalarType() || Type->isAnyComplexType()) 12575 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12576 break; 12577 case BO_Mul: 12578 case BO_LAnd: 12579 if (Type->isScalarType() || Type->isAnyComplexType()) { 12580 // '*' and '&&' reduction ops - initializer is '1'. 12581 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12582 } 12583 break; 12584 case BO_And: { 12585 // '&' reduction op - initializer is '~0'. 12586 QualType OrigType = Type; 12587 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12588 Type = ComplexTy->getElementType(); 12589 if (Type->isRealFloatingType()) { 12590 llvm::APFloat InitValue = 12591 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12592 /*isIEEE=*/true); 12593 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12594 Type, ELoc); 12595 } else if (Type->isScalarType()) { 12596 uint64_t Size = Context.getTypeSize(Type); 12597 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12598 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12599 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12600 } 12601 if (Init && OrigType->isAnyComplexType()) { 12602 // Init = 0xFFFF + 0xFFFFi; 12603 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12604 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12605 } 12606 Type = OrigType; 12607 break; 12608 } 12609 case BO_LT: 12610 case BO_GT: { 12611 // 'min' reduction op - initializer is 'Largest representable number in 12612 // the reduction list item type'. 12613 // 'max' reduction op - initializer is 'Least representable number in 12614 // the reduction list item type'. 12615 if (Type->isIntegerType() || Type->isPointerType()) { 12616 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12617 uint64_t Size = Context.getTypeSize(Type); 12618 QualType IntTy = 12619 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12620 llvm::APInt InitValue = 12621 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12622 : llvm::APInt::getMinValue(Size) 12623 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12624 : llvm::APInt::getMaxValue(Size); 12625 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12626 if (Type->isPointerType()) { 12627 // Cast to pointer type. 12628 ExprResult CastExpr = S.BuildCStyleCastExpr( 12629 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12630 if (CastExpr.isInvalid()) 12631 continue; 12632 Init = CastExpr.get(); 12633 } 12634 } else if (Type->isRealFloatingType()) { 12635 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12636 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12637 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12638 Type, ELoc); 12639 } 12640 break; 12641 } 12642 case BO_PtrMemD: 12643 case BO_PtrMemI: 12644 case BO_MulAssign: 12645 case BO_Div: 12646 case BO_Rem: 12647 case BO_Sub: 12648 case BO_Shl: 12649 case BO_Shr: 12650 case BO_LE: 12651 case BO_GE: 12652 case BO_EQ: 12653 case BO_NE: 12654 case BO_Cmp: 12655 case BO_AndAssign: 12656 case BO_XorAssign: 12657 case BO_OrAssign: 12658 case BO_Assign: 12659 case BO_AddAssign: 12660 case BO_SubAssign: 12661 case BO_DivAssign: 12662 case BO_RemAssign: 12663 case BO_ShlAssign: 12664 case BO_ShrAssign: 12665 case BO_Comma: 12666 llvm_unreachable("Unexpected reduction operation"); 12667 } 12668 } 12669 if (Init && DeclareReductionRef.isUnset()) 12670 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12671 else if (!Init) 12672 S.ActOnUninitializedDecl(RHSVD); 12673 if (RHSVD->isInvalidDecl()) 12674 continue; 12675 if (!RHSVD->hasInit() && 12676 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12677 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12678 << Type << ReductionIdRange; 12679 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12680 VarDecl::DeclarationOnly; 12681 S.Diag(D->getLocation(), 12682 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12683 << D; 12684 continue; 12685 } 12686 // Store initializer for single element in private copy. Will be used during 12687 // codegen. 12688 PrivateVD->setInit(RHSVD->getInit()); 12689 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12690 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12691 ExprResult ReductionOp; 12692 if (DeclareReductionRef.isUsable()) { 12693 QualType RedTy = DeclareReductionRef.get()->getType(); 12694 QualType PtrRedTy = Context.getPointerType(RedTy); 12695 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12696 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12697 if (!BasePath.empty()) { 12698 LHS = S.DefaultLvalueConversion(LHS.get()); 12699 RHS = S.DefaultLvalueConversion(RHS.get()); 12700 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12701 CK_UncheckedDerivedToBase, LHS.get(), 12702 &BasePath, LHS.get()->getValueKind()); 12703 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12704 CK_UncheckedDerivedToBase, RHS.get(), 12705 &BasePath, RHS.get()->getValueKind()); 12706 } 12707 FunctionProtoType::ExtProtoInfo EPI; 12708 QualType Params[] = {PtrRedTy, PtrRedTy}; 12709 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12710 auto *OVE = new (Context) OpaqueValueExpr( 12711 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12712 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12713 Expr *Args[] = {LHS.get(), RHS.get()}; 12714 ReductionOp = 12715 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12716 } else { 12717 ReductionOp = S.BuildBinOp( 12718 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12719 if (ReductionOp.isUsable()) { 12720 if (BOK != BO_LT && BOK != BO_GT) { 12721 ReductionOp = 12722 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12723 BO_Assign, LHSDRE, ReductionOp.get()); 12724 } else { 12725 auto *ConditionalOp = new (Context) 12726 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12727 Type, VK_LValue, OK_Ordinary); 12728 ReductionOp = 12729 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12730 BO_Assign, LHSDRE, ConditionalOp); 12731 } 12732 if (ReductionOp.isUsable()) 12733 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12734 /*DiscardedValue*/ false); 12735 } 12736 if (!ReductionOp.isUsable()) 12737 continue; 12738 } 12739 12740 // OpenMP [2.15.4.6, Restrictions, p.2] 12741 // A list item that appears in an in_reduction clause of a task construct 12742 // must appear in a task_reduction clause of a construct associated with a 12743 // taskgroup region that includes the participating task in its taskgroup 12744 // set. The construct associated with the innermost region that meets this 12745 // condition must specify the same reduction-identifier as the in_reduction 12746 // clause. 12747 if (ClauseKind == OMPC_in_reduction) { 12748 SourceRange ParentSR; 12749 BinaryOperatorKind ParentBOK; 12750 const Expr *ParentReductionOp; 12751 Expr *ParentBOKTD, *ParentReductionOpTD; 12752 DSAStackTy::DSAVarData ParentBOKDSA = 12753 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12754 ParentBOKTD); 12755 DSAStackTy::DSAVarData ParentReductionOpDSA = 12756 Stack->getTopMostTaskgroupReductionData( 12757 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12758 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12759 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12760 if (!IsParentBOK && !IsParentReductionOp) { 12761 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12762 continue; 12763 } 12764 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12765 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12766 IsParentReductionOp) { 12767 bool EmitError = true; 12768 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12769 llvm::FoldingSetNodeID RedId, ParentRedId; 12770 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12771 DeclareReductionRef.get()->Profile(RedId, Context, 12772 /*Canonical=*/true); 12773 EmitError = RedId != ParentRedId; 12774 } 12775 if (EmitError) { 12776 S.Diag(ReductionId.getBeginLoc(), 12777 diag::err_omp_reduction_identifier_mismatch) 12778 << ReductionIdRange << RefExpr->getSourceRange(); 12779 S.Diag(ParentSR.getBegin(), 12780 diag::note_omp_previous_reduction_identifier) 12781 << ParentSR 12782 << (IsParentBOK ? ParentBOKDSA.RefExpr 12783 : ParentReductionOpDSA.RefExpr) 12784 ->getSourceRange(); 12785 continue; 12786 } 12787 } 12788 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12789 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12790 } 12791 12792 DeclRefExpr *Ref = nullptr; 12793 Expr *VarsExpr = RefExpr->IgnoreParens(); 12794 if (!VD && !S.CurContext->isDependentContext()) { 12795 if (ASE || OASE) { 12796 TransformExprToCaptures RebuildToCapture(S, D); 12797 VarsExpr = 12798 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 12799 Ref = RebuildToCapture.getCapturedExpr(); 12800 } else { 12801 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 12802 } 12803 if (!S.isOpenMPCapturedDecl(D)) { 12804 RD.ExprCaptures.emplace_back(Ref->getDecl()); 12805 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12806 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 12807 if (!RefRes.isUsable()) 12808 continue; 12809 ExprResult PostUpdateRes = 12810 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12811 RefRes.get()); 12812 if (!PostUpdateRes.isUsable()) 12813 continue; 12814 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 12815 Stack->getCurrentDirective() == OMPD_taskgroup) { 12816 S.Diag(RefExpr->getExprLoc(), 12817 diag::err_omp_reduction_non_addressable_expression) 12818 << RefExpr->getSourceRange(); 12819 continue; 12820 } 12821 RD.ExprPostUpdates.emplace_back( 12822 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 12823 } 12824 } 12825 } 12826 // All reduction items are still marked as reduction (to do not increase 12827 // code base size). 12828 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 12829 if (CurrDir == OMPD_taskgroup) { 12830 if (DeclareReductionRef.isUsable()) 12831 Stack->addTaskgroupReductionData(D, ReductionIdRange, 12832 DeclareReductionRef.get()); 12833 else 12834 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 12835 } 12836 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 12837 TaskgroupDescriptor); 12838 } 12839 return RD.Vars.empty(); 12840 } 12841 12842 OMPClause *Sema::ActOnOpenMPReductionClause( 12843 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12844 SourceLocation ColonLoc, SourceLocation EndLoc, 12845 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12846 ArrayRef<Expr *> UnresolvedReductions) { 12847 ReductionData RD(VarList.size()); 12848 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 12849 StartLoc, LParenLoc, ColonLoc, EndLoc, 12850 ReductionIdScopeSpec, ReductionId, 12851 UnresolvedReductions, RD)) 12852 return nullptr; 12853 12854 return OMPReductionClause::Create( 12855 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12856 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12857 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12858 buildPreInits(Context, RD.ExprCaptures), 12859 buildPostUpdate(*this, RD.ExprPostUpdates)); 12860 } 12861 12862 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 12863 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12864 SourceLocation ColonLoc, SourceLocation EndLoc, 12865 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12866 ArrayRef<Expr *> UnresolvedReductions) { 12867 ReductionData RD(VarList.size()); 12868 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 12869 StartLoc, LParenLoc, ColonLoc, EndLoc, 12870 ReductionIdScopeSpec, ReductionId, 12871 UnresolvedReductions, RD)) 12872 return nullptr; 12873 12874 return OMPTaskReductionClause::Create( 12875 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12876 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12877 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12878 buildPreInits(Context, RD.ExprCaptures), 12879 buildPostUpdate(*this, RD.ExprPostUpdates)); 12880 } 12881 12882 OMPClause *Sema::ActOnOpenMPInReductionClause( 12883 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12884 SourceLocation ColonLoc, SourceLocation EndLoc, 12885 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12886 ArrayRef<Expr *> UnresolvedReductions) { 12887 ReductionData RD(VarList.size()); 12888 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 12889 StartLoc, LParenLoc, ColonLoc, EndLoc, 12890 ReductionIdScopeSpec, ReductionId, 12891 UnresolvedReductions, RD)) 12892 return nullptr; 12893 12894 return OMPInReductionClause::Create( 12895 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12896 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12897 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 12898 buildPreInits(Context, RD.ExprCaptures), 12899 buildPostUpdate(*this, RD.ExprPostUpdates)); 12900 } 12901 12902 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 12903 SourceLocation LinLoc) { 12904 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 12905 LinKind == OMPC_LINEAR_unknown) { 12906 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 12907 return true; 12908 } 12909 return false; 12910 } 12911 12912 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 12913 OpenMPLinearClauseKind LinKind, 12914 QualType Type) { 12915 const auto *VD = dyn_cast_or_null<VarDecl>(D); 12916 // A variable must not have an incomplete type or a reference type. 12917 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 12918 return true; 12919 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 12920 !Type->isReferenceType()) { 12921 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12922 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12923 return true; 12924 } 12925 Type = Type.getNonReferenceType(); 12926 12927 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12928 // A variable that is privatized must not have a const-qualified type 12929 // unless it is of class type with a mutable member. This restriction does 12930 // not apply to the firstprivate clause. 12931 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12932 return true; 12933 12934 // A list item must be of integral or pointer type. 12935 Type = Type.getUnqualifiedType().getCanonicalType(); 12936 const auto *Ty = Type.getTypePtrOrNull(); 12937 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12938 !Ty->isPointerType())) { 12939 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12940 if (D) { 12941 bool IsDecl = 12942 !VD || 12943 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12944 Diag(D->getLocation(), 12945 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12946 << D; 12947 } 12948 return true; 12949 } 12950 return false; 12951 } 12952 12953 OMPClause *Sema::ActOnOpenMPLinearClause( 12954 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12955 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12956 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12957 SmallVector<Expr *, 8> Vars; 12958 SmallVector<Expr *, 8> Privates; 12959 SmallVector<Expr *, 8> Inits; 12960 SmallVector<Decl *, 4> ExprCaptures; 12961 SmallVector<Expr *, 4> ExprPostUpdates; 12962 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12963 LinKind = OMPC_LINEAR_val; 12964 for (Expr *RefExpr : VarList) { 12965 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12966 SourceLocation ELoc; 12967 SourceRange ERange; 12968 Expr *SimpleRefExpr = RefExpr; 12969 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12970 if (Res.second) { 12971 // It will be analyzed later. 12972 Vars.push_back(RefExpr); 12973 Privates.push_back(nullptr); 12974 Inits.push_back(nullptr); 12975 } 12976 ValueDecl *D = Res.first; 12977 if (!D) 12978 continue; 12979 12980 QualType Type = D->getType(); 12981 auto *VD = dyn_cast<VarDecl>(D); 12982 12983 // OpenMP [2.14.3.7, linear clause] 12984 // A list-item cannot appear in more than one linear clause. 12985 // A list-item that appears in a linear clause cannot appear in any 12986 // other data-sharing attribute clause. 12987 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12988 if (DVar.RefExpr) { 12989 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12990 << getOpenMPClauseName(OMPC_linear); 12991 reportOriginalDsa(*this, DSAStack, D, DVar); 12992 continue; 12993 } 12994 12995 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12996 continue; 12997 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12998 12999 // Build private copy of original var. 13000 VarDecl *Private = 13001 buildVarDecl(*this, ELoc, Type, D->getName(), 13002 D->hasAttrs() ? &D->getAttrs() : nullptr, 13003 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13004 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13005 // Build var to save initial value. 13006 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13007 Expr *InitExpr; 13008 DeclRefExpr *Ref = nullptr; 13009 if (!VD && !CurContext->isDependentContext()) { 13010 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13011 if (!isOpenMPCapturedDecl(D)) { 13012 ExprCaptures.push_back(Ref->getDecl()); 13013 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13014 ExprResult RefRes = DefaultLvalueConversion(Ref); 13015 if (!RefRes.isUsable()) 13016 continue; 13017 ExprResult PostUpdateRes = 13018 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13019 SimpleRefExpr, RefRes.get()); 13020 if (!PostUpdateRes.isUsable()) 13021 continue; 13022 ExprPostUpdates.push_back( 13023 IgnoredValueConversions(PostUpdateRes.get()).get()); 13024 } 13025 } 13026 } 13027 if (LinKind == OMPC_LINEAR_uval) 13028 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13029 else 13030 InitExpr = VD ? SimpleRefExpr : Ref; 13031 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13032 /*DirectInit=*/false); 13033 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13034 13035 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13036 Vars.push_back((VD || CurContext->isDependentContext()) 13037 ? RefExpr->IgnoreParens() 13038 : Ref); 13039 Privates.push_back(PrivateRef); 13040 Inits.push_back(InitRef); 13041 } 13042 13043 if (Vars.empty()) 13044 return nullptr; 13045 13046 Expr *StepExpr = Step; 13047 Expr *CalcStepExpr = nullptr; 13048 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13049 !Step->isInstantiationDependent() && 13050 !Step->containsUnexpandedParameterPack()) { 13051 SourceLocation StepLoc = Step->getBeginLoc(); 13052 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13053 if (Val.isInvalid()) 13054 return nullptr; 13055 StepExpr = Val.get(); 13056 13057 // Build var to save the step value. 13058 VarDecl *SaveVar = 13059 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13060 ExprResult SaveRef = 13061 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13062 ExprResult CalcStep = 13063 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13064 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13065 13066 // Warn about zero linear step (it would be probably better specified as 13067 // making corresponding variables 'const'). 13068 llvm::APSInt Result; 13069 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13070 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13071 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13072 << (Vars.size() > 1); 13073 if (!IsConstant && CalcStep.isUsable()) { 13074 // Calculate the step beforehand instead of doing this on each iteration. 13075 // (This is not used if the number of iterations may be kfold-ed). 13076 CalcStepExpr = CalcStep.get(); 13077 } 13078 } 13079 13080 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13081 ColonLoc, EndLoc, Vars, Privates, Inits, 13082 StepExpr, CalcStepExpr, 13083 buildPreInits(Context, ExprCaptures), 13084 buildPostUpdate(*this, ExprPostUpdates)); 13085 } 13086 13087 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13088 Expr *NumIterations, Sema &SemaRef, 13089 Scope *S, DSAStackTy *Stack) { 13090 // Walk the vars and build update/final expressions for the CodeGen. 13091 SmallVector<Expr *, 8> Updates; 13092 SmallVector<Expr *, 8> Finals; 13093 SmallVector<Expr *, 8> UsedExprs; 13094 Expr *Step = Clause.getStep(); 13095 Expr *CalcStep = Clause.getCalcStep(); 13096 // OpenMP [2.14.3.7, linear clause] 13097 // If linear-step is not specified it is assumed to be 1. 13098 if (!Step) 13099 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13100 else if (CalcStep) 13101 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13102 bool HasErrors = false; 13103 auto CurInit = Clause.inits().begin(); 13104 auto CurPrivate = Clause.privates().begin(); 13105 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13106 for (Expr *RefExpr : Clause.varlists()) { 13107 SourceLocation ELoc; 13108 SourceRange ERange; 13109 Expr *SimpleRefExpr = RefExpr; 13110 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13111 ValueDecl *D = Res.first; 13112 if (Res.second || !D) { 13113 Updates.push_back(nullptr); 13114 Finals.push_back(nullptr); 13115 HasErrors = true; 13116 continue; 13117 } 13118 auto &&Info = Stack->isLoopControlVariable(D); 13119 // OpenMP [2.15.11, distribute simd Construct] 13120 // A list item may not appear in a linear clause, unless it is the loop 13121 // iteration variable. 13122 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13123 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13124 SemaRef.Diag(ELoc, 13125 diag::err_omp_linear_distribute_var_non_loop_iteration); 13126 Updates.push_back(nullptr); 13127 Finals.push_back(nullptr); 13128 HasErrors = true; 13129 continue; 13130 } 13131 Expr *InitExpr = *CurInit; 13132 13133 // Build privatized reference to the current linear var. 13134 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13135 Expr *CapturedRef; 13136 if (LinKind == OMPC_LINEAR_uval) 13137 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13138 else 13139 CapturedRef = 13140 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13141 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13142 /*RefersToCapture=*/true); 13143 13144 // Build update: Var = InitExpr + IV * Step 13145 ExprResult Update; 13146 if (!Info.first) 13147 Update = buildCounterUpdate( 13148 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13149 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13150 else 13151 Update = *CurPrivate; 13152 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13153 /*DiscardedValue*/ false); 13154 13155 // Build final: Var = InitExpr + NumIterations * Step 13156 ExprResult Final; 13157 if (!Info.first) 13158 Final = 13159 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13160 InitExpr, NumIterations, Step, /*Subtract=*/false, 13161 /*IsNonRectangularLB=*/false); 13162 else 13163 Final = *CurPrivate; 13164 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13165 /*DiscardedValue*/ false); 13166 13167 if (!Update.isUsable() || !Final.isUsable()) { 13168 Updates.push_back(nullptr); 13169 Finals.push_back(nullptr); 13170 UsedExprs.push_back(nullptr); 13171 HasErrors = true; 13172 } else { 13173 Updates.push_back(Update.get()); 13174 Finals.push_back(Final.get()); 13175 if (!Info.first) 13176 UsedExprs.push_back(SimpleRefExpr); 13177 } 13178 ++CurInit; 13179 ++CurPrivate; 13180 } 13181 if (Expr *S = Clause.getStep()) 13182 UsedExprs.push_back(S); 13183 // Fill the remaining part with the nullptr. 13184 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13185 Clause.setUpdates(Updates); 13186 Clause.setFinals(Finals); 13187 Clause.setUsedExprs(UsedExprs); 13188 return HasErrors; 13189 } 13190 13191 OMPClause *Sema::ActOnOpenMPAlignedClause( 13192 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13193 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13194 SmallVector<Expr *, 8> Vars; 13195 for (Expr *RefExpr : VarList) { 13196 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13197 SourceLocation ELoc; 13198 SourceRange ERange; 13199 Expr *SimpleRefExpr = RefExpr; 13200 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13201 if (Res.second) { 13202 // It will be analyzed later. 13203 Vars.push_back(RefExpr); 13204 } 13205 ValueDecl *D = Res.first; 13206 if (!D) 13207 continue; 13208 13209 QualType QType = D->getType(); 13210 auto *VD = dyn_cast<VarDecl>(D); 13211 13212 // OpenMP [2.8.1, simd construct, Restrictions] 13213 // The type of list items appearing in the aligned clause must be 13214 // array, pointer, reference to array, or reference to pointer. 13215 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13216 const Type *Ty = QType.getTypePtrOrNull(); 13217 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13218 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13219 << QType << getLangOpts().CPlusPlus << ERange; 13220 bool IsDecl = 13221 !VD || 13222 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13223 Diag(D->getLocation(), 13224 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13225 << D; 13226 continue; 13227 } 13228 13229 // OpenMP [2.8.1, simd construct, Restrictions] 13230 // A list-item cannot appear in more than one aligned clause. 13231 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 13232 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 13233 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 13234 << getOpenMPClauseName(OMPC_aligned); 13235 continue; 13236 } 13237 13238 DeclRefExpr *Ref = nullptr; 13239 if (!VD && isOpenMPCapturedDecl(D)) 13240 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13241 Vars.push_back(DefaultFunctionArrayConversion( 13242 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 13243 .get()); 13244 } 13245 13246 // OpenMP [2.8.1, simd construct, Description] 13247 // The parameter of the aligned clause, alignment, must be a constant 13248 // positive integer expression. 13249 // If no optional parameter is specified, implementation-defined default 13250 // alignments for SIMD instructions on the target platforms are assumed. 13251 if (Alignment != nullptr) { 13252 ExprResult AlignResult = 13253 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 13254 if (AlignResult.isInvalid()) 13255 return nullptr; 13256 Alignment = AlignResult.get(); 13257 } 13258 if (Vars.empty()) 13259 return nullptr; 13260 13261 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 13262 EndLoc, Vars, Alignment); 13263 } 13264 13265 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 13266 SourceLocation StartLoc, 13267 SourceLocation LParenLoc, 13268 SourceLocation EndLoc) { 13269 SmallVector<Expr *, 8> Vars; 13270 SmallVector<Expr *, 8> SrcExprs; 13271 SmallVector<Expr *, 8> DstExprs; 13272 SmallVector<Expr *, 8> AssignmentOps; 13273 for (Expr *RefExpr : VarList) { 13274 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 13275 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13276 // It will be analyzed later. 13277 Vars.push_back(RefExpr); 13278 SrcExprs.push_back(nullptr); 13279 DstExprs.push_back(nullptr); 13280 AssignmentOps.push_back(nullptr); 13281 continue; 13282 } 13283 13284 SourceLocation ELoc = RefExpr->getExprLoc(); 13285 // OpenMP [2.1, C/C++] 13286 // A list item is a variable name. 13287 // OpenMP [2.14.4.1, Restrictions, p.1] 13288 // A list item that appears in a copyin clause must be threadprivate. 13289 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 13290 if (!DE || !isa<VarDecl>(DE->getDecl())) { 13291 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 13292 << 0 << RefExpr->getSourceRange(); 13293 continue; 13294 } 13295 13296 Decl *D = DE->getDecl(); 13297 auto *VD = cast<VarDecl>(D); 13298 13299 QualType Type = VD->getType(); 13300 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 13301 // It will be analyzed later. 13302 Vars.push_back(DE); 13303 SrcExprs.push_back(nullptr); 13304 DstExprs.push_back(nullptr); 13305 AssignmentOps.push_back(nullptr); 13306 continue; 13307 } 13308 13309 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 13310 // A list item that appears in a copyin clause must be threadprivate. 13311 if (!DSAStack->isThreadPrivate(VD)) { 13312 Diag(ELoc, diag::err_omp_required_access) 13313 << getOpenMPClauseName(OMPC_copyin) 13314 << getOpenMPDirectiveName(OMPD_threadprivate); 13315 continue; 13316 } 13317 13318 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13319 // A variable of class type (or array thereof) that appears in a 13320 // copyin clause requires an accessible, unambiguous copy assignment 13321 // operator for the class type. 13322 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13323 VarDecl *SrcVD = 13324 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 13325 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13326 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 13327 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 13328 VarDecl *DstVD = 13329 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 13330 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13331 DeclRefExpr *PseudoDstExpr = 13332 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 13333 // For arrays generate assignment operation for single element and replace 13334 // it by the original array element in CodeGen. 13335 ExprResult AssignmentOp = 13336 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 13337 PseudoSrcExpr); 13338 if (AssignmentOp.isInvalid()) 13339 continue; 13340 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 13341 /*DiscardedValue*/ false); 13342 if (AssignmentOp.isInvalid()) 13343 continue; 13344 13345 DSAStack->addDSA(VD, DE, OMPC_copyin); 13346 Vars.push_back(DE); 13347 SrcExprs.push_back(PseudoSrcExpr); 13348 DstExprs.push_back(PseudoDstExpr); 13349 AssignmentOps.push_back(AssignmentOp.get()); 13350 } 13351 13352 if (Vars.empty()) 13353 return nullptr; 13354 13355 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13356 SrcExprs, DstExprs, AssignmentOps); 13357 } 13358 13359 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 13360 SourceLocation StartLoc, 13361 SourceLocation LParenLoc, 13362 SourceLocation EndLoc) { 13363 SmallVector<Expr *, 8> Vars; 13364 SmallVector<Expr *, 8> SrcExprs; 13365 SmallVector<Expr *, 8> DstExprs; 13366 SmallVector<Expr *, 8> AssignmentOps; 13367 for (Expr *RefExpr : VarList) { 13368 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13369 SourceLocation ELoc; 13370 SourceRange ERange; 13371 Expr *SimpleRefExpr = RefExpr; 13372 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13373 if (Res.second) { 13374 // It will be analyzed later. 13375 Vars.push_back(RefExpr); 13376 SrcExprs.push_back(nullptr); 13377 DstExprs.push_back(nullptr); 13378 AssignmentOps.push_back(nullptr); 13379 } 13380 ValueDecl *D = Res.first; 13381 if (!D) 13382 continue; 13383 13384 QualType Type = D->getType(); 13385 auto *VD = dyn_cast<VarDecl>(D); 13386 13387 // OpenMP [2.14.4.2, Restrictions, p.2] 13388 // A list item that appears in a copyprivate clause may not appear in a 13389 // private or firstprivate clause on the single construct. 13390 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13391 DSAStackTy::DSAVarData DVar = 13392 DSAStack->getTopDSA(D, /*FromParent=*/false); 13393 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13394 DVar.RefExpr) { 13395 Diag(ELoc, diag::err_omp_wrong_dsa) 13396 << getOpenMPClauseName(DVar.CKind) 13397 << getOpenMPClauseName(OMPC_copyprivate); 13398 reportOriginalDsa(*this, DSAStack, D, DVar); 13399 continue; 13400 } 13401 13402 // OpenMP [2.11.4.2, Restrictions, p.1] 13403 // All list items that appear in a copyprivate clause must be either 13404 // threadprivate or private in the enclosing context. 13405 if (DVar.CKind == OMPC_unknown) { 13406 DVar = DSAStack->getImplicitDSA(D, false); 13407 if (DVar.CKind == OMPC_shared) { 13408 Diag(ELoc, diag::err_omp_required_access) 13409 << getOpenMPClauseName(OMPC_copyprivate) 13410 << "threadprivate or private in the enclosing context"; 13411 reportOriginalDsa(*this, DSAStack, D, DVar); 13412 continue; 13413 } 13414 } 13415 } 13416 13417 // Variably modified types are not supported. 13418 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13419 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13420 << getOpenMPClauseName(OMPC_copyprivate) << Type 13421 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13422 bool IsDecl = 13423 !VD || 13424 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13425 Diag(D->getLocation(), 13426 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13427 << D; 13428 continue; 13429 } 13430 13431 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13432 // A variable of class type (or array thereof) that appears in a 13433 // copyin clause requires an accessible, unambiguous copy assignment 13434 // operator for the class type. 13435 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13436 .getUnqualifiedType(); 13437 VarDecl *SrcVD = 13438 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13439 D->hasAttrs() ? &D->getAttrs() : nullptr); 13440 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13441 VarDecl *DstVD = 13442 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13443 D->hasAttrs() ? &D->getAttrs() : nullptr); 13444 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13445 ExprResult AssignmentOp = BuildBinOp( 13446 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13447 if (AssignmentOp.isInvalid()) 13448 continue; 13449 AssignmentOp = 13450 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13451 if (AssignmentOp.isInvalid()) 13452 continue; 13453 13454 // No need to mark vars as copyprivate, they are already threadprivate or 13455 // implicitly private. 13456 assert(VD || isOpenMPCapturedDecl(D)); 13457 Vars.push_back( 13458 VD ? RefExpr->IgnoreParens() 13459 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13460 SrcExprs.push_back(PseudoSrcExpr); 13461 DstExprs.push_back(PseudoDstExpr); 13462 AssignmentOps.push_back(AssignmentOp.get()); 13463 } 13464 13465 if (Vars.empty()) 13466 return nullptr; 13467 13468 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13469 Vars, SrcExprs, DstExprs, AssignmentOps); 13470 } 13471 13472 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13473 SourceLocation StartLoc, 13474 SourceLocation LParenLoc, 13475 SourceLocation EndLoc) { 13476 if (VarList.empty()) 13477 return nullptr; 13478 13479 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13480 } 13481 13482 OMPClause * 13483 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13484 SourceLocation DepLoc, SourceLocation ColonLoc, 13485 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13486 SourceLocation LParenLoc, SourceLocation EndLoc) { 13487 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13488 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13489 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13490 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13491 return nullptr; 13492 } 13493 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13494 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13495 DepKind == OMPC_DEPEND_sink)) { 13496 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13497 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13498 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13499 /*Last=*/OMPC_DEPEND_unknown, Except) 13500 << getOpenMPClauseName(OMPC_depend); 13501 return nullptr; 13502 } 13503 SmallVector<Expr *, 8> Vars; 13504 DSAStackTy::OperatorOffsetTy OpsOffs; 13505 llvm::APSInt DepCounter(/*BitWidth=*/32); 13506 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13507 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13508 if (const Expr *OrderedCountExpr = 13509 DSAStack->getParentOrderedRegionParam().first) { 13510 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13511 TotalDepCount.setIsUnsigned(/*Val=*/true); 13512 } 13513 } 13514 for (Expr *RefExpr : VarList) { 13515 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13516 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13517 // It will be analyzed later. 13518 Vars.push_back(RefExpr); 13519 continue; 13520 } 13521 13522 SourceLocation ELoc = RefExpr->getExprLoc(); 13523 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13524 if (DepKind == OMPC_DEPEND_sink) { 13525 if (DSAStack->getParentOrderedRegionParam().first && 13526 DepCounter >= TotalDepCount) { 13527 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13528 continue; 13529 } 13530 ++DepCounter; 13531 // OpenMP [2.13.9, Summary] 13532 // depend(dependence-type : vec), where dependence-type is: 13533 // 'sink' and where vec is the iteration vector, which has the form: 13534 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13535 // where n is the value specified by the ordered clause in the loop 13536 // directive, xi denotes the loop iteration variable of the i-th nested 13537 // loop associated with the loop directive, and di is a constant 13538 // non-negative integer. 13539 if (CurContext->isDependentContext()) { 13540 // It will be analyzed later. 13541 Vars.push_back(RefExpr); 13542 continue; 13543 } 13544 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13545 OverloadedOperatorKind OOK = OO_None; 13546 SourceLocation OOLoc; 13547 Expr *LHS = SimpleExpr; 13548 Expr *RHS = nullptr; 13549 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13550 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13551 OOLoc = BO->getOperatorLoc(); 13552 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13553 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13554 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13555 OOK = OCE->getOperator(); 13556 OOLoc = OCE->getOperatorLoc(); 13557 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13558 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13559 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13560 OOK = MCE->getMethodDecl() 13561 ->getNameInfo() 13562 .getName() 13563 .getCXXOverloadedOperator(); 13564 OOLoc = MCE->getCallee()->getExprLoc(); 13565 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13566 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13567 } 13568 SourceLocation ELoc; 13569 SourceRange ERange; 13570 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13571 if (Res.second) { 13572 // It will be analyzed later. 13573 Vars.push_back(RefExpr); 13574 } 13575 ValueDecl *D = Res.first; 13576 if (!D) 13577 continue; 13578 13579 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13580 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13581 continue; 13582 } 13583 if (RHS) { 13584 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13585 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13586 if (RHSRes.isInvalid()) 13587 continue; 13588 } 13589 if (!CurContext->isDependentContext() && 13590 DSAStack->getParentOrderedRegionParam().first && 13591 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13592 const ValueDecl *VD = 13593 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13594 if (VD) 13595 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13596 << 1 << VD; 13597 else 13598 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13599 continue; 13600 } 13601 OpsOffs.emplace_back(RHS, OOK); 13602 } else { 13603 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13604 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13605 (ASE && 13606 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13607 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13608 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13609 << RefExpr->getSourceRange(); 13610 continue; 13611 } 13612 13613 ExprResult Res; 13614 { 13615 Sema::TentativeAnalysisScope Trap(*this); 13616 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 13617 RefExpr->IgnoreParenImpCasts()); 13618 } 13619 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13620 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13621 << RefExpr->getSourceRange(); 13622 continue; 13623 } 13624 } 13625 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13626 } 13627 13628 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13629 TotalDepCount > VarList.size() && 13630 DSAStack->getParentOrderedRegionParam().first && 13631 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13632 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13633 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13634 } 13635 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13636 Vars.empty()) 13637 return nullptr; 13638 13639 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13640 DepKind, DepLoc, ColonLoc, Vars, 13641 TotalDepCount.getZExtValue()); 13642 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13643 DSAStack->isParentOrderedRegion()) 13644 DSAStack->addDoacrossDependClause(C, OpsOffs); 13645 return C; 13646 } 13647 13648 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13649 SourceLocation LParenLoc, 13650 SourceLocation EndLoc) { 13651 Expr *ValExpr = Device; 13652 Stmt *HelperValStmt = nullptr; 13653 13654 // OpenMP [2.9.1, Restrictions] 13655 // The device expression must evaluate to a non-negative integer value. 13656 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13657 /*StrictlyPositive=*/false)) 13658 return nullptr; 13659 13660 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13661 OpenMPDirectiveKind CaptureRegion = 13662 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13663 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13664 ValExpr = MakeFullExpr(ValExpr).get(); 13665 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13666 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13667 HelperValStmt = buildPreInits(Context, Captures); 13668 } 13669 13670 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13671 StartLoc, LParenLoc, EndLoc); 13672 } 13673 13674 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13675 DSAStackTy *Stack, QualType QTy, 13676 bool FullCheck = true) { 13677 NamedDecl *ND; 13678 if (QTy->isIncompleteType(&ND)) { 13679 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13680 return false; 13681 } 13682 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13683 !QTy.isTrivialType(SemaRef.Context)) 13684 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13685 return true; 13686 } 13687 13688 /// Return true if it can be proven that the provided array expression 13689 /// (array section or array subscript) does NOT specify the whole size of the 13690 /// array whose base type is \a BaseQTy. 13691 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13692 const Expr *E, 13693 QualType BaseQTy) { 13694 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13695 13696 // If this is an array subscript, it refers to the whole size if the size of 13697 // the dimension is constant and equals 1. Also, an array section assumes the 13698 // format of an array subscript if no colon is used. 13699 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13700 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13701 return ATy->getSize().getSExtValue() != 1; 13702 // Size can't be evaluated statically. 13703 return false; 13704 } 13705 13706 assert(OASE && "Expecting array section if not an array subscript."); 13707 const Expr *LowerBound = OASE->getLowerBound(); 13708 const Expr *Length = OASE->getLength(); 13709 13710 // If there is a lower bound that does not evaluates to zero, we are not 13711 // covering the whole dimension. 13712 if (LowerBound) { 13713 Expr::EvalResult Result; 13714 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13715 return false; // Can't get the integer value as a constant. 13716 13717 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13718 if (ConstLowerBound.getSExtValue()) 13719 return true; 13720 } 13721 13722 // If we don't have a length we covering the whole dimension. 13723 if (!Length) 13724 return false; 13725 13726 // If the base is a pointer, we don't have a way to get the size of the 13727 // pointee. 13728 if (BaseQTy->isPointerType()) 13729 return false; 13730 13731 // We can only check if the length is the same as the size of the dimension 13732 // if we have a constant array. 13733 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13734 if (!CATy) 13735 return false; 13736 13737 Expr::EvalResult Result; 13738 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13739 return false; // Can't get the integer value as a constant. 13740 13741 llvm::APSInt ConstLength = Result.Val.getInt(); 13742 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13743 } 13744 13745 // Return true if it can be proven that the provided array expression (array 13746 // section or array subscript) does NOT specify a single element of the array 13747 // whose base type is \a BaseQTy. 13748 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13749 const Expr *E, 13750 QualType BaseQTy) { 13751 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13752 13753 // An array subscript always refer to a single element. Also, an array section 13754 // assumes the format of an array subscript if no colon is used. 13755 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13756 return false; 13757 13758 assert(OASE && "Expecting array section if not an array subscript."); 13759 const Expr *Length = OASE->getLength(); 13760 13761 // If we don't have a length we have to check if the array has unitary size 13762 // for this dimension. Also, we should always expect a length if the base type 13763 // is pointer. 13764 if (!Length) { 13765 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13766 return ATy->getSize().getSExtValue() != 1; 13767 // We cannot assume anything. 13768 return false; 13769 } 13770 13771 // Check if the length evaluates to 1. 13772 Expr::EvalResult Result; 13773 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13774 return false; // Can't get the integer value as a constant. 13775 13776 llvm::APSInt ConstLength = Result.Val.getInt(); 13777 return ConstLength.getSExtValue() != 1; 13778 } 13779 13780 // Return the expression of the base of the mappable expression or null if it 13781 // cannot be determined and do all the necessary checks to see if the expression 13782 // is valid as a standalone mappable expression. In the process, record all the 13783 // components of the expression. 13784 static const Expr *checkMapClauseExpressionBase( 13785 Sema &SemaRef, Expr *E, 13786 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13787 OpenMPClauseKind CKind, bool NoDiagnose) { 13788 SourceLocation ELoc = E->getExprLoc(); 13789 SourceRange ERange = E->getSourceRange(); 13790 13791 // The base of elements of list in a map clause have to be either: 13792 // - a reference to variable or field. 13793 // - a member expression. 13794 // - an array expression. 13795 // 13796 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 13797 // reference to 'r'. 13798 // 13799 // If we have: 13800 // 13801 // struct SS { 13802 // Bla S; 13803 // foo() { 13804 // #pragma omp target map (S.Arr[:12]); 13805 // } 13806 // } 13807 // 13808 // We want to retrieve the member expression 'this->S'; 13809 13810 const Expr *RelevantExpr = nullptr; 13811 13812 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 13813 // If a list item is an array section, it must specify contiguous storage. 13814 // 13815 // For this restriction it is sufficient that we make sure only references 13816 // to variables or fields and array expressions, and that no array sections 13817 // exist except in the rightmost expression (unless they cover the whole 13818 // dimension of the array). E.g. these would be invalid: 13819 // 13820 // r.ArrS[3:5].Arr[6:7] 13821 // 13822 // r.ArrS[3:5].x 13823 // 13824 // but these would be valid: 13825 // r.ArrS[3].Arr[6:7] 13826 // 13827 // r.ArrS[3].x 13828 13829 bool AllowUnitySizeArraySection = true; 13830 bool AllowWholeSizeArraySection = true; 13831 13832 while (!RelevantExpr) { 13833 E = E->IgnoreParenImpCasts(); 13834 13835 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 13836 if (!isa<VarDecl>(CurE->getDecl())) 13837 return nullptr; 13838 13839 RelevantExpr = CurE; 13840 13841 // If we got a reference to a declaration, we should not expect any array 13842 // section before that. 13843 AllowUnitySizeArraySection = false; 13844 AllowWholeSizeArraySection = false; 13845 13846 // Record the component. 13847 CurComponents.emplace_back(CurE, CurE->getDecl()); 13848 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 13849 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 13850 13851 if (isa<CXXThisExpr>(BaseE)) 13852 // We found a base expression: this->Val. 13853 RelevantExpr = CurE; 13854 else 13855 E = BaseE; 13856 13857 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 13858 if (!NoDiagnose) { 13859 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 13860 << CurE->getSourceRange(); 13861 return nullptr; 13862 } 13863 if (RelevantExpr) 13864 return nullptr; 13865 continue; 13866 } 13867 13868 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 13869 13870 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 13871 // A bit-field cannot appear in a map clause. 13872 // 13873 if (FD->isBitField()) { 13874 if (!NoDiagnose) { 13875 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 13876 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 13877 return nullptr; 13878 } 13879 if (RelevantExpr) 13880 return nullptr; 13881 continue; 13882 } 13883 13884 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13885 // If the type of a list item is a reference to a type T then the type 13886 // will be considered to be T for all purposes of this clause. 13887 QualType CurType = BaseE->getType().getNonReferenceType(); 13888 13889 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 13890 // A list item cannot be a variable that is a member of a structure with 13891 // a union type. 13892 // 13893 if (CurType->isUnionType()) { 13894 if (!NoDiagnose) { 13895 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 13896 << CurE->getSourceRange(); 13897 return nullptr; 13898 } 13899 continue; 13900 } 13901 13902 // If we got a member expression, we should not expect any array section 13903 // before that: 13904 // 13905 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 13906 // If a list item is an element of a structure, only the rightmost symbol 13907 // of the variable reference can be an array section. 13908 // 13909 AllowUnitySizeArraySection = false; 13910 AllowWholeSizeArraySection = false; 13911 13912 // Record the component. 13913 CurComponents.emplace_back(CurE, FD); 13914 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 13915 E = CurE->getBase()->IgnoreParenImpCasts(); 13916 13917 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 13918 if (!NoDiagnose) { 13919 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13920 << 0 << CurE->getSourceRange(); 13921 return nullptr; 13922 } 13923 continue; 13924 } 13925 13926 // If we got an array subscript that express the whole dimension we 13927 // can have any array expressions before. If it only expressing part of 13928 // the dimension, we can only have unitary-size array expressions. 13929 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 13930 E->getType())) 13931 AllowWholeSizeArraySection = false; 13932 13933 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13934 Expr::EvalResult Result; 13935 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13936 if (!Result.Val.getInt().isNullValue()) { 13937 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13938 diag::err_omp_invalid_map_this_expr); 13939 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13940 diag::note_omp_invalid_subscript_on_this_ptr_map); 13941 } 13942 } 13943 RelevantExpr = TE; 13944 } 13945 13946 // Record the component - we don't have any declaration associated. 13947 CurComponents.emplace_back(CurE, nullptr); 13948 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13949 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13950 E = CurE->getBase()->IgnoreParenImpCasts(); 13951 13952 QualType CurType = 13953 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13954 13955 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13956 // If the type of a list item is a reference to a type T then the type 13957 // will be considered to be T for all purposes of this clause. 13958 if (CurType->isReferenceType()) 13959 CurType = CurType->getPointeeType(); 13960 13961 bool IsPointer = CurType->isAnyPointerType(); 13962 13963 if (!IsPointer && !CurType->isArrayType()) { 13964 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13965 << 0 << CurE->getSourceRange(); 13966 return nullptr; 13967 } 13968 13969 bool NotWhole = 13970 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13971 bool NotUnity = 13972 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13973 13974 if (AllowWholeSizeArraySection) { 13975 // Any array section is currently allowed. Allowing a whole size array 13976 // section implies allowing a unity array section as well. 13977 // 13978 // If this array section refers to the whole dimension we can still 13979 // accept other array sections before this one, except if the base is a 13980 // pointer. Otherwise, only unitary sections are accepted. 13981 if (NotWhole || IsPointer) 13982 AllowWholeSizeArraySection = false; 13983 } else if (AllowUnitySizeArraySection && NotUnity) { 13984 // A unity or whole array section is not allowed and that is not 13985 // compatible with the properties of the current array section. 13986 SemaRef.Diag( 13987 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13988 << CurE->getSourceRange(); 13989 return nullptr; 13990 } 13991 13992 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13993 Expr::EvalResult ResultR; 13994 Expr::EvalResult ResultL; 13995 if (CurE->getLength()->EvaluateAsInt(ResultR, 13996 SemaRef.getASTContext())) { 13997 if (!ResultR.Val.getInt().isOneValue()) { 13998 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13999 diag::err_omp_invalid_map_this_expr); 14000 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14001 diag::note_omp_invalid_length_on_this_ptr_mapping); 14002 } 14003 } 14004 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14005 ResultL, SemaRef.getASTContext())) { 14006 if (!ResultL.Val.getInt().isNullValue()) { 14007 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14008 diag::err_omp_invalid_map_this_expr); 14009 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14010 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14011 } 14012 } 14013 RelevantExpr = TE; 14014 } 14015 14016 // Record the component - we don't have any declaration associated. 14017 CurComponents.emplace_back(CurE, nullptr); 14018 } else { 14019 if (!NoDiagnose) { 14020 // If nothing else worked, this is not a valid map clause expression. 14021 SemaRef.Diag( 14022 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14023 << ERange; 14024 } 14025 return nullptr; 14026 } 14027 } 14028 14029 return RelevantExpr; 14030 } 14031 14032 // Return true if expression E associated with value VD has conflicts with other 14033 // map information. 14034 static bool checkMapConflicts( 14035 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14036 bool CurrentRegionOnly, 14037 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14038 OpenMPClauseKind CKind) { 14039 assert(VD && E); 14040 SourceLocation ELoc = E->getExprLoc(); 14041 SourceRange ERange = E->getSourceRange(); 14042 14043 // In order to easily check the conflicts we need to match each component of 14044 // the expression under test with the components of the expressions that are 14045 // already in the stack. 14046 14047 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14048 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14049 "Map clause expression with unexpected base!"); 14050 14051 // Variables to help detecting enclosing problems in data environment nests. 14052 bool IsEnclosedByDataEnvironmentExpr = false; 14053 const Expr *EnclosingExpr = nullptr; 14054 14055 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14056 VD, CurrentRegionOnly, 14057 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14058 ERange, CKind, &EnclosingExpr, 14059 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14060 StackComponents, 14061 OpenMPClauseKind) { 14062 assert(!StackComponents.empty() && 14063 "Map clause expression with no components!"); 14064 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14065 "Map clause expression with unexpected base!"); 14066 (void)VD; 14067 14068 // The whole expression in the stack. 14069 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14070 14071 // Expressions must start from the same base. Here we detect at which 14072 // point both expressions diverge from each other and see if we can 14073 // detect if the memory referred to both expressions is contiguous and 14074 // do not overlap. 14075 auto CI = CurComponents.rbegin(); 14076 auto CE = CurComponents.rend(); 14077 auto SI = StackComponents.rbegin(); 14078 auto SE = StackComponents.rend(); 14079 for (; CI != CE && SI != SE; ++CI, ++SI) { 14080 14081 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14082 // At most one list item can be an array item derived from a given 14083 // variable in map clauses of the same construct. 14084 if (CurrentRegionOnly && 14085 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14086 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14087 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14088 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14089 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14090 diag::err_omp_multiple_array_items_in_map_clause) 14091 << CI->getAssociatedExpression()->getSourceRange(); 14092 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14093 diag::note_used_here) 14094 << SI->getAssociatedExpression()->getSourceRange(); 14095 return true; 14096 } 14097 14098 // Do both expressions have the same kind? 14099 if (CI->getAssociatedExpression()->getStmtClass() != 14100 SI->getAssociatedExpression()->getStmtClass()) 14101 break; 14102 14103 // Are we dealing with different variables/fields? 14104 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14105 break; 14106 } 14107 // Check if the extra components of the expressions in the enclosing 14108 // data environment are redundant for the current base declaration. 14109 // If they are, the maps completely overlap, which is legal. 14110 for (; SI != SE; ++SI) { 14111 QualType Type; 14112 if (const auto *ASE = 14113 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14114 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14115 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14116 SI->getAssociatedExpression())) { 14117 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14118 Type = 14119 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14120 } 14121 if (Type.isNull() || Type->isAnyPointerType() || 14122 checkArrayExpressionDoesNotReferToWholeSize( 14123 SemaRef, SI->getAssociatedExpression(), Type)) 14124 break; 14125 } 14126 14127 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14128 // List items of map clauses in the same construct must not share 14129 // original storage. 14130 // 14131 // If the expressions are exactly the same or one is a subset of the 14132 // other, it means they are sharing storage. 14133 if (CI == CE && SI == SE) { 14134 if (CurrentRegionOnly) { 14135 if (CKind == OMPC_map) { 14136 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14137 } else { 14138 assert(CKind == OMPC_to || CKind == OMPC_from); 14139 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14140 << ERange; 14141 } 14142 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14143 << RE->getSourceRange(); 14144 return true; 14145 } 14146 // If we find the same expression in the enclosing data environment, 14147 // that is legal. 14148 IsEnclosedByDataEnvironmentExpr = true; 14149 return false; 14150 } 14151 14152 QualType DerivedType = 14153 std::prev(CI)->getAssociatedDeclaration()->getType(); 14154 SourceLocation DerivedLoc = 14155 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14156 14157 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14158 // If the type of a list item is a reference to a type T then the type 14159 // will be considered to be T for all purposes of this clause. 14160 DerivedType = DerivedType.getNonReferenceType(); 14161 14162 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14163 // A variable for which the type is pointer and an array section 14164 // derived from that variable must not appear as list items of map 14165 // clauses of the same construct. 14166 // 14167 // Also, cover one of the cases in: 14168 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14169 // If any part of the original storage of a list item has corresponding 14170 // storage in the device data environment, all of the original storage 14171 // must have corresponding storage in the device data environment. 14172 // 14173 if (DerivedType->isAnyPointerType()) { 14174 if (CI == CE || SI == SE) { 14175 SemaRef.Diag( 14176 DerivedLoc, 14177 diag::err_omp_pointer_mapped_along_with_derived_section) 14178 << DerivedLoc; 14179 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14180 << RE->getSourceRange(); 14181 return true; 14182 } 14183 if (CI->getAssociatedExpression()->getStmtClass() != 14184 SI->getAssociatedExpression()->getStmtClass() || 14185 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14186 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14187 assert(CI != CE && SI != SE); 14188 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14189 << DerivedLoc; 14190 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14191 << RE->getSourceRange(); 14192 return true; 14193 } 14194 } 14195 14196 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14197 // List items of map clauses in the same construct must not share 14198 // original storage. 14199 // 14200 // An expression is a subset of the other. 14201 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14202 if (CKind == OMPC_map) { 14203 if (CI != CE || SI != SE) { 14204 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14205 // a pointer. 14206 auto Begin = 14207 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14208 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14209 auto It = Begin; 14210 while (It != End && !It->getAssociatedDeclaration()) 14211 std::advance(It, 1); 14212 assert(It != End && 14213 "Expected at least one component with the declaration."); 14214 if (It != Begin && It->getAssociatedDeclaration() 14215 ->getType() 14216 .getCanonicalType() 14217 ->isAnyPointerType()) { 14218 IsEnclosedByDataEnvironmentExpr = false; 14219 EnclosingExpr = nullptr; 14220 return false; 14221 } 14222 } 14223 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14224 } else { 14225 assert(CKind == OMPC_to || CKind == OMPC_from); 14226 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14227 << ERange; 14228 } 14229 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14230 << RE->getSourceRange(); 14231 return true; 14232 } 14233 14234 // The current expression uses the same base as other expression in the 14235 // data environment but does not contain it completely. 14236 if (!CurrentRegionOnly && SI != SE) 14237 EnclosingExpr = RE; 14238 14239 // The current expression is a subset of the expression in the data 14240 // environment. 14241 IsEnclosedByDataEnvironmentExpr |= 14242 (!CurrentRegionOnly && CI != CE && SI == SE); 14243 14244 return false; 14245 }); 14246 14247 if (CurrentRegionOnly) 14248 return FoundError; 14249 14250 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14251 // If any part of the original storage of a list item has corresponding 14252 // storage in the device data environment, all of the original storage must 14253 // have corresponding storage in the device data environment. 14254 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 14255 // If a list item is an element of a structure, and a different element of 14256 // the structure has a corresponding list item in the device data environment 14257 // prior to a task encountering the construct associated with the map clause, 14258 // then the list item must also have a corresponding list item in the device 14259 // data environment prior to the task encountering the construct. 14260 // 14261 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 14262 SemaRef.Diag(ELoc, 14263 diag::err_omp_original_storage_is_shared_and_does_not_contain) 14264 << ERange; 14265 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 14266 << EnclosingExpr->getSourceRange(); 14267 return true; 14268 } 14269 14270 return FoundError; 14271 } 14272 14273 // Look up the user-defined mapper given the mapper name and mapped type, and 14274 // build a reference to it. 14275 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 14276 CXXScopeSpec &MapperIdScopeSpec, 14277 const DeclarationNameInfo &MapperId, 14278 QualType Type, 14279 Expr *UnresolvedMapper) { 14280 if (MapperIdScopeSpec.isInvalid()) 14281 return ExprError(); 14282 // Find all user-defined mappers with the given MapperId. 14283 SmallVector<UnresolvedSet<8>, 4> Lookups; 14284 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 14285 Lookup.suppressDiagnostics(); 14286 if (S) { 14287 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 14288 NamedDecl *D = Lookup.getRepresentativeDecl(); 14289 while (S && !S->isDeclScope(D)) 14290 S = S->getParent(); 14291 if (S) 14292 S = S->getParent(); 14293 Lookups.emplace_back(); 14294 Lookups.back().append(Lookup.begin(), Lookup.end()); 14295 Lookup.clear(); 14296 } 14297 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 14298 // Extract the user-defined mappers with the given MapperId. 14299 Lookups.push_back(UnresolvedSet<8>()); 14300 for (NamedDecl *D : ULE->decls()) { 14301 auto *DMD = cast<OMPDeclareMapperDecl>(D); 14302 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 14303 Lookups.back().addDecl(DMD); 14304 } 14305 } 14306 // Defer the lookup for dependent types. The results will be passed through 14307 // UnresolvedMapper on instantiation. 14308 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 14309 Type->isInstantiationDependentType() || 14310 Type->containsUnexpandedParameterPack() || 14311 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14312 return !D->isInvalidDecl() && 14313 (D->getType()->isDependentType() || 14314 D->getType()->isInstantiationDependentType() || 14315 D->getType()->containsUnexpandedParameterPack()); 14316 })) { 14317 UnresolvedSet<8> URS; 14318 for (const UnresolvedSet<8> &Set : Lookups) { 14319 if (Set.empty()) 14320 continue; 14321 URS.append(Set.begin(), Set.end()); 14322 } 14323 return UnresolvedLookupExpr::Create( 14324 SemaRef.Context, /*NamingClass=*/nullptr, 14325 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 14326 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 14327 } 14328 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14329 // The type must be of struct, union or class type in C and C++ 14330 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 14331 return ExprEmpty(); 14332 SourceLocation Loc = MapperId.getLoc(); 14333 // Perform argument dependent lookup. 14334 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 14335 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 14336 // Return the first user-defined mapper with the desired type. 14337 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14338 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 14339 if (!D->isInvalidDecl() && 14340 SemaRef.Context.hasSameType(D->getType(), Type)) 14341 return D; 14342 return nullptr; 14343 })) 14344 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14345 // Find the first user-defined mapper with a type derived from the desired 14346 // type. 14347 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14348 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 14349 if (!D->isInvalidDecl() && 14350 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 14351 !Type.isMoreQualifiedThan(D->getType())) 14352 return D; 14353 return nullptr; 14354 })) { 14355 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14356 /*DetectVirtual=*/false); 14357 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 14358 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14359 VD->getType().getUnqualifiedType()))) { 14360 if (SemaRef.CheckBaseClassAccess( 14361 Loc, VD->getType(), Type, Paths.front(), 14362 /*DiagID=*/0) != Sema::AR_inaccessible) { 14363 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14364 } 14365 } 14366 } 14367 } 14368 // Report error if a mapper is specified, but cannot be found. 14369 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 14370 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 14371 << Type << MapperId.getName(); 14372 return ExprError(); 14373 } 14374 return ExprEmpty(); 14375 } 14376 14377 namespace { 14378 // Utility struct that gathers all the related lists associated with a mappable 14379 // expression. 14380 struct MappableVarListInfo { 14381 // The list of expressions. 14382 ArrayRef<Expr *> VarList; 14383 // The list of processed expressions. 14384 SmallVector<Expr *, 16> ProcessedVarList; 14385 // The mappble components for each expression. 14386 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14387 // The base declaration of the variable. 14388 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14389 // The reference to the user-defined mapper associated with every expression. 14390 SmallVector<Expr *, 16> UDMapperList; 14391 14392 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14393 // We have a list of components and base declarations for each entry in the 14394 // variable list. 14395 VarComponents.reserve(VarList.size()); 14396 VarBaseDeclarations.reserve(VarList.size()); 14397 } 14398 }; 14399 } 14400 14401 // Check the validity of the provided variable list for the provided clause kind 14402 // \a CKind. In the check process the valid expressions, mappable expression 14403 // components, variables, and user-defined mappers are extracted and used to 14404 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14405 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14406 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14407 static void checkMappableExpressionList( 14408 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14409 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14410 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14411 ArrayRef<Expr *> UnresolvedMappers, 14412 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14413 bool IsMapTypeImplicit = false) { 14414 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14415 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14416 "Unexpected clause kind with mappable expressions!"); 14417 14418 // If the identifier of user-defined mapper is not specified, it is "default". 14419 // We do not change the actual name in this clause to distinguish whether a 14420 // mapper is specified explicitly, i.e., it is not explicitly specified when 14421 // MapperId.getName() is empty. 14422 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14423 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14424 MapperId.setName(DeclNames.getIdentifier( 14425 &SemaRef.getASTContext().Idents.get("default"))); 14426 } 14427 14428 // Iterators to find the current unresolved mapper expression. 14429 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14430 bool UpdateUMIt = false; 14431 Expr *UnresolvedMapper = nullptr; 14432 14433 // Keep track of the mappable components and base declarations in this clause. 14434 // Each entry in the list is going to have a list of components associated. We 14435 // record each set of the components so that we can build the clause later on. 14436 // In the end we should have the same amount of declarations and component 14437 // lists. 14438 14439 for (Expr *RE : MVLI.VarList) { 14440 assert(RE && "Null expr in omp to/from/map clause"); 14441 SourceLocation ELoc = RE->getExprLoc(); 14442 14443 // Find the current unresolved mapper expression. 14444 if (UpdateUMIt && UMIt != UMEnd) { 14445 UMIt++; 14446 assert( 14447 UMIt != UMEnd && 14448 "Expect the size of UnresolvedMappers to match with that of VarList"); 14449 } 14450 UpdateUMIt = true; 14451 if (UMIt != UMEnd) 14452 UnresolvedMapper = *UMIt; 14453 14454 const Expr *VE = RE->IgnoreParenLValueCasts(); 14455 14456 if (VE->isValueDependent() || VE->isTypeDependent() || 14457 VE->isInstantiationDependent() || 14458 VE->containsUnexpandedParameterPack()) { 14459 // Try to find the associated user-defined mapper. 14460 ExprResult ER = buildUserDefinedMapperRef( 14461 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14462 VE->getType().getCanonicalType(), UnresolvedMapper); 14463 if (ER.isInvalid()) 14464 continue; 14465 MVLI.UDMapperList.push_back(ER.get()); 14466 // We can only analyze this information once the missing information is 14467 // resolved. 14468 MVLI.ProcessedVarList.push_back(RE); 14469 continue; 14470 } 14471 14472 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14473 14474 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14475 SemaRef.Diag(ELoc, 14476 diag::err_omp_expected_named_var_member_or_array_expression) 14477 << RE->getSourceRange(); 14478 continue; 14479 } 14480 14481 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14482 ValueDecl *CurDeclaration = nullptr; 14483 14484 // Obtain the array or member expression bases if required. Also, fill the 14485 // components array with all the components identified in the process. 14486 const Expr *BE = checkMapClauseExpressionBase( 14487 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14488 if (!BE) 14489 continue; 14490 14491 assert(!CurComponents.empty() && 14492 "Invalid mappable expression information."); 14493 14494 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14495 // Add store "this" pointer to class in DSAStackTy for future checking 14496 DSAS->addMappedClassesQualTypes(TE->getType()); 14497 // Try to find the associated user-defined mapper. 14498 ExprResult ER = buildUserDefinedMapperRef( 14499 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14500 VE->getType().getCanonicalType(), UnresolvedMapper); 14501 if (ER.isInvalid()) 14502 continue; 14503 MVLI.UDMapperList.push_back(ER.get()); 14504 // Skip restriction checking for variable or field declarations 14505 MVLI.ProcessedVarList.push_back(RE); 14506 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14507 MVLI.VarComponents.back().append(CurComponents.begin(), 14508 CurComponents.end()); 14509 MVLI.VarBaseDeclarations.push_back(nullptr); 14510 continue; 14511 } 14512 14513 // For the following checks, we rely on the base declaration which is 14514 // expected to be associated with the last component. The declaration is 14515 // expected to be a variable or a field (if 'this' is being mapped). 14516 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14517 assert(CurDeclaration && "Null decl on map clause."); 14518 assert( 14519 CurDeclaration->isCanonicalDecl() && 14520 "Expecting components to have associated only canonical declarations."); 14521 14522 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14523 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14524 14525 assert((VD || FD) && "Only variables or fields are expected here!"); 14526 (void)FD; 14527 14528 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14529 // threadprivate variables cannot appear in a map clause. 14530 // OpenMP 4.5 [2.10.5, target update Construct] 14531 // threadprivate variables cannot appear in a from clause. 14532 if (VD && DSAS->isThreadPrivate(VD)) { 14533 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14534 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14535 << getOpenMPClauseName(CKind); 14536 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14537 continue; 14538 } 14539 14540 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14541 // A list item cannot appear in both a map clause and a data-sharing 14542 // attribute clause on the same construct. 14543 14544 // Check conflicts with other map clause expressions. We check the conflicts 14545 // with the current construct separately from the enclosing data 14546 // environment, because the restrictions are different. We only have to 14547 // check conflicts across regions for the map clauses. 14548 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14549 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14550 break; 14551 if (CKind == OMPC_map && 14552 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14553 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14554 break; 14555 14556 // OpenMP 4.5 [2.10.5, target update Construct] 14557 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14558 // If the type of a list item is a reference to a type T then the type will 14559 // be considered to be T for all purposes of this clause. 14560 auto I = llvm::find_if( 14561 CurComponents, 14562 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14563 return MC.getAssociatedDeclaration(); 14564 }); 14565 assert(I != CurComponents.end() && "Null decl on map clause."); 14566 QualType Type = 14567 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14568 14569 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14570 // A list item in a to or from clause must have a mappable type. 14571 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14572 // A list item must have a mappable type. 14573 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14574 DSAS, Type)) 14575 continue; 14576 14577 if (CKind == OMPC_map) { 14578 // target enter data 14579 // OpenMP [2.10.2, Restrictions, p. 99] 14580 // A map-type must be specified in all map clauses and must be either 14581 // to or alloc. 14582 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14583 if (DKind == OMPD_target_enter_data && 14584 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14585 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14586 << (IsMapTypeImplicit ? 1 : 0) 14587 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14588 << getOpenMPDirectiveName(DKind); 14589 continue; 14590 } 14591 14592 // target exit_data 14593 // OpenMP [2.10.3, Restrictions, p. 102] 14594 // A map-type must be specified in all map clauses and must be either 14595 // from, release, or delete. 14596 if (DKind == OMPD_target_exit_data && 14597 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14598 MapType == OMPC_MAP_delete)) { 14599 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14600 << (IsMapTypeImplicit ? 1 : 0) 14601 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14602 << getOpenMPDirectiveName(DKind); 14603 continue; 14604 } 14605 14606 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14607 // A list item cannot appear in both a map clause and a data-sharing 14608 // attribute clause on the same construct 14609 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 14610 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14611 if (isOpenMPPrivate(DVar.CKind)) { 14612 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14613 << getOpenMPClauseName(DVar.CKind) 14614 << getOpenMPClauseName(OMPC_map) 14615 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14616 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14617 continue; 14618 } 14619 } 14620 } 14621 14622 // Try to find the associated user-defined mapper. 14623 ExprResult ER = buildUserDefinedMapperRef( 14624 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14625 Type.getCanonicalType(), UnresolvedMapper); 14626 if (ER.isInvalid()) 14627 continue; 14628 MVLI.UDMapperList.push_back(ER.get()); 14629 14630 // Save the current expression. 14631 MVLI.ProcessedVarList.push_back(RE); 14632 14633 // Store the components in the stack so that they can be used to check 14634 // against other clauses later on. 14635 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14636 /*WhereFoundClauseKind=*/OMPC_map); 14637 14638 // Save the components and declaration to create the clause. For purposes of 14639 // the clause creation, any component list that has has base 'this' uses 14640 // null as base declaration. 14641 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14642 MVLI.VarComponents.back().append(CurComponents.begin(), 14643 CurComponents.end()); 14644 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14645 : CurDeclaration); 14646 } 14647 } 14648 14649 OMPClause *Sema::ActOnOpenMPMapClause( 14650 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14651 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14652 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14653 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14654 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14655 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14656 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14657 OMPC_MAP_MODIFIER_unknown, 14658 OMPC_MAP_MODIFIER_unknown}; 14659 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14660 14661 // Process map-type-modifiers, flag errors for duplicate modifiers. 14662 unsigned Count = 0; 14663 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14664 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14665 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14666 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14667 continue; 14668 } 14669 assert(Count < OMPMapClause::NumberOfModifiers && 14670 "Modifiers exceed the allowed number of map type modifiers"); 14671 Modifiers[Count] = MapTypeModifiers[I]; 14672 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14673 ++Count; 14674 } 14675 14676 MappableVarListInfo MVLI(VarList); 14677 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14678 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14679 MapType, IsMapTypeImplicit); 14680 14681 // We need to produce a map clause even if we don't have variables so that 14682 // other diagnostics related with non-existing map clauses are accurate. 14683 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14684 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14685 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14686 MapperIdScopeSpec.getWithLocInContext(Context), 14687 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14688 } 14689 14690 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14691 TypeResult ParsedType) { 14692 assert(ParsedType.isUsable()); 14693 14694 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14695 if (ReductionType.isNull()) 14696 return QualType(); 14697 14698 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14699 // A type name in a declare reduction directive cannot be a function type, an 14700 // array type, a reference type, or a type qualified with const, volatile or 14701 // restrict. 14702 if (ReductionType.hasQualifiers()) { 14703 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14704 return QualType(); 14705 } 14706 14707 if (ReductionType->isFunctionType()) { 14708 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14709 return QualType(); 14710 } 14711 if (ReductionType->isReferenceType()) { 14712 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14713 return QualType(); 14714 } 14715 if (ReductionType->isArrayType()) { 14716 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14717 return QualType(); 14718 } 14719 return ReductionType; 14720 } 14721 14722 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14723 Scope *S, DeclContext *DC, DeclarationName Name, 14724 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14725 AccessSpecifier AS, Decl *PrevDeclInScope) { 14726 SmallVector<Decl *, 8> Decls; 14727 Decls.reserve(ReductionTypes.size()); 14728 14729 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14730 forRedeclarationInCurContext()); 14731 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14732 // A reduction-identifier may not be re-declared in the current scope for the 14733 // same type or for a type that is compatible according to the base language 14734 // rules. 14735 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14736 OMPDeclareReductionDecl *PrevDRD = nullptr; 14737 bool InCompoundScope = true; 14738 if (S != nullptr) { 14739 // Find previous declaration with the same name not referenced in other 14740 // declarations. 14741 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14742 InCompoundScope = 14743 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14744 LookupName(Lookup, S); 14745 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14746 /*AllowInlineNamespace=*/false); 14747 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14748 LookupResult::Filter Filter = Lookup.makeFilter(); 14749 while (Filter.hasNext()) { 14750 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14751 if (InCompoundScope) { 14752 auto I = UsedAsPrevious.find(PrevDecl); 14753 if (I == UsedAsPrevious.end()) 14754 UsedAsPrevious[PrevDecl] = false; 14755 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14756 UsedAsPrevious[D] = true; 14757 } 14758 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14759 PrevDecl->getLocation(); 14760 } 14761 Filter.done(); 14762 if (InCompoundScope) { 14763 for (const auto &PrevData : UsedAsPrevious) { 14764 if (!PrevData.second) { 14765 PrevDRD = PrevData.first; 14766 break; 14767 } 14768 } 14769 } 14770 } else if (PrevDeclInScope != nullptr) { 14771 auto *PrevDRDInScope = PrevDRD = 14772 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14773 do { 14774 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14775 PrevDRDInScope->getLocation(); 14776 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14777 } while (PrevDRDInScope != nullptr); 14778 } 14779 for (const auto &TyData : ReductionTypes) { 14780 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14781 bool Invalid = false; 14782 if (I != PreviousRedeclTypes.end()) { 14783 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14784 << TyData.first; 14785 Diag(I->second, diag::note_previous_definition); 14786 Invalid = true; 14787 } 14788 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 14789 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 14790 Name, TyData.first, PrevDRD); 14791 DC->addDecl(DRD); 14792 DRD->setAccess(AS); 14793 Decls.push_back(DRD); 14794 if (Invalid) 14795 DRD->setInvalidDecl(); 14796 else 14797 PrevDRD = DRD; 14798 } 14799 14800 return DeclGroupPtrTy::make( 14801 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 14802 } 14803 14804 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 14805 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14806 14807 // Enter new function scope. 14808 PushFunctionScope(); 14809 setFunctionHasBranchProtectedScope(); 14810 getCurFunction()->setHasOMPDeclareReductionCombiner(); 14811 14812 if (S != nullptr) 14813 PushDeclContext(S, DRD); 14814 else 14815 CurContext = DRD; 14816 14817 PushExpressionEvaluationContext( 14818 ExpressionEvaluationContext::PotentiallyEvaluated); 14819 14820 QualType ReductionType = DRD->getType(); 14821 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 14822 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 14823 // uses semantics of argument handles by value, but it should be passed by 14824 // reference. C lang does not support references, so pass all parameters as 14825 // pointers. 14826 // Create 'T omp_in;' variable. 14827 VarDecl *OmpInParm = 14828 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 14829 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 14830 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 14831 // uses semantics of argument handles by value, but it should be passed by 14832 // reference. C lang does not support references, so pass all parameters as 14833 // pointers. 14834 // Create 'T omp_out;' variable. 14835 VarDecl *OmpOutParm = 14836 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 14837 if (S != nullptr) { 14838 PushOnScopeChains(OmpInParm, S); 14839 PushOnScopeChains(OmpOutParm, S); 14840 } else { 14841 DRD->addDecl(OmpInParm); 14842 DRD->addDecl(OmpOutParm); 14843 } 14844 Expr *InE = 14845 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 14846 Expr *OutE = 14847 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 14848 DRD->setCombinerData(InE, OutE); 14849 } 14850 14851 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 14852 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14853 DiscardCleanupsInEvaluationContext(); 14854 PopExpressionEvaluationContext(); 14855 14856 PopDeclContext(); 14857 PopFunctionScopeInfo(); 14858 14859 if (Combiner != nullptr) 14860 DRD->setCombiner(Combiner); 14861 else 14862 DRD->setInvalidDecl(); 14863 } 14864 14865 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 14866 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14867 14868 // Enter new function scope. 14869 PushFunctionScope(); 14870 setFunctionHasBranchProtectedScope(); 14871 14872 if (S != nullptr) 14873 PushDeclContext(S, DRD); 14874 else 14875 CurContext = DRD; 14876 14877 PushExpressionEvaluationContext( 14878 ExpressionEvaluationContext::PotentiallyEvaluated); 14879 14880 QualType ReductionType = DRD->getType(); 14881 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 14882 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 14883 // uses semantics of argument handles by value, but it should be passed by 14884 // reference. C lang does not support references, so pass all parameters as 14885 // pointers. 14886 // Create 'T omp_priv;' variable. 14887 VarDecl *OmpPrivParm = 14888 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 14889 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 14890 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 14891 // uses semantics of argument handles by value, but it should be passed by 14892 // reference. C lang does not support references, so pass all parameters as 14893 // pointers. 14894 // Create 'T omp_orig;' variable. 14895 VarDecl *OmpOrigParm = 14896 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 14897 if (S != nullptr) { 14898 PushOnScopeChains(OmpPrivParm, S); 14899 PushOnScopeChains(OmpOrigParm, S); 14900 } else { 14901 DRD->addDecl(OmpPrivParm); 14902 DRD->addDecl(OmpOrigParm); 14903 } 14904 Expr *OrigE = 14905 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 14906 Expr *PrivE = 14907 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 14908 DRD->setInitializerData(OrigE, PrivE); 14909 return OmpPrivParm; 14910 } 14911 14912 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 14913 VarDecl *OmpPrivParm) { 14914 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14915 DiscardCleanupsInEvaluationContext(); 14916 PopExpressionEvaluationContext(); 14917 14918 PopDeclContext(); 14919 PopFunctionScopeInfo(); 14920 14921 if (Initializer != nullptr) { 14922 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 14923 } else if (OmpPrivParm->hasInit()) { 14924 DRD->setInitializer(OmpPrivParm->getInit(), 14925 OmpPrivParm->isDirectInit() 14926 ? OMPDeclareReductionDecl::DirectInit 14927 : OMPDeclareReductionDecl::CopyInit); 14928 } else { 14929 DRD->setInvalidDecl(); 14930 } 14931 } 14932 14933 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14934 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14935 for (Decl *D : DeclReductions.get()) { 14936 if (IsValid) { 14937 if (S) 14938 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14939 /*AddToContext=*/false); 14940 } else { 14941 D->setInvalidDecl(); 14942 } 14943 } 14944 return DeclReductions; 14945 } 14946 14947 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14948 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14949 QualType T = TInfo->getType(); 14950 if (D.isInvalidType()) 14951 return true; 14952 14953 if (getLangOpts().CPlusPlus) { 14954 // Check that there are no default arguments (C++ only). 14955 CheckExtraCXXDefaultArguments(D); 14956 } 14957 14958 return CreateParsedType(T, TInfo); 14959 } 14960 14961 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14962 TypeResult ParsedType) { 14963 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14964 14965 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14966 assert(!MapperType.isNull() && "Expect valid mapper type"); 14967 14968 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14969 // The type must be of struct, union or class type in C and C++ 14970 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14971 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14972 return QualType(); 14973 } 14974 return MapperType; 14975 } 14976 14977 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14978 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14979 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14980 Decl *PrevDeclInScope) { 14981 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14982 forRedeclarationInCurContext()); 14983 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14984 // A mapper-identifier may not be redeclared in the current scope for the 14985 // same type or for a type that is compatible according to the base language 14986 // rules. 14987 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14988 OMPDeclareMapperDecl *PrevDMD = nullptr; 14989 bool InCompoundScope = true; 14990 if (S != nullptr) { 14991 // Find previous declaration with the same name not referenced in other 14992 // declarations. 14993 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14994 InCompoundScope = 14995 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14996 LookupName(Lookup, S); 14997 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14998 /*AllowInlineNamespace=*/false); 14999 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15000 LookupResult::Filter Filter = Lookup.makeFilter(); 15001 while (Filter.hasNext()) { 15002 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15003 if (InCompoundScope) { 15004 auto I = UsedAsPrevious.find(PrevDecl); 15005 if (I == UsedAsPrevious.end()) 15006 UsedAsPrevious[PrevDecl] = false; 15007 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15008 UsedAsPrevious[D] = true; 15009 } 15010 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15011 PrevDecl->getLocation(); 15012 } 15013 Filter.done(); 15014 if (InCompoundScope) { 15015 for (const auto &PrevData : UsedAsPrevious) { 15016 if (!PrevData.second) { 15017 PrevDMD = PrevData.first; 15018 break; 15019 } 15020 } 15021 } 15022 } else if (PrevDeclInScope) { 15023 auto *PrevDMDInScope = PrevDMD = 15024 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15025 do { 15026 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15027 PrevDMDInScope->getLocation(); 15028 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15029 } while (PrevDMDInScope != nullptr); 15030 } 15031 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15032 bool Invalid = false; 15033 if (I != PreviousRedeclTypes.end()) { 15034 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15035 << MapperType << Name; 15036 Diag(I->second, diag::note_previous_definition); 15037 Invalid = true; 15038 } 15039 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15040 MapperType, VN, PrevDMD); 15041 DC->addDecl(DMD); 15042 DMD->setAccess(AS); 15043 if (Invalid) 15044 DMD->setInvalidDecl(); 15045 15046 // Enter new function scope. 15047 PushFunctionScope(); 15048 setFunctionHasBranchProtectedScope(); 15049 15050 CurContext = DMD; 15051 15052 return DMD; 15053 } 15054 15055 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15056 Scope *S, 15057 QualType MapperType, 15058 SourceLocation StartLoc, 15059 DeclarationName VN) { 15060 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15061 if (S) 15062 PushOnScopeChains(VD, S); 15063 else 15064 DMD->addDecl(VD); 15065 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15066 DMD->setMapperVarRef(MapperVarRefExpr); 15067 } 15068 15069 Sema::DeclGroupPtrTy 15070 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15071 ArrayRef<OMPClause *> ClauseList) { 15072 PopDeclContext(); 15073 PopFunctionScopeInfo(); 15074 15075 if (D) { 15076 if (S) 15077 PushOnScopeChains(D, S, /*AddToContext=*/false); 15078 D->CreateClauses(Context, ClauseList); 15079 } 15080 15081 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15082 } 15083 15084 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15085 SourceLocation StartLoc, 15086 SourceLocation LParenLoc, 15087 SourceLocation EndLoc) { 15088 Expr *ValExpr = NumTeams; 15089 Stmt *HelperValStmt = nullptr; 15090 15091 // OpenMP [teams Constrcut, Restrictions] 15092 // The num_teams expression must evaluate to a positive integer value. 15093 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15094 /*StrictlyPositive=*/true)) 15095 return nullptr; 15096 15097 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15098 OpenMPDirectiveKind CaptureRegion = 15099 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15100 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15101 ValExpr = MakeFullExpr(ValExpr).get(); 15102 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15103 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15104 HelperValStmt = buildPreInits(Context, Captures); 15105 } 15106 15107 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15108 StartLoc, LParenLoc, EndLoc); 15109 } 15110 15111 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15112 SourceLocation StartLoc, 15113 SourceLocation LParenLoc, 15114 SourceLocation EndLoc) { 15115 Expr *ValExpr = ThreadLimit; 15116 Stmt *HelperValStmt = nullptr; 15117 15118 // OpenMP [teams Constrcut, Restrictions] 15119 // The thread_limit expression must evaluate to a positive integer value. 15120 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15121 /*StrictlyPositive=*/true)) 15122 return nullptr; 15123 15124 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15125 OpenMPDirectiveKind CaptureRegion = 15126 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15127 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15128 ValExpr = MakeFullExpr(ValExpr).get(); 15129 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15130 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15131 HelperValStmt = buildPreInits(Context, Captures); 15132 } 15133 15134 return new (Context) OMPThreadLimitClause( 15135 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15136 } 15137 15138 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15139 SourceLocation StartLoc, 15140 SourceLocation LParenLoc, 15141 SourceLocation EndLoc) { 15142 Expr *ValExpr = Priority; 15143 15144 // OpenMP [2.9.1, task Constrcut] 15145 // The priority-value is a non-negative numerical scalar expression. 15146 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15147 /*StrictlyPositive=*/false)) 15148 return nullptr; 15149 15150 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15151 } 15152 15153 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15154 SourceLocation StartLoc, 15155 SourceLocation LParenLoc, 15156 SourceLocation EndLoc) { 15157 Expr *ValExpr = Grainsize; 15158 15159 // OpenMP [2.9.2, taskloop Constrcut] 15160 // The parameter of the grainsize clause must be a positive integer 15161 // expression. 15162 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 15163 /*StrictlyPositive=*/true)) 15164 return nullptr; 15165 15166 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15167 } 15168 15169 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15170 SourceLocation StartLoc, 15171 SourceLocation LParenLoc, 15172 SourceLocation EndLoc) { 15173 Expr *ValExpr = NumTasks; 15174 15175 // OpenMP [2.9.2, taskloop Constrcut] 15176 // The parameter of the num_tasks clause must be a positive integer 15177 // expression. 15178 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 15179 /*StrictlyPositive=*/true)) 15180 return nullptr; 15181 15182 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15183 } 15184 15185 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15186 SourceLocation LParenLoc, 15187 SourceLocation EndLoc) { 15188 // OpenMP [2.13.2, critical construct, Description] 15189 // ... where hint-expression is an integer constant expression that evaluates 15190 // to a valid lock hint. 15191 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15192 if (HintExpr.isInvalid()) 15193 return nullptr; 15194 return new (Context) 15195 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 15196 } 15197 15198 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 15199 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 15200 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 15201 SourceLocation EndLoc) { 15202 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 15203 std::string Values; 15204 Values += "'"; 15205 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 15206 Values += "'"; 15207 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 15208 << Values << getOpenMPClauseName(OMPC_dist_schedule); 15209 return nullptr; 15210 } 15211 Expr *ValExpr = ChunkSize; 15212 Stmt *HelperValStmt = nullptr; 15213 if (ChunkSize) { 15214 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 15215 !ChunkSize->isInstantiationDependent() && 15216 !ChunkSize->containsUnexpandedParameterPack()) { 15217 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 15218 ExprResult Val = 15219 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 15220 if (Val.isInvalid()) 15221 return nullptr; 15222 15223 ValExpr = Val.get(); 15224 15225 // OpenMP [2.7.1, Restrictions] 15226 // chunk_size must be a loop invariant integer expression with a positive 15227 // value. 15228 llvm::APSInt Result; 15229 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 15230 if (Result.isSigned() && !Result.isStrictlyPositive()) { 15231 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 15232 << "dist_schedule" << ChunkSize->getSourceRange(); 15233 return nullptr; 15234 } 15235 } else if (getOpenMPCaptureRegionForClause( 15236 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 15237 OMPD_unknown && 15238 !CurContext->isDependentContext()) { 15239 ValExpr = MakeFullExpr(ValExpr).get(); 15240 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15241 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15242 HelperValStmt = buildPreInits(Context, Captures); 15243 } 15244 } 15245 } 15246 15247 return new (Context) 15248 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 15249 Kind, ValExpr, HelperValStmt); 15250 } 15251 15252 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 15253 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 15254 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 15255 SourceLocation KindLoc, SourceLocation EndLoc) { 15256 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 15257 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 15258 std::string Value; 15259 SourceLocation Loc; 15260 Value += "'"; 15261 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 15262 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15263 OMPC_DEFAULTMAP_MODIFIER_tofrom); 15264 Loc = MLoc; 15265 } else { 15266 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15267 OMPC_DEFAULTMAP_scalar); 15268 Loc = KindLoc; 15269 } 15270 Value += "'"; 15271 Diag(Loc, diag::err_omp_unexpected_clause_value) 15272 << Value << getOpenMPClauseName(OMPC_defaultmap); 15273 return nullptr; 15274 } 15275 DSAStack->setDefaultDMAToFromScalar(StartLoc); 15276 15277 return new (Context) 15278 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 15279 } 15280 15281 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 15282 DeclContext *CurLexicalContext = getCurLexicalContext(); 15283 if (!CurLexicalContext->isFileContext() && 15284 !CurLexicalContext->isExternCContext() && 15285 !CurLexicalContext->isExternCXXContext() && 15286 !isa<CXXRecordDecl>(CurLexicalContext) && 15287 !isa<ClassTemplateDecl>(CurLexicalContext) && 15288 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 15289 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 15290 Diag(Loc, diag::err_omp_region_not_file_context); 15291 return false; 15292 } 15293 ++DeclareTargetNestingLevel; 15294 return true; 15295 } 15296 15297 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 15298 assert(DeclareTargetNestingLevel > 0 && 15299 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 15300 --DeclareTargetNestingLevel; 15301 } 15302 15303 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 15304 CXXScopeSpec &ScopeSpec, 15305 const DeclarationNameInfo &Id, 15306 OMPDeclareTargetDeclAttr::MapTypeTy MT, 15307 NamedDeclSetType &SameDirectiveDecls) { 15308 LookupResult Lookup(*this, Id, LookupOrdinaryName); 15309 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 15310 15311 if (Lookup.isAmbiguous()) 15312 return; 15313 Lookup.suppressDiagnostics(); 15314 15315 if (!Lookup.isSingleResult()) { 15316 VarOrFuncDeclFilterCCC CCC(*this); 15317 if (TypoCorrection Corrected = 15318 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 15319 CTK_ErrorRecovery)) { 15320 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 15321 << Id.getName()); 15322 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 15323 return; 15324 } 15325 15326 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 15327 return; 15328 } 15329 15330 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 15331 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 15332 isa<FunctionTemplateDecl>(ND)) { 15333 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 15334 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 15335 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15336 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 15337 cast<ValueDecl>(ND)); 15338 if (!Res) { 15339 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 15340 ND->addAttr(A); 15341 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15342 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 15343 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 15344 } else if (*Res != MT) { 15345 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 15346 << Id.getName(); 15347 } 15348 } else { 15349 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 15350 } 15351 } 15352 15353 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 15354 Sema &SemaRef, Decl *D) { 15355 if (!D || !isa<VarDecl>(D)) 15356 return; 15357 auto *VD = cast<VarDecl>(D); 15358 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15359 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15360 if (SemaRef.LangOpts.OpenMP >= 50 && 15361 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 15362 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 15363 VD->hasGlobalStorage()) { 15364 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15365 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15366 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 15367 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 15368 // If a lambda declaration and definition appears between a 15369 // declare target directive and the matching end declare target 15370 // directive, all variables that are captured by the lambda 15371 // expression must also appear in a to clause. 15372 SemaRef.Diag(VD->getLocation(), 15373 diag::err_omp_lambda_capture_in_declare_target_not_to); 15374 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 15375 << VD << 0 << SR; 15376 return; 15377 } 15378 } 15379 if (MapTy.hasValue()) 15380 return; 15381 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 15382 SemaRef.Diag(SL, diag::note_used_here) << SR; 15383 } 15384 15385 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 15386 Sema &SemaRef, DSAStackTy *Stack, 15387 ValueDecl *VD) { 15388 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 15389 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 15390 /*FullCheck=*/false); 15391 } 15392 15393 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 15394 SourceLocation IdLoc) { 15395 if (!D || D->isInvalidDecl()) 15396 return; 15397 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 15398 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15399 if (auto *VD = dyn_cast<VarDecl>(D)) { 15400 // Only global variables can be marked as declare target. 15401 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15402 !VD->isStaticDataMember()) 15403 return; 15404 // 2.10.6: threadprivate variable cannot appear in a declare target 15405 // directive. 15406 if (DSAStack->isThreadPrivate(VD)) { 15407 Diag(SL, diag::err_omp_threadprivate_in_target); 15408 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15409 return; 15410 } 15411 } 15412 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 15413 D = FTD->getTemplatedDecl(); 15414 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 15415 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15416 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 15417 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 15418 Diag(IdLoc, diag::err_omp_function_in_link_clause); 15419 Diag(FD->getLocation(), diag::note_defined_here) << FD; 15420 return; 15421 } 15422 // Mark the function as must be emitted for the device. 15423 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid()) 15424 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 15425 } 15426 if (auto *VD = dyn_cast<ValueDecl>(D)) { 15427 // Problem if any with var declared with incomplete type will be reported 15428 // as normal, so no need to check it here. 15429 if ((E || !VD->getType()->isIncompleteType()) && 15430 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 15431 return; 15432 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 15433 // Checking declaration inside declare target region. 15434 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 15435 isa<FunctionTemplateDecl>(D)) { 15436 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 15437 Context, OMPDeclareTargetDeclAttr::MT_To); 15438 D->addAttr(A); 15439 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15440 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 15441 } 15442 return; 15443 } 15444 } 15445 if (!E) 15446 return; 15447 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15448 } 15449 15450 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15451 CXXScopeSpec &MapperIdScopeSpec, 15452 DeclarationNameInfo &MapperId, 15453 const OMPVarListLocTy &Locs, 15454 ArrayRef<Expr *> UnresolvedMappers) { 15455 MappableVarListInfo MVLI(VarList); 15456 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15457 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15458 if (MVLI.ProcessedVarList.empty()) 15459 return nullptr; 15460 15461 return OMPToClause::Create( 15462 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15463 MVLI.VarComponents, MVLI.UDMapperList, 15464 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15465 } 15466 15467 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15468 CXXScopeSpec &MapperIdScopeSpec, 15469 DeclarationNameInfo &MapperId, 15470 const OMPVarListLocTy &Locs, 15471 ArrayRef<Expr *> UnresolvedMappers) { 15472 MappableVarListInfo MVLI(VarList); 15473 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15474 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15475 if (MVLI.ProcessedVarList.empty()) 15476 return nullptr; 15477 15478 return OMPFromClause::Create( 15479 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15480 MVLI.VarComponents, MVLI.UDMapperList, 15481 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15482 } 15483 15484 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15485 const OMPVarListLocTy &Locs) { 15486 MappableVarListInfo MVLI(VarList); 15487 SmallVector<Expr *, 8> PrivateCopies; 15488 SmallVector<Expr *, 8> Inits; 15489 15490 for (Expr *RefExpr : VarList) { 15491 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15492 SourceLocation ELoc; 15493 SourceRange ERange; 15494 Expr *SimpleRefExpr = RefExpr; 15495 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15496 if (Res.second) { 15497 // It will be analyzed later. 15498 MVLI.ProcessedVarList.push_back(RefExpr); 15499 PrivateCopies.push_back(nullptr); 15500 Inits.push_back(nullptr); 15501 } 15502 ValueDecl *D = Res.first; 15503 if (!D) 15504 continue; 15505 15506 QualType Type = D->getType(); 15507 Type = Type.getNonReferenceType().getUnqualifiedType(); 15508 15509 auto *VD = dyn_cast<VarDecl>(D); 15510 15511 // Item should be a pointer or reference to pointer. 15512 if (!Type->isPointerType()) { 15513 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15514 << 0 << RefExpr->getSourceRange(); 15515 continue; 15516 } 15517 15518 // Build the private variable and the expression that refers to it. 15519 auto VDPrivate = 15520 buildVarDecl(*this, ELoc, Type, D->getName(), 15521 D->hasAttrs() ? &D->getAttrs() : nullptr, 15522 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15523 if (VDPrivate->isInvalidDecl()) 15524 continue; 15525 15526 CurContext->addDecl(VDPrivate); 15527 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15528 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15529 15530 // Add temporary variable to initialize the private copy of the pointer. 15531 VarDecl *VDInit = 15532 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15533 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15534 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15535 AddInitializerToDecl(VDPrivate, 15536 DefaultLvalueConversion(VDInitRefExpr).get(), 15537 /*DirectInit=*/false); 15538 15539 // If required, build a capture to implement the privatization initialized 15540 // with the current list item value. 15541 DeclRefExpr *Ref = nullptr; 15542 if (!VD) 15543 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15544 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15545 PrivateCopies.push_back(VDPrivateRefExpr); 15546 Inits.push_back(VDInitRefExpr); 15547 15548 // We need to add a data sharing attribute for this variable to make sure it 15549 // is correctly captured. A variable that shows up in a use_device_ptr has 15550 // similar properties of a first private variable. 15551 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15552 15553 // Create a mappable component for the list item. List items in this clause 15554 // only need a component. 15555 MVLI.VarBaseDeclarations.push_back(D); 15556 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15557 MVLI.VarComponents.back().push_back( 15558 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15559 } 15560 15561 if (MVLI.ProcessedVarList.empty()) 15562 return nullptr; 15563 15564 return OMPUseDevicePtrClause::Create( 15565 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15566 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15567 } 15568 15569 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15570 const OMPVarListLocTy &Locs) { 15571 MappableVarListInfo MVLI(VarList); 15572 for (Expr *RefExpr : VarList) { 15573 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15574 SourceLocation ELoc; 15575 SourceRange ERange; 15576 Expr *SimpleRefExpr = RefExpr; 15577 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15578 if (Res.second) { 15579 // It will be analyzed later. 15580 MVLI.ProcessedVarList.push_back(RefExpr); 15581 } 15582 ValueDecl *D = Res.first; 15583 if (!D) 15584 continue; 15585 15586 QualType Type = D->getType(); 15587 // item should be a pointer or array or reference to pointer or array 15588 if (!Type.getNonReferenceType()->isPointerType() && 15589 !Type.getNonReferenceType()->isArrayType()) { 15590 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15591 << 0 << RefExpr->getSourceRange(); 15592 continue; 15593 } 15594 15595 // Check if the declaration in the clause does not show up in any data 15596 // sharing attribute. 15597 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15598 if (isOpenMPPrivate(DVar.CKind)) { 15599 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15600 << getOpenMPClauseName(DVar.CKind) 15601 << getOpenMPClauseName(OMPC_is_device_ptr) 15602 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15603 reportOriginalDsa(*this, DSAStack, D, DVar); 15604 continue; 15605 } 15606 15607 const Expr *ConflictExpr; 15608 if (DSAStack->checkMappableExprComponentListsForDecl( 15609 D, /*CurrentRegionOnly=*/true, 15610 [&ConflictExpr]( 15611 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15612 OpenMPClauseKind) -> bool { 15613 ConflictExpr = R.front().getAssociatedExpression(); 15614 return true; 15615 })) { 15616 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15617 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15618 << ConflictExpr->getSourceRange(); 15619 continue; 15620 } 15621 15622 // Store the components in the stack so that they can be used to check 15623 // against other clauses later on. 15624 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15625 DSAStack->addMappableExpressionComponents( 15626 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15627 15628 // Record the expression we've just processed. 15629 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15630 15631 // Create a mappable component for the list item. List items in this clause 15632 // only need a component. We use a null declaration to signal fields in 15633 // 'this'. 15634 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15635 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15636 "Unexpected device pointer expression!"); 15637 MVLI.VarBaseDeclarations.push_back( 15638 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15639 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15640 MVLI.VarComponents.back().push_back(MC); 15641 } 15642 15643 if (MVLI.ProcessedVarList.empty()) 15644 return nullptr; 15645 15646 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15647 MVLI.VarBaseDeclarations, 15648 MVLI.VarComponents); 15649 } 15650 15651 OMPClause *Sema::ActOnOpenMPAllocateClause( 15652 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15653 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15654 if (Allocator) { 15655 // OpenMP [2.11.4 allocate Clause, Description] 15656 // allocator is an expression of omp_allocator_handle_t type. 15657 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15658 return nullptr; 15659 15660 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15661 if (AllocatorRes.isInvalid()) 15662 return nullptr; 15663 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15664 DSAStack->getOMPAllocatorHandleT(), 15665 Sema::AA_Initializing, 15666 /*AllowExplicit=*/true); 15667 if (AllocatorRes.isInvalid()) 15668 return nullptr; 15669 Allocator = AllocatorRes.get(); 15670 } else { 15671 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15672 // allocate clauses that appear on a target construct or on constructs in a 15673 // target region must specify an allocator expression unless a requires 15674 // directive with the dynamic_allocators clause is present in the same 15675 // compilation unit. 15676 if (LangOpts.OpenMPIsDevice && 15677 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15678 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15679 } 15680 // Analyze and build list of variables. 15681 SmallVector<Expr *, 8> Vars; 15682 for (Expr *RefExpr : VarList) { 15683 assert(RefExpr && "NULL expr in OpenMP private clause."); 15684 SourceLocation ELoc; 15685 SourceRange ERange; 15686 Expr *SimpleRefExpr = RefExpr; 15687 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15688 if (Res.second) { 15689 // It will be analyzed later. 15690 Vars.push_back(RefExpr); 15691 } 15692 ValueDecl *D = Res.first; 15693 if (!D) 15694 continue; 15695 15696 auto *VD = dyn_cast<VarDecl>(D); 15697 DeclRefExpr *Ref = nullptr; 15698 if (!VD && !CurContext->isDependentContext()) 15699 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15700 Vars.push_back((VD || CurContext->isDependentContext()) 15701 ? RefExpr->IgnoreParens() 15702 : Ref); 15703 } 15704 15705 if (Vars.empty()) 15706 return nullptr; 15707 15708 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15709 ColonLoc, EndLoc, Vars); 15710 } 15711