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 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1581 "Expected OpenMP device compilation."); 1582 assert(Callee && "Callee may not be null."); 1583 FunctionDecl *Caller = getCurFunctionDecl(); 1584 1585 // If the caller is known-emitted, mark the callee as known-emitted. 1586 // Otherwise, mark the call in our call graph so we can traverse it later. 1587 if (!isOpenMPDeviceDelayedContext(*this) || 1588 (Caller && isKnownEmitted(*this, Caller))) 1589 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1590 else if (Caller) 1591 DeviceCallGraph[Caller].insert({Callee, Loc}); 1592 } 1593 1594 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1595 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1596 "OpenMP device compilation mode is expected."); 1597 QualType Ty = E->getType(); 1598 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1599 ((Ty->isFloat128Type() || 1600 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1601 !Context.getTargetInfo().hasFloat128Type()) || 1602 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1603 !Context.getTargetInfo().hasInt128Type())) 1604 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1605 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1606 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1607 } 1608 1609 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1610 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1611 1612 ASTContext &Ctx = getASTContext(); 1613 bool IsByRef = true; 1614 1615 // Find the directive that is associated with the provided scope. 1616 D = cast<ValueDecl>(D->getCanonicalDecl()); 1617 QualType Ty = D->getType(); 1618 1619 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1620 // This table summarizes how a given variable should be passed to the device 1621 // given its type and the clauses where it appears. This table is based on 1622 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1623 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1624 // 1625 // ========================================================================= 1626 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1627 // | |(tofrom:scalar)| | pvt | | | | 1628 // ========================================================================= 1629 // | scl | | | | - | | bycopy| 1630 // | scl | | - | x | - | - | bycopy| 1631 // | scl | | x | - | - | - | null | 1632 // | scl | x | | | - | | byref | 1633 // | scl | x | - | x | - | - | bycopy| 1634 // | scl | x | x | - | - | - | null | 1635 // | scl | | - | - | - | x | byref | 1636 // | scl | x | - | - | - | x | byref | 1637 // 1638 // | agg | n.a. | | | - | | byref | 1639 // | agg | n.a. | - | x | - | - | byref | 1640 // | agg | n.a. | x | - | - | - | null | 1641 // | agg | n.a. | - | - | - | x | byref | 1642 // | agg | n.a. | - | - | - | x[] | byref | 1643 // 1644 // | ptr | n.a. | | | - | | bycopy| 1645 // | ptr | n.a. | - | x | - | - | bycopy| 1646 // | ptr | n.a. | x | - | - | - | null | 1647 // | ptr | n.a. | - | - | - | x | byref | 1648 // | ptr | n.a. | - | - | - | x[] | bycopy| 1649 // | ptr | n.a. | - | - | x | | bycopy| 1650 // | ptr | n.a. | - | - | x | x | bycopy| 1651 // | ptr | n.a. | - | - | x | x[] | bycopy| 1652 // ========================================================================= 1653 // Legend: 1654 // scl - scalar 1655 // ptr - pointer 1656 // agg - aggregate 1657 // x - applies 1658 // - - invalid in this combination 1659 // [] - mapped with an array section 1660 // byref - should be mapped by reference 1661 // byval - should be mapped by value 1662 // null - initialize a local variable to null on the device 1663 // 1664 // Observations: 1665 // - All scalar declarations that show up in a map clause have to be passed 1666 // by reference, because they may have been mapped in the enclosing data 1667 // environment. 1668 // - If the scalar value does not fit the size of uintptr, it has to be 1669 // passed by reference, regardless the result in the table above. 1670 // - For pointers mapped by value that have either an implicit map or an 1671 // array section, the runtime library may pass the NULL value to the 1672 // device instead of the value passed to it by the compiler. 1673 1674 if (Ty->isReferenceType()) 1675 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1676 1677 // Locate map clauses and see if the variable being captured is referred to 1678 // in any of those clauses. Here we only care about variables, not fields, 1679 // because fields are part of aggregates. 1680 bool IsVariableUsedInMapClause = false; 1681 bool IsVariableAssociatedWithSection = false; 1682 1683 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1684 D, Level, 1685 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1686 OMPClauseMappableExprCommon::MappableExprComponentListRef 1687 MapExprComponents, 1688 OpenMPClauseKind WhereFoundClauseKind) { 1689 // Only the map clause information influences how a variable is 1690 // captured. E.g. is_device_ptr does not require changing the default 1691 // behavior. 1692 if (WhereFoundClauseKind != OMPC_map) 1693 return false; 1694 1695 auto EI = MapExprComponents.rbegin(); 1696 auto EE = MapExprComponents.rend(); 1697 1698 assert(EI != EE && "Invalid map expression!"); 1699 1700 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1701 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1702 1703 ++EI; 1704 if (EI == EE) 1705 return false; 1706 1707 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1708 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1709 isa<MemberExpr>(EI->getAssociatedExpression())) { 1710 IsVariableAssociatedWithSection = true; 1711 // There is nothing more we need to know about this variable. 1712 return true; 1713 } 1714 1715 // Keep looking for more map info. 1716 return false; 1717 }); 1718 1719 if (IsVariableUsedInMapClause) { 1720 // If variable is identified in a map clause it is always captured by 1721 // reference except if it is a pointer that is dereferenced somehow. 1722 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1723 } else { 1724 // By default, all the data that has a scalar type is mapped by copy 1725 // (except for reduction variables). 1726 IsByRef = 1727 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1728 !Ty->isAnyPointerType()) || 1729 !Ty->isScalarType() || 1730 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1731 DSAStack->hasExplicitDSA( 1732 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1733 } 1734 } 1735 1736 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1737 IsByRef = 1738 !DSAStack->hasExplicitDSA( 1739 D, 1740 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1741 Level, /*NotLastprivate=*/true) && 1742 // If the variable is artificial and must be captured by value - try to 1743 // capture by value. 1744 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1745 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1746 } 1747 1748 // When passing data by copy, we need to make sure it fits the uintptr size 1749 // and alignment, because the runtime library only deals with uintptr types. 1750 // If it does not fit the uintptr size, we need to pass the data by reference 1751 // instead. 1752 if (!IsByRef && 1753 (Ctx.getTypeSizeInChars(Ty) > 1754 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1755 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1756 IsByRef = true; 1757 } 1758 1759 return IsByRef; 1760 } 1761 1762 unsigned Sema::getOpenMPNestingLevel() const { 1763 assert(getLangOpts().OpenMP); 1764 return DSAStack->getNestingLevel(); 1765 } 1766 1767 bool Sema::isInOpenMPTargetExecutionDirective() const { 1768 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1769 !DSAStack->isClauseParsingMode()) || 1770 DSAStack->hasDirective( 1771 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1772 SourceLocation) -> bool { 1773 return isOpenMPTargetExecutionDirective(K); 1774 }, 1775 false); 1776 } 1777 1778 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1779 unsigned StopAt) { 1780 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1781 D = getCanonicalDecl(D); 1782 1783 // If we want to determine whether the variable should be captured from the 1784 // perspective of the current capturing scope, and we've already left all the 1785 // capturing scopes of the top directive on the stack, check from the 1786 // perspective of its parent directive (if any) instead. 1787 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1788 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1789 1790 // If we are attempting to capture a global variable in a directive with 1791 // 'target' we return true so that this global is also mapped to the device. 1792 // 1793 auto *VD = dyn_cast<VarDecl>(D); 1794 if (VD && !VD->hasLocalStorage() && 1795 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1796 if (isInOpenMPDeclareTargetContext()) { 1797 // Try to mark variable as declare target if it is used in capturing 1798 // regions. 1799 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1800 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1801 return nullptr; 1802 } else if (isInOpenMPTargetExecutionDirective()) { 1803 // If the declaration is enclosed in a 'declare target' directive, 1804 // then it should not be captured. 1805 // 1806 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1807 return nullptr; 1808 return VD; 1809 } 1810 } 1811 1812 if (CheckScopeInfo) { 1813 bool OpenMPFound = false; 1814 for (unsigned I = StopAt + 1; I > 0; --I) { 1815 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1816 if(!isa<CapturingScopeInfo>(FSI)) 1817 return nullptr; 1818 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1819 if (RSI->CapRegionKind == CR_OpenMP) { 1820 OpenMPFound = true; 1821 break; 1822 } 1823 } 1824 if (!OpenMPFound) 1825 return nullptr; 1826 } 1827 1828 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1829 (!DSAStack->isClauseParsingMode() || 1830 DSAStack->getParentDirective() != OMPD_unknown)) { 1831 auto &&Info = DSAStack->isLoopControlVariable(D); 1832 if (Info.first || 1833 (VD && VD->hasLocalStorage() && 1834 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1835 (VD && DSAStack->isForceVarCapturing())) 1836 return VD ? VD : Info.second; 1837 DSAStackTy::DSAVarData DVarPrivate = 1838 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1839 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1840 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1841 // Threadprivate variables must not be captured. 1842 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1843 return nullptr; 1844 // The variable is not private or it is the variable in the directive with 1845 // default(none) clause and not used in any clause. 1846 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1847 [](OpenMPDirectiveKind) { return true; }, 1848 DSAStack->isClauseParsingMode()); 1849 if (DVarPrivate.CKind != OMPC_unknown || 1850 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1851 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1852 } 1853 return nullptr; 1854 } 1855 1856 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1857 unsigned Level) const { 1858 SmallVector<OpenMPDirectiveKind, 4> Regions; 1859 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1860 FunctionScopesIndex -= Regions.size(); 1861 } 1862 1863 void Sema::startOpenMPLoop() { 1864 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1865 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1866 DSAStack->loopInit(); 1867 } 1868 1869 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1870 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1871 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1872 if (DSAStack->getAssociatedLoops() > 0 && 1873 !DSAStack->isLoopStarted()) { 1874 DSAStack->resetPossibleLoopCounter(D); 1875 DSAStack->loopStart(); 1876 return true; 1877 } 1878 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1879 DSAStack->isLoopControlVariable(D).first) && 1880 !DSAStack->hasExplicitDSA( 1881 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1882 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1883 return true; 1884 } 1885 if (const auto *VD = dyn_cast<VarDecl>(D)) { 1886 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 1887 DSAStack->isForceVarCapturing() && 1888 !DSAStack->hasExplicitDSA( 1889 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 1890 return true; 1891 } 1892 return DSAStack->hasExplicitDSA( 1893 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1894 (DSAStack->isClauseParsingMode() && 1895 DSAStack->getClauseParsingMode() == OMPC_private) || 1896 // Consider taskgroup reduction descriptor variable a private to avoid 1897 // possible capture in the region. 1898 (DSAStack->hasExplicitDirective( 1899 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1900 Level) && 1901 DSAStack->isTaskgroupReductionRef(D, Level)); 1902 } 1903 1904 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1905 unsigned Level) { 1906 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1907 D = getCanonicalDecl(D); 1908 OpenMPClauseKind OMPC = OMPC_unknown; 1909 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1910 const unsigned NewLevel = I - 1; 1911 if (DSAStack->hasExplicitDSA(D, 1912 [&OMPC](const OpenMPClauseKind K) { 1913 if (isOpenMPPrivate(K)) { 1914 OMPC = K; 1915 return true; 1916 } 1917 return false; 1918 }, 1919 NewLevel)) 1920 break; 1921 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1922 D, NewLevel, 1923 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1924 OpenMPClauseKind) { return true; })) { 1925 OMPC = OMPC_map; 1926 break; 1927 } 1928 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1929 NewLevel)) { 1930 OMPC = OMPC_map; 1931 if (D->getType()->isScalarType() && 1932 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1933 DefaultMapAttributes::DMA_tofrom_scalar) 1934 OMPC = OMPC_firstprivate; 1935 break; 1936 } 1937 } 1938 if (OMPC != OMPC_unknown) 1939 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1940 } 1941 1942 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1943 unsigned Level) const { 1944 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1945 // Return true if the current level is no longer enclosed in a target region. 1946 1947 const auto *VD = dyn_cast<VarDecl>(D); 1948 return VD && !VD->hasLocalStorage() && 1949 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1950 Level); 1951 } 1952 1953 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1954 1955 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1956 const DeclarationNameInfo &DirName, 1957 Scope *CurScope, SourceLocation Loc) { 1958 DSAStack->push(DKind, DirName, CurScope, Loc); 1959 PushExpressionEvaluationContext( 1960 ExpressionEvaluationContext::PotentiallyEvaluated); 1961 } 1962 1963 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1964 DSAStack->setClauseParsingMode(K); 1965 } 1966 1967 void Sema::EndOpenMPClause() { 1968 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1969 } 1970 1971 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 1972 ArrayRef<OMPClause *> Clauses); 1973 1974 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1975 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1976 // A variable of class type (or array thereof) that appears in a lastprivate 1977 // clause requires an accessible, unambiguous default constructor for the 1978 // class type, unless the list item is also specified in a firstprivate 1979 // clause. 1980 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1981 for (OMPClause *C : D->clauses()) { 1982 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1983 SmallVector<Expr *, 8> PrivateCopies; 1984 for (Expr *DE : Clause->varlists()) { 1985 if (DE->isValueDependent() || DE->isTypeDependent()) { 1986 PrivateCopies.push_back(nullptr); 1987 continue; 1988 } 1989 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1990 auto *VD = cast<VarDecl>(DRE->getDecl()); 1991 QualType Type = VD->getType().getNonReferenceType(); 1992 const DSAStackTy::DSAVarData DVar = 1993 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1994 if (DVar.CKind == OMPC_lastprivate) { 1995 // Generate helper private variable and initialize it with the 1996 // default value. The address of the original variable is replaced 1997 // by the address of the new private variable in CodeGen. This new 1998 // variable is not added to IdResolver, so the code in the OpenMP 1999 // region uses original variable for proper diagnostics. 2000 VarDecl *VDPrivate = buildVarDecl( 2001 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2002 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2003 ActOnUninitializedDecl(VDPrivate); 2004 if (VDPrivate->isInvalidDecl()) { 2005 PrivateCopies.push_back(nullptr); 2006 continue; 2007 } 2008 PrivateCopies.push_back(buildDeclRefExpr( 2009 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2010 } else { 2011 // The variable is also a firstprivate, so initialization sequence 2012 // for private copy is generated already. 2013 PrivateCopies.push_back(nullptr); 2014 } 2015 } 2016 Clause->setPrivateCopies(PrivateCopies); 2017 } 2018 } 2019 // Check allocate clauses. 2020 if (!CurContext->isDependentContext()) 2021 checkAllocateClauses(*this, DSAStack, D->clauses()); 2022 } 2023 2024 DSAStack->pop(); 2025 DiscardCleanupsInEvaluationContext(); 2026 PopExpressionEvaluationContext(); 2027 } 2028 2029 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2030 Expr *NumIterations, Sema &SemaRef, 2031 Scope *S, DSAStackTy *Stack); 2032 2033 namespace { 2034 2035 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2036 private: 2037 Sema &SemaRef; 2038 2039 public: 2040 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2041 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2042 NamedDecl *ND = Candidate.getCorrectionDecl(); 2043 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2044 return VD->hasGlobalStorage() && 2045 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2046 SemaRef.getCurScope()); 2047 } 2048 return false; 2049 } 2050 2051 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2052 return std::make_unique<VarDeclFilterCCC>(*this); 2053 } 2054 2055 }; 2056 2057 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2058 private: 2059 Sema &SemaRef; 2060 2061 public: 2062 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2063 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2064 NamedDecl *ND = Candidate.getCorrectionDecl(); 2065 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2066 isa<FunctionDecl>(ND))) { 2067 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2068 SemaRef.getCurScope()); 2069 } 2070 return false; 2071 } 2072 2073 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2074 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2075 } 2076 }; 2077 2078 } // namespace 2079 2080 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2081 CXXScopeSpec &ScopeSpec, 2082 const DeclarationNameInfo &Id, 2083 OpenMPDirectiveKind Kind) { 2084 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2085 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2086 2087 if (Lookup.isAmbiguous()) 2088 return ExprError(); 2089 2090 VarDecl *VD; 2091 if (!Lookup.isSingleResult()) { 2092 VarDeclFilterCCC CCC(*this); 2093 if (TypoCorrection Corrected = 2094 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2095 CTK_ErrorRecovery)) { 2096 diagnoseTypo(Corrected, 2097 PDiag(Lookup.empty() 2098 ? diag::err_undeclared_var_use_suggest 2099 : diag::err_omp_expected_var_arg_suggest) 2100 << Id.getName()); 2101 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2102 } else { 2103 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2104 : diag::err_omp_expected_var_arg) 2105 << Id.getName(); 2106 return ExprError(); 2107 } 2108 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2109 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2110 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2111 return ExprError(); 2112 } 2113 Lookup.suppressDiagnostics(); 2114 2115 // OpenMP [2.9.2, Syntax, C/C++] 2116 // Variables must be file-scope, namespace-scope, or static block-scope. 2117 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2118 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2119 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2120 bool IsDecl = 2121 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2122 Diag(VD->getLocation(), 2123 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2124 << VD; 2125 return ExprError(); 2126 } 2127 2128 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2129 NamedDecl *ND = CanonicalVD; 2130 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2131 // A threadprivate directive for file-scope variables must appear outside 2132 // any definition or declaration. 2133 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2134 !getCurLexicalContext()->isTranslationUnit()) { 2135 Diag(Id.getLoc(), diag::err_omp_var_scope) 2136 << getOpenMPDirectiveName(Kind) << VD; 2137 bool IsDecl = 2138 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2139 Diag(VD->getLocation(), 2140 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2141 << VD; 2142 return ExprError(); 2143 } 2144 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2145 // A threadprivate directive for static class member variables must appear 2146 // in the class definition, in the same scope in which the member 2147 // variables are declared. 2148 if (CanonicalVD->isStaticDataMember() && 2149 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2150 Diag(Id.getLoc(), diag::err_omp_var_scope) 2151 << getOpenMPDirectiveName(Kind) << VD; 2152 bool IsDecl = 2153 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2154 Diag(VD->getLocation(), 2155 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2156 << VD; 2157 return ExprError(); 2158 } 2159 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2160 // A threadprivate directive for namespace-scope variables must appear 2161 // outside any definition or declaration other than the namespace 2162 // definition itself. 2163 if (CanonicalVD->getDeclContext()->isNamespace() && 2164 (!getCurLexicalContext()->isFileContext() || 2165 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2166 Diag(Id.getLoc(), diag::err_omp_var_scope) 2167 << getOpenMPDirectiveName(Kind) << VD; 2168 bool IsDecl = 2169 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2170 Diag(VD->getLocation(), 2171 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2172 << VD; 2173 return ExprError(); 2174 } 2175 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2176 // A threadprivate directive for static block-scope variables must appear 2177 // in the scope of the variable and not in a nested scope. 2178 if (CanonicalVD->isLocalVarDecl() && CurScope && 2179 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2180 Diag(Id.getLoc(), diag::err_omp_var_scope) 2181 << getOpenMPDirectiveName(Kind) << VD; 2182 bool IsDecl = 2183 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2184 Diag(VD->getLocation(), 2185 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2186 << VD; 2187 return ExprError(); 2188 } 2189 2190 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2191 // A threadprivate directive must lexically precede all references to any 2192 // of the variables in its list. 2193 if (Kind == OMPD_threadprivate && VD->isUsed() && 2194 !DSAStack->isThreadPrivate(VD)) { 2195 Diag(Id.getLoc(), diag::err_omp_var_used) 2196 << getOpenMPDirectiveName(Kind) << VD; 2197 return ExprError(); 2198 } 2199 2200 QualType ExprType = VD->getType().getNonReferenceType(); 2201 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2202 SourceLocation(), VD, 2203 /*RefersToEnclosingVariableOrCapture=*/false, 2204 Id.getLoc(), ExprType, VK_LValue); 2205 } 2206 2207 Sema::DeclGroupPtrTy 2208 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2209 ArrayRef<Expr *> VarList) { 2210 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2211 CurContext->addDecl(D); 2212 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2213 } 2214 return nullptr; 2215 } 2216 2217 namespace { 2218 class LocalVarRefChecker final 2219 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2220 Sema &SemaRef; 2221 2222 public: 2223 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2224 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2225 if (VD->hasLocalStorage()) { 2226 SemaRef.Diag(E->getBeginLoc(), 2227 diag::err_omp_local_var_in_threadprivate_init) 2228 << E->getSourceRange(); 2229 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2230 << VD << VD->getSourceRange(); 2231 return true; 2232 } 2233 } 2234 return false; 2235 } 2236 bool VisitStmt(const Stmt *S) { 2237 for (const Stmt *Child : S->children()) { 2238 if (Child && Visit(Child)) 2239 return true; 2240 } 2241 return false; 2242 } 2243 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2244 }; 2245 } // namespace 2246 2247 OMPThreadPrivateDecl * 2248 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2249 SmallVector<Expr *, 8> Vars; 2250 for (Expr *RefExpr : VarList) { 2251 auto *DE = cast<DeclRefExpr>(RefExpr); 2252 auto *VD = cast<VarDecl>(DE->getDecl()); 2253 SourceLocation ILoc = DE->getExprLoc(); 2254 2255 // Mark variable as used. 2256 VD->setReferenced(); 2257 VD->markUsed(Context); 2258 2259 QualType QType = VD->getType(); 2260 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2261 // It will be analyzed later. 2262 Vars.push_back(DE); 2263 continue; 2264 } 2265 2266 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2267 // A threadprivate variable must not have an incomplete type. 2268 if (RequireCompleteType(ILoc, VD->getType(), 2269 diag::err_omp_threadprivate_incomplete_type)) { 2270 continue; 2271 } 2272 2273 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2274 // A threadprivate variable must not have a reference type. 2275 if (VD->getType()->isReferenceType()) { 2276 Diag(ILoc, diag::err_omp_ref_type_arg) 2277 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2278 bool IsDecl = 2279 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2280 Diag(VD->getLocation(), 2281 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2282 << VD; 2283 continue; 2284 } 2285 2286 // Check if this is a TLS variable. If TLS is not being supported, produce 2287 // the corresponding diagnostic. 2288 if ((VD->getTLSKind() != VarDecl::TLS_None && 2289 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2290 getLangOpts().OpenMPUseTLS && 2291 getASTContext().getTargetInfo().isTLSSupported())) || 2292 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2293 !VD->isLocalVarDecl())) { 2294 Diag(ILoc, diag::err_omp_var_thread_local) 2295 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2296 bool IsDecl = 2297 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2298 Diag(VD->getLocation(), 2299 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2300 << VD; 2301 continue; 2302 } 2303 2304 // Check if initial value of threadprivate variable reference variable with 2305 // local storage (it is not supported by runtime). 2306 if (const Expr *Init = VD->getAnyInitializer()) { 2307 LocalVarRefChecker Checker(*this); 2308 if (Checker.Visit(Init)) 2309 continue; 2310 } 2311 2312 Vars.push_back(RefExpr); 2313 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2314 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2315 Context, SourceRange(Loc, Loc))); 2316 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2317 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2318 } 2319 OMPThreadPrivateDecl *D = nullptr; 2320 if (!Vars.empty()) { 2321 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2322 Vars); 2323 D->setAccess(AS_public); 2324 } 2325 return D; 2326 } 2327 2328 static OMPAllocateDeclAttr::AllocatorTypeTy 2329 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2330 if (!Allocator) 2331 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2332 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2333 Allocator->isInstantiationDependent() || 2334 Allocator->containsUnexpandedParameterPack()) 2335 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2336 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2337 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2338 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2339 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2340 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2341 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2342 llvm::FoldingSetNodeID AEId, DAEId; 2343 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2344 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2345 if (AEId == DAEId) { 2346 AllocatorKindRes = AllocatorKind; 2347 break; 2348 } 2349 } 2350 return AllocatorKindRes; 2351 } 2352 2353 static bool checkPreviousOMPAllocateAttribute( 2354 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2355 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2356 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2357 return false; 2358 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2359 Expr *PrevAllocator = A->getAllocator(); 2360 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2361 getAllocatorKind(S, Stack, PrevAllocator); 2362 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2363 if (AllocatorsMatch && 2364 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2365 Allocator && PrevAllocator) { 2366 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2367 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2368 llvm::FoldingSetNodeID AEId, PAEId; 2369 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2370 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2371 AllocatorsMatch = AEId == PAEId; 2372 } 2373 if (!AllocatorsMatch) { 2374 SmallString<256> AllocatorBuffer; 2375 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2376 if (Allocator) 2377 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2378 SmallString<256> PrevAllocatorBuffer; 2379 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2380 if (PrevAllocator) 2381 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2382 S.getPrintingPolicy()); 2383 2384 SourceLocation AllocatorLoc = 2385 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2386 SourceRange AllocatorRange = 2387 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2388 SourceLocation PrevAllocatorLoc = 2389 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2390 SourceRange PrevAllocatorRange = 2391 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2392 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2393 << (Allocator ? 1 : 0) << AllocatorStream.str() 2394 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2395 << AllocatorRange; 2396 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2397 << PrevAllocatorRange; 2398 return true; 2399 } 2400 return false; 2401 } 2402 2403 static void 2404 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2405 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2406 Expr *Allocator, SourceRange SR) { 2407 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2408 return; 2409 if (Allocator && 2410 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2411 Allocator->isInstantiationDependent() || 2412 Allocator->containsUnexpandedParameterPack())) 2413 return; 2414 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2415 Allocator, SR); 2416 VD->addAttr(A); 2417 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2418 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2419 } 2420 2421 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2422 SourceLocation Loc, ArrayRef<Expr *> VarList, 2423 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2424 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2425 Expr *Allocator = nullptr; 2426 if (Clauses.empty()) { 2427 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2428 // allocate directives that appear in a target region must specify an 2429 // allocator clause unless a requires directive with the dynamic_allocators 2430 // clause is present in the same compilation unit. 2431 if (LangOpts.OpenMPIsDevice && 2432 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2433 targetDiag(Loc, diag::err_expected_allocator_clause); 2434 } else { 2435 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2436 } 2437 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2438 getAllocatorKind(*this, DSAStack, Allocator); 2439 SmallVector<Expr *, 8> Vars; 2440 for (Expr *RefExpr : VarList) { 2441 auto *DE = cast<DeclRefExpr>(RefExpr); 2442 auto *VD = cast<VarDecl>(DE->getDecl()); 2443 2444 // Check if this is a TLS variable or global register. 2445 if (VD->getTLSKind() != VarDecl::TLS_None || 2446 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2447 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2448 !VD->isLocalVarDecl())) 2449 continue; 2450 2451 // If the used several times in the allocate directive, the same allocator 2452 // must be used. 2453 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2454 AllocatorKind, Allocator)) 2455 continue; 2456 2457 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2458 // If a list item has a static storage type, the allocator expression in the 2459 // allocator clause must be a constant expression that evaluates to one of 2460 // the predefined memory allocator values. 2461 if (Allocator && VD->hasGlobalStorage()) { 2462 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2463 Diag(Allocator->getExprLoc(), 2464 diag::err_omp_expected_predefined_allocator) 2465 << Allocator->getSourceRange(); 2466 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2467 VarDecl::DeclarationOnly; 2468 Diag(VD->getLocation(), 2469 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2470 << VD; 2471 continue; 2472 } 2473 } 2474 2475 Vars.push_back(RefExpr); 2476 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2477 DE->getSourceRange()); 2478 } 2479 if (Vars.empty()) 2480 return nullptr; 2481 if (!Owner) 2482 Owner = getCurLexicalContext(); 2483 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2484 D->setAccess(AS_public); 2485 Owner->addDecl(D); 2486 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2487 } 2488 2489 Sema::DeclGroupPtrTy 2490 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2491 ArrayRef<OMPClause *> ClauseList) { 2492 OMPRequiresDecl *D = nullptr; 2493 if (!CurContext->isFileContext()) { 2494 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2495 } else { 2496 D = CheckOMPRequiresDecl(Loc, ClauseList); 2497 if (D) { 2498 CurContext->addDecl(D); 2499 DSAStack->addRequiresDecl(D); 2500 } 2501 } 2502 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2503 } 2504 2505 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2506 ArrayRef<OMPClause *> ClauseList) { 2507 /// For target specific clauses, the requires directive cannot be 2508 /// specified after the handling of any of the target regions in the 2509 /// current compilation unit. 2510 ArrayRef<SourceLocation> TargetLocations = 2511 DSAStack->getEncounteredTargetLocs(); 2512 if (!TargetLocations.empty()) { 2513 for (const OMPClause *CNew : ClauseList) { 2514 // Check if any of the requires clauses affect target regions. 2515 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2516 isa<OMPUnifiedAddressClause>(CNew) || 2517 isa<OMPReverseOffloadClause>(CNew) || 2518 isa<OMPDynamicAllocatorsClause>(CNew)) { 2519 Diag(Loc, diag::err_omp_target_before_requires) 2520 << getOpenMPClauseName(CNew->getClauseKind()); 2521 for (SourceLocation TargetLoc : TargetLocations) { 2522 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2523 } 2524 } 2525 } 2526 } 2527 2528 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2529 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2530 ClauseList); 2531 return nullptr; 2532 } 2533 2534 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2535 const ValueDecl *D, 2536 const DSAStackTy::DSAVarData &DVar, 2537 bool IsLoopIterVar = false) { 2538 if (DVar.RefExpr) { 2539 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2540 << getOpenMPClauseName(DVar.CKind); 2541 return; 2542 } 2543 enum { 2544 PDSA_StaticMemberShared, 2545 PDSA_StaticLocalVarShared, 2546 PDSA_LoopIterVarPrivate, 2547 PDSA_LoopIterVarLinear, 2548 PDSA_LoopIterVarLastprivate, 2549 PDSA_ConstVarShared, 2550 PDSA_GlobalVarShared, 2551 PDSA_TaskVarFirstprivate, 2552 PDSA_LocalVarPrivate, 2553 PDSA_Implicit 2554 } Reason = PDSA_Implicit; 2555 bool ReportHint = false; 2556 auto ReportLoc = D->getLocation(); 2557 auto *VD = dyn_cast<VarDecl>(D); 2558 if (IsLoopIterVar) { 2559 if (DVar.CKind == OMPC_private) 2560 Reason = PDSA_LoopIterVarPrivate; 2561 else if (DVar.CKind == OMPC_lastprivate) 2562 Reason = PDSA_LoopIterVarLastprivate; 2563 else 2564 Reason = PDSA_LoopIterVarLinear; 2565 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2566 DVar.CKind == OMPC_firstprivate) { 2567 Reason = PDSA_TaskVarFirstprivate; 2568 ReportLoc = DVar.ImplicitDSALoc; 2569 } else if (VD && VD->isStaticLocal()) 2570 Reason = PDSA_StaticLocalVarShared; 2571 else if (VD && VD->isStaticDataMember()) 2572 Reason = PDSA_StaticMemberShared; 2573 else if (VD && VD->isFileVarDecl()) 2574 Reason = PDSA_GlobalVarShared; 2575 else if (D->getType().isConstant(SemaRef.getASTContext())) 2576 Reason = PDSA_ConstVarShared; 2577 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2578 ReportHint = true; 2579 Reason = PDSA_LocalVarPrivate; 2580 } 2581 if (Reason != PDSA_Implicit) { 2582 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2583 << Reason << ReportHint 2584 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2585 } else if (DVar.ImplicitDSALoc.isValid()) { 2586 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2587 << getOpenMPClauseName(DVar.CKind); 2588 } 2589 } 2590 2591 namespace { 2592 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2593 DSAStackTy *Stack; 2594 Sema &SemaRef; 2595 bool ErrorFound = false; 2596 CapturedStmt *CS = nullptr; 2597 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2598 llvm::SmallVector<Expr *, 4> ImplicitMap; 2599 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2600 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2601 2602 void VisitSubCaptures(OMPExecutableDirective *S) { 2603 // Check implicitly captured variables. 2604 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2605 return; 2606 visitSubCaptures(S->getInnermostCapturedStmt()); 2607 } 2608 2609 public: 2610 void VisitDeclRefExpr(DeclRefExpr *E) { 2611 if (E->isTypeDependent() || E->isValueDependent() || 2612 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2613 return; 2614 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2615 // Check the datasharing rules for the expressions in the clauses. 2616 if (!CS) { 2617 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2618 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2619 Visit(CED->getInit()); 2620 return; 2621 } 2622 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2623 // Do not analyze internal variables and do not enclose them into 2624 // implicit clauses. 2625 return; 2626 VD = VD->getCanonicalDecl(); 2627 // Skip internally declared variables. 2628 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2629 return; 2630 2631 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2632 // Check if the variable has explicit DSA set and stop analysis if it so. 2633 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2634 return; 2635 2636 // Skip internally declared static variables. 2637 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2638 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2639 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2640 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2641 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2642 return; 2643 2644 SourceLocation ELoc = E->getExprLoc(); 2645 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2646 // The default(none) clause requires that each variable that is referenced 2647 // in the construct, and does not have a predetermined data-sharing 2648 // attribute, must have its data-sharing attribute explicitly determined 2649 // by being listed in a data-sharing attribute clause. 2650 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2651 isImplicitOrExplicitTaskingRegion(DKind) && 2652 VarsWithInheritedDSA.count(VD) == 0) { 2653 VarsWithInheritedDSA[VD] = E; 2654 return; 2655 } 2656 2657 if (isOpenMPTargetExecutionDirective(DKind) && 2658 !Stack->isLoopControlVariable(VD).first) { 2659 if (!Stack->checkMappableExprComponentListsForDecl( 2660 VD, /*CurrentRegionOnly=*/true, 2661 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2662 StackComponents, 2663 OpenMPClauseKind) { 2664 // Variable is used if it has been marked as an array, array 2665 // section or the variable iself. 2666 return StackComponents.size() == 1 || 2667 std::all_of( 2668 std::next(StackComponents.rbegin()), 2669 StackComponents.rend(), 2670 [](const OMPClauseMappableExprCommon:: 2671 MappableComponent &MC) { 2672 return MC.getAssociatedDeclaration() == 2673 nullptr && 2674 (isa<OMPArraySectionExpr>( 2675 MC.getAssociatedExpression()) || 2676 isa<ArraySubscriptExpr>( 2677 MC.getAssociatedExpression())); 2678 }); 2679 })) { 2680 bool IsFirstprivate = false; 2681 // By default lambdas are captured as firstprivates. 2682 if (const auto *RD = 2683 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2684 IsFirstprivate = RD->isLambda(); 2685 IsFirstprivate = 2686 IsFirstprivate || 2687 (VD->getType().getNonReferenceType()->isScalarType() && 2688 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2689 if (IsFirstprivate) 2690 ImplicitFirstprivate.emplace_back(E); 2691 else 2692 ImplicitMap.emplace_back(E); 2693 return; 2694 } 2695 } 2696 2697 // OpenMP [2.9.3.6, Restrictions, p.2] 2698 // A list item that appears in a reduction clause of the innermost 2699 // enclosing worksharing or parallel construct may not be accessed in an 2700 // explicit task. 2701 DVar = Stack->hasInnermostDSA( 2702 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2703 [](OpenMPDirectiveKind K) { 2704 return isOpenMPParallelDirective(K) || 2705 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2706 }, 2707 /*FromParent=*/true); 2708 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2709 ErrorFound = true; 2710 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2711 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2712 return; 2713 } 2714 2715 // Define implicit data-sharing attributes for task. 2716 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2717 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2718 !Stack->isLoopControlVariable(VD).first) { 2719 ImplicitFirstprivate.push_back(E); 2720 return; 2721 } 2722 2723 // Store implicitly used globals with declare target link for parent 2724 // target. 2725 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2726 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2727 Stack->addToParentTargetRegionLinkGlobals(E); 2728 return; 2729 } 2730 } 2731 } 2732 void VisitMemberExpr(MemberExpr *E) { 2733 if (E->isTypeDependent() || E->isValueDependent() || 2734 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2735 return; 2736 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2737 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2738 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2739 if (!FD) 2740 return; 2741 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2742 // Check if the variable has explicit DSA set and stop analysis if it 2743 // so. 2744 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2745 return; 2746 2747 if (isOpenMPTargetExecutionDirective(DKind) && 2748 !Stack->isLoopControlVariable(FD).first && 2749 !Stack->checkMappableExprComponentListsForDecl( 2750 FD, /*CurrentRegionOnly=*/true, 2751 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2752 StackComponents, 2753 OpenMPClauseKind) { 2754 return isa<CXXThisExpr>( 2755 cast<MemberExpr>( 2756 StackComponents.back().getAssociatedExpression()) 2757 ->getBase() 2758 ->IgnoreParens()); 2759 })) { 2760 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2761 // A bit-field cannot appear in a map clause. 2762 // 2763 if (FD->isBitField()) 2764 return; 2765 2766 // Check to see if the member expression is referencing a class that 2767 // has already been explicitly mapped 2768 if (Stack->isClassPreviouslyMapped(TE->getType())) 2769 return; 2770 2771 ImplicitMap.emplace_back(E); 2772 return; 2773 } 2774 2775 SourceLocation ELoc = E->getExprLoc(); 2776 // OpenMP [2.9.3.6, Restrictions, p.2] 2777 // A list item that appears in a reduction clause of the innermost 2778 // enclosing worksharing or parallel construct may not be accessed in 2779 // an explicit task. 2780 DVar = Stack->hasInnermostDSA( 2781 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2782 [](OpenMPDirectiveKind K) { 2783 return isOpenMPParallelDirective(K) || 2784 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2785 }, 2786 /*FromParent=*/true); 2787 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2788 ErrorFound = true; 2789 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2790 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2791 return; 2792 } 2793 2794 // Define implicit data-sharing attributes for task. 2795 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2796 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2797 !Stack->isLoopControlVariable(FD).first) { 2798 // Check if there is a captured expression for the current field in the 2799 // region. Do not mark it as firstprivate unless there is no captured 2800 // expression. 2801 // TODO: try to make it firstprivate. 2802 if (DVar.CKind != OMPC_unknown) 2803 ImplicitFirstprivate.push_back(E); 2804 } 2805 return; 2806 } 2807 if (isOpenMPTargetExecutionDirective(DKind)) { 2808 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2809 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2810 /*NoDiagnose=*/true)) 2811 return; 2812 const auto *VD = cast<ValueDecl>( 2813 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2814 if (!Stack->checkMappableExprComponentListsForDecl( 2815 VD, /*CurrentRegionOnly=*/true, 2816 [&CurComponents]( 2817 OMPClauseMappableExprCommon::MappableExprComponentListRef 2818 StackComponents, 2819 OpenMPClauseKind) { 2820 auto CCI = CurComponents.rbegin(); 2821 auto CCE = CurComponents.rend(); 2822 for (const auto &SC : llvm::reverse(StackComponents)) { 2823 // Do both expressions have the same kind? 2824 if (CCI->getAssociatedExpression()->getStmtClass() != 2825 SC.getAssociatedExpression()->getStmtClass()) 2826 if (!(isa<OMPArraySectionExpr>( 2827 SC.getAssociatedExpression()) && 2828 isa<ArraySubscriptExpr>( 2829 CCI->getAssociatedExpression()))) 2830 return false; 2831 2832 const Decl *CCD = CCI->getAssociatedDeclaration(); 2833 const Decl *SCD = SC.getAssociatedDeclaration(); 2834 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2835 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2836 if (SCD != CCD) 2837 return false; 2838 std::advance(CCI, 1); 2839 if (CCI == CCE) 2840 break; 2841 } 2842 return true; 2843 })) { 2844 Visit(E->getBase()); 2845 } 2846 } else { 2847 Visit(E->getBase()); 2848 } 2849 } 2850 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2851 for (OMPClause *C : S->clauses()) { 2852 // Skip analysis of arguments of implicitly defined firstprivate clause 2853 // for task|target directives. 2854 // Skip analysis of arguments of implicitly defined map clause for target 2855 // directives. 2856 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2857 C->isImplicit())) { 2858 for (Stmt *CC : C->children()) { 2859 if (CC) 2860 Visit(CC); 2861 } 2862 } 2863 } 2864 // Check implicitly captured variables. 2865 VisitSubCaptures(S); 2866 } 2867 void VisitStmt(Stmt *S) { 2868 for (Stmt *C : S->children()) { 2869 if (C) { 2870 // Check implicitly captured variables in the task-based directives to 2871 // check if they must be firstprivatized. 2872 Visit(C); 2873 } 2874 } 2875 } 2876 2877 void visitSubCaptures(CapturedStmt *S) { 2878 for (const CapturedStmt::Capture &Cap : S->captures()) { 2879 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 2880 continue; 2881 VarDecl *VD = Cap.getCapturedVar(); 2882 // Do not try to map the variable if it or its sub-component was mapped 2883 // already. 2884 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2885 Stack->checkMappableExprComponentListsForDecl( 2886 VD, /*CurrentRegionOnly=*/true, 2887 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2888 OpenMPClauseKind) { return true; })) 2889 continue; 2890 DeclRefExpr *DRE = buildDeclRefExpr( 2891 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2892 Cap.getLocation(), /*RefersToCapture=*/true); 2893 Visit(DRE); 2894 } 2895 } 2896 bool isErrorFound() const { return ErrorFound; } 2897 ArrayRef<Expr *> getImplicitFirstprivate() const { 2898 return ImplicitFirstprivate; 2899 } 2900 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2901 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2902 return VarsWithInheritedDSA; 2903 } 2904 2905 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2906 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2907 // Process declare target link variables for the target directives. 2908 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2909 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2910 Visit(E); 2911 } 2912 } 2913 }; 2914 } // namespace 2915 2916 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2917 switch (DKind) { 2918 case OMPD_parallel: 2919 case OMPD_parallel_for: 2920 case OMPD_parallel_for_simd: 2921 case OMPD_parallel_sections: 2922 case OMPD_teams: 2923 case OMPD_teams_distribute: 2924 case OMPD_teams_distribute_simd: { 2925 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2926 QualType KmpInt32PtrTy = 2927 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2928 Sema::CapturedParamNameType Params[] = { 2929 std::make_pair(".global_tid.", KmpInt32PtrTy), 2930 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2931 std::make_pair(StringRef(), QualType()) // __context with shared vars 2932 }; 2933 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2934 Params); 2935 break; 2936 } 2937 case OMPD_target_teams: 2938 case OMPD_target_parallel: 2939 case OMPD_target_parallel_for: 2940 case OMPD_target_parallel_for_simd: 2941 case OMPD_target_teams_distribute: 2942 case OMPD_target_teams_distribute_simd: { 2943 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2944 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2945 QualType KmpInt32PtrTy = 2946 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2947 QualType Args[] = {VoidPtrTy}; 2948 FunctionProtoType::ExtProtoInfo EPI; 2949 EPI.Variadic = true; 2950 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2951 Sema::CapturedParamNameType Params[] = { 2952 std::make_pair(".global_tid.", KmpInt32Ty), 2953 std::make_pair(".part_id.", KmpInt32PtrTy), 2954 std::make_pair(".privates.", VoidPtrTy), 2955 std::make_pair( 2956 ".copy_fn.", 2957 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2958 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2959 std::make_pair(StringRef(), QualType()) // __context with shared vars 2960 }; 2961 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2962 Params); 2963 // Mark this captured region as inlined, because we don't use outlined 2964 // function directly. 2965 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2966 AlwaysInlineAttr::CreateImplicit( 2967 Context, AlwaysInlineAttr::Keyword_forceinline)); 2968 Sema::CapturedParamNameType ParamsTarget[] = { 2969 std::make_pair(StringRef(), QualType()) // __context with shared vars 2970 }; 2971 // Start a captured region for 'target' with no implicit parameters. 2972 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2973 ParamsTarget); 2974 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2975 std::make_pair(".global_tid.", KmpInt32PtrTy), 2976 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2977 std::make_pair(StringRef(), QualType()) // __context with shared vars 2978 }; 2979 // Start a captured region for 'teams' or 'parallel'. Both regions have 2980 // the same implicit parameters. 2981 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2982 ParamsTeamsOrParallel); 2983 break; 2984 } 2985 case OMPD_target: 2986 case OMPD_target_simd: { 2987 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2988 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2989 QualType KmpInt32PtrTy = 2990 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2991 QualType Args[] = {VoidPtrTy}; 2992 FunctionProtoType::ExtProtoInfo EPI; 2993 EPI.Variadic = true; 2994 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2995 Sema::CapturedParamNameType Params[] = { 2996 std::make_pair(".global_tid.", KmpInt32Ty), 2997 std::make_pair(".part_id.", KmpInt32PtrTy), 2998 std::make_pair(".privates.", VoidPtrTy), 2999 std::make_pair( 3000 ".copy_fn.", 3001 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3002 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3003 std::make_pair(StringRef(), QualType()) // __context with shared vars 3004 }; 3005 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3006 Params); 3007 // Mark this captured region as inlined, because we don't use outlined 3008 // function directly. 3009 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3010 AlwaysInlineAttr::CreateImplicit( 3011 Context, AlwaysInlineAttr::Keyword_forceinline)); 3012 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3013 std::make_pair(StringRef(), QualType())); 3014 break; 3015 } 3016 case OMPD_simd: 3017 case OMPD_for: 3018 case OMPD_for_simd: 3019 case OMPD_sections: 3020 case OMPD_section: 3021 case OMPD_single: 3022 case OMPD_master: 3023 case OMPD_critical: 3024 case OMPD_taskgroup: 3025 case OMPD_distribute: 3026 case OMPD_distribute_simd: 3027 case OMPD_ordered: 3028 case OMPD_atomic: 3029 case OMPD_target_data: { 3030 Sema::CapturedParamNameType Params[] = { 3031 std::make_pair(StringRef(), QualType()) // __context with shared vars 3032 }; 3033 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3034 Params); 3035 break; 3036 } 3037 case OMPD_task: { 3038 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3039 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3040 QualType KmpInt32PtrTy = 3041 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3042 QualType Args[] = {VoidPtrTy}; 3043 FunctionProtoType::ExtProtoInfo EPI; 3044 EPI.Variadic = true; 3045 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3046 Sema::CapturedParamNameType Params[] = { 3047 std::make_pair(".global_tid.", KmpInt32Ty), 3048 std::make_pair(".part_id.", KmpInt32PtrTy), 3049 std::make_pair(".privates.", VoidPtrTy), 3050 std::make_pair( 3051 ".copy_fn.", 3052 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3053 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3054 std::make_pair(StringRef(), QualType()) // __context with shared vars 3055 }; 3056 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3057 Params); 3058 // Mark this captured region as inlined, because we don't use outlined 3059 // function directly. 3060 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3061 AlwaysInlineAttr::CreateImplicit( 3062 Context, AlwaysInlineAttr::Keyword_forceinline)); 3063 break; 3064 } 3065 case OMPD_taskloop: 3066 case OMPD_taskloop_simd: { 3067 QualType KmpInt32Ty = 3068 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3069 .withConst(); 3070 QualType KmpUInt64Ty = 3071 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3072 .withConst(); 3073 QualType KmpInt64Ty = 3074 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3075 .withConst(); 3076 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3077 QualType KmpInt32PtrTy = 3078 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3079 QualType Args[] = {VoidPtrTy}; 3080 FunctionProtoType::ExtProtoInfo EPI; 3081 EPI.Variadic = true; 3082 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3083 Sema::CapturedParamNameType Params[] = { 3084 std::make_pair(".global_tid.", KmpInt32Ty), 3085 std::make_pair(".part_id.", KmpInt32PtrTy), 3086 std::make_pair(".privates.", VoidPtrTy), 3087 std::make_pair( 3088 ".copy_fn.", 3089 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3090 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3091 std::make_pair(".lb.", KmpUInt64Ty), 3092 std::make_pair(".ub.", KmpUInt64Ty), 3093 std::make_pair(".st.", KmpInt64Ty), 3094 std::make_pair(".liter.", KmpInt32Ty), 3095 std::make_pair(".reductions.", VoidPtrTy), 3096 std::make_pair(StringRef(), QualType()) // __context with shared vars 3097 }; 3098 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3099 Params); 3100 // Mark this captured region as inlined, because we don't use outlined 3101 // function directly. 3102 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3103 AlwaysInlineAttr::CreateImplicit( 3104 Context, AlwaysInlineAttr::Keyword_forceinline)); 3105 break; 3106 } 3107 case OMPD_distribute_parallel_for_simd: 3108 case OMPD_distribute_parallel_for: { 3109 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3110 QualType KmpInt32PtrTy = 3111 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3112 Sema::CapturedParamNameType Params[] = { 3113 std::make_pair(".global_tid.", KmpInt32PtrTy), 3114 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3115 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3116 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3117 std::make_pair(StringRef(), QualType()) // __context with shared vars 3118 }; 3119 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3120 Params); 3121 break; 3122 } 3123 case OMPD_target_teams_distribute_parallel_for: 3124 case OMPD_target_teams_distribute_parallel_for_simd: { 3125 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3126 QualType KmpInt32PtrTy = 3127 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3128 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3129 3130 QualType Args[] = {VoidPtrTy}; 3131 FunctionProtoType::ExtProtoInfo EPI; 3132 EPI.Variadic = true; 3133 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3134 Sema::CapturedParamNameType Params[] = { 3135 std::make_pair(".global_tid.", KmpInt32Ty), 3136 std::make_pair(".part_id.", KmpInt32PtrTy), 3137 std::make_pair(".privates.", VoidPtrTy), 3138 std::make_pair( 3139 ".copy_fn.", 3140 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3141 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3142 std::make_pair(StringRef(), QualType()) // __context with shared vars 3143 }; 3144 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3145 Params); 3146 // Mark this captured region as inlined, because we don't use outlined 3147 // function directly. 3148 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3149 AlwaysInlineAttr::CreateImplicit( 3150 Context, AlwaysInlineAttr::Keyword_forceinline)); 3151 Sema::CapturedParamNameType ParamsTarget[] = { 3152 std::make_pair(StringRef(), QualType()) // __context with shared vars 3153 }; 3154 // Start a captured region for 'target' with no implicit parameters. 3155 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3156 ParamsTarget); 3157 3158 Sema::CapturedParamNameType ParamsTeams[] = { 3159 std::make_pair(".global_tid.", KmpInt32PtrTy), 3160 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3161 std::make_pair(StringRef(), QualType()) // __context with shared vars 3162 }; 3163 // Start a captured region for 'target' with no implicit parameters. 3164 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3165 ParamsTeams); 3166 3167 Sema::CapturedParamNameType ParamsParallel[] = { 3168 std::make_pair(".global_tid.", KmpInt32PtrTy), 3169 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3170 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3171 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3172 std::make_pair(StringRef(), QualType()) // __context with shared vars 3173 }; 3174 // Start a captured region for 'teams' or 'parallel'. Both regions have 3175 // the same implicit parameters. 3176 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3177 ParamsParallel); 3178 break; 3179 } 3180 3181 case OMPD_teams_distribute_parallel_for: 3182 case OMPD_teams_distribute_parallel_for_simd: { 3183 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3184 QualType KmpInt32PtrTy = 3185 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3186 3187 Sema::CapturedParamNameType ParamsTeams[] = { 3188 std::make_pair(".global_tid.", KmpInt32PtrTy), 3189 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3190 std::make_pair(StringRef(), QualType()) // __context with shared vars 3191 }; 3192 // Start a captured region for 'target' with no implicit parameters. 3193 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3194 ParamsTeams); 3195 3196 Sema::CapturedParamNameType ParamsParallel[] = { 3197 std::make_pair(".global_tid.", KmpInt32PtrTy), 3198 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3199 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3200 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3201 std::make_pair(StringRef(), QualType()) // __context with shared vars 3202 }; 3203 // Start a captured region for 'teams' or 'parallel'. Both regions have 3204 // the same implicit parameters. 3205 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3206 ParamsParallel); 3207 break; 3208 } 3209 case OMPD_target_update: 3210 case OMPD_target_enter_data: 3211 case OMPD_target_exit_data: { 3212 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3213 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3214 QualType KmpInt32PtrTy = 3215 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3216 QualType Args[] = {VoidPtrTy}; 3217 FunctionProtoType::ExtProtoInfo EPI; 3218 EPI.Variadic = true; 3219 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3220 Sema::CapturedParamNameType Params[] = { 3221 std::make_pair(".global_tid.", KmpInt32Ty), 3222 std::make_pair(".part_id.", KmpInt32PtrTy), 3223 std::make_pair(".privates.", VoidPtrTy), 3224 std::make_pair( 3225 ".copy_fn.", 3226 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3227 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3228 std::make_pair(StringRef(), QualType()) // __context with shared vars 3229 }; 3230 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3231 Params); 3232 // Mark this captured region as inlined, because we don't use outlined 3233 // function directly. 3234 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3235 AlwaysInlineAttr::CreateImplicit( 3236 Context, AlwaysInlineAttr::Keyword_forceinline)); 3237 break; 3238 } 3239 case OMPD_threadprivate: 3240 case OMPD_allocate: 3241 case OMPD_taskyield: 3242 case OMPD_barrier: 3243 case OMPD_taskwait: 3244 case OMPD_cancellation_point: 3245 case OMPD_cancel: 3246 case OMPD_flush: 3247 case OMPD_declare_reduction: 3248 case OMPD_declare_mapper: 3249 case OMPD_declare_simd: 3250 case OMPD_declare_target: 3251 case OMPD_end_declare_target: 3252 case OMPD_requires: 3253 llvm_unreachable("OpenMP Directive is not allowed"); 3254 case OMPD_unknown: 3255 llvm_unreachable("Unknown OpenMP directive"); 3256 } 3257 } 3258 3259 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3260 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3261 getOpenMPCaptureRegions(CaptureRegions, DKind); 3262 return CaptureRegions.size(); 3263 } 3264 3265 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3266 Expr *CaptureExpr, bool WithInit, 3267 bool AsExpression) { 3268 assert(CaptureExpr); 3269 ASTContext &C = S.getASTContext(); 3270 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3271 QualType Ty = Init->getType(); 3272 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3273 if (S.getLangOpts().CPlusPlus) { 3274 Ty = C.getLValueReferenceType(Ty); 3275 } else { 3276 Ty = C.getPointerType(Ty); 3277 ExprResult Res = 3278 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3279 if (!Res.isUsable()) 3280 return nullptr; 3281 Init = Res.get(); 3282 } 3283 WithInit = true; 3284 } 3285 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3286 CaptureExpr->getBeginLoc()); 3287 if (!WithInit) 3288 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3289 S.CurContext->addHiddenDecl(CED); 3290 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3291 return CED; 3292 } 3293 3294 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3295 bool WithInit) { 3296 OMPCapturedExprDecl *CD; 3297 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3298 CD = cast<OMPCapturedExprDecl>(VD); 3299 else 3300 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3301 /*AsExpression=*/false); 3302 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3303 CaptureExpr->getExprLoc()); 3304 } 3305 3306 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3307 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3308 if (!Ref) { 3309 OMPCapturedExprDecl *CD = buildCaptureDecl( 3310 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3311 /*WithInit=*/true, /*AsExpression=*/true); 3312 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3313 CaptureExpr->getExprLoc()); 3314 } 3315 ExprResult Res = Ref; 3316 if (!S.getLangOpts().CPlusPlus && 3317 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3318 Ref->getType()->isPointerType()) { 3319 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3320 if (!Res.isUsable()) 3321 return ExprError(); 3322 } 3323 return S.DefaultLvalueConversion(Res.get()); 3324 } 3325 3326 namespace { 3327 // OpenMP directives parsed in this section are represented as a 3328 // CapturedStatement with an associated statement. If a syntax error 3329 // is detected during the parsing of the associated statement, the 3330 // compiler must abort processing and close the CapturedStatement. 3331 // 3332 // Combined directives such as 'target parallel' have more than one 3333 // nested CapturedStatements. This RAII ensures that we unwind out 3334 // of all the nested CapturedStatements when an error is found. 3335 class CaptureRegionUnwinderRAII { 3336 private: 3337 Sema &S; 3338 bool &ErrorFound; 3339 OpenMPDirectiveKind DKind = OMPD_unknown; 3340 3341 public: 3342 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3343 OpenMPDirectiveKind DKind) 3344 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3345 ~CaptureRegionUnwinderRAII() { 3346 if (ErrorFound) { 3347 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3348 while (--ThisCaptureLevel >= 0) 3349 S.ActOnCapturedRegionError(); 3350 } 3351 } 3352 }; 3353 } // namespace 3354 3355 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3356 // Capture variables captured by reference in lambdas for target-based 3357 // directives. 3358 if (!CurContext->isDependentContext() && 3359 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3360 isOpenMPTargetDataManagementDirective( 3361 DSAStack->getCurrentDirective()))) { 3362 QualType Type = V->getType(); 3363 if (const auto *RD = Type.getCanonicalType() 3364 .getNonReferenceType() 3365 ->getAsCXXRecordDecl()) { 3366 bool SavedForceCaptureByReferenceInTargetExecutable = 3367 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3368 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3369 /*V=*/true); 3370 if (RD->isLambda()) { 3371 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3372 FieldDecl *ThisCapture; 3373 RD->getCaptureFields(Captures, ThisCapture); 3374 for (const LambdaCapture &LC : RD->captures()) { 3375 if (LC.getCaptureKind() == LCK_ByRef) { 3376 VarDecl *VD = LC.getCapturedVar(); 3377 DeclContext *VDC = VD->getDeclContext(); 3378 if (!VDC->Encloses(CurContext)) 3379 continue; 3380 MarkVariableReferenced(LC.getLocation(), VD); 3381 } else if (LC.getCaptureKind() == LCK_This) { 3382 QualType ThisTy = getCurrentThisType(); 3383 if (!ThisTy.isNull() && 3384 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3385 CheckCXXThisCapture(LC.getLocation()); 3386 } 3387 } 3388 } 3389 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3390 SavedForceCaptureByReferenceInTargetExecutable); 3391 } 3392 } 3393 } 3394 3395 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3396 ArrayRef<OMPClause *> Clauses) { 3397 bool ErrorFound = false; 3398 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3399 *this, ErrorFound, DSAStack->getCurrentDirective()); 3400 if (!S.isUsable()) { 3401 ErrorFound = true; 3402 return StmtError(); 3403 } 3404 3405 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3406 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3407 OMPOrderedClause *OC = nullptr; 3408 OMPScheduleClause *SC = nullptr; 3409 SmallVector<const OMPLinearClause *, 4> LCs; 3410 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3411 // This is required for proper codegen. 3412 for (OMPClause *Clause : Clauses) { 3413 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3414 Clause->getClauseKind() == OMPC_in_reduction) { 3415 // Capture taskgroup task_reduction descriptors inside the tasking regions 3416 // with the corresponding in_reduction items. 3417 auto *IRC = cast<OMPInReductionClause>(Clause); 3418 for (Expr *E : IRC->taskgroup_descriptors()) 3419 if (E) 3420 MarkDeclarationsReferencedInExpr(E); 3421 } 3422 if (isOpenMPPrivate(Clause->getClauseKind()) || 3423 Clause->getClauseKind() == OMPC_copyprivate || 3424 (getLangOpts().OpenMPUseTLS && 3425 getASTContext().getTargetInfo().isTLSSupported() && 3426 Clause->getClauseKind() == OMPC_copyin)) { 3427 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3428 // Mark all variables in private list clauses as used in inner region. 3429 for (Stmt *VarRef : Clause->children()) { 3430 if (auto *E = cast_or_null<Expr>(VarRef)) { 3431 MarkDeclarationsReferencedInExpr(E); 3432 } 3433 } 3434 DSAStack->setForceVarCapturing(/*V=*/false); 3435 } else if (CaptureRegions.size() > 1 || 3436 CaptureRegions.back() != OMPD_unknown) { 3437 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3438 PICs.push_back(C); 3439 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3440 if (Expr *E = C->getPostUpdateExpr()) 3441 MarkDeclarationsReferencedInExpr(E); 3442 } 3443 } 3444 if (Clause->getClauseKind() == OMPC_schedule) 3445 SC = cast<OMPScheduleClause>(Clause); 3446 else if (Clause->getClauseKind() == OMPC_ordered) 3447 OC = cast<OMPOrderedClause>(Clause); 3448 else if (Clause->getClauseKind() == OMPC_linear) 3449 LCs.push_back(cast<OMPLinearClause>(Clause)); 3450 } 3451 // OpenMP, 2.7.1 Loop Construct, Restrictions 3452 // The nonmonotonic modifier cannot be specified if an ordered clause is 3453 // specified. 3454 if (SC && 3455 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3456 SC->getSecondScheduleModifier() == 3457 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3458 OC) { 3459 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3460 ? SC->getFirstScheduleModifierLoc() 3461 : SC->getSecondScheduleModifierLoc(), 3462 diag::err_omp_schedule_nonmonotonic_ordered) 3463 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3464 ErrorFound = true; 3465 } 3466 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3467 for (const OMPLinearClause *C : LCs) { 3468 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3469 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3470 } 3471 ErrorFound = true; 3472 } 3473 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3474 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3475 OC->getNumForLoops()) { 3476 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3477 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3478 ErrorFound = true; 3479 } 3480 if (ErrorFound) { 3481 return StmtError(); 3482 } 3483 StmtResult SR = S; 3484 unsigned CompletedRegions = 0; 3485 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3486 // Mark all variables in private list clauses as used in inner region. 3487 // Required for proper codegen of combined directives. 3488 // TODO: add processing for other clauses. 3489 if (ThisCaptureRegion != OMPD_unknown) { 3490 for (const clang::OMPClauseWithPreInit *C : PICs) { 3491 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3492 // Find the particular capture region for the clause if the 3493 // directive is a combined one with multiple capture regions. 3494 // If the directive is not a combined one, the capture region 3495 // associated with the clause is OMPD_unknown and is generated 3496 // only once. 3497 if (CaptureRegion == ThisCaptureRegion || 3498 CaptureRegion == OMPD_unknown) { 3499 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3500 for (Decl *D : DS->decls()) 3501 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3502 } 3503 } 3504 } 3505 } 3506 if (++CompletedRegions == CaptureRegions.size()) 3507 DSAStack->setBodyComplete(); 3508 SR = ActOnCapturedRegionEnd(SR.get()); 3509 } 3510 return SR; 3511 } 3512 3513 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3514 OpenMPDirectiveKind CancelRegion, 3515 SourceLocation StartLoc) { 3516 // CancelRegion is only needed for cancel and cancellation_point. 3517 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3518 return false; 3519 3520 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3521 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3522 return false; 3523 3524 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3525 << getOpenMPDirectiveName(CancelRegion); 3526 return true; 3527 } 3528 3529 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3530 OpenMPDirectiveKind CurrentRegion, 3531 const DeclarationNameInfo &CurrentName, 3532 OpenMPDirectiveKind CancelRegion, 3533 SourceLocation StartLoc) { 3534 if (Stack->getCurScope()) { 3535 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3536 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3537 bool NestingProhibited = false; 3538 bool CloseNesting = true; 3539 bool OrphanSeen = false; 3540 enum { 3541 NoRecommend, 3542 ShouldBeInParallelRegion, 3543 ShouldBeInOrderedRegion, 3544 ShouldBeInTargetRegion, 3545 ShouldBeInTeamsRegion 3546 } Recommend = NoRecommend; 3547 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3548 // OpenMP [2.16, Nesting of Regions] 3549 // OpenMP constructs may not be nested inside a simd region. 3550 // OpenMP [2.8.1,simd Construct, Restrictions] 3551 // An ordered construct with the simd clause is the only OpenMP 3552 // construct that can appear in the simd region. 3553 // Allowing a SIMD construct nested in another SIMD construct is an 3554 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3555 // message. 3556 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3557 ? diag::err_omp_prohibited_region_simd 3558 : diag::warn_omp_nesting_simd); 3559 return CurrentRegion != OMPD_simd; 3560 } 3561 if (ParentRegion == OMPD_atomic) { 3562 // OpenMP [2.16, Nesting of Regions] 3563 // OpenMP constructs may not be nested inside an atomic region. 3564 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3565 return true; 3566 } 3567 if (CurrentRegion == OMPD_section) { 3568 // OpenMP [2.7.2, sections Construct, Restrictions] 3569 // Orphaned section directives are prohibited. That is, the section 3570 // directives must appear within the sections construct and must not be 3571 // encountered elsewhere in the sections region. 3572 if (ParentRegion != OMPD_sections && 3573 ParentRegion != OMPD_parallel_sections) { 3574 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3575 << (ParentRegion != OMPD_unknown) 3576 << getOpenMPDirectiveName(ParentRegion); 3577 return true; 3578 } 3579 return false; 3580 } 3581 // Allow some constructs (except teams and cancellation constructs) to be 3582 // orphaned (they could be used in functions, called from OpenMP regions 3583 // with the required preconditions). 3584 if (ParentRegion == OMPD_unknown && 3585 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3586 CurrentRegion != OMPD_cancellation_point && 3587 CurrentRegion != OMPD_cancel) 3588 return false; 3589 if (CurrentRegion == OMPD_cancellation_point || 3590 CurrentRegion == OMPD_cancel) { 3591 // OpenMP [2.16, Nesting of Regions] 3592 // A cancellation point construct for which construct-type-clause is 3593 // taskgroup must be nested inside a task construct. A cancellation 3594 // point construct for which construct-type-clause is not taskgroup must 3595 // be closely nested inside an OpenMP construct that matches the type 3596 // specified in construct-type-clause. 3597 // A cancel construct for which construct-type-clause is taskgroup must be 3598 // nested inside a task construct. A cancel construct for which 3599 // construct-type-clause is not taskgroup must be closely nested inside an 3600 // OpenMP construct that matches the type specified in 3601 // construct-type-clause. 3602 NestingProhibited = 3603 !((CancelRegion == OMPD_parallel && 3604 (ParentRegion == OMPD_parallel || 3605 ParentRegion == OMPD_target_parallel)) || 3606 (CancelRegion == OMPD_for && 3607 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3608 ParentRegion == OMPD_target_parallel_for || 3609 ParentRegion == OMPD_distribute_parallel_for || 3610 ParentRegion == OMPD_teams_distribute_parallel_for || 3611 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3612 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3613 (CancelRegion == OMPD_sections && 3614 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3615 ParentRegion == OMPD_parallel_sections))); 3616 OrphanSeen = ParentRegion == OMPD_unknown; 3617 } else if (CurrentRegion == OMPD_master) { 3618 // OpenMP [2.16, Nesting of Regions] 3619 // A master region may not be closely nested inside a worksharing, 3620 // atomic, or explicit task region. 3621 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3622 isOpenMPTaskingDirective(ParentRegion); 3623 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3624 // OpenMP [2.16, Nesting of Regions] 3625 // A critical region may not be nested (closely or otherwise) inside a 3626 // critical region with the same name. Note that this restriction is not 3627 // sufficient to prevent deadlock. 3628 SourceLocation PreviousCriticalLoc; 3629 bool DeadLock = Stack->hasDirective( 3630 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3631 const DeclarationNameInfo &DNI, 3632 SourceLocation Loc) { 3633 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3634 PreviousCriticalLoc = Loc; 3635 return true; 3636 } 3637 return false; 3638 }, 3639 false /* skip top directive */); 3640 if (DeadLock) { 3641 SemaRef.Diag(StartLoc, 3642 diag::err_omp_prohibited_region_critical_same_name) 3643 << CurrentName.getName(); 3644 if (PreviousCriticalLoc.isValid()) 3645 SemaRef.Diag(PreviousCriticalLoc, 3646 diag::note_omp_previous_critical_region); 3647 return true; 3648 } 3649 } else if (CurrentRegion == OMPD_barrier) { 3650 // OpenMP [2.16, Nesting of Regions] 3651 // A barrier region may not be closely nested inside a worksharing, 3652 // explicit task, critical, ordered, atomic, or master region. 3653 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3654 isOpenMPTaskingDirective(ParentRegion) || 3655 ParentRegion == OMPD_master || 3656 ParentRegion == OMPD_critical || 3657 ParentRegion == OMPD_ordered; 3658 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3659 !isOpenMPParallelDirective(CurrentRegion) && 3660 !isOpenMPTeamsDirective(CurrentRegion)) { 3661 // OpenMP [2.16, Nesting of Regions] 3662 // A worksharing region may not be closely nested inside a worksharing, 3663 // explicit task, critical, ordered, atomic, or master region. 3664 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3665 isOpenMPTaskingDirective(ParentRegion) || 3666 ParentRegion == OMPD_master || 3667 ParentRegion == OMPD_critical || 3668 ParentRegion == OMPD_ordered; 3669 Recommend = ShouldBeInParallelRegion; 3670 } else if (CurrentRegion == OMPD_ordered) { 3671 // OpenMP [2.16, Nesting of Regions] 3672 // An ordered region may not be closely nested inside a critical, 3673 // atomic, or explicit task region. 3674 // An ordered region must be closely nested inside a loop region (or 3675 // parallel loop region) with an ordered clause. 3676 // OpenMP [2.8.1,simd Construct, Restrictions] 3677 // An ordered construct with the simd clause is the only OpenMP construct 3678 // that can appear in the simd region. 3679 NestingProhibited = ParentRegion == OMPD_critical || 3680 isOpenMPTaskingDirective(ParentRegion) || 3681 !(isOpenMPSimdDirective(ParentRegion) || 3682 Stack->isParentOrderedRegion()); 3683 Recommend = ShouldBeInOrderedRegion; 3684 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3685 // OpenMP [2.16, Nesting of Regions] 3686 // If specified, a teams construct must be contained within a target 3687 // construct. 3688 NestingProhibited = ParentRegion != OMPD_target; 3689 OrphanSeen = ParentRegion == OMPD_unknown; 3690 Recommend = ShouldBeInTargetRegion; 3691 } 3692 if (!NestingProhibited && 3693 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3694 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3695 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3696 // OpenMP [2.16, Nesting of Regions] 3697 // distribute, parallel, parallel sections, parallel workshare, and the 3698 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3699 // constructs that can be closely nested in the teams region. 3700 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3701 !isOpenMPDistributeDirective(CurrentRegion); 3702 Recommend = ShouldBeInParallelRegion; 3703 } 3704 if (!NestingProhibited && 3705 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3706 // OpenMP 4.5 [2.17 Nesting of Regions] 3707 // The region associated with the distribute construct must be strictly 3708 // nested inside a teams region 3709 NestingProhibited = 3710 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3711 Recommend = ShouldBeInTeamsRegion; 3712 } 3713 if (!NestingProhibited && 3714 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3715 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3716 // OpenMP 4.5 [2.17 Nesting of Regions] 3717 // If a target, target update, target data, target enter data, or 3718 // target exit data construct is encountered during execution of a 3719 // target region, the behavior is unspecified. 3720 NestingProhibited = Stack->hasDirective( 3721 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3722 SourceLocation) { 3723 if (isOpenMPTargetExecutionDirective(K)) { 3724 OffendingRegion = K; 3725 return true; 3726 } 3727 return false; 3728 }, 3729 false /* don't skip top directive */); 3730 CloseNesting = false; 3731 } 3732 if (NestingProhibited) { 3733 if (OrphanSeen) { 3734 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3735 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3736 } else { 3737 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3738 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3739 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3740 } 3741 return true; 3742 } 3743 } 3744 return false; 3745 } 3746 3747 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3748 ArrayRef<OMPClause *> Clauses, 3749 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3750 bool ErrorFound = false; 3751 unsigned NamedModifiersNumber = 0; 3752 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3753 OMPD_unknown + 1); 3754 SmallVector<SourceLocation, 4> NameModifierLoc; 3755 for (const OMPClause *C : Clauses) { 3756 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3757 // At most one if clause without a directive-name-modifier can appear on 3758 // the directive. 3759 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3760 if (FoundNameModifiers[CurNM]) { 3761 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3762 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3763 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3764 ErrorFound = true; 3765 } else if (CurNM != OMPD_unknown) { 3766 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3767 ++NamedModifiersNumber; 3768 } 3769 FoundNameModifiers[CurNM] = IC; 3770 if (CurNM == OMPD_unknown) 3771 continue; 3772 // Check if the specified name modifier is allowed for the current 3773 // directive. 3774 // At most one if clause with the particular directive-name-modifier can 3775 // appear on the directive. 3776 bool MatchFound = false; 3777 for (auto NM : AllowedNameModifiers) { 3778 if (CurNM == NM) { 3779 MatchFound = true; 3780 break; 3781 } 3782 } 3783 if (!MatchFound) { 3784 S.Diag(IC->getNameModifierLoc(), 3785 diag::err_omp_wrong_if_directive_name_modifier) 3786 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3787 ErrorFound = true; 3788 } 3789 } 3790 } 3791 // If any if clause on the directive includes a directive-name-modifier then 3792 // all if clauses on the directive must include a directive-name-modifier. 3793 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3794 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3795 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3796 diag::err_omp_no_more_if_clause); 3797 } else { 3798 std::string Values; 3799 std::string Sep(", "); 3800 unsigned AllowedCnt = 0; 3801 unsigned TotalAllowedNum = 3802 AllowedNameModifiers.size() - NamedModifiersNumber; 3803 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3804 ++Cnt) { 3805 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3806 if (!FoundNameModifiers[NM]) { 3807 Values += "'"; 3808 Values += getOpenMPDirectiveName(NM); 3809 Values += "'"; 3810 if (AllowedCnt + 2 == TotalAllowedNum) 3811 Values += " or "; 3812 else if (AllowedCnt + 1 != TotalAllowedNum) 3813 Values += Sep; 3814 ++AllowedCnt; 3815 } 3816 } 3817 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3818 diag::err_omp_unnamed_if_clause) 3819 << (TotalAllowedNum > 1) << Values; 3820 } 3821 for (SourceLocation Loc : NameModifierLoc) { 3822 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3823 } 3824 ErrorFound = true; 3825 } 3826 return ErrorFound; 3827 } 3828 3829 static std::pair<ValueDecl *, bool> 3830 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 3831 SourceRange &ERange, bool AllowArraySection = false) { 3832 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 3833 RefExpr->containsUnexpandedParameterPack()) 3834 return std::make_pair(nullptr, true); 3835 3836 // OpenMP [3.1, C/C++] 3837 // A list item is a variable name. 3838 // OpenMP [2.9.3.3, Restrictions, p.1] 3839 // A variable that is part of another variable (as an array or 3840 // structure element) cannot appear in a private clause. 3841 RefExpr = RefExpr->IgnoreParens(); 3842 enum { 3843 NoArrayExpr = -1, 3844 ArraySubscript = 0, 3845 OMPArraySection = 1 3846 } IsArrayExpr = NoArrayExpr; 3847 if (AllowArraySection) { 3848 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 3849 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 3850 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3851 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3852 RefExpr = Base; 3853 IsArrayExpr = ArraySubscript; 3854 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 3855 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 3856 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 3857 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 3858 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3859 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3860 RefExpr = Base; 3861 IsArrayExpr = OMPArraySection; 3862 } 3863 } 3864 ELoc = RefExpr->getExprLoc(); 3865 ERange = RefExpr->getSourceRange(); 3866 RefExpr = RefExpr->IgnoreParenImpCasts(); 3867 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 3868 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 3869 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 3870 (S.getCurrentThisType().isNull() || !ME || 3871 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 3872 !isa<FieldDecl>(ME->getMemberDecl()))) { 3873 if (IsArrayExpr != NoArrayExpr) { 3874 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 3875 << ERange; 3876 } else { 3877 S.Diag(ELoc, 3878 AllowArraySection 3879 ? diag::err_omp_expected_var_name_member_expr_or_array_item 3880 : diag::err_omp_expected_var_name_member_expr) 3881 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 3882 } 3883 return std::make_pair(nullptr, false); 3884 } 3885 return std::make_pair( 3886 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 3887 } 3888 3889 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 3890 ArrayRef<OMPClause *> Clauses) { 3891 assert(!S.CurContext->isDependentContext() && 3892 "Expected non-dependent context."); 3893 auto AllocateRange = 3894 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 3895 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 3896 DeclToCopy; 3897 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 3898 return isOpenMPPrivate(C->getClauseKind()); 3899 }); 3900 for (OMPClause *Cl : PrivateRange) { 3901 MutableArrayRef<Expr *>::iterator I, It, Et; 3902 if (Cl->getClauseKind() == OMPC_private) { 3903 auto *PC = cast<OMPPrivateClause>(Cl); 3904 I = PC->private_copies().begin(); 3905 It = PC->varlist_begin(); 3906 Et = PC->varlist_end(); 3907 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 3908 auto *PC = cast<OMPFirstprivateClause>(Cl); 3909 I = PC->private_copies().begin(); 3910 It = PC->varlist_begin(); 3911 Et = PC->varlist_end(); 3912 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 3913 auto *PC = cast<OMPLastprivateClause>(Cl); 3914 I = PC->private_copies().begin(); 3915 It = PC->varlist_begin(); 3916 Et = PC->varlist_end(); 3917 } else if (Cl->getClauseKind() == OMPC_linear) { 3918 auto *PC = cast<OMPLinearClause>(Cl); 3919 I = PC->privates().begin(); 3920 It = PC->varlist_begin(); 3921 Et = PC->varlist_end(); 3922 } else if (Cl->getClauseKind() == OMPC_reduction) { 3923 auto *PC = cast<OMPReductionClause>(Cl); 3924 I = PC->privates().begin(); 3925 It = PC->varlist_begin(); 3926 Et = PC->varlist_end(); 3927 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 3928 auto *PC = cast<OMPTaskReductionClause>(Cl); 3929 I = PC->privates().begin(); 3930 It = PC->varlist_begin(); 3931 Et = PC->varlist_end(); 3932 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 3933 auto *PC = cast<OMPInReductionClause>(Cl); 3934 I = PC->privates().begin(); 3935 It = PC->varlist_begin(); 3936 Et = PC->varlist_end(); 3937 } else { 3938 llvm_unreachable("Expected private clause."); 3939 } 3940 for (Expr *E : llvm::make_range(It, Et)) { 3941 if (!*I) { 3942 ++I; 3943 continue; 3944 } 3945 SourceLocation ELoc; 3946 SourceRange ERange; 3947 Expr *SimpleRefExpr = E; 3948 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 3949 /*AllowArraySection=*/true); 3950 DeclToCopy.try_emplace(Res.first, 3951 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 3952 ++I; 3953 } 3954 } 3955 for (OMPClause *C : AllocateRange) { 3956 auto *AC = cast<OMPAllocateClause>(C); 3957 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3958 getAllocatorKind(S, Stack, AC->getAllocator()); 3959 // OpenMP, 2.11.4 allocate Clause, Restrictions. 3960 // For task, taskloop or target directives, allocation requests to memory 3961 // allocators with the trait access set to thread result in unspecified 3962 // behavior. 3963 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 3964 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 3965 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 3966 S.Diag(AC->getAllocator()->getExprLoc(), 3967 diag::warn_omp_allocate_thread_on_task_target_directive) 3968 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3969 } 3970 for (Expr *E : AC->varlists()) { 3971 SourceLocation ELoc; 3972 SourceRange ERange; 3973 Expr *SimpleRefExpr = E; 3974 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 3975 ValueDecl *VD = Res.first; 3976 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 3977 if (!isOpenMPPrivate(Data.CKind)) { 3978 S.Diag(E->getExprLoc(), 3979 diag::err_omp_expected_private_copy_for_allocate); 3980 continue; 3981 } 3982 VarDecl *PrivateVD = DeclToCopy[VD]; 3983 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 3984 AllocatorKind, AC->getAllocator())) 3985 continue; 3986 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 3987 E->getSourceRange()); 3988 } 3989 } 3990 } 3991 3992 StmtResult Sema::ActOnOpenMPExecutableDirective( 3993 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3994 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3995 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3996 StmtResult Res = StmtError(); 3997 // First check CancelRegion which is then used in checkNestingOfRegions. 3998 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3999 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4000 StartLoc)) 4001 return StmtError(); 4002 4003 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4004 VarsWithInheritedDSAType VarsWithInheritedDSA; 4005 bool ErrorFound = false; 4006 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4007 if (AStmt && !CurContext->isDependentContext()) { 4008 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4009 4010 // Check default data sharing attributes for referenced variables. 4011 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4012 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4013 Stmt *S = AStmt; 4014 while (--ThisCaptureLevel >= 0) 4015 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4016 DSAChecker.Visit(S); 4017 if (!isOpenMPTargetDataManagementDirective(Kind) && 4018 !isOpenMPTaskingDirective(Kind)) { 4019 // Visit subcaptures to generate implicit clauses for captured vars. 4020 auto *CS = cast<CapturedStmt>(AStmt); 4021 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4022 getOpenMPCaptureRegions(CaptureRegions, Kind); 4023 // Ignore outer tasking regions for target directives. 4024 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4025 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4026 DSAChecker.visitSubCaptures(CS); 4027 } 4028 if (DSAChecker.isErrorFound()) 4029 return StmtError(); 4030 // Generate list of implicitly defined firstprivate variables. 4031 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4032 4033 SmallVector<Expr *, 4> ImplicitFirstprivates( 4034 DSAChecker.getImplicitFirstprivate().begin(), 4035 DSAChecker.getImplicitFirstprivate().end()); 4036 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4037 DSAChecker.getImplicitMap().end()); 4038 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4039 for (OMPClause *C : Clauses) { 4040 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4041 for (Expr *E : IRC->taskgroup_descriptors()) 4042 if (E) 4043 ImplicitFirstprivates.emplace_back(E); 4044 } 4045 } 4046 if (!ImplicitFirstprivates.empty()) { 4047 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4048 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4049 SourceLocation())) { 4050 ClausesWithImplicit.push_back(Implicit); 4051 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4052 ImplicitFirstprivates.size(); 4053 } else { 4054 ErrorFound = true; 4055 } 4056 } 4057 if (!ImplicitMaps.empty()) { 4058 CXXScopeSpec MapperIdScopeSpec; 4059 DeclarationNameInfo MapperId; 4060 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4061 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4062 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4063 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4064 ClausesWithImplicit.emplace_back(Implicit); 4065 ErrorFound |= 4066 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4067 } else { 4068 ErrorFound = true; 4069 } 4070 } 4071 } 4072 4073 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4074 switch (Kind) { 4075 case OMPD_parallel: 4076 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4077 EndLoc); 4078 AllowedNameModifiers.push_back(OMPD_parallel); 4079 break; 4080 case OMPD_simd: 4081 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4082 VarsWithInheritedDSA); 4083 break; 4084 case OMPD_for: 4085 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4086 VarsWithInheritedDSA); 4087 break; 4088 case OMPD_for_simd: 4089 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4090 EndLoc, VarsWithInheritedDSA); 4091 break; 4092 case OMPD_sections: 4093 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4094 EndLoc); 4095 break; 4096 case OMPD_section: 4097 assert(ClausesWithImplicit.empty() && 4098 "No clauses are allowed for 'omp section' directive"); 4099 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4100 break; 4101 case OMPD_single: 4102 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4103 EndLoc); 4104 break; 4105 case OMPD_master: 4106 assert(ClausesWithImplicit.empty() && 4107 "No clauses are allowed for 'omp master' directive"); 4108 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4109 break; 4110 case OMPD_critical: 4111 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4112 StartLoc, EndLoc); 4113 break; 4114 case OMPD_parallel_for: 4115 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4116 EndLoc, VarsWithInheritedDSA); 4117 AllowedNameModifiers.push_back(OMPD_parallel); 4118 break; 4119 case OMPD_parallel_for_simd: 4120 Res = ActOnOpenMPParallelForSimdDirective( 4121 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4122 AllowedNameModifiers.push_back(OMPD_parallel); 4123 break; 4124 case OMPD_parallel_sections: 4125 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4126 StartLoc, EndLoc); 4127 AllowedNameModifiers.push_back(OMPD_parallel); 4128 break; 4129 case OMPD_task: 4130 Res = 4131 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4132 AllowedNameModifiers.push_back(OMPD_task); 4133 break; 4134 case OMPD_taskyield: 4135 assert(ClausesWithImplicit.empty() && 4136 "No clauses are allowed for 'omp taskyield' directive"); 4137 assert(AStmt == nullptr && 4138 "No associated statement allowed for 'omp taskyield' directive"); 4139 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4140 break; 4141 case OMPD_barrier: 4142 assert(ClausesWithImplicit.empty() && 4143 "No clauses are allowed for 'omp barrier' directive"); 4144 assert(AStmt == nullptr && 4145 "No associated statement allowed for 'omp barrier' directive"); 4146 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4147 break; 4148 case OMPD_taskwait: 4149 assert(ClausesWithImplicit.empty() && 4150 "No clauses are allowed for 'omp taskwait' directive"); 4151 assert(AStmt == nullptr && 4152 "No associated statement allowed for 'omp taskwait' directive"); 4153 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4154 break; 4155 case OMPD_taskgroup: 4156 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4157 EndLoc); 4158 break; 4159 case OMPD_flush: 4160 assert(AStmt == nullptr && 4161 "No associated statement allowed for 'omp flush' directive"); 4162 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4163 break; 4164 case OMPD_ordered: 4165 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4166 EndLoc); 4167 break; 4168 case OMPD_atomic: 4169 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4170 EndLoc); 4171 break; 4172 case OMPD_teams: 4173 Res = 4174 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4175 break; 4176 case OMPD_target: 4177 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4178 EndLoc); 4179 AllowedNameModifiers.push_back(OMPD_target); 4180 break; 4181 case OMPD_target_parallel: 4182 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4183 StartLoc, EndLoc); 4184 AllowedNameModifiers.push_back(OMPD_target); 4185 AllowedNameModifiers.push_back(OMPD_parallel); 4186 break; 4187 case OMPD_target_parallel_for: 4188 Res = ActOnOpenMPTargetParallelForDirective( 4189 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4190 AllowedNameModifiers.push_back(OMPD_target); 4191 AllowedNameModifiers.push_back(OMPD_parallel); 4192 break; 4193 case OMPD_cancellation_point: 4194 assert(ClausesWithImplicit.empty() && 4195 "No clauses are allowed for 'omp cancellation point' directive"); 4196 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4197 "cancellation point' directive"); 4198 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4199 break; 4200 case OMPD_cancel: 4201 assert(AStmt == nullptr && 4202 "No associated statement allowed for 'omp cancel' directive"); 4203 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4204 CancelRegion); 4205 AllowedNameModifiers.push_back(OMPD_cancel); 4206 break; 4207 case OMPD_target_data: 4208 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4209 EndLoc); 4210 AllowedNameModifiers.push_back(OMPD_target_data); 4211 break; 4212 case OMPD_target_enter_data: 4213 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4214 EndLoc, AStmt); 4215 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4216 break; 4217 case OMPD_target_exit_data: 4218 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4219 EndLoc, AStmt); 4220 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4221 break; 4222 case OMPD_taskloop: 4223 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4224 EndLoc, VarsWithInheritedDSA); 4225 AllowedNameModifiers.push_back(OMPD_taskloop); 4226 break; 4227 case OMPD_taskloop_simd: 4228 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4229 EndLoc, VarsWithInheritedDSA); 4230 AllowedNameModifiers.push_back(OMPD_taskloop); 4231 break; 4232 case OMPD_distribute: 4233 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4234 EndLoc, VarsWithInheritedDSA); 4235 break; 4236 case OMPD_target_update: 4237 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4238 EndLoc, AStmt); 4239 AllowedNameModifiers.push_back(OMPD_target_update); 4240 break; 4241 case OMPD_distribute_parallel_for: 4242 Res = ActOnOpenMPDistributeParallelForDirective( 4243 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4244 AllowedNameModifiers.push_back(OMPD_parallel); 4245 break; 4246 case OMPD_distribute_parallel_for_simd: 4247 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4248 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4249 AllowedNameModifiers.push_back(OMPD_parallel); 4250 break; 4251 case OMPD_distribute_simd: 4252 Res = ActOnOpenMPDistributeSimdDirective( 4253 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4254 break; 4255 case OMPD_target_parallel_for_simd: 4256 Res = ActOnOpenMPTargetParallelForSimdDirective( 4257 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4258 AllowedNameModifiers.push_back(OMPD_target); 4259 AllowedNameModifiers.push_back(OMPD_parallel); 4260 break; 4261 case OMPD_target_simd: 4262 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4263 EndLoc, VarsWithInheritedDSA); 4264 AllowedNameModifiers.push_back(OMPD_target); 4265 break; 4266 case OMPD_teams_distribute: 4267 Res = ActOnOpenMPTeamsDistributeDirective( 4268 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4269 break; 4270 case OMPD_teams_distribute_simd: 4271 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4272 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4273 break; 4274 case OMPD_teams_distribute_parallel_for_simd: 4275 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4276 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4277 AllowedNameModifiers.push_back(OMPD_parallel); 4278 break; 4279 case OMPD_teams_distribute_parallel_for: 4280 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4281 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4282 AllowedNameModifiers.push_back(OMPD_parallel); 4283 break; 4284 case OMPD_target_teams: 4285 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4286 EndLoc); 4287 AllowedNameModifiers.push_back(OMPD_target); 4288 break; 4289 case OMPD_target_teams_distribute: 4290 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4291 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4292 AllowedNameModifiers.push_back(OMPD_target); 4293 break; 4294 case OMPD_target_teams_distribute_parallel_for: 4295 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4296 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4297 AllowedNameModifiers.push_back(OMPD_target); 4298 AllowedNameModifiers.push_back(OMPD_parallel); 4299 break; 4300 case OMPD_target_teams_distribute_parallel_for_simd: 4301 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 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_simd: 4307 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4308 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4309 AllowedNameModifiers.push_back(OMPD_target); 4310 break; 4311 case OMPD_declare_target: 4312 case OMPD_end_declare_target: 4313 case OMPD_threadprivate: 4314 case OMPD_allocate: 4315 case OMPD_declare_reduction: 4316 case OMPD_declare_mapper: 4317 case OMPD_declare_simd: 4318 case OMPD_requires: 4319 llvm_unreachable("OpenMP Directive is not allowed"); 4320 case OMPD_unknown: 4321 llvm_unreachable("Unknown OpenMP directive"); 4322 } 4323 4324 ErrorFound = Res.isInvalid() || ErrorFound; 4325 4326 // Check variables in the clauses if default(none) was specified. 4327 if (DSAStack->getDefaultDSA() == DSA_none) { 4328 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4329 for (OMPClause *C : Clauses) { 4330 switch (C->getClauseKind()) { 4331 case OMPC_num_threads: 4332 case OMPC_dist_schedule: 4333 // Do not analyse if no parent teams directive. 4334 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4335 break; 4336 continue; 4337 case OMPC_if: 4338 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4339 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4340 break; 4341 continue; 4342 case OMPC_schedule: 4343 break; 4344 case OMPC_ordered: 4345 case OMPC_device: 4346 case OMPC_num_teams: 4347 case OMPC_thread_limit: 4348 case OMPC_priority: 4349 case OMPC_grainsize: 4350 case OMPC_num_tasks: 4351 case OMPC_hint: 4352 case OMPC_collapse: 4353 case OMPC_safelen: 4354 case OMPC_simdlen: 4355 case OMPC_final: 4356 case OMPC_default: 4357 case OMPC_proc_bind: 4358 case OMPC_private: 4359 case OMPC_firstprivate: 4360 case OMPC_lastprivate: 4361 case OMPC_shared: 4362 case OMPC_reduction: 4363 case OMPC_task_reduction: 4364 case OMPC_in_reduction: 4365 case OMPC_linear: 4366 case OMPC_aligned: 4367 case OMPC_copyin: 4368 case OMPC_copyprivate: 4369 case OMPC_nowait: 4370 case OMPC_untied: 4371 case OMPC_mergeable: 4372 case OMPC_allocate: 4373 case OMPC_read: 4374 case OMPC_write: 4375 case OMPC_update: 4376 case OMPC_capture: 4377 case OMPC_seq_cst: 4378 case OMPC_depend: 4379 case OMPC_threads: 4380 case OMPC_simd: 4381 case OMPC_map: 4382 case OMPC_nogroup: 4383 case OMPC_defaultmap: 4384 case OMPC_to: 4385 case OMPC_from: 4386 case OMPC_use_device_ptr: 4387 case OMPC_is_device_ptr: 4388 continue; 4389 case OMPC_allocator: 4390 case OMPC_flush: 4391 case OMPC_threadprivate: 4392 case OMPC_uniform: 4393 case OMPC_unknown: 4394 case OMPC_unified_address: 4395 case OMPC_unified_shared_memory: 4396 case OMPC_reverse_offload: 4397 case OMPC_dynamic_allocators: 4398 case OMPC_atomic_default_mem_order: 4399 llvm_unreachable("Unexpected clause"); 4400 } 4401 for (Stmt *CC : C->children()) { 4402 if (CC) 4403 DSAChecker.Visit(CC); 4404 } 4405 } 4406 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4407 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4408 } 4409 for (const auto &P : VarsWithInheritedDSA) { 4410 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4411 continue; 4412 ErrorFound = true; 4413 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4414 << P.first << P.second->getSourceRange(); 4415 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4416 } 4417 4418 if (!AllowedNameModifiers.empty()) 4419 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4420 ErrorFound; 4421 4422 if (ErrorFound) 4423 return StmtError(); 4424 4425 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4426 Res.getAs<OMPExecutableDirective>() 4427 ->getStructuredBlock() 4428 ->setIsOMPStructuredBlock(true); 4429 } 4430 4431 if (!CurContext->isDependentContext() && 4432 isOpenMPTargetExecutionDirective(Kind) && 4433 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4434 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4435 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4436 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4437 // Register target to DSA Stack. 4438 DSAStack->addTargetDirLocation(StartLoc); 4439 } 4440 4441 return Res; 4442 } 4443 4444 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4445 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4446 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4447 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4448 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4449 assert(Aligneds.size() == Alignments.size()); 4450 assert(Linears.size() == LinModifiers.size()); 4451 assert(Linears.size() == Steps.size()); 4452 if (!DG || DG.get().isNull()) 4453 return DeclGroupPtrTy(); 4454 4455 if (!DG.get().isSingleDecl()) { 4456 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4457 return DG; 4458 } 4459 Decl *ADecl = DG.get().getSingleDecl(); 4460 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4461 ADecl = FTD->getTemplatedDecl(); 4462 4463 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4464 if (!FD) { 4465 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4466 return DeclGroupPtrTy(); 4467 } 4468 4469 // OpenMP [2.8.2, declare simd construct, Description] 4470 // The parameter of the simdlen clause must be a constant positive integer 4471 // expression. 4472 ExprResult SL; 4473 if (Simdlen) 4474 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4475 // OpenMP [2.8.2, declare simd construct, Description] 4476 // The special this pointer can be used as if was one of the arguments to the 4477 // function in any of the linear, aligned, or uniform clauses. 4478 // The uniform clause declares one or more arguments to have an invariant 4479 // value for all concurrent invocations of the function in the execution of a 4480 // single SIMD loop. 4481 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4482 const Expr *UniformedLinearThis = nullptr; 4483 for (const Expr *E : Uniforms) { 4484 E = E->IgnoreParenImpCasts(); 4485 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4486 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4487 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4488 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4489 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4490 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4491 continue; 4492 } 4493 if (isa<CXXThisExpr>(E)) { 4494 UniformedLinearThis = E; 4495 continue; 4496 } 4497 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4498 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4499 } 4500 // OpenMP [2.8.2, declare simd construct, Description] 4501 // The aligned clause declares that the object to which each list item points 4502 // is aligned to the number of bytes expressed in the optional parameter of 4503 // the aligned clause. 4504 // The special this pointer can be used as if was one of the arguments to the 4505 // function in any of the linear, aligned, or uniform clauses. 4506 // The type of list items appearing in the aligned clause must be array, 4507 // pointer, reference to array, or reference to pointer. 4508 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4509 const Expr *AlignedThis = nullptr; 4510 for (const Expr *E : Aligneds) { 4511 E = E->IgnoreParenImpCasts(); 4512 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4513 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4514 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4515 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4516 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4517 ->getCanonicalDecl() == CanonPVD) { 4518 // OpenMP [2.8.1, simd construct, Restrictions] 4519 // A list-item cannot appear in more than one aligned clause. 4520 if (AlignedArgs.count(CanonPVD) > 0) { 4521 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4522 << 1 << E->getSourceRange(); 4523 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4524 diag::note_omp_explicit_dsa) 4525 << getOpenMPClauseName(OMPC_aligned); 4526 continue; 4527 } 4528 AlignedArgs[CanonPVD] = E; 4529 QualType QTy = PVD->getType() 4530 .getNonReferenceType() 4531 .getUnqualifiedType() 4532 .getCanonicalType(); 4533 const Type *Ty = QTy.getTypePtrOrNull(); 4534 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4535 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4536 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4537 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4538 } 4539 continue; 4540 } 4541 } 4542 if (isa<CXXThisExpr>(E)) { 4543 if (AlignedThis) { 4544 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4545 << 2 << E->getSourceRange(); 4546 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4547 << getOpenMPClauseName(OMPC_aligned); 4548 } 4549 AlignedThis = E; 4550 continue; 4551 } 4552 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4553 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4554 } 4555 // The optional parameter of the aligned clause, alignment, must be a constant 4556 // positive integer expression. If no optional parameter is specified, 4557 // implementation-defined default alignments for SIMD instructions on the 4558 // target platforms are assumed. 4559 SmallVector<const Expr *, 4> NewAligns; 4560 for (Expr *E : Alignments) { 4561 ExprResult Align; 4562 if (E) 4563 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4564 NewAligns.push_back(Align.get()); 4565 } 4566 // OpenMP [2.8.2, declare simd construct, Description] 4567 // The linear clause declares one or more list items to be private to a SIMD 4568 // lane and to have a linear relationship with respect to the iteration space 4569 // of a loop. 4570 // The special this pointer can be used as if was one of the arguments to the 4571 // function in any of the linear, aligned, or uniform clauses. 4572 // When a linear-step expression is specified in a linear clause it must be 4573 // either a constant integer expression or an integer-typed parameter that is 4574 // specified in a uniform clause on the directive. 4575 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4576 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4577 auto MI = LinModifiers.begin(); 4578 for (const Expr *E : Linears) { 4579 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4580 ++MI; 4581 E = E->IgnoreParenImpCasts(); 4582 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4583 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4584 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4585 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4586 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4587 ->getCanonicalDecl() == CanonPVD) { 4588 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4589 // A list-item cannot appear in more than one linear clause. 4590 if (LinearArgs.count(CanonPVD) > 0) { 4591 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4592 << getOpenMPClauseName(OMPC_linear) 4593 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4594 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4595 diag::note_omp_explicit_dsa) 4596 << getOpenMPClauseName(OMPC_linear); 4597 continue; 4598 } 4599 // Each argument can appear in at most one uniform or linear clause. 4600 if (UniformedArgs.count(CanonPVD) > 0) { 4601 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4602 << getOpenMPClauseName(OMPC_linear) 4603 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4604 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4605 diag::note_omp_explicit_dsa) 4606 << getOpenMPClauseName(OMPC_uniform); 4607 continue; 4608 } 4609 LinearArgs[CanonPVD] = E; 4610 if (E->isValueDependent() || E->isTypeDependent() || 4611 E->isInstantiationDependent() || 4612 E->containsUnexpandedParameterPack()) 4613 continue; 4614 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4615 PVD->getOriginalType()); 4616 continue; 4617 } 4618 } 4619 if (isa<CXXThisExpr>(E)) { 4620 if (UniformedLinearThis) { 4621 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4622 << getOpenMPClauseName(OMPC_linear) 4623 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4624 << E->getSourceRange(); 4625 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4626 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4627 : OMPC_linear); 4628 continue; 4629 } 4630 UniformedLinearThis = E; 4631 if (E->isValueDependent() || E->isTypeDependent() || 4632 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4633 continue; 4634 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4635 E->getType()); 4636 continue; 4637 } 4638 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4639 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4640 } 4641 Expr *Step = nullptr; 4642 Expr *NewStep = nullptr; 4643 SmallVector<Expr *, 4> NewSteps; 4644 for (Expr *E : Steps) { 4645 // Skip the same step expression, it was checked already. 4646 if (Step == E || !E) { 4647 NewSteps.push_back(E ? NewStep : nullptr); 4648 continue; 4649 } 4650 Step = E; 4651 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4652 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4653 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4654 if (UniformedArgs.count(CanonPVD) == 0) { 4655 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4656 << Step->getSourceRange(); 4657 } else if (E->isValueDependent() || E->isTypeDependent() || 4658 E->isInstantiationDependent() || 4659 E->containsUnexpandedParameterPack() || 4660 CanonPVD->getType()->hasIntegerRepresentation()) { 4661 NewSteps.push_back(Step); 4662 } else { 4663 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4664 << Step->getSourceRange(); 4665 } 4666 continue; 4667 } 4668 NewStep = Step; 4669 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4670 !Step->isInstantiationDependent() && 4671 !Step->containsUnexpandedParameterPack()) { 4672 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4673 .get(); 4674 if (NewStep) 4675 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4676 } 4677 NewSteps.push_back(NewStep); 4678 } 4679 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4680 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4681 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4682 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4683 const_cast<Expr **>(Linears.data()), Linears.size(), 4684 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4685 NewSteps.data(), NewSteps.size(), SR); 4686 ADecl->addAttr(NewAttr); 4687 return ConvertDeclToDeclGroup(ADecl); 4688 } 4689 4690 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4691 Stmt *AStmt, 4692 SourceLocation StartLoc, 4693 SourceLocation EndLoc) { 4694 if (!AStmt) 4695 return StmtError(); 4696 4697 auto *CS = cast<CapturedStmt>(AStmt); 4698 // 1.2.2 OpenMP Language Terminology 4699 // Structured block - An executable statement with a single entry at the 4700 // top and a single exit at the bottom. 4701 // The point of exit cannot be a branch out of the structured block. 4702 // longjmp() and throw() must not violate the entry/exit criteria. 4703 CS->getCapturedDecl()->setNothrow(); 4704 4705 setFunctionHasBranchProtectedScope(); 4706 4707 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4708 DSAStack->isCancelRegion()); 4709 } 4710 4711 namespace { 4712 /// Iteration space of a single for loop. 4713 struct LoopIterationSpace final { 4714 /// True if the condition operator is the strict compare operator (<, > or 4715 /// !=). 4716 bool IsStrictCompare = false; 4717 /// Condition of the loop. 4718 Expr *PreCond = nullptr; 4719 /// This expression calculates the number of iterations in the loop. 4720 /// It is always possible to calculate it before starting the loop. 4721 Expr *NumIterations = nullptr; 4722 /// The loop counter variable. 4723 Expr *CounterVar = nullptr; 4724 /// Private loop counter variable. 4725 Expr *PrivateCounterVar = nullptr; 4726 /// This is initializer for the initial value of #CounterVar. 4727 Expr *CounterInit = nullptr; 4728 /// This is step for the #CounterVar used to generate its update: 4729 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4730 Expr *CounterStep = nullptr; 4731 /// Should step be subtracted? 4732 bool Subtract = false; 4733 /// Source range of the loop init. 4734 SourceRange InitSrcRange; 4735 /// Source range of the loop condition. 4736 SourceRange CondSrcRange; 4737 /// Source range of the loop increment. 4738 SourceRange IncSrcRange; 4739 /// Minimum value that can have the loop control variable. Used to support 4740 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 4741 /// since only such variables can be used in non-loop invariant expressions. 4742 Expr *MinValue = nullptr; 4743 /// Maximum value that can have the loop control variable. Used to support 4744 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 4745 /// since only such variables can be used in non-loop invariant expressions. 4746 Expr *MaxValue = nullptr; 4747 /// true, if the lower bound depends on the outer loop control var. 4748 bool IsNonRectangularLB = false; 4749 /// true, if the upper bound depends on the outer loop control var. 4750 bool IsNonRectangularUB = false; 4751 /// Index of the loop this loop depends on and forms non-rectangular loop 4752 /// nest. 4753 unsigned LoopDependentIdx = 0; 4754 /// Final condition for the non-rectangular loop nest support. It is used to 4755 /// check that the number of iterations for this particular counter must be 4756 /// finished. 4757 Expr *FinalCondition = nullptr; 4758 }; 4759 4760 /// Helper class for checking canonical form of the OpenMP loops and 4761 /// extracting iteration space of each loop in the loop nest, that will be used 4762 /// for IR generation. 4763 class OpenMPIterationSpaceChecker { 4764 /// Reference to Sema. 4765 Sema &SemaRef; 4766 /// Data-sharing stack. 4767 DSAStackTy &Stack; 4768 /// A location for diagnostics (when there is no some better location). 4769 SourceLocation DefaultLoc; 4770 /// A location for diagnostics (when increment is not compatible). 4771 SourceLocation ConditionLoc; 4772 /// A source location for referring to loop init later. 4773 SourceRange InitSrcRange; 4774 /// A source location for referring to condition later. 4775 SourceRange ConditionSrcRange; 4776 /// A source location for referring to increment later. 4777 SourceRange IncrementSrcRange; 4778 /// Loop variable. 4779 ValueDecl *LCDecl = nullptr; 4780 /// Reference to loop variable. 4781 Expr *LCRef = nullptr; 4782 /// Lower bound (initializer for the var). 4783 Expr *LB = nullptr; 4784 /// Upper bound. 4785 Expr *UB = nullptr; 4786 /// Loop step (increment). 4787 Expr *Step = nullptr; 4788 /// This flag is true when condition is one of: 4789 /// Var < UB 4790 /// Var <= UB 4791 /// UB > Var 4792 /// UB >= Var 4793 /// This will have no value when the condition is != 4794 llvm::Optional<bool> TestIsLessOp; 4795 /// This flag is true when condition is strict ( < or > ). 4796 bool TestIsStrictOp = false; 4797 /// This flag is true when step is subtracted on each iteration. 4798 bool SubtractStep = false; 4799 /// The outer loop counter this loop depends on (if any). 4800 const ValueDecl *DepDecl = nullptr; 4801 /// Contains number of loop (starts from 1) on which loop counter init 4802 /// expression of this loop depends on. 4803 Optional<unsigned> InitDependOnLC; 4804 /// Contains number of loop (starts from 1) on which loop counter condition 4805 /// expression of this loop depends on. 4806 Optional<unsigned> CondDependOnLC; 4807 /// Checks if the provide statement depends on the loop counter. 4808 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 4809 /// Original condition required for checking of the exit condition for 4810 /// non-rectangular loop. 4811 Expr *Condition = nullptr; 4812 4813 public: 4814 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 4815 SourceLocation DefaultLoc) 4816 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 4817 ConditionLoc(DefaultLoc) {} 4818 /// Check init-expr for canonical loop form and save loop counter 4819 /// variable - #Var and its initialization value - #LB. 4820 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4821 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4822 /// for less/greater and for strict/non-strict comparison. 4823 bool checkAndSetCond(Expr *S); 4824 /// Check incr-expr for canonical loop form and return true if it 4825 /// does not conform, otherwise save loop step (#Step). 4826 bool checkAndSetInc(Expr *S); 4827 /// Return the loop counter variable. 4828 ValueDecl *getLoopDecl() const { return LCDecl; } 4829 /// Return the reference expression to loop counter variable. 4830 Expr *getLoopDeclRefExpr() const { return LCRef; } 4831 /// Source range of the loop init. 4832 SourceRange getInitSrcRange() const { return InitSrcRange; } 4833 /// Source range of the loop condition. 4834 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4835 /// Source range of the loop increment. 4836 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4837 /// True if the step should be subtracted. 4838 bool shouldSubtractStep() const { return SubtractStep; } 4839 /// True, if the compare operator is strict (<, > or !=). 4840 bool isStrictTestOp() const { return TestIsStrictOp; } 4841 /// Build the expression to calculate the number of iterations. 4842 Expr *buildNumIterations( 4843 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 4844 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4845 /// Build the precondition expression for the loops. 4846 Expr * 4847 buildPreCond(Scope *S, Expr *Cond, 4848 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4849 /// Build reference expression to the counter be used for codegen. 4850 DeclRefExpr * 4851 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4852 DSAStackTy &DSA) const; 4853 /// Build reference expression to the private counter be used for 4854 /// codegen. 4855 Expr *buildPrivateCounterVar() const; 4856 /// Build initialization of the counter be used for codegen. 4857 Expr *buildCounterInit() const; 4858 /// Build step of the counter be used for codegen. 4859 Expr *buildCounterStep() const; 4860 /// Build loop data with counter value for depend clauses in ordered 4861 /// directives. 4862 Expr * 4863 buildOrderedLoopData(Scope *S, Expr *Counter, 4864 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4865 SourceLocation Loc, Expr *Inc = nullptr, 4866 OverloadedOperatorKind OOK = OO_Amp); 4867 /// Builds the minimum value for the loop counter. 4868 std::pair<Expr *, Expr *> buildMinMaxValues( 4869 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4870 /// Builds final condition for the non-rectangular loops. 4871 Expr *buildFinalCondition(Scope *S) const; 4872 /// Return true if any expression is dependent. 4873 bool dependent() const; 4874 /// Returns true if the initializer forms non-rectangular loop. 4875 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 4876 /// Returns true if the condition forms non-rectangular loop. 4877 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 4878 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 4879 unsigned getLoopDependentIdx() const { 4880 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 4881 } 4882 4883 private: 4884 /// Check the right-hand side of an assignment in the increment 4885 /// expression. 4886 bool checkAndSetIncRHS(Expr *RHS); 4887 /// Helper to set loop counter variable and its initializer. 4888 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 4889 bool EmitDiags); 4890 /// Helper to set upper bound. 4891 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4892 SourceRange SR, SourceLocation SL); 4893 /// Helper to set loop increment. 4894 bool setStep(Expr *NewStep, bool Subtract); 4895 }; 4896 4897 bool OpenMPIterationSpaceChecker::dependent() const { 4898 if (!LCDecl) { 4899 assert(!LB && !UB && !Step); 4900 return false; 4901 } 4902 return LCDecl->getType()->isDependentType() || 4903 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4904 (Step && Step->isValueDependent()); 4905 } 4906 4907 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4908 Expr *NewLCRefExpr, 4909 Expr *NewLB, bool EmitDiags) { 4910 // State consistency checking to ensure correct usage. 4911 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4912 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4913 if (!NewLCDecl || !NewLB) 4914 return true; 4915 LCDecl = getCanonicalDecl(NewLCDecl); 4916 LCRef = NewLCRefExpr; 4917 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4918 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4919 if ((Ctor->isCopyOrMoveConstructor() || 4920 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4921 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4922 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4923 LB = NewLB; 4924 if (EmitDiags) 4925 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 4926 return false; 4927 } 4928 4929 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4930 llvm::Optional<bool> LessOp, 4931 bool StrictOp, SourceRange SR, 4932 SourceLocation SL) { 4933 // State consistency checking to ensure correct usage. 4934 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4935 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4936 if (!NewUB) 4937 return true; 4938 UB = NewUB; 4939 if (LessOp) 4940 TestIsLessOp = LessOp; 4941 TestIsStrictOp = StrictOp; 4942 ConditionSrcRange = SR; 4943 ConditionLoc = SL; 4944 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 4945 return false; 4946 } 4947 4948 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4949 // State consistency checking to ensure correct usage. 4950 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4951 if (!NewStep) 4952 return true; 4953 if (!NewStep->isValueDependent()) { 4954 // Check that the step is integer expression. 4955 SourceLocation StepLoc = NewStep->getBeginLoc(); 4956 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4957 StepLoc, getExprAsWritten(NewStep)); 4958 if (Val.isInvalid()) 4959 return true; 4960 NewStep = Val.get(); 4961 4962 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4963 // If test-expr is of form var relational-op b and relational-op is < or 4964 // <= then incr-expr must cause var to increase on each iteration of the 4965 // loop. If test-expr is of form var relational-op b and relational-op is 4966 // > or >= then incr-expr must cause var to decrease on each iteration of 4967 // the loop. 4968 // If test-expr is of form b relational-op var and relational-op is < or 4969 // <= then incr-expr must cause var to decrease on each iteration of the 4970 // loop. If test-expr is of form b relational-op var and relational-op is 4971 // > or >= then incr-expr must cause var to increase on each iteration of 4972 // the loop. 4973 llvm::APSInt Result; 4974 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4975 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4976 bool IsConstNeg = 4977 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4978 bool IsConstPos = 4979 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4980 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4981 4982 // != with increment is treated as <; != with decrement is treated as > 4983 if (!TestIsLessOp.hasValue()) 4984 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4985 if (UB && (IsConstZero || 4986 (TestIsLessOp.getValue() ? 4987 (IsConstNeg || (IsUnsigned && Subtract)) : 4988 (IsConstPos || (IsUnsigned && !Subtract))))) { 4989 SemaRef.Diag(NewStep->getExprLoc(), 4990 diag::err_omp_loop_incr_not_compatible) 4991 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4992 SemaRef.Diag(ConditionLoc, 4993 diag::note_omp_loop_cond_requres_compatible_incr) 4994 << TestIsLessOp.getValue() << ConditionSrcRange; 4995 return true; 4996 } 4997 if (TestIsLessOp.getValue() == Subtract) { 4998 NewStep = 4999 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5000 .get(); 5001 Subtract = !Subtract; 5002 } 5003 } 5004 5005 Step = NewStep; 5006 SubtractStep = Subtract; 5007 return false; 5008 } 5009 5010 namespace { 5011 /// Checker for the non-rectangular loops. Checks if the initializer or 5012 /// condition expression references loop counter variable. 5013 class LoopCounterRefChecker final 5014 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5015 Sema &SemaRef; 5016 DSAStackTy &Stack; 5017 const ValueDecl *CurLCDecl = nullptr; 5018 const ValueDecl *DepDecl = nullptr; 5019 const ValueDecl *PrevDepDecl = nullptr; 5020 bool IsInitializer = true; 5021 unsigned BaseLoopId = 0; 5022 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5023 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5024 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5025 << (IsInitializer ? 0 : 1); 5026 return false; 5027 } 5028 const auto &&Data = Stack.isLoopControlVariable(VD); 5029 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5030 // The type of the loop iterator on which we depend may not have a random 5031 // access iterator type. 5032 if (Data.first && VD->getType()->isRecordType()) { 5033 SmallString<128> Name; 5034 llvm::raw_svector_ostream OS(Name); 5035 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5036 /*Qualified=*/true); 5037 SemaRef.Diag(E->getExprLoc(), 5038 diag::err_omp_wrong_dependency_iterator_type) 5039 << OS.str(); 5040 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5041 return false; 5042 } 5043 if (Data.first && 5044 (DepDecl || (PrevDepDecl && 5045 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5046 if (!DepDecl && PrevDepDecl) 5047 DepDecl = PrevDepDecl; 5048 SmallString<128> Name; 5049 llvm::raw_svector_ostream OS(Name); 5050 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5051 /*Qualified=*/true); 5052 SemaRef.Diag(E->getExprLoc(), 5053 diag::err_omp_invariant_or_linear_dependency) 5054 << OS.str(); 5055 return false; 5056 } 5057 if (Data.first) { 5058 DepDecl = VD; 5059 BaseLoopId = Data.first; 5060 } 5061 return Data.first; 5062 } 5063 5064 public: 5065 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5066 const ValueDecl *VD = E->getDecl(); 5067 if (isa<VarDecl>(VD)) 5068 return checkDecl(E, VD); 5069 return false; 5070 } 5071 bool VisitMemberExpr(const MemberExpr *E) { 5072 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5073 const ValueDecl *VD = E->getMemberDecl(); 5074 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5075 return checkDecl(E, VD); 5076 } 5077 return false; 5078 } 5079 bool VisitStmt(const Stmt *S) { 5080 bool Res = false; 5081 for (const Stmt *Child : S->children()) 5082 Res = (Child && Visit(Child)) || Res; 5083 return Res; 5084 } 5085 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5086 const ValueDecl *CurLCDecl, bool IsInitializer, 5087 const ValueDecl *PrevDepDecl = nullptr) 5088 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5089 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5090 unsigned getBaseLoopId() const { 5091 assert(CurLCDecl && "Expected loop dependency."); 5092 return BaseLoopId; 5093 } 5094 const ValueDecl *getDepDecl() const { 5095 assert(CurLCDecl && "Expected loop dependency."); 5096 return DepDecl; 5097 } 5098 }; 5099 } // namespace 5100 5101 Optional<unsigned> 5102 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5103 bool IsInitializer) { 5104 // Check for the non-rectangular loops. 5105 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5106 DepDecl); 5107 if (LoopStmtChecker.Visit(S)) { 5108 DepDecl = LoopStmtChecker.getDepDecl(); 5109 return LoopStmtChecker.getBaseLoopId(); 5110 } 5111 return llvm::None; 5112 } 5113 5114 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5115 // Check init-expr for canonical loop form and save loop counter 5116 // variable - #Var and its initialization value - #LB. 5117 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5118 // var = lb 5119 // integer-type var = lb 5120 // random-access-iterator-type var = lb 5121 // pointer-type var = lb 5122 // 5123 if (!S) { 5124 if (EmitDiags) { 5125 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5126 } 5127 return true; 5128 } 5129 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5130 if (!ExprTemp->cleanupsHaveSideEffects()) 5131 S = ExprTemp->getSubExpr(); 5132 5133 InitSrcRange = S->getSourceRange(); 5134 if (Expr *E = dyn_cast<Expr>(S)) 5135 S = E->IgnoreParens(); 5136 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5137 if (BO->getOpcode() == BO_Assign) { 5138 Expr *LHS = BO->getLHS()->IgnoreParens(); 5139 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5140 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5141 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5142 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5143 EmitDiags); 5144 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5145 } 5146 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5147 if (ME->isArrow() && 5148 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5149 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5150 EmitDiags); 5151 } 5152 } 5153 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5154 if (DS->isSingleDecl()) { 5155 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5156 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5157 // Accept non-canonical init form here but emit ext. warning. 5158 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5159 SemaRef.Diag(S->getBeginLoc(), 5160 diag::ext_omp_loop_not_canonical_init) 5161 << S->getSourceRange(); 5162 return setLCDeclAndLB( 5163 Var, 5164 buildDeclRefExpr(SemaRef, Var, 5165 Var->getType().getNonReferenceType(), 5166 DS->getBeginLoc()), 5167 Var->getInit(), EmitDiags); 5168 } 5169 } 5170 } 5171 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5172 if (CE->getOperator() == OO_Equal) { 5173 Expr *LHS = CE->getArg(0); 5174 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5175 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5176 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5177 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5178 EmitDiags); 5179 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5180 } 5181 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5182 if (ME->isArrow() && 5183 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5184 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5185 EmitDiags); 5186 } 5187 } 5188 } 5189 5190 if (dependent() || SemaRef.CurContext->isDependentContext()) 5191 return false; 5192 if (EmitDiags) { 5193 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5194 << S->getSourceRange(); 5195 } 5196 return true; 5197 } 5198 5199 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5200 /// variable (which may be the loop variable) if possible. 5201 static const ValueDecl *getInitLCDecl(const Expr *E) { 5202 if (!E) 5203 return nullptr; 5204 E = getExprAsWritten(E); 5205 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5206 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5207 if ((Ctor->isCopyOrMoveConstructor() || 5208 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5209 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5210 E = CE->getArg(0)->IgnoreParenImpCasts(); 5211 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5212 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5213 return getCanonicalDecl(VD); 5214 } 5215 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5216 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5217 return getCanonicalDecl(ME->getMemberDecl()); 5218 return nullptr; 5219 } 5220 5221 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5222 // Check test-expr for canonical form, save upper-bound UB, flags for 5223 // less/greater and for strict/non-strict comparison. 5224 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5225 // var relational-op b 5226 // b relational-op var 5227 // 5228 if (!S) { 5229 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 5230 return true; 5231 } 5232 Condition = S; 5233 S = getExprAsWritten(S); 5234 SourceLocation CondLoc = S->getBeginLoc(); 5235 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5236 if (BO->isRelationalOp()) { 5237 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5238 return setUB(BO->getRHS(), 5239 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5240 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5241 BO->getSourceRange(), BO->getOperatorLoc()); 5242 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5243 return setUB(BO->getLHS(), 5244 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5245 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5246 BO->getSourceRange(), BO->getOperatorLoc()); 5247 } else if (BO->getOpcode() == BO_NE) 5248 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 5249 BO->getRHS() : BO->getLHS(), 5250 /*LessOp=*/llvm::None, 5251 /*StrictOp=*/true, 5252 BO->getSourceRange(), BO->getOperatorLoc()); 5253 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5254 if (CE->getNumArgs() == 2) { 5255 auto Op = CE->getOperator(); 5256 switch (Op) { 5257 case OO_Greater: 5258 case OO_GreaterEqual: 5259 case OO_Less: 5260 case OO_LessEqual: 5261 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5262 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5263 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5264 CE->getOperatorLoc()); 5265 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5266 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5267 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5268 CE->getOperatorLoc()); 5269 break; 5270 case OO_ExclaimEqual: 5271 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 5272 CE->getArg(1) : CE->getArg(0), 5273 /*LessOp=*/llvm::None, 5274 /*StrictOp=*/true, 5275 CE->getSourceRange(), 5276 CE->getOperatorLoc()); 5277 break; 5278 default: 5279 break; 5280 } 5281 } 5282 } 5283 if (dependent() || SemaRef.CurContext->isDependentContext()) 5284 return false; 5285 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5286 << S->getSourceRange() << LCDecl; 5287 return true; 5288 } 5289 5290 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5291 // RHS of canonical loop form increment can be: 5292 // var + incr 5293 // incr + var 5294 // var - incr 5295 // 5296 RHS = RHS->IgnoreParenImpCasts(); 5297 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5298 if (BO->isAdditiveOp()) { 5299 bool IsAdd = BO->getOpcode() == BO_Add; 5300 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5301 return setStep(BO->getRHS(), !IsAdd); 5302 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5303 return setStep(BO->getLHS(), /*Subtract=*/false); 5304 } 5305 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5306 bool IsAdd = CE->getOperator() == OO_Plus; 5307 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5308 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5309 return setStep(CE->getArg(1), !IsAdd); 5310 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5311 return setStep(CE->getArg(0), /*Subtract=*/false); 5312 } 5313 } 5314 if (dependent() || SemaRef.CurContext->isDependentContext()) 5315 return false; 5316 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5317 << RHS->getSourceRange() << LCDecl; 5318 return true; 5319 } 5320 5321 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5322 // Check incr-expr for canonical loop form and return true if it 5323 // does not conform. 5324 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5325 // ++var 5326 // var++ 5327 // --var 5328 // var-- 5329 // var += incr 5330 // var -= incr 5331 // var = var + incr 5332 // var = incr + var 5333 // var = var - incr 5334 // 5335 if (!S) { 5336 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5337 return true; 5338 } 5339 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5340 if (!ExprTemp->cleanupsHaveSideEffects()) 5341 S = ExprTemp->getSubExpr(); 5342 5343 IncrementSrcRange = S->getSourceRange(); 5344 S = S->IgnoreParens(); 5345 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5346 if (UO->isIncrementDecrementOp() && 5347 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5348 return setStep(SemaRef 5349 .ActOnIntegerConstant(UO->getBeginLoc(), 5350 (UO->isDecrementOp() ? -1 : 1)) 5351 .get(), 5352 /*Subtract=*/false); 5353 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5354 switch (BO->getOpcode()) { 5355 case BO_AddAssign: 5356 case BO_SubAssign: 5357 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5358 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5359 break; 5360 case BO_Assign: 5361 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5362 return checkAndSetIncRHS(BO->getRHS()); 5363 break; 5364 default: 5365 break; 5366 } 5367 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5368 switch (CE->getOperator()) { 5369 case OO_PlusPlus: 5370 case OO_MinusMinus: 5371 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5372 return setStep(SemaRef 5373 .ActOnIntegerConstant( 5374 CE->getBeginLoc(), 5375 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5376 .get(), 5377 /*Subtract=*/false); 5378 break; 5379 case OO_PlusEqual: 5380 case OO_MinusEqual: 5381 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5382 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5383 break; 5384 case OO_Equal: 5385 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5386 return checkAndSetIncRHS(CE->getArg(1)); 5387 break; 5388 default: 5389 break; 5390 } 5391 } 5392 if (dependent() || SemaRef.CurContext->isDependentContext()) 5393 return false; 5394 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5395 << S->getSourceRange() << LCDecl; 5396 return true; 5397 } 5398 5399 static ExprResult 5400 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5401 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5402 if (SemaRef.CurContext->isDependentContext()) 5403 return ExprResult(Capture); 5404 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5405 return SemaRef.PerformImplicitConversion( 5406 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5407 /*AllowExplicit=*/true); 5408 auto I = Captures.find(Capture); 5409 if (I != Captures.end()) 5410 return buildCapture(SemaRef, Capture, I->second); 5411 DeclRefExpr *Ref = nullptr; 5412 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5413 Captures[Capture] = Ref; 5414 return Res; 5415 } 5416 5417 /// Build the expression to calculate the number of iterations. 5418 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5419 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5420 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5421 ExprResult Diff; 5422 QualType VarType = LCDecl->getType().getNonReferenceType(); 5423 if (VarType->isIntegerType() || VarType->isPointerType() || 5424 SemaRef.getLangOpts().CPlusPlus) { 5425 Expr *LBVal = LB; 5426 Expr *UBVal = UB; 5427 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5428 // max(LB(MinVal), LB(MaxVal)) 5429 if (InitDependOnLC) { 5430 const LoopIterationSpace &IS = 5431 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5432 InitDependOnLC.getValueOr( 5433 CondDependOnLC.getValueOr(0))]; 5434 if (!IS.MinValue || !IS.MaxValue) 5435 return nullptr; 5436 // OuterVar = Min 5437 ExprResult MinValue = 5438 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5439 if (!MinValue.isUsable()) 5440 return nullptr; 5441 5442 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5443 IS.CounterVar, MinValue.get()); 5444 if (!LBMinVal.isUsable()) 5445 return nullptr; 5446 // OuterVar = Min, LBVal 5447 LBMinVal = 5448 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5449 if (!LBMinVal.isUsable()) 5450 return nullptr; 5451 // (OuterVar = Min, LBVal) 5452 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5453 if (!LBMinVal.isUsable()) 5454 return nullptr; 5455 5456 // OuterVar = Max 5457 ExprResult MaxValue = 5458 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5459 if (!MaxValue.isUsable()) 5460 return nullptr; 5461 5462 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5463 IS.CounterVar, MaxValue.get()); 5464 if (!LBMaxVal.isUsable()) 5465 return nullptr; 5466 // OuterVar = Max, LBVal 5467 LBMaxVal = 5468 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5469 if (!LBMaxVal.isUsable()) 5470 return nullptr; 5471 // (OuterVar = Max, LBVal) 5472 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5473 if (!LBMaxVal.isUsable()) 5474 return nullptr; 5475 5476 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5477 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5478 if (!LBMin || !LBMax) 5479 return nullptr; 5480 // LB(MinVal) < LB(MaxVal) 5481 ExprResult MinLessMaxRes = 5482 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 5483 if (!MinLessMaxRes.isUsable()) 5484 return nullptr; 5485 Expr *MinLessMax = 5486 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 5487 if (!MinLessMax) 5488 return nullptr; 5489 if (TestIsLessOp.getValue()) { 5490 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 5491 // LB(MaxVal)) 5492 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5493 MinLessMax, LBMin, LBMax); 5494 if (!MinLB.isUsable()) 5495 return nullptr; 5496 LBVal = MinLB.get(); 5497 } else { 5498 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 5499 // LB(MaxVal)) 5500 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5501 MinLessMax, LBMax, LBMin); 5502 if (!MaxLB.isUsable()) 5503 return nullptr; 5504 LBVal = MaxLB.get(); 5505 } 5506 } 5507 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 5508 // min(UB(MinVal), UB(MaxVal)) 5509 if (CondDependOnLC) { 5510 const LoopIterationSpace &IS = 5511 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5512 InitDependOnLC.getValueOr( 5513 CondDependOnLC.getValueOr(0))]; 5514 if (!IS.MinValue || !IS.MaxValue) 5515 return nullptr; 5516 // OuterVar = Min 5517 ExprResult MinValue = 5518 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5519 if (!MinValue.isUsable()) 5520 return nullptr; 5521 5522 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5523 IS.CounterVar, MinValue.get()); 5524 if (!UBMinVal.isUsable()) 5525 return nullptr; 5526 // OuterVar = Min, UBVal 5527 UBMinVal = 5528 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 5529 if (!UBMinVal.isUsable()) 5530 return nullptr; 5531 // (OuterVar = Min, UBVal) 5532 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 5533 if (!UBMinVal.isUsable()) 5534 return nullptr; 5535 5536 // OuterVar = Max 5537 ExprResult MaxValue = 5538 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5539 if (!MaxValue.isUsable()) 5540 return nullptr; 5541 5542 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5543 IS.CounterVar, MaxValue.get()); 5544 if (!UBMaxVal.isUsable()) 5545 return nullptr; 5546 // OuterVar = Max, UBVal 5547 UBMaxVal = 5548 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 5549 if (!UBMaxVal.isUsable()) 5550 return nullptr; 5551 // (OuterVar = Max, UBVal) 5552 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 5553 if (!UBMaxVal.isUsable()) 5554 return nullptr; 5555 5556 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 5557 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 5558 if (!UBMin || !UBMax) 5559 return nullptr; 5560 // UB(MinVal) > UB(MaxVal) 5561 ExprResult MinGreaterMaxRes = 5562 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 5563 if (!MinGreaterMaxRes.isUsable()) 5564 return nullptr; 5565 Expr *MinGreaterMax = 5566 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 5567 if (!MinGreaterMax) 5568 return nullptr; 5569 if (TestIsLessOp.getValue()) { 5570 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 5571 // UB(MaxVal)) 5572 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 5573 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 5574 if (!MaxUB.isUsable()) 5575 return nullptr; 5576 UBVal = MaxUB.get(); 5577 } else { 5578 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 5579 // UB(MaxVal)) 5580 ExprResult MinUB = SemaRef.ActOnConditionalOp( 5581 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 5582 if (!MinUB.isUsable()) 5583 return nullptr; 5584 UBVal = MinUB.get(); 5585 } 5586 } 5587 // Upper - Lower 5588 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 5589 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 5590 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5591 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5592 if (!Upper || !Lower) 5593 return nullptr; 5594 5595 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5596 5597 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5598 // BuildBinOp already emitted error, this one is to point user to upper 5599 // and lower bound, and to tell what is passed to 'operator-'. 5600 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5601 << Upper->getSourceRange() << Lower->getSourceRange(); 5602 return nullptr; 5603 } 5604 } 5605 5606 if (!Diff.isUsable()) 5607 return nullptr; 5608 5609 // Upper - Lower [- 1] 5610 if (TestIsStrictOp) 5611 Diff = SemaRef.BuildBinOp( 5612 S, DefaultLoc, BO_Sub, Diff.get(), 5613 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5614 if (!Diff.isUsable()) 5615 return nullptr; 5616 5617 // Upper - Lower [- 1] + Step 5618 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5619 if (!NewStep.isUsable()) 5620 return nullptr; 5621 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5622 if (!Diff.isUsable()) 5623 return nullptr; 5624 5625 // Parentheses (for dumping/debugging purposes only). 5626 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5627 if (!Diff.isUsable()) 5628 return nullptr; 5629 5630 // (Upper - Lower [- 1] + Step) / Step 5631 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5632 if (!Diff.isUsable()) 5633 return nullptr; 5634 5635 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5636 QualType Type = Diff.get()->getType(); 5637 ASTContext &C = SemaRef.Context; 5638 bool UseVarType = VarType->hasIntegerRepresentation() && 5639 C.getTypeSize(Type) > C.getTypeSize(VarType); 5640 if (!Type->isIntegerType() || UseVarType) { 5641 unsigned NewSize = 5642 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5643 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5644 : Type->hasSignedIntegerRepresentation(); 5645 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5646 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5647 Diff = SemaRef.PerformImplicitConversion( 5648 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5649 if (!Diff.isUsable()) 5650 return nullptr; 5651 } 5652 } 5653 if (LimitedType) { 5654 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5655 if (NewSize != C.getTypeSize(Type)) { 5656 if (NewSize < C.getTypeSize(Type)) { 5657 assert(NewSize == 64 && "incorrect loop var size"); 5658 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5659 << InitSrcRange << ConditionSrcRange; 5660 } 5661 QualType NewType = C.getIntTypeForBitwidth( 5662 NewSize, Type->hasSignedIntegerRepresentation() || 5663 C.getTypeSize(Type) < NewSize); 5664 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5665 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5666 Sema::AA_Converting, true); 5667 if (!Diff.isUsable()) 5668 return nullptr; 5669 } 5670 } 5671 } 5672 5673 return Diff.get(); 5674 } 5675 5676 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 5677 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5678 // Do not build for iterators, they cannot be used in non-rectangular loop 5679 // nests. 5680 if (LCDecl->getType()->isRecordType()) 5681 return std::make_pair(nullptr, nullptr); 5682 // If we subtract, the min is in the condition, otherwise the min is in the 5683 // init value. 5684 Expr *MinExpr = nullptr; 5685 Expr *MaxExpr = nullptr; 5686 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5687 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5688 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 5689 : CondDependOnLC.hasValue(); 5690 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 5691 : InitDependOnLC.hasValue(); 5692 Expr *Lower = 5693 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5694 Expr *Upper = 5695 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5696 if (!Upper || !Lower) 5697 return std::make_pair(nullptr, nullptr); 5698 5699 if (TestIsLessOp.getValue()) 5700 MinExpr = Lower; 5701 else 5702 MaxExpr = Upper; 5703 5704 // Build minimum/maximum value based on number of iterations. 5705 ExprResult Diff; 5706 QualType VarType = LCDecl->getType().getNonReferenceType(); 5707 5708 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5709 if (!Diff.isUsable()) 5710 return std::make_pair(nullptr, nullptr); 5711 5712 // Upper - Lower [- 1] 5713 if (TestIsStrictOp) 5714 Diff = SemaRef.BuildBinOp( 5715 S, DefaultLoc, BO_Sub, Diff.get(), 5716 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5717 if (!Diff.isUsable()) 5718 return std::make_pair(nullptr, nullptr); 5719 5720 // Upper - Lower [- 1] + Step 5721 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5722 if (!NewStep.isUsable()) 5723 return std::make_pair(nullptr, nullptr); 5724 5725 // Parentheses (for dumping/debugging purposes only). 5726 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5727 if (!Diff.isUsable()) 5728 return std::make_pair(nullptr, nullptr); 5729 5730 // (Upper - Lower [- 1]) / Step 5731 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5732 if (!Diff.isUsable()) 5733 return std::make_pair(nullptr, nullptr); 5734 5735 // ((Upper - Lower [- 1]) / Step) * Step 5736 // Parentheses (for dumping/debugging purposes only). 5737 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5738 if (!Diff.isUsable()) 5739 return std::make_pair(nullptr, nullptr); 5740 5741 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 5742 if (!Diff.isUsable()) 5743 return std::make_pair(nullptr, nullptr); 5744 5745 // Convert to the original type or ptrdiff_t, if original type is pointer. 5746 if (!VarType->isAnyPointerType() && 5747 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 5748 Diff = SemaRef.PerformImplicitConversion( 5749 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 5750 } else if (VarType->isAnyPointerType() && 5751 !SemaRef.Context.hasSameType( 5752 Diff.get()->getType(), 5753 SemaRef.Context.getUnsignedPointerDiffType())) { 5754 Diff = SemaRef.PerformImplicitConversion( 5755 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 5756 Sema::AA_Converting, /*AllowExplicit=*/true); 5757 } 5758 if (!Diff.isUsable()) 5759 return std::make_pair(nullptr, nullptr); 5760 5761 // Parentheses (for dumping/debugging purposes only). 5762 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5763 if (!Diff.isUsable()) 5764 return std::make_pair(nullptr, nullptr); 5765 5766 if (TestIsLessOp.getValue()) { 5767 // MinExpr = Lower; 5768 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 5769 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 5770 if (!Diff.isUsable()) 5771 return std::make_pair(nullptr, nullptr); 5772 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5773 if (!Diff.isUsable()) 5774 return std::make_pair(nullptr, nullptr); 5775 MaxExpr = Diff.get(); 5776 } else { 5777 // MaxExpr = Upper; 5778 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 5779 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 5780 if (!Diff.isUsable()) 5781 return std::make_pair(nullptr, nullptr); 5782 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5783 if (!Diff.isUsable()) 5784 return std::make_pair(nullptr, nullptr); 5785 MinExpr = Diff.get(); 5786 } 5787 5788 return std::make_pair(MinExpr, MaxExpr); 5789 } 5790 5791 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 5792 if (InitDependOnLC || CondDependOnLC) 5793 return Condition; 5794 return nullptr; 5795 } 5796 5797 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5798 Scope *S, Expr *Cond, 5799 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5800 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5801 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5802 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5803 5804 ExprResult NewLB = 5805 InitDependOnLC ? LB : tryBuildCapture(SemaRef, LB, Captures); 5806 ExprResult NewUB = 5807 CondDependOnLC ? UB : tryBuildCapture(SemaRef, UB, Captures); 5808 if (!NewLB.isUsable() || !NewUB.isUsable()) 5809 return nullptr; 5810 5811 ExprResult CondExpr = 5812 SemaRef.BuildBinOp(S, DefaultLoc, 5813 TestIsLessOp.getValue() ? 5814 (TestIsStrictOp ? BO_LT : BO_LE) : 5815 (TestIsStrictOp ? BO_GT : BO_GE), 5816 NewLB.get(), NewUB.get()); 5817 if (CondExpr.isUsable()) { 5818 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 5819 SemaRef.Context.BoolTy)) 5820 CondExpr = SemaRef.PerformImplicitConversion( 5821 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 5822 /*AllowExplicit=*/true); 5823 } 5824 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5825 // Otherwise use original loop condition and evaluate it in runtime. 5826 return CondExpr.isUsable() ? CondExpr.get() : Cond; 5827 } 5828 5829 /// Build reference expression to the counter be used for codegen. 5830 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 5831 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5832 DSAStackTy &DSA) const { 5833 auto *VD = dyn_cast<VarDecl>(LCDecl); 5834 if (!VD) { 5835 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 5836 DeclRefExpr *Ref = buildDeclRefExpr( 5837 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 5838 const DSAStackTy::DSAVarData Data = 5839 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 5840 // If the loop control decl is explicitly marked as private, do not mark it 5841 // as captured again. 5842 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 5843 Captures.insert(std::make_pair(LCRef, Ref)); 5844 return Ref; 5845 } 5846 return cast<DeclRefExpr>(LCRef); 5847 } 5848 5849 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 5850 if (LCDecl && !LCDecl->isInvalidDecl()) { 5851 QualType Type = LCDecl->getType().getNonReferenceType(); 5852 VarDecl *PrivateVar = buildVarDecl( 5853 SemaRef, DefaultLoc, Type, LCDecl->getName(), 5854 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 5855 isa<VarDecl>(LCDecl) 5856 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 5857 : nullptr); 5858 if (PrivateVar->isInvalidDecl()) 5859 return nullptr; 5860 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 5861 } 5862 return nullptr; 5863 } 5864 5865 /// Build initialization of the counter to be used for codegen. 5866 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 5867 5868 /// Build step of the counter be used for codegen. 5869 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 5870 5871 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 5872 Scope *S, Expr *Counter, 5873 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 5874 Expr *Inc, OverloadedOperatorKind OOK) { 5875 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 5876 if (!Cnt) 5877 return nullptr; 5878 if (Inc) { 5879 assert((OOK == OO_Plus || OOK == OO_Minus) && 5880 "Expected only + or - operations for depend clauses."); 5881 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 5882 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 5883 if (!Cnt) 5884 return nullptr; 5885 } 5886 ExprResult Diff; 5887 QualType VarType = LCDecl->getType().getNonReferenceType(); 5888 if (VarType->isIntegerType() || VarType->isPointerType() || 5889 SemaRef.getLangOpts().CPlusPlus) { 5890 // Upper - Lower 5891 Expr *Upper = TestIsLessOp.getValue() 5892 ? Cnt 5893 : tryBuildCapture(SemaRef, UB, Captures).get(); 5894 Expr *Lower = TestIsLessOp.getValue() 5895 ? tryBuildCapture(SemaRef, LB, Captures).get() 5896 : Cnt; 5897 if (!Upper || !Lower) 5898 return nullptr; 5899 5900 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5901 5902 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5903 // BuildBinOp already emitted error, this one is to point user to upper 5904 // and lower bound, and to tell what is passed to 'operator-'. 5905 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5906 << Upper->getSourceRange() << Lower->getSourceRange(); 5907 return nullptr; 5908 } 5909 } 5910 5911 if (!Diff.isUsable()) 5912 return nullptr; 5913 5914 // Parentheses (for dumping/debugging purposes only). 5915 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5916 if (!Diff.isUsable()) 5917 return nullptr; 5918 5919 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5920 if (!NewStep.isUsable()) 5921 return nullptr; 5922 // (Upper - Lower) / Step 5923 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5924 if (!Diff.isUsable()) 5925 return nullptr; 5926 5927 return Diff.get(); 5928 } 5929 } // namespace 5930 5931 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5932 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5933 assert(Init && "Expected loop in canonical form."); 5934 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5935 if (AssociatedLoops > 0 && 5936 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5937 DSAStack->loopStart(); 5938 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 5939 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5940 if (ValueDecl *D = ISC.getLoopDecl()) { 5941 auto *VD = dyn_cast<VarDecl>(D); 5942 DeclRefExpr *PrivateRef = nullptr; 5943 if (!VD) { 5944 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5945 VD = Private; 5946 } else { 5947 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5948 /*WithInit=*/false); 5949 VD = cast<VarDecl>(PrivateRef->getDecl()); 5950 } 5951 } 5952 DSAStack->addLoopControlVariable(D, VD); 5953 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5954 if (LD != D->getCanonicalDecl()) { 5955 DSAStack->resetPossibleLoopCounter(); 5956 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5957 MarkDeclarationsReferencedInExpr( 5958 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5959 Var->getType().getNonLValueExprType(Context), 5960 ForLoc, /*RefersToCapture=*/true)); 5961 } 5962 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 5963 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 5964 // Referenced in a Construct, C/C++]. The loop iteration variable in the 5965 // associated for-loop of a simd construct with just one associated 5966 // for-loop may be listed in a linear clause with a constant-linear-step 5967 // that is the increment of the associated for-loop. The loop iteration 5968 // variable(s) in the associated for-loop(s) of a for or parallel for 5969 // construct may be listed in a private or lastprivate clause. 5970 DSAStackTy::DSAVarData DVar = 5971 DSAStack->getTopDSA(D, /*FromParent=*/false); 5972 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 5973 // is declared in the loop and it is predetermined as a private. 5974 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5975 OpenMPClauseKind PredeterminedCKind = 5976 isOpenMPSimdDirective(DKind) 5977 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 5978 : OMPC_private; 5979 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5980 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 5981 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 5982 DVar.CKind != OMPC_private))) || 5983 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5984 isOpenMPDistributeDirective(DKind)) && 5985 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5986 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5987 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 5988 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5989 << getOpenMPClauseName(DVar.CKind) 5990 << getOpenMPDirectiveName(DKind) 5991 << getOpenMPClauseName(PredeterminedCKind); 5992 if (DVar.RefExpr == nullptr) 5993 DVar.CKind = PredeterminedCKind; 5994 reportOriginalDsa(*this, DSAStack, D, DVar, 5995 /*IsLoopIterVar=*/true); 5996 } else if (LoopDeclRefExpr) { 5997 // Make the loop iteration variable private (for worksharing 5998 // constructs), linear (for simd directives with the only one 5999 // associated loop) or lastprivate (for simd directives with several 6000 // collapsed or ordered loops). 6001 if (DVar.CKind == OMPC_unknown) 6002 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6003 PrivateRef); 6004 } 6005 } 6006 } 6007 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6008 } 6009 } 6010 6011 /// Called on a for stmt to check and extract its iteration space 6012 /// for further processing (such as collapsing). 6013 static bool checkOpenMPIterationSpace( 6014 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6015 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6016 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6017 Expr *OrderedLoopCountExpr, 6018 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6019 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6020 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6021 // OpenMP [2.6, Canonical Loop Form] 6022 // for (init-expr; test-expr; incr-expr) structured-block 6023 auto *For = dyn_cast_or_null<ForStmt>(S); 6024 if (!For) { 6025 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6026 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6027 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6028 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6029 if (TotalNestedLoopCount > 1) { 6030 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6031 SemaRef.Diag(DSA.getConstructLoc(), 6032 diag::note_omp_collapse_ordered_expr) 6033 << 2 << CollapseLoopCountExpr->getSourceRange() 6034 << OrderedLoopCountExpr->getSourceRange(); 6035 else if (CollapseLoopCountExpr) 6036 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6037 diag::note_omp_collapse_ordered_expr) 6038 << 0 << CollapseLoopCountExpr->getSourceRange(); 6039 else 6040 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6041 diag::note_omp_collapse_ordered_expr) 6042 << 1 << OrderedLoopCountExpr->getSourceRange(); 6043 } 6044 return true; 6045 } 6046 assert(For->getBody()); 6047 6048 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 6049 6050 // Check init. 6051 Stmt *Init = For->getInit(); 6052 if (ISC.checkAndSetInit(Init)) 6053 return true; 6054 6055 bool HasErrors = false; 6056 6057 // Check loop variable's type. 6058 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6059 // OpenMP [2.6, Canonical Loop Form] 6060 // Var is one of the following: 6061 // A variable of signed or unsigned integer type. 6062 // For C++, a variable of a random access iterator type. 6063 // For C, a variable of a pointer type. 6064 QualType VarType = LCDecl->getType().getNonReferenceType(); 6065 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6066 !VarType->isPointerType() && 6067 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6068 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6069 << SemaRef.getLangOpts().CPlusPlus; 6070 HasErrors = true; 6071 } 6072 6073 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6074 // a Construct 6075 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6076 // parallel for construct is (are) private. 6077 // The loop iteration variable in the associated for-loop of a simd 6078 // construct with just one associated for-loop is linear with a 6079 // constant-linear-step that is the increment of the associated for-loop. 6080 // Exclude loop var from the list of variables with implicitly defined data 6081 // sharing attributes. 6082 VarsWithImplicitDSA.erase(LCDecl); 6083 6084 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6085 6086 // Check test-expr. 6087 HasErrors |= ISC.checkAndSetCond(For->getCond()); 6088 6089 // Check incr-expr. 6090 HasErrors |= ISC.checkAndSetInc(For->getInc()); 6091 } 6092 6093 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6094 return HasErrors; 6095 6096 // Build the loop's iteration space representation. 6097 ResultIterSpaces[CurrentNestedLoopCount].PreCond = 6098 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 6099 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6100 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6101 (isOpenMPWorksharingDirective(DKind) || 6102 isOpenMPTaskLoopDirective(DKind) || 6103 isOpenMPDistributeDirective(DKind)), 6104 Captures); 6105 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6106 ISC.buildCounterVar(Captures, DSA); 6107 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6108 ISC.buildPrivateCounterVar(); 6109 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6110 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6111 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6112 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6113 ISC.getConditionSrcRange(); 6114 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6115 ISC.getIncrementSrcRange(); 6116 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6117 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6118 ISC.isStrictTestOp(); 6119 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6120 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6121 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6122 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6123 ISC.buildFinalCondition(DSA.getCurScope()); 6124 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6125 ISC.doesInitDependOnLC(); 6126 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6127 ISC.doesCondDependOnLC(); 6128 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6129 ISC.getLoopDependentIdx(); 6130 6131 HasErrors |= 6132 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6133 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6134 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6135 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6136 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6137 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6138 if (!HasErrors && DSA.isOrderedRegion()) { 6139 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6140 if (CurrentNestedLoopCount < 6141 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6142 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6143 CurrentNestedLoopCount, 6144 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6145 DSA.getOrderedRegionParam().second->setLoopCounter( 6146 CurrentNestedLoopCount, 6147 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6148 } 6149 } 6150 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6151 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6152 // Erroneous case - clause has some problems. 6153 continue; 6154 } 6155 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6156 Pair.second.size() <= CurrentNestedLoopCount) { 6157 // Erroneous case - clause has some problems. 6158 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6159 continue; 6160 } 6161 Expr *CntValue; 6162 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6163 CntValue = ISC.buildOrderedLoopData( 6164 DSA.getCurScope(), 6165 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6166 Pair.first->getDependencyLoc()); 6167 else 6168 CntValue = ISC.buildOrderedLoopData( 6169 DSA.getCurScope(), 6170 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6171 Pair.first->getDependencyLoc(), 6172 Pair.second[CurrentNestedLoopCount].first, 6173 Pair.second[CurrentNestedLoopCount].second); 6174 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6175 } 6176 } 6177 6178 return HasErrors; 6179 } 6180 6181 /// Build 'VarRef = Start. 6182 static ExprResult 6183 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6184 ExprResult Start, bool IsNonRectangularLB, 6185 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6186 // Build 'VarRef = Start. 6187 ExprResult NewStart = IsNonRectangularLB 6188 ? Start.get() 6189 : tryBuildCapture(SemaRef, Start.get(), Captures); 6190 if (!NewStart.isUsable()) 6191 return ExprError(); 6192 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6193 VarRef.get()->getType())) { 6194 NewStart = SemaRef.PerformImplicitConversion( 6195 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6196 /*AllowExplicit=*/true); 6197 if (!NewStart.isUsable()) 6198 return ExprError(); 6199 } 6200 6201 ExprResult Init = 6202 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6203 return Init; 6204 } 6205 6206 /// Build 'VarRef = Start + Iter * Step'. 6207 static ExprResult buildCounterUpdate( 6208 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6209 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6210 bool IsNonRectangularLB, 6211 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6212 // Add parentheses (for debugging purposes only). 6213 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6214 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6215 !Step.isUsable()) 6216 return ExprError(); 6217 6218 ExprResult NewStep = Step; 6219 if (Captures) 6220 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6221 if (NewStep.isInvalid()) 6222 return ExprError(); 6223 ExprResult Update = 6224 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6225 if (!Update.isUsable()) 6226 return ExprError(); 6227 6228 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6229 // 'VarRef = Start (+|-) Iter * Step'. 6230 if (!Start.isUsable()) 6231 return ExprError(); 6232 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6233 if (!NewStart.isUsable()) 6234 return ExprError(); 6235 if (Captures && !IsNonRectangularLB) 6236 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6237 if (NewStart.isInvalid()) 6238 return ExprError(); 6239 6240 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6241 ExprResult SavedUpdate = Update; 6242 ExprResult UpdateVal; 6243 if (VarRef.get()->getType()->isOverloadableType() || 6244 NewStart.get()->getType()->isOverloadableType() || 6245 Update.get()->getType()->isOverloadableType()) { 6246 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 6247 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 6248 Update = 6249 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6250 if (Update.isUsable()) { 6251 UpdateVal = 6252 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6253 VarRef.get(), SavedUpdate.get()); 6254 if (UpdateVal.isUsable()) { 6255 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6256 UpdateVal.get()); 6257 } 6258 } 6259 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 6260 } 6261 6262 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6263 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6264 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6265 NewStart.get(), SavedUpdate.get()); 6266 if (!Update.isUsable()) 6267 return ExprError(); 6268 6269 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6270 VarRef.get()->getType())) { 6271 Update = SemaRef.PerformImplicitConversion( 6272 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6273 if (!Update.isUsable()) 6274 return ExprError(); 6275 } 6276 6277 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6278 } 6279 return Update; 6280 } 6281 6282 /// Convert integer expression \a E to make it have at least \a Bits 6283 /// bits. 6284 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6285 if (E == nullptr) 6286 return ExprError(); 6287 ASTContext &C = SemaRef.Context; 6288 QualType OldType = E->getType(); 6289 unsigned HasBits = C.getTypeSize(OldType); 6290 if (HasBits >= Bits) 6291 return ExprResult(E); 6292 // OK to convert to signed, because new type has more bits than old. 6293 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6294 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6295 true); 6296 } 6297 6298 /// Check if the given expression \a E is a constant integer that fits 6299 /// into \a Bits bits. 6300 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6301 if (E == nullptr) 6302 return false; 6303 llvm::APSInt Result; 6304 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6305 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6306 return false; 6307 } 6308 6309 /// Build preinits statement for the given declarations. 6310 static Stmt *buildPreInits(ASTContext &Context, 6311 MutableArrayRef<Decl *> PreInits) { 6312 if (!PreInits.empty()) { 6313 return new (Context) DeclStmt( 6314 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6315 SourceLocation(), SourceLocation()); 6316 } 6317 return nullptr; 6318 } 6319 6320 /// Build preinits statement for the given declarations. 6321 static Stmt * 6322 buildPreInits(ASTContext &Context, 6323 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6324 if (!Captures.empty()) { 6325 SmallVector<Decl *, 16> PreInits; 6326 for (const auto &Pair : Captures) 6327 PreInits.push_back(Pair.second->getDecl()); 6328 return buildPreInits(Context, PreInits); 6329 } 6330 return nullptr; 6331 } 6332 6333 /// Build postupdate expression for the given list of postupdates expressions. 6334 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6335 Expr *PostUpdate = nullptr; 6336 if (!PostUpdates.empty()) { 6337 for (Expr *E : PostUpdates) { 6338 Expr *ConvE = S.BuildCStyleCastExpr( 6339 E->getExprLoc(), 6340 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6341 E->getExprLoc(), E) 6342 .get(); 6343 PostUpdate = PostUpdate 6344 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6345 PostUpdate, ConvE) 6346 .get() 6347 : ConvE; 6348 } 6349 } 6350 return PostUpdate; 6351 } 6352 6353 /// Called on a for stmt to check itself and nested loops (if any). 6354 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6355 /// number of collapsed loops otherwise. 6356 static unsigned 6357 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6358 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6359 DSAStackTy &DSA, 6360 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6361 OMPLoopDirective::HelperExprs &Built) { 6362 unsigned NestedLoopCount = 1; 6363 if (CollapseLoopCountExpr) { 6364 // Found 'collapse' clause - calculate collapse number. 6365 Expr::EvalResult Result; 6366 if (!CollapseLoopCountExpr->isValueDependent() && 6367 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6368 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6369 } else { 6370 Built.clear(/*Size=*/1); 6371 return 1; 6372 } 6373 } 6374 unsigned OrderedLoopCount = 1; 6375 if (OrderedLoopCountExpr) { 6376 // Found 'ordered' clause - calculate collapse number. 6377 Expr::EvalResult EVResult; 6378 if (!OrderedLoopCountExpr->isValueDependent() && 6379 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6380 SemaRef.getASTContext())) { 6381 llvm::APSInt Result = EVResult.Val.getInt(); 6382 if (Result.getLimitedValue() < NestedLoopCount) { 6383 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6384 diag::err_omp_wrong_ordered_loop_count) 6385 << OrderedLoopCountExpr->getSourceRange(); 6386 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6387 diag::note_collapse_loop_count) 6388 << CollapseLoopCountExpr->getSourceRange(); 6389 } 6390 OrderedLoopCount = Result.getLimitedValue(); 6391 } else { 6392 Built.clear(/*Size=*/1); 6393 return 1; 6394 } 6395 } 6396 // This is helper routine for loop directives (e.g., 'for', 'simd', 6397 // 'for simd', etc.). 6398 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6399 SmallVector<LoopIterationSpace, 4> IterSpaces( 6400 std::max(OrderedLoopCount, NestedLoopCount)); 6401 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6402 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6403 if (checkOpenMPIterationSpace( 6404 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6405 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6406 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6407 return 0; 6408 // Move on to the next nested for loop, or to the loop body. 6409 // OpenMP [2.8.1, simd construct, Restrictions] 6410 // All loops associated with the construct must be perfectly nested; that 6411 // is, there must be no intervening code nor any OpenMP directive between 6412 // any two loops. 6413 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6414 } 6415 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6416 if (checkOpenMPIterationSpace( 6417 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6418 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6419 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6420 return 0; 6421 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6422 // Handle initialization of captured loop iterator variables. 6423 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6424 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6425 Captures[DRE] = DRE; 6426 } 6427 } 6428 // Move on to the next nested for loop, or to the loop body. 6429 // OpenMP [2.8.1, simd construct, Restrictions] 6430 // All loops associated with the construct must be perfectly nested; that 6431 // is, there must be no intervening code nor any OpenMP directive between 6432 // any two loops. 6433 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6434 } 6435 6436 Built.clear(/* size */ NestedLoopCount); 6437 6438 if (SemaRef.CurContext->isDependentContext()) 6439 return NestedLoopCount; 6440 6441 // An example of what is generated for the following code: 6442 // 6443 // #pragma omp simd collapse(2) ordered(2) 6444 // for (i = 0; i < NI; ++i) 6445 // for (k = 0; k < NK; ++k) 6446 // for (j = J0; j < NJ; j+=2) { 6447 // <loop body> 6448 // } 6449 // 6450 // We generate the code below. 6451 // Note: the loop body may be outlined in CodeGen. 6452 // Note: some counters may be C++ classes, operator- is used to find number of 6453 // iterations and operator+= to calculate counter value. 6454 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6455 // or i64 is currently supported). 6456 // 6457 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6458 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6459 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6460 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6461 // // similar updates for vars in clauses (e.g. 'linear') 6462 // <loop body (using local i and j)> 6463 // } 6464 // i = NI; // assign final values of counters 6465 // j = NJ; 6466 // 6467 6468 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6469 // the iteration counts of the collapsed for loops. 6470 // Precondition tests if there is at least one iteration (all conditions are 6471 // true). 6472 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6473 Expr *N0 = IterSpaces[0].NumIterations; 6474 ExprResult LastIteration32 = 6475 widenIterationCount(/*Bits=*/32, 6476 SemaRef 6477 .PerformImplicitConversion( 6478 N0->IgnoreImpCasts(), N0->getType(), 6479 Sema::AA_Converting, /*AllowExplicit=*/true) 6480 .get(), 6481 SemaRef); 6482 ExprResult LastIteration64 = widenIterationCount( 6483 /*Bits=*/64, 6484 SemaRef 6485 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6486 Sema::AA_Converting, 6487 /*AllowExplicit=*/true) 6488 .get(), 6489 SemaRef); 6490 6491 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6492 return NestedLoopCount; 6493 6494 ASTContext &C = SemaRef.Context; 6495 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6496 6497 Scope *CurScope = DSA.getCurScope(); 6498 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6499 if (PreCond.isUsable()) { 6500 PreCond = 6501 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6502 PreCond.get(), IterSpaces[Cnt].PreCond); 6503 } 6504 Expr *N = IterSpaces[Cnt].NumIterations; 6505 SourceLocation Loc = N->getExprLoc(); 6506 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6507 if (LastIteration32.isUsable()) 6508 LastIteration32 = SemaRef.BuildBinOp( 6509 CurScope, Loc, BO_Mul, LastIteration32.get(), 6510 SemaRef 6511 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6512 Sema::AA_Converting, 6513 /*AllowExplicit=*/true) 6514 .get()); 6515 if (LastIteration64.isUsable()) 6516 LastIteration64 = SemaRef.BuildBinOp( 6517 CurScope, Loc, BO_Mul, LastIteration64.get(), 6518 SemaRef 6519 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6520 Sema::AA_Converting, 6521 /*AllowExplicit=*/true) 6522 .get()); 6523 } 6524 6525 // Choose either the 32-bit or 64-bit version. 6526 ExprResult LastIteration = LastIteration64; 6527 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6528 (LastIteration32.isUsable() && 6529 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6530 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6531 fitsInto( 6532 /*Bits=*/32, 6533 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6534 LastIteration64.get(), SemaRef)))) 6535 LastIteration = LastIteration32; 6536 QualType VType = LastIteration.get()->getType(); 6537 QualType RealVType = VType; 6538 QualType StrideVType = VType; 6539 if (isOpenMPTaskLoopDirective(DKind)) { 6540 VType = 6541 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6542 StrideVType = 6543 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6544 } 6545 6546 if (!LastIteration.isUsable()) 6547 return 0; 6548 6549 // Save the number of iterations. 6550 ExprResult NumIterations = LastIteration; 6551 { 6552 LastIteration = SemaRef.BuildBinOp( 6553 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6554 LastIteration.get(), 6555 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6556 if (!LastIteration.isUsable()) 6557 return 0; 6558 } 6559 6560 // Calculate the last iteration number beforehand instead of doing this on 6561 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6562 llvm::APSInt Result; 6563 bool IsConstant = 6564 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6565 ExprResult CalcLastIteration; 6566 if (!IsConstant) { 6567 ExprResult SaveRef = 6568 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6569 LastIteration = SaveRef; 6570 6571 // Prepare SaveRef + 1. 6572 NumIterations = SemaRef.BuildBinOp( 6573 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6574 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6575 if (!NumIterations.isUsable()) 6576 return 0; 6577 } 6578 6579 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6580 6581 // Build variables passed into runtime, necessary for worksharing directives. 6582 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6583 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6584 isOpenMPDistributeDirective(DKind)) { 6585 // Lower bound variable, initialized with zero. 6586 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6587 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6588 SemaRef.AddInitializerToDecl(LBDecl, 6589 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6590 /*DirectInit*/ false); 6591 6592 // Upper bound variable, initialized with last iteration number. 6593 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6594 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6595 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6596 /*DirectInit*/ false); 6597 6598 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6599 // This will be used to implement clause 'lastprivate'. 6600 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6601 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6602 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6603 SemaRef.AddInitializerToDecl(ILDecl, 6604 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6605 /*DirectInit*/ false); 6606 6607 // Stride variable returned by runtime (we initialize it to 1 by default). 6608 VarDecl *STDecl = 6609 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6610 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6611 SemaRef.AddInitializerToDecl(STDecl, 6612 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6613 /*DirectInit*/ false); 6614 6615 // Build expression: UB = min(UB, LastIteration) 6616 // It is necessary for CodeGen of directives with static scheduling. 6617 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6618 UB.get(), LastIteration.get()); 6619 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6620 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6621 LastIteration.get(), UB.get()); 6622 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6623 CondOp.get()); 6624 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6625 6626 // If we have a combined directive that combines 'distribute', 'for' or 6627 // 'simd' we need to be able to access the bounds of the schedule of the 6628 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6629 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6630 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6631 // Lower bound variable, initialized with zero. 6632 VarDecl *CombLBDecl = 6633 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6634 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6635 SemaRef.AddInitializerToDecl( 6636 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6637 /*DirectInit*/ false); 6638 6639 // Upper bound variable, initialized with last iteration number. 6640 VarDecl *CombUBDecl = 6641 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6642 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6643 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6644 /*DirectInit*/ false); 6645 6646 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6647 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6648 ExprResult CombCondOp = 6649 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6650 LastIteration.get(), CombUB.get()); 6651 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6652 CombCondOp.get()); 6653 CombEUB = 6654 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6655 6656 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6657 // We expect to have at least 2 more parameters than the 'parallel' 6658 // directive does - the lower and upper bounds of the previous schedule. 6659 assert(CD->getNumParams() >= 4 && 6660 "Unexpected number of parameters in loop combined directive"); 6661 6662 // Set the proper type for the bounds given what we learned from the 6663 // enclosed loops. 6664 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6665 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6666 6667 // Previous lower and upper bounds are obtained from the region 6668 // parameters. 6669 PrevLB = 6670 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6671 PrevUB = 6672 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6673 } 6674 } 6675 6676 // Build the iteration variable and its initialization before loop. 6677 ExprResult IV; 6678 ExprResult Init, CombInit; 6679 { 6680 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6681 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6682 Expr *RHS = 6683 (isOpenMPWorksharingDirective(DKind) || 6684 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6685 ? LB.get() 6686 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6687 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6688 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6689 6690 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6691 Expr *CombRHS = 6692 (isOpenMPWorksharingDirective(DKind) || 6693 isOpenMPTaskLoopDirective(DKind) || 6694 isOpenMPDistributeDirective(DKind)) 6695 ? CombLB.get() 6696 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6697 CombInit = 6698 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6699 CombInit = 6700 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6701 } 6702 } 6703 6704 bool UseStrictCompare = 6705 RealVType->hasUnsignedIntegerRepresentation() && 6706 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6707 return LIS.IsStrictCompare; 6708 }); 6709 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6710 // unsigned IV)) for worksharing loops. 6711 SourceLocation CondLoc = AStmt->getBeginLoc(); 6712 Expr *BoundUB = UB.get(); 6713 if (UseStrictCompare) { 6714 BoundUB = 6715 SemaRef 6716 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6717 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6718 .get(); 6719 BoundUB = 6720 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6721 } 6722 ExprResult Cond = 6723 (isOpenMPWorksharingDirective(DKind) || 6724 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6725 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6726 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6727 BoundUB) 6728 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6729 NumIterations.get()); 6730 ExprResult CombDistCond; 6731 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6732 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6733 NumIterations.get()); 6734 } 6735 6736 ExprResult CombCond; 6737 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6738 Expr *BoundCombUB = CombUB.get(); 6739 if (UseStrictCompare) { 6740 BoundCombUB = 6741 SemaRef 6742 .BuildBinOp( 6743 CurScope, CondLoc, BO_Add, BoundCombUB, 6744 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6745 .get(); 6746 BoundCombUB = 6747 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6748 .get(); 6749 } 6750 CombCond = 6751 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6752 IV.get(), BoundCombUB); 6753 } 6754 // Loop increment (IV = IV + 1) 6755 SourceLocation IncLoc = AStmt->getBeginLoc(); 6756 ExprResult Inc = 6757 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6758 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6759 if (!Inc.isUsable()) 6760 return 0; 6761 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6762 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6763 if (!Inc.isUsable()) 6764 return 0; 6765 6766 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6767 // Used for directives with static scheduling. 6768 // In combined construct, add combined version that use CombLB and CombUB 6769 // base variables for the update 6770 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6771 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6772 isOpenMPDistributeDirective(DKind)) { 6773 // LB + ST 6774 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6775 if (!NextLB.isUsable()) 6776 return 0; 6777 // LB = LB + ST 6778 NextLB = 6779 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6780 NextLB = 6781 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6782 if (!NextLB.isUsable()) 6783 return 0; 6784 // UB + ST 6785 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6786 if (!NextUB.isUsable()) 6787 return 0; 6788 // UB = UB + ST 6789 NextUB = 6790 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6791 NextUB = 6792 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6793 if (!NextUB.isUsable()) 6794 return 0; 6795 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6796 CombNextLB = 6797 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6798 if (!NextLB.isUsable()) 6799 return 0; 6800 // LB = LB + ST 6801 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6802 CombNextLB.get()); 6803 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6804 /*DiscardedValue*/ false); 6805 if (!CombNextLB.isUsable()) 6806 return 0; 6807 // UB + ST 6808 CombNextUB = 6809 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 6810 if (!CombNextUB.isUsable()) 6811 return 0; 6812 // UB = UB + ST 6813 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 6814 CombNextUB.get()); 6815 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 6816 /*DiscardedValue*/ false); 6817 if (!CombNextUB.isUsable()) 6818 return 0; 6819 } 6820 } 6821 6822 // Create increment expression for distribute loop when combined in a same 6823 // directive with for as IV = IV + ST; ensure upper bound expression based 6824 // on PrevUB instead of NumIterations - used to implement 'for' when found 6825 // in combination with 'distribute', like in 'distribute parallel for' 6826 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 6827 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 6828 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6829 DistCond = SemaRef.BuildBinOp( 6830 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 6831 assert(DistCond.isUsable() && "distribute cond expr was not built"); 6832 6833 DistInc = 6834 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 6835 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6836 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 6837 DistInc.get()); 6838 DistInc = 6839 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 6840 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6841 6842 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 6843 // construct 6844 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 6845 ExprResult IsUBGreater = 6846 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 6847 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6848 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 6849 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 6850 CondOp.get()); 6851 PrevEUB = 6852 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 6853 6854 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 6855 // parallel for is in combination with a distribute directive with 6856 // schedule(static, 1) 6857 Expr *BoundPrevUB = PrevUB.get(); 6858 if (UseStrictCompare) { 6859 BoundPrevUB = 6860 SemaRef 6861 .BuildBinOp( 6862 CurScope, CondLoc, BO_Add, BoundPrevUB, 6863 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6864 .get(); 6865 BoundPrevUB = 6866 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 6867 .get(); 6868 } 6869 ParForInDistCond = 6870 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6871 IV.get(), BoundPrevUB); 6872 } 6873 6874 // Build updates and final values of the loop counters. 6875 bool HasErrors = false; 6876 Built.Counters.resize(NestedLoopCount); 6877 Built.Inits.resize(NestedLoopCount); 6878 Built.Updates.resize(NestedLoopCount); 6879 Built.Finals.resize(NestedLoopCount); 6880 Built.DependentCounters.resize(NestedLoopCount); 6881 Built.DependentInits.resize(NestedLoopCount); 6882 Built.FinalsConditions.resize(NestedLoopCount); 6883 { 6884 // We implement the following algorithm for obtaining the 6885 // original loop iteration variable values based on the 6886 // value of the collapsed loop iteration variable IV. 6887 // 6888 // Let n+1 be the number of collapsed loops in the nest. 6889 // Iteration variables (I0, I1, .... In) 6890 // Iteration counts (N0, N1, ... Nn) 6891 // 6892 // Acc = IV; 6893 // 6894 // To compute Ik for loop k, 0 <= k <= n, generate: 6895 // Prod = N(k+1) * N(k+2) * ... * Nn; 6896 // Ik = Acc / Prod; 6897 // Acc -= Ik * Prod; 6898 // 6899 ExprResult Acc = IV; 6900 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6901 LoopIterationSpace &IS = IterSpaces[Cnt]; 6902 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 6903 ExprResult Iter; 6904 6905 // Compute prod 6906 ExprResult Prod = 6907 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6908 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 6909 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 6910 IterSpaces[K].NumIterations); 6911 6912 // Iter = Acc / Prod 6913 // If there is at least one more inner loop to avoid 6914 // multiplication by 1. 6915 if (Cnt + 1 < NestedLoopCount) 6916 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 6917 Acc.get(), Prod.get()); 6918 else 6919 Iter = Acc; 6920 if (!Iter.isUsable()) { 6921 HasErrors = true; 6922 break; 6923 } 6924 6925 // Update Acc: 6926 // Acc -= Iter * Prod 6927 // Check if there is at least one more inner loop to avoid 6928 // multiplication by 1. 6929 if (Cnt + 1 < NestedLoopCount) 6930 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 6931 Iter.get(), Prod.get()); 6932 else 6933 Prod = Iter; 6934 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 6935 Acc.get(), Prod.get()); 6936 6937 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 6938 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 6939 DeclRefExpr *CounterVar = buildDeclRefExpr( 6940 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 6941 /*RefersToCapture=*/true); 6942 ExprResult Init = 6943 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 6944 IS.CounterInit, IS.IsNonRectangularLB, Captures); 6945 if (!Init.isUsable()) { 6946 HasErrors = true; 6947 break; 6948 } 6949 ExprResult Update = buildCounterUpdate( 6950 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 6951 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 6952 if (!Update.isUsable()) { 6953 HasErrors = true; 6954 break; 6955 } 6956 6957 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6958 ExprResult Final = 6959 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 6960 IS.CounterInit, IS.NumIterations, IS.CounterStep, 6961 IS.Subtract, IS.IsNonRectangularLB, &Captures); 6962 if (!Final.isUsable()) { 6963 HasErrors = true; 6964 break; 6965 } 6966 6967 if (!Update.isUsable() || !Final.isUsable()) { 6968 HasErrors = true; 6969 break; 6970 } 6971 // Save results 6972 Built.Counters[Cnt] = IS.CounterVar; 6973 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6974 Built.Inits[Cnt] = Init.get(); 6975 Built.Updates[Cnt] = Update.get(); 6976 Built.Finals[Cnt] = Final.get(); 6977 Built.DependentCounters[Cnt] = nullptr; 6978 Built.DependentInits[Cnt] = nullptr; 6979 Built.FinalsConditions[Cnt] = nullptr; 6980 if (IS.IsNonRectangularLB) { 6981 Built.DependentCounters[Cnt] = 6982 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 6983 Built.DependentInits[Cnt] = 6984 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 6985 Built.FinalsConditions[Cnt] = IS.FinalCondition; 6986 } 6987 } 6988 } 6989 6990 if (HasErrors) 6991 return 0; 6992 6993 // Save results 6994 Built.IterationVarRef = IV.get(); 6995 Built.LastIteration = LastIteration.get(); 6996 Built.NumIterations = NumIterations.get(); 6997 Built.CalcLastIteration = SemaRef 6998 .ActOnFinishFullExpr(CalcLastIteration.get(), 6999 /*DiscardedValue=*/false) 7000 .get(); 7001 Built.PreCond = PreCond.get(); 7002 Built.PreInits = buildPreInits(C, Captures); 7003 Built.Cond = Cond.get(); 7004 Built.Init = Init.get(); 7005 Built.Inc = Inc.get(); 7006 Built.LB = LB.get(); 7007 Built.UB = UB.get(); 7008 Built.IL = IL.get(); 7009 Built.ST = ST.get(); 7010 Built.EUB = EUB.get(); 7011 Built.NLB = NextLB.get(); 7012 Built.NUB = NextUB.get(); 7013 Built.PrevLB = PrevLB.get(); 7014 Built.PrevUB = PrevUB.get(); 7015 Built.DistInc = DistInc.get(); 7016 Built.PrevEUB = PrevEUB.get(); 7017 Built.DistCombinedFields.LB = CombLB.get(); 7018 Built.DistCombinedFields.UB = CombUB.get(); 7019 Built.DistCombinedFields.EUB = CombEUB.get(); 7020 Built.DistCombinedFields.Init = CombInit.get(); 7021 Built.DistCombinedFields.Cond = CombCond.get(); 7022 Built.DistCombinedFields.NLB = CombNextLB.get(); 7023 Built.DistCombinedFields.NUB = CombNextUB.get(); 7024 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7025 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7026 7027 return NestedLoopCount; 7028 } 7029 7030 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7031 auto CollapseClauses = 7032 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7033 if (CollapseClauses.begin() != CollapseClauses.end()) 7034 return (*CollapseClauses.begin())->getNumForLoops(); 7035 return nullptr; 7036 } 7037 7038 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7039 auto OrderedClauses = 7040 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7041 if (OrderedClauses.begin() != OrderedClauses.end()) 7042 return (*OrderedClauses.begin())->getNumForLoops(); 7043 return nullptr; 7044 } 7045 7046 static bool checkSimdlenSafelenSpecified(Sema &S, 7047 const ArrayRef<OMPClause *> Clauses) { 7048 const OMPSafelenClause *Safelen = nullptr; 7049 const OMPSimdlenClause *Simdlen = nullptr; 7050 7051 for (const OMPClause *Clause : Clauses) { 7052 if (Clause->getClauseKind() == OMPC_safelen) 7053 Safelen = cast<OMPSafelenClause>(Clause); 7054 else if (Clause->getClauseKind() == OMPC_simdlen) 7055 Simdlen = cast<OMPSimdlenClause>(Clause); 7056 if (Safelen && Simdlen) 7057 break; 7058 } 7059 7060 if (Simdlen && Safelen) { 7061 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7062 const Expr *SafelenLength = Safelen->getSafelen(); 7063 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7064 SimdlenLength->isInstantiationDependent() || 7065 SimdlenLength->containsUnexpandedParameterPack()) 7066 return false; 7067 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7068 SafelenLength->isInstantiationDependent() || 7069 SafelenLength->containsUnexpandedParameterPack()) 7070 return false; 7071 Expr::EvalResult SimdlenResult, SafelenResult; 7072 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7073 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7074 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7075 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7076 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7077 // If both simdlen and safelen clauses are specified, the value of the 7078 // simdlen parameter must be less than or equal to the value of the safelen 7079 // parameter. 7080 if (SimdlenRes > SafelenRes) { 7081 S.Diag(SimdlenLength->getExprLoc(), 7082 diag::err_omp_wrong_simdlen_safelen_values) 7083 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7084 return true; 7085 } 7086 } 7087 return false; 7088 } 7089 7090 StmtResult 7091 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7092 SourceLocation StartLoc, SourceLocation EndLoc, 7093 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7094 if (!AStmt) 7095 return StmtError(); 7096 7097 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7098 OMPLoopDirective::HelperExprs B; 7099 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7100 // define the nested loops number. 7101 unsigned NestedLoopCount = checkOpenMPLoop( 7102 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7103 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7104 if (NestedLoopCount == 0) 7105 return StmtError(); 7106 7107 assert((CurContext->isDependentContext() || B.builtAll()) && 7108 "omp simd loop exprs were not built"); 7109 7110 if (!CurContext->isDependentContext()) { 7111 // Finalize the clauses that need pre-built expressions for CodeGen. 7112 for (OMPClause *C : Clauses) { 7113 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7114 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7115 B.NumIterations, *this, CurScope, 7116 DSAStack)) 7117 return StmtError(); 7118 } 7119 } 7120 7121 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7122 return StmtError(); 7123 7124 setFunctionHasBranchProtectedScope(); 7125 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7126 Clauses, AStmt, B); 7127 } 7128 7129 StmtResult 7130 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7131 SourceLocation StartLoc, SourceLocation EndLoc, 7132 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7133 if (!AStmt) 7134 return StmtError(); 7135 7136 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7137 OMPLoopDirective::HelperExprs B; 7138 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7139 // define the nested loops number. 7140 unsigned NestedLoopCount = checkOpenMPLoop( 7141 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7142 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7143 if (NestedLoopCount == 0) 7144 return StmtError(); 7145 7146 assert((CurContext->isDependentContext() || B.builtAll()) && 7147 "omp for loop exprs were not built"); 7148 7149 if (!CurContext->isDependentContext()) { 7150 // Finalize the clauses that need pre-built expressions for CodeGen. 7151 for (OMPClause *C : Clauses) { 7152 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7153 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7154 B.NumIterations, *this, CurScope, 7155 DSAStack)) 7156 return StmtError(); 7157 } 7158 } 7159 7160 setFunctionHasBranchProtectedScope(); 7161 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7162 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7163 } 7164 7165 StmtResult Sema::ActOnOpenMPForSimdDirective( 7166 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7167 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7168 if (!AStmt) 7169 return StmtError(); 7170 7171 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7172 OMPLoopDirective::HelperExprs B; 7173 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7174 // define the nested loops number. 7175 unsigned NestedLoopCount = 7176 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7177 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7178 VarsWithImplicitDSA, B); 7179 if (NestedLoopCount == 0) 7180 return StmtError(); 7181 7182 assert((CurContext->isDependentContext() || B.builtAll()) && 7183 "omp for simd loop exprs were not built"); 7184 7185 if (!CurContext->isDependentContext()) { 7186 // Finalize the clauses that need pre-built expressions for CodeGen. 7187 for (OMPClause *C : Clauses) { 7188 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7189 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7190 B.NumIterations, *this, CurScope, 7191 DSAStack)) 7192 return StmtError(); 7193 } 7194 } 7195 7196 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7197 return StmtError(); 7198 7199 setFunctionHasBranchProtectedScope(); 7200 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7201 Clauses, AStmt, B); 7202 } 7203 7204 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7205 Stmt *AStmt, 7206 SourceLocation StartLoc, 7207 SourceLocation EndLoc) { 7208 if (!AStmt) 7209 return StmtError(); 7210 7211 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7212 auto BaseStmt = AStmt; 7213 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7214 BaseStmt = CS->getCapturedStmt(); 7215 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7216 auto S = C->children(); 7217 if (S.begin() == S.end()) 7218 return StmtError(); 7219 // All associated statements must be '#pragma omp section' except for 7220 // the first one. 7221 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7222 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7223 if (SectionStmt) 7224 Diag(SectionStmt->getBeginLoc(), 7225 diag::err_omp_sections_substmt_not_section); 7226 return StmtError(); 7227 } 7228 cast<OMPSectionDirective>(SectionStmt) 7229 ->setHasCancel(DSAStack->isCancelRegion()); 7230 } 7231 } else { 7232 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7233 return StmtError(); 7234 } 7235 7236 setFunctionHasBranchProtectedScope(); 7237 7238 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7239 DSAStack->isCancelRegion()); 7240 } 7241 7242 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7243 SourceLocation StartLoc, 7244 SourceLocation EndLoc) { 7245 if (!AStmt) 7246 return StmtError(); 7247 7248 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7249 7250 setFunctionHasBranchProtectedScope(); 7251 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7252 7253 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7254 DSAStack->isCancelRegion()); 7255 } 7256 7257 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7258 Stmt *AStmt, 7259 SourceLocation StartLoc, 7260 SourceLocation EndLoc) { 7261 if (!AStmt) 7262 return StmtError(); 7263 7264 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7265 7266 setFunctionHasBranchProtectedScope(); 7267 7268 // OpenMP [2.7.3, single Construct, Restrictions] 7269 // The copyprivate clause must not be used with the nowait clause. 7270 const OMPClause *Nowait = nullptr; 7271 const OMPClause *Copyprivate = nullptr; 7272 for (const OMPClause *Clause : Clauses) { 7273 if (Clause->getClauseKind() == OMPC_nowait) 7274 Nowait = Clause; 7275 else if (Clause->getClauseKind() == OMPC_copyprivate) 7276 Copyprivate = Clause; 7277 if (Copyprivate && Nowait) { 7278 Diag(Copyprivate->getBeginLoc(), 7279 diag::err_omp_single_copyprivate_with_nowait); 7280 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7281 return StmtError(); 7282 } 7283 } 7284 7285 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7286 } 7287 7288 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7289 SourceLocation StartLoc, 7290 SourceLocation EndLoc) { 7291 if (!AStmt) 7292 return StmtError(); 7293 7294 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7295 7296 setFunctionHasBranchProtectedScope(); 7297 7298 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7299 } 7300 7301 StmtResult Sema::ActOnOpenMPCriticalDirective( 7302 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7303 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7304 if (!AStmt) 7305 return StmtError(); 7306 7307 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7308 7309 bool ErrorFound = false; 7310 llvm::APSInt Hint; 7311 SourceLocation HintLoc; 7312 bool DependentHint = false; 7313 for (const OMPClause *C : Clauses) { 7314 if (C->getClauseKind() == OMPC_hint) { 7315 if (!DirName.getName()) { 7316 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7317 ErrorFound = true; 7318 } 7319 Expr *E = cast<OMPHintClause>(C)->getHint(); 7320 if (E->isTypeDependent() || E->isValueDependent() || 7321 E->isInstantiationDependent()) { 7322 DependentHint = true; 7323 } else { 7324 Hint = E->EvaluateKnownConstInt(Context); 7325 HintLoc = C->getBeginLoc(); 7326 } 7327 } 7328 } 7329 if (ErrorFound) 7330 return StmtError(); 7331 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7332 if (Pair.first && DirName.getName() && !DependentHint) { 7333 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7334 Diag(StartLoc, diag::err_omp_critical_with_hint); 7335 if (HintLoc.isValid()) 7336 Diag(HintLoc, diag::note_omp_critical_hint_here) 7337 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7338 else 7339 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7340 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7341 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7342 << 1 7343 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7344 /*Radix=*/10, /*Signed=*/false); 7345 } else { 7346 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7347 } 7348 } 7349 } 7350 7351 setFunctionHasBranchProtectedScope(); 7352 7353 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7354 Clauses, AStmt); 7355 if (!Pair.first && DirName.getName() && !DependentHint) 7356 DSAStack->addCriticalWithHint(Dir, Hint); 7357 return Dir; 7358 } 7359 7360 StmtResult Sema::ActOnOpenMPParallelForDirective( 7361 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7362 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7363 if (!AStmt) 7364 return StmtError(); 7365 7366 auto *CS = cast<CapturedStmt>(AStmt); 7367 // 1.2.2 OpenMP Language Terminology 7368 // Structured block - An executable statement with a single entry at the 7369 // top and a single exit at the bottom. 7370 // The point of exit cannot be a branch out of the structured block. 7371 // longjmp() and throw() must not violate the entry/exit criteria. 7372 CS->getCapturedDecl()->setNothrow(); 7373 7374 OMPLoopDirective::HelperExprs B; 7375 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7376 // define the nested loops number. 7377 unsigned NestedLoopCount = 7378 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7379 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7380 VarsWithImplicitDSA, B); 7381 if (NestedLoopCount == 0) 7382 return StmtError(); 7383 7384 assert((CurContext->isDependentContext() || B.builtAll()) && 7385 "omp parallel for loop exprs were not built"); 7386 7387 if (!CurContext->isDependentContext()) { 7388 // Finalize the clauses that need pre-built expressions for CodeGen. 7389 for (OMPClause *C : Clauses) { 7390 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7391 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7392 B.NumIterations, *this, CurScope, 7393 DSAStack)) 7394 return StmtError(); 7395 } 7396 } 7397 7398 setFunctionHasBranchProtectedScope(); 7399 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7400 NestedLoopCount, Clauses, AStmt, B, 7401 DSAStack->isCancelRegion()); 7402 } 7403 7404 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7405 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7406 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7407 if (!AStmt) 7408 return StmtError(); 7409 7410 auto *CS = cast<CapturedStmt>(AStmt); 7411 // 1.2.2 OpenMP Language Terminology 7412 // Structured block - An executable statement with a single entry at the 7413 // top and a single exit at the bottom. 7414 // The point of exit cannot be a branch out of the structured block. 7415 // longjmp() and throw() must not violate the entry/exit criteria. 7416 CS->getCapturedDecl()->setNothrow(); 7417 7418 OMPLoopDirective::HelperExprs B; 7419 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7420 // define the nested loops number. 7421 unsigned NestedLoopCount = 7422 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7423 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7424 VarsWithImplicitDSA, B); 7425 if (NestedLoopCount == 0) 7426 return StmtError(); 7427 7428 if (!CurContext->isDependentContext()) { 7429 // Finalize the clauses that need pre-built expressions for CodeGen. 7430 for (OMPClause *C : Clauses) { 7431 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7432 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7433 B.NumIterations, *this, CurScope, 7434 DSAStack)) 7435 return StmtError(); 7436 } 7437 } 7438 7439 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7440 return StmtError(); 7441 7442 setFunctionHasBranchProtectedScope(); 7443 return OMPParallelForSimdDirective::Create( 7444 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7445 } 7446 7447 StmtResult 7448 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7449 Stmt *AStmt, SourceLocation StartLoc, 7450 SourceLocation EndLoc) { 7451 if (!AStmt) 7452 return StmtError(); 7453 7454 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7455 auto BaseStmt = AStmt; 7456 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7457 BaseStmt = CS->getCapturedStmt(); 7458 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7459 auto S = C->children(); 7460 if (S.begin() == S.end()) 7461 return StmtError(); 7462 // All associated statements must be '#pragma omp section' except for 7463 // the first one. 7464 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7465 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7466 if (SectionStmt) 7467 Diag(SectionStmt->getBeginLoc(), 7468 diag::err_omp_parallel_sections_substmt_not_section); 7469 return StmtError(); 7470 } 7471 cast<OMPSectionDirective>(SectionStmt) 7472 ->setHasCancel(DSAStack->isCancelRegion()); 7473 } 7474 } else { 7475 Diag(AStmt->getBeginLoc(), 7476 diag::err_omp_parallel_sections_not_compound_stmt); 7477 return StmtError(); 7478 } 7479 7480 setFunctionHasBranchProtectedScope(); 7481 7482 return OMPParallelSectionsDirective::Create( 7483 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7484 } 7485 7486 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7487 Stmt *AStmt, SourceLocation StartLoc, 7488 SourceLocation EndLoc) { 7489 if (!AStmt) 7490 return StmtError(); 7491 7492 auto *CS = cast<CapturedStmt>(AStmt); 7493 // 1.2.2 OpenMP Language Terminology 7494 // Structured block - An executable statement with a single entry at the 7495 // top and a single exit at the bottom. 7496 // The point of exit cannot be a branch out of the structured block. 7497 // longjmp() and throw() must not violate the entry/exit criteria. 7498 CS->getCapturedDecl()->setNothrow(); 7499 7500 setFunctionHasBranchProtectedScope(); 7501 7502 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7503 DSAStack->isCancelRegion()); 7504 } 7505 7506 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7507 SourceLocation EndLoc) { 7508 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7509 } 7510 7511 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7512 SourceLocation EndLoc) { 7513 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7514 } 7515 7516 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7517 SourceLocation EndLoc) { 7518 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7519 } 7520 7521 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7522 Stmt *AStmt, 7523 SourceLocation StartLoc, 7524 SourceLocation EndLoc) { 7525 if (!AStmt) 7526 return StmtError(); 7527 7528 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7529 7530 setFunctionHasBranchProtectedScope(); 7531 7532 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7533 AStmt, 7534 DSAStack->getTaskgroupReductionRef()); 7535 } 7536 7537 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7538 SourceLocation StartLoc, 7539 SourceLocation EndLoc) { 7540 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7541 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7542 } 7543 7544 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7545 Stmt *AStmt, 7546 SourceLocation StartLoc, 7547 SourceLocation EndLoc) { 7548 const OMPClause *DependFound = nullptr; 7549 const OMPClause *DependSourceClause = nullptr; 7550 const OMPClause *DependSinkClause = nullptr; 7551 bool ErrorFound = false; 7552 const OMPThreadsClause *TC = nullptr; 7553 const OMPSIMDClause *SC = nullptr; 7554 for (const OMPClause *C : Clauses) { 7555 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7556 DependFound = C; 7557 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7558 if (DependSourceClause) { 7559 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7560 << getOpenMPDirectiveName(OMPD_ordered) 7561 << getOpenMPClauseName(OMPC_depend) << 2; 7562 ErrorFound = true; 7563 } else { 7564 DependSourceClause = C; 7565 } 7566 if (DependSinkClause) { 7567 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7568 << 0; 7569 ErrorFound = true; 7570 } 7571 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7572 if (DependSourceClause) { 7573 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7574 << 1; 7575 ErrorFound = true; 7576 } 7577 DependSinkClause = C; 7578 } 7579 } else if (C->getClauseKind() == OMPC_threads) { 7580 TC = cast<OMPThreadsClause>(C); 7581 } else if (C->getClauseKind() == OMPC_simd) { 7582 SC = cast<OMPSIMDClause>(C); 7583 } 7584 } 7585 if (!ErrorFound && !SC && 7586 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7587 // OpenMP [2.8.1,simd Construct, Restrictions] 7588 // An ordered construct with the simd clause is the only OpenMP construct 7589 // that can appear in the simd region. 7590 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7591 ErrorFound = true; 7592 } else if (DependFound && (TC || SC)) { 7593 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7594 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7595 ErrorFound = true; 7596 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7597 Diag(DependFound->getBeginLoc(), 7598 diag::err_omp_ordered_directive_without_param); 7599 ErrorFound = true; 7600 } else if (TC || Clauses.empty()) { 7601 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7602 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7603 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7604 << (TC != nullptr); 7605 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7606 ErrorFound = true; 7607 } 7608 } 7609 if ((!AStmt && !DependFound) || ErrorFound) 7610 return StmtError(); 7611 7612 if (AStmt) { 7613 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7614 7615 setFunctionHasBranchProtectedScope(); 7616 } 7617 7618 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7619 } 7620 7621 namespace { 7622 /// Helper class for checking expression in 'omp atomic [update]' 7623 /// construct. 7624 class OpenMPAtomicUpdateChecker { 7625 /// Error results for atomic update expressions. 7626 enum ExprAnalysisErrorCode { 7627 /// A statement is not an expression statement. 7628 NotAnExpression, 7629 /// Expression is not builtin binary or unary operation. 7630 NotABinaryOrUnaryExpression, 7631 /// Unary operation is not post-/pre- increment/decrement operation. 7632 NotAnUnaryIncDecExpression, 7633 /// An expression is not of scalar type. 7634 NotAScalarType, 7635 /// A binary operation is not an assignment operation. 7636 NotAnAssignmentOp, 7637 /// RHS part of the binary operation is not a binary expression. 7638 NotABinaryExpression, 7639 /// RHS part is not additive/multiplicative/shift/biwise binary 7640 /// expression. 7641 NotABinaryOperator, 7642 /// RHS binary operation does not have reference to the updated LHS 7643 /// part. 7644 NotAnUpdateExpression, 7645 /// No errors is found. 7646 NoError 7647 }; 7648 /// Reference to Sema. 7649 Sema &SemaRef; 7650 /// A location for note diagnostics (when error is found). 7651 SourceLocation NoteLoc; 7652 /// 'x' lvalue part of the source atomic expression. 7653 Expr *X; 7654 /// 'expr' rvalue part of the source atomic expression. 7655 Expr *E; 7656 /// Helper expression of the form 7657 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7658 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7659 Expr *UpdateExpr; 7660 /// Is 'x' a LHS in a RHS part of full update expression. It is 7661 /// important for non-associative operations. 7662 bool IsXLHSInRHSPart; 7663 BinaryOperatorKind Op; 7664 SourceLocation OpLoc; 7665 /// true if the source expression is a postfix unary operation, false 7666 /// if it is a prefix unary operation. 7667 bool IsPostfixUpdate; 7668 7669 public: 7670 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7671 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7672 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7673 /// Check specified statement that it is suitable for 'atomic update' 7674 /// constructs and extract 'x', 'expr' and Operation from the original 7675 /// expression. If DiagId and NoteId == 0, then only check is performed 7676 /// without error notification. 7677 /// \param DiagId Diagnostic which should be emitted if error is found. 7678 /// \param NoteId Diagnostic note for the main error message. 7679 /// \return true if statement is not an update expression, false otherwise. 7680 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7681 /// Return the 'x' lvalue part of the source atomic expression. 7682 Expr *getX() const { return X; } 7683 /// Return the 'expr' rvalue part of the source atomic expression. 7684 Expr *getExpr() const { return E; } 7685 /// Return the update expression used in calculation of the updated 7686 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7687 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7688 Expr *getUpdateExpr() const { return UpdateExpr; } 7689 /// Return true if 'x' is LHS in RHS part of full update expression, 7690 /// false otherwise. 7691 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7692 7693 /// true if the source expression is a postfix unary operation, false 7694 /// if it is a prefix unary operation. 7695 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7696 7697 private: 7698 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7699 unsigned NoteId = 0); 7700 }; 7701 } // namespace 7702 7703 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7704 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7705 ExprAnalysisErrorCode ErrorFound = NoError; 7706 SourceLocation ErrorLoc, NoteLoc; 7707 SourceRange ErrorRange, NoteRange; 7708 // Allowed constructs are: 7709 // x = x binop expr; 7710 // x = expr binop x; 7711 if (AtomicBinOp->getOpcode() == BO_Assign) { 7712 X = AtomicBinOp->getLHS(); 7713 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7714 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7715 if (AtomicInnerBinOp->isMultiplicativeOp() || 7716 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7717 AtomicInnerBinOp->isBitwiseOp()) { 7718 Op = AtomicInnerBinOp->getOpcode(); 7719 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7720 Expr *LHS = AtomicInnerBinOp->getLHS(); 7721 Expr *RHS = AtomicInnerBinOp->getRHS(); 7722 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7723 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7724 /*Canonical=*/true); 7725 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7726 /*Canonical=*/true); 7727 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7728 /*Canonical=*/true); 7729 if (XId == LHSId) { 7730 E = RHS; 7731 IsXLHSInRHSPart = true; 7732 } else if (XId == RHSId) { 7733 E = LHS; 7734 IsXLHSInRHSPart = false; 7735 } else { 7736 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7737 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7738 NoteLoc = X->getExprLoc(); 7739 NoteRange = X->getSourceRange(); 7740 ErrorFound = NotAnUpdateExpression; 7741 } 7742 } else { 7743 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7744 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7745 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7746 NoteRange = SourceRange(NoteLoc, NoteLoc); 7747 ErrorFound = NotABinaryOperator; 7748 } 7749 } else { 7750 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7751 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7752 ErrorFound = NotABinaryExpression; 7753 } 7754 } else { 7755 ErrorLoc = AtomicBinOp->getExprLoc(); 7756 ErrorRange = AtomicBinOp->getSourceRange(); 7757 NoteLoc = AtomicBinOp->getOperatorLoc(); 7758 NoteRange = SourceRange(NoteLoc, NoteLoc); 7759 ErrorFound = NotAnAssignmentOp; 7760 } 7761 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7762 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7763 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7764 return true; 7765 } 7766 if (SemaRef.CurContext->isDependentContext()) 7767 E = X = UpdateExpr = nullptr; 7768 return ErrorFound != NoError; 7769 } 7770 7771 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7772 unsigned NoteId) { 7773 ExprAnalysisErrorCode ErrorFound = NoError; 7774 SourceLocation ErrorLoc, NoteLoc; 7775 SourceRange ErrorRange, NoteRange; 7776 // Allowed constructs are: 7777 // x++; 7778 // x--; 7779 // ++x; 7780 // --x; 7781 // x binop= expr; 7782 // x = x binop expr; 7783 // x = expr binop x; 7784 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7785 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7786 if (AtomicBody->getType()->isScalarType() || 7787 AtomicBody->isInstantiationDependent()) { 7788 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7789 AtomicBody->IgnoreParenImpCasts())) { 7790 // Check for Compound Assignment Operation 7791 Op = BinaryOperator::getOpForCompoundAssignment( 7792 AtomicCompAssignOp->getOpcode()); 7793 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7794 E = AtomicCompAssignOp->getRHS(); 7795 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7796 IsXLHSInRHSPart = true; 7797 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7798 AtomicBody->IgnoreParenImpCasts())) { 7799 // Check for Binary Operation 7800 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7801 return true; 7802 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7803 AtomicBody->IgnoreParenImpCasts())) { 7804 // Check for Unary Operation 7805 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7806 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7807 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7808 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7809 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 7810 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 7811 IsXLHSInRHSPart = true; 7812 } else { 7813 ErrorFound = NotAnUnaryIncDecExpression; 7814 ErrorLoc = AtomicUnaryOp->getExprLoc(); 7815 ErrorRange = AtomicUnaryOp->getSourceRange(); 7816 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 7817 NoteRange = SourceRange(NoteLoc, NoteLoc); 7818 } 7819 } else if (!AtomicBody->isInstantiationDependent()) { 7820 ErrorFound = NotABinaryOrUnaryExpression; 7821 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 7822 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 7823 } 7824 } else { 7825 ErrorFound = NotAScalarType; 7826 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 7827 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7828 } 7829 } else { 7830 ErrorFound = NotAnExpression; 7831 NoteLoc = ErrorLoc = S->getBeginLoc(); 7832 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7833 } 7834 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7835 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7836 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7837 return true; 7838 } 7839 if (SemaRef.CurContext->isDependentContext()) 7840 E = X = UpdateExpr = nullptr; 7841 if (ErrorFound == NoError && E && X) { 7842 // Build an update expression of form 'OpaqueValueExpr(x) binop 7843 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 7844 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 7845 auto *OVEX = new (SemaRef.getASTContext()) 7846 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 7847 auto *OVEExpr = new (SemaRef.getASTContext()) 7848 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 7849 ExprResult Update = 7850 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 7851 IsXLHSInRHSPart ? OVEExpr : OVEX); 7852 if (Update.isInvalid()) 7853 return true; 7854 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 7855 Sema::AA_Casting); 7856 if (Update.isInvalid()) 7857 return true; 7858 UpdateExpr = Update.get(); 7859 } 7860 return ErrorFound != NoError; 7861 } 7862 7863 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 7864 Stmt *AStmt, 7865 SourceLocation StartLoc, 7866 SourceLocation EndLoc) { 7867 if (!AStmt) 7868 return StmtError(); 7869 7870 auto *CS = cast<CapturedStmt>(AStmt); 7871 // 1.2.2 OpenMP Language Terminology 7872 // Structured block - An executable statement with a single entry at the 7873 // top and a single exit at the bottom. 7874 // The point of exit cannot be a branch out of the structured block. 7875 // longjmp() and throw() must not violate the entry/exit criteria. 7876 OpenMPClauseKind AtomicKind = OMPC_unknown; 7877 SourceLocation AtomicKindLoc; 7878 for (const OMPClause *C : Clauses) { 7879 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 7880 C->getClauseKind() == OMPC_update || 7881 C->getClauseKind() == OMPC_capture) { 7882 if (AtomicKind != OMPC_unknown) { 7883 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 7884 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 7885 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 7886 << getOpenMPClauseName(AtomicKind); 7887 } else { 7888 AtomicKind = C->getClauseKind(); 7889 AtomicKindLoc = C->getBeginLoc(); 7890 } 7891 } 7892 } 7893 7894 Stmt *Body = CS->getCapturedStmt(); 7895 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 7896 Body = EWC->getSubExpr(); 7897 7898 Expr *X = nullptr; 7899 Expr *V = nullptr; 7900 Expr *E = nullptr; 7901 Expr *UE = nullptr; 7902 bool IsXLHSInRHSPart = false; 7903 bool IsPostfixUpdate = false; 7904 // OpenMP [2.12.6, atomic Construct] 7905 // In the next expressions: 7906 // * x and v (as applicable) are both l-value expressions with scalar type. 7907 // * During the execution of an atomic region, multiple syntactic 7908 // occurrences of x must designate the same storage location. 7909 // * Neither of v and expr (as applicable) may access the storage location 7910 // designated by x. 7911 // * Neither of x and expr (as applicable) may access the storage location 7912 // designated by v. 7913 // * expr is an expression with scalar type. 7914 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 7915 // * binop, binop=, ++, and -- are not overloaded operators. 7916 // * The expression x binop expr must be numerically equivalent to x binop 7917 // (expr). This requirement is satisfied if the operators in expr have 7918 // precedence greater than binop, or by using parentheses around expr or 7919 // subexpressions of expr. 7920 // * The expression expr binop x must be numerically equivalent to (expr) 7921 // binop x. This requirement is satisfied if the operators in expr have 7922 // precedence equal to or greater than binop, or by using parentheses around 7923 // expr or subexpressions of expr. 7924 // * For forms that allow multiple occurrences of x, the number of times 7925 // that x is evaluated is unspecified. 7926 if (AtomicKind == OMPC_read) { 7927 enum { 7928 NotAnExpression, 7929 NotAnAssignmentOp, 7930 NotAScalarType, 7931 NotAnLValue, 7932 NoError 7933 } ErrorFound = NoError; 7934 SourceLocation ErrorLoc, NoteLoc; 7935 SourceRange ErrorRange, NoteRange; 7936 // If clause is read: 7937 // v = x; 7938 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7939 const auto *AtomicBinOp = 7940 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7941 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7942 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7943 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 7944 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7945 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 7946 if (!X->isLValue() || !V->isLValue()) { 7947 const Expr *NotLValueExpr = X->isLValue() ? V : X; 7948 ErrorFound = NotAnLValue; 7949 ErrorLoc = AtomicBinOp->getExprLoc(); 7950 ErrorRange = AtomicBinOp->getSourceRange(); 7951 NoteLoc = NotLValueExpr->getExprLoc(); 7952 NoteRange = NotLValueExpr->getSourceRange(); 7953 } 7954 } else if (!X->isInstantiationDependent() || 7955 !V->isInstantiationDependent()) { 7956 const Expr *NotScalarExpr = 7957 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7958 ? V 7959 : X; 7960 ErrorFound = NotAScalarType; 7961 ErrorLoc = AtomicBinOp->getExprLoc(); 7962 ErrorRange = AtomicBinOp->getSourceRange(); 7963 NoteLoc = NotScalarExpr->getExprLoc(); 7964 NoteRange = NotScalarExpr->getSourceRange(); 7965 } 7966 } else if (!AtomicBody->isInstantiationDependent()) { 7967 ErrorFound = NotAnAssignmentOp; 7968 ErrorLoc = AtomicBody->getExprLoc(); 7969 ErrorRange = AtomicBody->getSourceRange(); 7970 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7971 : AtomicBody->getExprLoc(); 7972 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7973 : AtomicBody->getSourceRange(); 7974 } 7975 } else { 7976 ErrorFound = NotAnExpression; 7977 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7978 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7979 } 7980 if (ErrorFound != NoError) { 7981 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7982 << ErrorRange; 7983 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7984 << NoteRange; 7985 return StmtError(); 7986 } 7987 if (CurContext->isDependentContext()) 7988 V = X = nullptr; 7989 } else if (AtomicKind == OMPC_write) { 7990 enum { 7991 NotAnExpression, 7992 NotAnAssignmentOp, 7993 NotAScalarType, 7994 NotAnLValue, 7995 NoError 7996 } ErrorFound = NoError; 7997 SourceLocation ErrorLoc, NoteLoc; 7998 SourceRange ErrorRange, NoteRange; 7999 // If clause is write: 8000 // x = expr; 8001 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8002 const auto *AtomicBinOp = 8003 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8004 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8005 X = AtomicBinOp->getLHS(); 8006 E = AtomicBinOp->getRHS(); 8007 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8008 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8009 if (!X->isLValue()) { 8010 ErrorFound = NotAnLValue; 8011 ErrorLoc = AtomicBinOp->getExprLoc(); 8012 ErrorRange = AtomicBinOp->getSourceRange(); 8013 NoteLoc = X->getExprLoc(); 8014 NoteRange = X->getSourceRange(); 8015 } 8016 } else if (!X->isInstantiationDependent() || 8017 !E->isInstantiationDependent()) { 8018 const Expr *NotScalarExpr = 8019 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8020 ? E 8021 : X; 8022 ErrorFound = NotAScalarType; 8023 ErrorLoc = AtomicBinOp->getExprLoc(); 8024 ErrorRange = AtomicBinOp->getSourceRange(); 8025 NoteLoc = NotScalarExpr->getExprLoc(); 8026 NoteRange = NotScalarExpr->getSourceRange(); 8027 } 8028 } else if (!AtomicBody->isInstantiationDependent()) { 8029 ErrorFound = NotAnAssignmentOp; 8030 ErrorLoc = AtomicBody->getExprLoc(); 8031 ErrorRange = AtomicBody->getSourceRange(); 8032 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8033 : AtomicBody->getExprLoc(); 8034 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8035 : AtomicBody->getSourceRange(); 8036 } 8037 } else { 8038 ErrorFound = NotAnExpression; 8039 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8040 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8041 } 8042 if (ErrorFound != NoError) { 8043 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8044 << ErrorRange; 8045 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8046 << NoteRange; 8047 return StmtError(); 8048 } 8049 if (CurContext->isDependentContext()) 8050 E = X = nullptr; 8051 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8052 // If clause is update: 8053 // x++; 8054 // x--; 8055 // ++x; 8056 // --x; 8057 // x binop= expr; 8058 // x = x binop expr; 8059 // x = expr binop x; 8060 OpenMPAtomicUpdateChecker Checker(*this); 8061 if (Checker.checkStatement( 8062 Body, (AtomicKind == OMPC_update) 8063 ? diag::err_omp_atomic_update_not_expression_statement 8064 : diag::err_omp_atomic_not_expression_statement, 8065 diag::note_omp_atomic_update)) 8066 return StmtError(); 8067 if (!CurContext->isDependentContext()) { 8068 E = Checker.getExpr(); 8069 X = Checker.getX(); 8070 UE = Checker.getUpdateExpr(); 8071 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8072 } 8073 } else if (AtomicKind == OMPC_capture) { 8074 enum { 8075 NotAnAssignmentOp, 8076 NotACompoundStatement, 8077 NotTwoSubstatements, 8078 NotASpecificExpression, 8079 NoError 8080 } ErrorFound = NoError; 8081 SourceLocation ErrorLoc, NoteLoc; 8082 SourceRange ErrorRange, NoteRange; 8083 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8084 // If clause is a capture: 8085 // v = x++; 8086 // v = x--; 8087 // v = ++x; 8088 // v = --x; 8089 // v = x binop= expr; 8090 // v = x = x binop expr; 8091 // v = x = expr binop x; 8092 const auto *AtomicBinOp = 8093 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8094 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8095 V = AtomicBinOp->getLHS(); 8096 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8097 OpenMPAtomicUpdateChecker Checker(*this); 8098 if (Checker.checkStatement( 8099 Body, diag::err_omp_atomic_capture_not_expression_statement, 8100 diag::note_omp_atomic_update)) 8101 return StmtError(); 8102 E = Checker.getExpr(); 8103 X = Checker.getX(); 8104 UE = Checker.getUpdateExpr(); 8105 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8106 IsPostfixUpdate = Checker.isPostfixUpdate(); 8107 } else if (!AtomicBody->isInstantiationDependent()) { 8108 ErrorLoc = AtomicBody->getExprLoc(); 8109 ErrorRange = AtomicBody->getSourceRange(); 8110 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8111 : AtomicBody->getExprLoc(); 8112 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8113 : AtomicBody->getSourceRange(); 8114 ErrorFound = NotAnAssignmentOp; 8115 } 8116 if (ErrorFound != NoError) { 8117 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8118 << ErrorRange; 8119 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8120 return StmtError(); 8121 } 8122 if (CurContext->isDependentContext()) 8123 UE = V = E = X = nullptr; 8124 } else { 8125 // If clause is a capture: 8126 // { v = x; x = expr; } 8127 // { v = x; x++; } 8128 // { v = x; x--; } 8129 // { v = x; ++x; } 8130 // { v = x; --x; } 8131 // { v = x; x binop= expr; } 8132 // { v = x; x = x binop expr; } 8133 // { v = x; x = expr binop x; } 8134 // { x++; v = x; } 8135 // { x--; v = x; } 8136 // { ++x; v = x; } 8137 // { --x; v = x; } 8138 // { x binop= expr; v = x; } 8139 // { x = x binop expr; v = x; } 8140 // { x = expr binop x; v = x; } 8141 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8142 // Check that this is { expr1; expr2; } 8143 if (CS->size() == 2) { 8144 Stmt *First = CS->body_front(); 8145 Stmt *Second = CS->body_back(); 8146 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8147 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8148 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8149 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8150 // Need to find what subexpression is 'v' and what is 'x'. 8151 OpenMPAtomicUpdateChecker Checker(*this); 8152 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8153 BinaryOperator *BinOp = nullptr; 8154 if (IsUpdateExprFound) { 8155 BinOp = dyn_cast<BinaryOperator>(First); 8156 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8157 } 8158 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8159 // { v = x; x++; } 8160 // { v = x; x--; } 8161 // { v = x; ++x; } 8162 // { v = x; --x; } 8163 // { v = x; x binop= expr; } 8164 // { v = x; x = x binop expr; } 8165 // { v = x; x = expr binop x; } 8166 // Check that the first expression has form v = x. 8167 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8168 llvm::FoldingSetNodeID XId, PossibleXId; 8169 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8170 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8171 IsUpdateExprFound = XId == PossibleXId; 8172 if (IsUpdateExprFound) { 8173 V = BinOp->getLHS(); 8174 X = Checker.getX(); 8175 E = Checker.getExpr(); 8176 UE = Checker.getUpdateExpr(); 8177 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8178 IsPostfixUpdate = true; 8179 } 8180 } 8181 if (!IsUpdateExprFound) { 8182 IsUpdateExprFound = !Checker.checkStatement(First); 8183 BinOp = nullptr; 8184 if (IsUpdateExprFound) { 8185 BinOp = dyn_cast<BinaryOperator>(Second); 8186 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8187 } 8188 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8189 // { x++; v = x; } 8190 // { x--; v = x; } 8191 // { ++x; v = x; } 8192 // { --x; v = x; } 8193 // { x binop= expr; v = x; } 8194 // { x = x binop expr; v = x; } 8195 // { x = expr binop x; v = x; } 8196 // Check that the second expression has form v = x. 8197 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8198 llvm::FoldingSetNodeID XId, PossibleXId; 8199 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8200 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8201 IsUpdateExprFound = XId == PossibleXId; 8202 if (IsUpdateExprFound) { 8203 V = BinOp->getLHS(); 8204 X = Checker.getX(); 8205 E = Checker.getExpr(); 8206 UE = Checker.getUpdateExpr(); 8207 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8208 IsPostfixUpdate = false; 8209 } 8210 } 8211 } 8212 if (!IsUpdateExprFound) { 8213 // { v = x; x = expr; } 8214 auto *FirstExpr = dyn_cast<Expr>(First); 8215 auto *SecondExpr = dyn_cast<Expr>(Second); 8216 if (!FirstExpr || !SecondExpr || 8217 !(FirstExpr->isInstantiationDependent() || 8218 SecondExpr->isInstantiationDependent())) { 8219 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8220 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8221 ErrorFound = NotAnAssignmentOp; 8222 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8223 : First->getBeginLoc(); 8224 NoteRange = ErrorRange = FirstBinOp 8225 ? FirstBinOp->getSourceRange() 8226 : SourceRange(ErrorLoc, ErrorLoc); 8227 } else { 8228 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8229 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8230 ErrorFound = NotAnAssignmentOp; 8231 NoteLoc = ErrorLoc = SecondBinOp 8232 ? SecondBinOp->getOperatorLoc() 8233 : Second->getBeginLoc(); 8234 NoteRange = ErrorRange = 8235 SecondBinOp ? SecondBinOp->getSourceRange() 8236 : SourceRange(ErrorLoc, ErrorLoc); 8237 } else { 8238 Expr *PossibleXRHSInFirst = 8239 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8240 Expr *PossibleXLHSInSecond = 8241 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8242 llvm::FoldingSetNodeID X1Id, X2Id; 8243 PossibleXRHSInFirst->Profile(X1Id, Context, 8244 /*Canonical=*/true); 8245 PossibleXLHSInSecond->Profile(X2Id, Context, 8246 /*Canonical=*/true); 8247 IsUpdateExprFound = X1Id == X2Id; 8248 if (IsUpdateExprFound) { 8249 V = FirstBinOp->getLHS(); 8250 X = SecondBinOp->getLHS(); 8251 E = SecondBinOp->getRHS(); 8252 UE = nullptr; 8253 IsXLHSInRHSPart = false; 8254 IsPostfixUpdate = true; 8255 } else { 8256 ErrorFound = NotASpecificExpression; 8257 ErrorLoc = FirstBinOp->getExprLoc(); 8258 ErrorRange = FirstBinOp->getSourceRange(); 8259 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8260 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8261 } 8262 } 8263 } 8264 } 8265 } 8266 } else { 8267 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8268 NoteRange = ErrorRange = 8269 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8270 ErrorFound = NotTwoSubstatements; 8271 } 8272 } else { 8273 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8274 NoteRange = ErrorRange = 8275 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8276 ErrorFound = NotACompoundStatement; 8277 } 8278 if (ErrorFound != NoError) { 8279 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8280 << ErrorRange; 8281 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8282 return StmtError(); 8283 } 8284 if (CurContext->isDependentContext()) 8285 UE = V = E = X = nullptr; 8286 } 8287 } 8288 8289 setFunctionHasBranchProtectedScope(); 8290 8291 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8292 X, V, E, UE, IsXLHSInRHSPart, 8293 IsPostfixUpdate); 8294 } 8295 8296 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8297 Stmt *AStmt, 8298 SourceLocation StartLoc, 8299 SourceLocation EndLoc) { 8300 if (!AStmt) 8301 return StmtError(); 8302 8303 auto *CS = cast<CapturedStmt>(AStmt); 8304 // 1.2.2 OpenMP Language Terminology 8305 // Structured block - An executable statement with a single entry at the 8306 // top and a single exit at the bottom. 8307 // The point of exit cannot be a branch out of the structured block. 8308 // longjmp() and throw() must not violate the entry/exit criteria. 8309 CS->getCapturedDecl()->setNothrow(); 8310 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8311 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8312 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8313 // 1.2.2 OpenMP Language Terminology 8314 // Structured block - An executable statement with a single entry at the 8315 // top and a single exit at the bottom. 8316 // The point of exit cannot be a branch out of the structured block. 8317 // longjmp() and throw() must not violate the entry/exit criteria. 8318 CS->getCapturedDecl()->setNothrow(); 8319 } 8320 8321 // OpenMP [2.16, Nesting of Regions] 8322 // If specified, a teams construct must be contained within a target 8323 // construct. That target construct must contain no statements or directives 8324 // outside of the teams construct. 8325 if (DSAStack->hasInnerTeamsRegion()) { 8326 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8327 bool OMPTeamsFound = true; 8328 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8329 auto I = CS->body_begin(); 8330 while (I != CS->body_end()) { 8331 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8332 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8333 OMPTeamsFound) { 8334 8335 OMPTeamsFound = false; 8336 break; 8337 } 8338 ++I; 8339 } 8340 assert(I != CS->body_end() && "Not found statement"); 8341 S = *I; 8342 } else { 8343 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8344 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8345 } 8346 if (!OMPTeamsFound) { 8347 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8348 Diag(DSAStack->getInnerTeamsRegionLoc(), 8349 diag::note_omp_nested_teams_construct_here); 8350 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8351 << isa<OMPExecutableDirective>(S); 8352 return StmtError(); 8353 } 8354 } 8355 8356 setFunctionHasBranchProtectedScope(); 8357 8358 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8359 } 8360 8361 StmtResult 8362 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8363 Stmt *AStmt, SourceLocation StartLoc, 8364 SourceLocation EndLoc) { 8365 if (!AStmt) 8366 return StmtError(); 8367 8368 auto *CS = cast<CapturedStmt>(AStmt); 8369 // 1.2.2 OpenMP Language Terminology 8370 // Structured block - An executable statement with a single entry at the 8371 // top and a single exit at the bottom. 8372 // The point of exit cannot be a branch out of the structured block. 8373 // longjmp() and throw() must not violate the entry/exit criteria. 8374 CS->getCapturedDecl()->setNothrow(); 8375 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8376 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8377 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8378 // 1.2.2 OpenMP Language Terminology 8379 // Structured block - An executable statement with a single entry at the 8380 // top and a single exit at the bottom. 8381 // The point of exit cannot be a branch out of the structured block. 8382 // longjmp() and throw() must not violate the entry/exit criteria. 8383 CS->getCapturedDecl()->setNothrow(); 8384 } 8385 8386 setFunctionHasBranchProtectedScope(); 8387 8388 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8389 AStmt); 8390 } 8391 8392 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8393 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8394 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8395 if (!AStmt) 8396 return StmtError(); 8397 8398 auto *CS = cast<CapturedStmt>(AStmt); 8399 // 1.2.2 OpenMP Language Terminology 8400 // Structured block - An executable statement with a single entry at the 8401 // top and a single exit at the bottom. 8402 // The point of exit cannot be a branch out of the structured block. 8403 // longjmp() and throw() must not violate the entry/exit criteria. 8404 CS->getCapturedDecl()->setNothrow(); 8405 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8406 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8407 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8408 // 1.2.2 OpenMP Language Terminology 8409 // Structured block - An executable statement with a single entry at the 8410 // top and a single exit at the bottom. 8411 // The point of exit cannot be a branch out of the structured block. 8412 // longjmp() and throw() must not violate the entry/exit criteria. 8413 CS->getCapturedDecl()->setNothrow(); 8414 } 8415 8416 OMPLoopDirective::HelperExprs B; 8417 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8418 // define the nested loops number. 8419 unsigned NestedLoopCount = 8420 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8421 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8422 VarsWithImplicitDSA, B); 8423 if (NestedLoopCount == 0) 8424 return StmtError(); 8425 8426 assert((CurContext->isDependentContext() || B.builtAll()) && 8427 "omp target parallel for loop exprs were not built"); 8428 8429 if (!CurContext->isDependentContext()) { 8430 // Finalize the clauses that need pre-built expressions for CodeGen. 8431 for (OMPClause *C : Clauses) { 8432 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8433 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8434 B.NumIterations, *this, CurScope, 8435 DSAStack)) 8436 return StmtError(); 8437 } 8438 } 8439 8440 setFunctionHasBranchProtectedScope(); 8441 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8442 NestedLoopCount, Clauses, AStmt, 8443 B, DSAStack->isCancelRegion()); 8444 } 8445 8446 /// Check for existence of a map clause in the list of clauses. 8447 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8448 const OpenMPClauseKind K) { 8449 return llvm::any_of( 8450 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8451 } 8452 8453 template <typename... Params> 8454 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8455 const Params... ClauseTypes) { 8456 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8457 } 8458 8459 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8460 Stmt *AStmt, 8461 SourceLocation StartLoc, 8462 SourceLocation EndLoc) { 8463 if (!AStmt) 8464 return StmtError(); 8465 8466 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8467 8468 // OpenMP [2.10.1, Restrictions, p. 97] 8469 // At least one map clause must appear on the directive. 8470 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8471 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8472 << "'map' or 'use_device_ptr'" 8473 << getOpenMPDirectiveName(OMPD_target_data); 8474 return StmtError(); 8475 } 8476 8477 setFunctionHasBranchProtectedScope(); 8478 8479 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8480 AStmt); 8481 } 8482 8483 StmtResult 8484 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8485 SourceLocation StartLoc, 8486 SourceLocation EndLoc, Stmt *AStmt) { 8487 if (!AStmt) 8488 return StmtError(); 8489 8490 auto *CS = cast<CapturedStmt>(AStmt); 8491 // 1.2.2 OpenMP Language Terminology 8492 // Structured block - An executable statement with a single entry at the 8493 // top and a single exit at the bottom. 8494 // The point of exit cannot be a branch out of the structured block. 8495 // longjmp() and throw() must not violate the entry/exit criteria. 8496 CS->getCapturedDecl()->setNothrow(); 8497 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8498 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8499 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8500 // 1.2.2 OpenMP Language Terminology 8501 // Structured block - An executable statement with a single entry at the 8502 // top and a single exit at the bottom. 8503 // The point of exit cannot be a branch out of the structured block. 8504 // longjmp() and throw() must not violate the entry/exit criteria. 8505 CS->getCapturedDecl()->setNothrow(); 8506 } 8507 8508 // OpenMP [2.10.2, Restrictions, p. 99] 8509 // At least one map clause must appear on the directive. 8510 if (!hasClauses(Clauses, OMPC_map)) { 8511 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8512 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8513 return StmtError(); 8514 } 8515 8516 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8517 AStmt); 8518 } 8519 8520 StmtResult 8521 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8522 SourceLocation StartLoc, 8523 SourceLocation EndLoc, Stmt *AStmt) { 8524 if (!AStmt) 8525 return StmtError(); 8526 8527 auto *CS = cast<CapturedStmt>(AStmt); 8528 // 1.2.2 OpenMP Language Terminology 8529 // Structured block - An executable statement with a single entry at the 8530 // top and a single exit at the bottom. 8531 // The point of exit cannot be a branch out of the structured block. 8532 // longjmp() and throw() must not violate the entry/exit criteria. 8533 CS->getCapturedDecl()->setNothrow(); 8534 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8535 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8536 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8537 // 1.2.2 OpenMP Language Terminology 8538 // Structured block - An executable statement with a single entry at the 8539 // top and a single exit at the bottom. 8540 // The point of exit cannot be a branch out of the structured block. 8541 // longjmp() and throw() must not violate the entry/exit criteria. 8542 CS->getCapturedDecl()->setNothrow(); 8543 } 8544 8545 // OpenMP [2.10.3, Restrictions, p. 102] 8546 // At least one map clause must appear on the directive. 8547 if (!hasClauses(Clauses, OMPC_map)) { 8548 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8549 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8550 return StmtError(); 8551 } 8552 8553 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8554 AStmt); 8555 } 8556 8557 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8558 SourceLocation StartLoc, 8559 SourceLocation EndLoc, 8560 Stmt *AStmt) { 8561 if (!AStmt) 8562 return StmtError(); 8563 8564 auto *CS = cast<CapturedStmt>(AStmt); 8565 // 1.2.2 OpenMP Language Terminology 8566 // Structured block - An executable statement with a single entry at the 8567 // top and a single exit at the bottom. 8568 // The point of exit cannot be a branch out of the structured block. 8569 // longjmp() and throw() must not violate the entry/exit criteria. 8570 CS->getCapturedDecl()->setNothrow(); 8571 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8572 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8573 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8574 // 1.2.2 OpenMP Language Terminology 8575 // Structured block - An executable statement with a single entry at the 8576 // top and a single exit at the bottom. 8577 // The point of exit cannot be a branch out of the structured block. 8578 // longjmp() and throw() must not violate the entry/exit criteria. 8579 CS->getCapturedDecl()->setNothrow(); 8580 } 8581 8582 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8583 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8584 return StmtError(); 8585 } 8586 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8587 AStmt); 8588 } 8589 8590 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8591 Stmt *AStmt, SourceLocation StartLoc, 8592 SourceLocation EndLoc) { 8593 if (!AStmt) 8594 return StmtError(); 8595 8596 auto *CS = cast<CapturedStmt>(AStmt); 8597 // 1.2.2 OpenMP Language Terminology 8598 // Structured block - An executable statement with a single entry at the 8599 // top and a single exit at the bottom. 8600 // The point of exit cannot be a branch out of the structured block. 8601 // longjmp() and throw() must not violate the entry/exit criteria. 8602 CS->getCapturedDecl()->setNothrow(); 8603 8604 setFunctionHasBranchProtectedScope(); 8605 8606 DSAStack->setParentTeamsRegionLoc(StartLoc); 8607 8608 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8609 } 8610 8611 StmtResult 8612 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8613 SourceLocation EndLoc, 8614 OpenMPDirectiveKind CancelRegion) { 8615 if (DSAStack->isParentNowaitRegion()) { 8616 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8617 return StmtError(); 8618 } 8619 if (DSAStack->isParentOrderedRegion()) { 8620 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8621 return StmtError(); 8622 } 8623 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8624 CancelRegion); 8625 } 8626 8627 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8628 SourceLocation StartLoc, 8629 SourceLocation EndLoc, 8630 OpenMPDirectiveKind CancelRegion) { 8631 if (DSAStack->isParentNowaitRegion()) { 8632 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8633 return StmtError(); 8634 } 8635 if (DSAStack->isParentOrderedRegion()) { 8636 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8637 return StmtError(); 8638 } 8639 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8640 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8641 CancelRegion); 8642 } 8643 8644 static bool checkGrainsizeNumTasksClauses(Sema &S, 8645 ArrayRef<OMPClause *> Clauses) { 8646 const OMPClause *PrevClause = nullptr; 8647 bool ErrorFound = false; 8648 for (const OMPClause *C : Clauses) { 8649 if (C->getClauseKind() == OMPC_grainsize || 8650 C->getClauseKind() == OMPC_num_tasks) { 8651 if (!PrevClause) 8652 PrevClause = C; 8653 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8654 S.Diag(C->getBeginLoc(), 8655 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8656 << getOpenMPClauseName(C->getClauseKind()) 8657 << getOpenMPClauseName(PrevClause->getClauseKind()); 8658 S.Diag(PrevClause->getBeginLoc(), 8659 diag::note_omp_previous_grainsize_num_tasks) 8660 << getOpenMPClauseName(PrevClause->getClauseKind()); 8661 ErrorFound = true; 8662 } 8663 } 8664 } 8665 return ErrorFound; 8666 } 8667 8668 static bool checkReductionClauseWithNogroup(Sema &S, 8669 ArrayRef<OMPClause *> Clauses) { 8670 const OMPClause *ReductionClause = nullptr; 8671 const OMPClause *NogroupClause = nullptr; 8672 for (const OMPClause *C : Clauses) { 8673 if (C->getClauseKind() == OMPC_reduction) { 8674 ReductionClause = C; 8675 if (NogroupClause) 8676 break; 8677 continue; 8678 } 8679 if (C->getClauseKind() == OMPC_nogroup) { 8680 NogroupClause = C; 8681 if (ReductionClause) 8682 break; 8683 continue; 8684 } 8685 } 8686 if (ReductionClause && NogroupClause) { 8687 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8688 << SourceRange(NogroupClause->getBeginLoc(), 8689 NogroupClause->getEndLoc()); 8690 return true; 8691 } 8692 return false; 8693 } 8694 8695 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8696 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8697 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8698 if (!AStmt) 8699 return StmtError(); 8700 8701 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8702 OMPLoopDirective::HelperExprs B; 8703 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8704 // define the nested loops number. 8705 unsigned NestedLoopCount = 8706 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8707 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8708 VarsWithImplicitDSA, B); 8709 if (NestedLoopCount == 0) 8710 return StmtError(); 8711 8712 assert((CurContext->isDependentContext() || B.builtAll()) && 8713 "omp for loop exprs were not built"); 8714 8715 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8716 // The grainsize clause and num_tasks clause are mutually exclusive and may 8717 // not appear on the same taskloop directive. 8718 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8719 return StmtError(); 8720 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8721 // If a reduction clause is present on the taskloop directive, the nogroup 8722 // clause must not be specified. 8723 if (checkReductionClauseWithNogroup(*this, Clauses)) 8724 return StmtError(); 8725 8726 setFunctionHasBranchProtectedScope(); 8727 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8728 NestedLoopCount, Clauses, AStmt, B); 8729 } 8730 8731 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8732 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8733 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8734 if (!AStmt) 8735 return StmtError(); 8736 8737 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8738 OMPLoopDirective::HelperExprs B; 8739 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8740 // define the nested loops number. 8741 unsigned NestedLoopCount = 8742 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8743 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8744 VarsWithImplicitDSA, B); 8745 if (NestedLoopCount == 0) 8746 return StmtError(); 8747 8748 assert((CurContext->isDependentContext() || B.builtAll()) && 8749 "omp for loop exprs were not built"); 8750 8751 if (!CurContext->isDependentContext()) { 8752 // Finalize the clauses that need pre-built expressions for CodeGen. 8753 for (OMPClause *C : Clauses) { 8754 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8755 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8756 B.NumIterations, *this, CurScope, 8757 DSAStack)) 8758 return StmtError(); 8759 } 8760 } 8761 8762 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8763 // The grainsize clause and num_tasks clause are mutually exclusive and may 8764 // not appear on the same taskloop directive. 8765 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8766 return StmtError(); 8767 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8768 // If a reduction clause is present on the taskloop directive, the nogroup 8769 // clause must not be specified. 8770 if (checkReductionClauseWithNogroup(*this, Clauses)) 8771 return StmtError(); 8772 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8773 return StmtError(); 8774 8775 setFunctionHasBranchProtectedScope(); 8776 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8777 NestedLoopCount, Clauses, AStmt, B); 8778 } 8779 8780 StmtResult Sema::ActOnOpenMPDistributeDirective( 8781 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8782 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8783 if (!AStmt) 8784 return StmtError(); 8785 8786 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8787 OMPLoopDirective::HelperExprs B; 8788 // In presence of clause 'collapse' with number of loops, it will 8789 // define the nested loops number. 8790 unsigned NestedLoopCount = 8791 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8792 nullptr /*ordered not a clause on distribute*/, AStmt, 8793 *this, *DSAStack, VarsWithImplicitDSA, B); 8794 if (NestedLoopCount == 0) 8795 return StmtError(); 8796 8797 assert((CurContext->isDependentContext() || B.builtAll()) && 8798 "omp for loop exprs were not built"); 8799 8800 setFunctionHasBranchProtectedScope(); 8801 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8802 NestedLoopCount, Clauses, AStmt, B); 8803 } 8804 8805 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8806 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8807 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8808 if (!AStmt) 8809 return StmtError(); 8810 8811 auto *CS = cast<CapturedStmt>(AStmt); 8812 // 1.2.2 OpenMP Language Terminology 8813 // Structured block - An executable statement with a single entry at the 8814 // top and a single exit at the bottom. 8815 // The point of exit cannot be a branch out of the structured block. 8816 // longjmp() and throw() must not violate the entry/exit criteria. 8817 CS->getCapturedDecl()->setNothrow(); 8818 for (int ThisCaptureLevel = 8819 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 8820 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8821 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8822 // 1.2.2 OpenMP Language Terminology 8823 // Structured block - An executable statement with a single entry at the 8824 // top and a single exit at the bottom. 8825 // The point of exit cannot be a branch out of the structured block. 8826 // longjmp() and throw() must not violate the entry/exit criteria. 8827 CS->getCapturedDecl()->setNothrow(); 8828 } 8829 8830 OMPLoopDirective::HelperExprs B; 8831 // In presence of clause 'collapse' with number of loops, it will 8832 // define the nested loops number. 8833 unsigned NestedLoopCount = checkOpenMPLoop( 8834 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8835 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8836 VarsWithImplicitDSA, B); 8837 if (NestedLoopCount == 0) 8838 return StmtError(); 8839 8840 assert((CurContext->isDependentContext() || B.builtAll()) && 8841 "omp for loop exprs were not built"); 8842 8843 setFunctionHasBranchProtectedScope(); 8844 return OMPDistributeParallelForDirective::Create( 8845 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8846 DSAStack->isCancelRegion()); 8847 } 8848 8849 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 8850 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8851 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8852 if (!AStmt) 8853 return StmtError(); 8854 8855 auto *CS = cast<CapturedStmt>(AStmt); 8856 // 1.2.2 OpenMP Language Terminology 8857 // Structured block - An executable statement with a single entry at the 8858 // top and a single exit at the bottom. 8859 // The point of exit cannot be a branch out of the structured block. 8860 // longjmp() and throw() must not violate the entry/exit criteria. 8861 CS->getCapturedDecl()->setNothrow(); 8862 for (int ThisCaptureLevel = 8863 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 8864 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8865 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8866 // 1.2.2 OpenMP Language Terminology 8867 // Structured block - An executable statement with a single entry at the 8868 // top and a single exit at the bottom. 8869 // The point of exit cannot be a branch out of the structured block. 8870 // longjmp() and throw() must not violate the entry/exit criteria. 8871 CS->getCapturedDecl()->setNothrow(); 8872 } 8873 8874 OMPLoopDirective::HelperExprs B; 8875 // In presence of clause 'collapse' with number of loops, it will 8876 // define the nested loops number. 8877 unsigned NestedLoopCount = checkOpenMPLoop( 8878 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8879 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8880 VarsWithImplicitDSA, B); 8881 if (NestedLoopCount == 0) 8882 return StmtError(); 8883 8884 assert((CurContext->isDependentContext() || B.builtAll()) && 8885 "omp for loop exprs were not built"); 8886 8887 if (!CurContext->isDependentContext()) { 8888 // Finalize the clauses that need pre-built expressions for CodeGen. 8889 for (OMPClause *C : Clauses) { 8890 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8891 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8892 B.NumIterations, *this, CurScope, 8893 DSAStack)) 8894 return StmtError(); 8895 } 8896 } 8897 8898 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8899 return StmtError(); 8900 8901 setFunctionHasBranchProtectedScope(); 8902 return OMPDistributeParallelForSimdDirective::Create( 8903 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8904 } 8905 8906 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 8907 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8908 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8909 if (!AStmt) 8910 return StmtError(); 8911 8912 auto *CS = cast<CapturedStmt>(AStmt); 8913 // 1.2.2 OpenMP Language Terminology 8914 // Structured block - An executable statement with a single entry at the 8915 // top and a single exit at the bottom. 8916 // The point of exit cannot be a branch out of the structured block. 8917 // longjmp() and throw() must not violate the entry/exit criteria. 8918 CS->getCapturedDecl()->setNothrow(); 8919 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 8920 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8921 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8922 // 1.2.2 OpenMP Language Terminology 8923 // Structured block - An executable statement with a single entry at the 8924 // top and a single exit at the bottom. 8925 // The point of exit cannot be a branch out of the structured block. 8926 // longjmp() and throw() must not violate the entry/exit criteria. 8927 CS->getCapturedDecl()->setNothrow(); 8928 } 8929 8930 OMPLoopDirective::HelperExprs B; 8931 // In presence of clause 'collapse' with number of loops, it will 8932 // define the nested loops number. 8933 unsigned NestedLoopCount = 8934 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 8935 nullptr /*ordered not a clause on distribute*/, CS, *this, 8936 *DSAStack, VarsWithImplicitDSA, B); 8937 if (NestedLoopCount == 0) 8938 return StmtError(); 8939 8940 assert((CurContext->isDependentContext() || B.builtAll()) && 8941 "omp for loop exprs were not built"); 8942 8943 if (!CurContext->isDependentContext()) { 8944 // Finalize the clauses that need pre-built expressions for CodeGen. 8945 for (OMPClause *C : Clauses) { 8946 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8947 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8948 B.NumIterations, *this, CurScope, 8949 DSAStack)) 8950 return StmtError(); 8951 } 8952 } 8953 8954 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8955 return StmtError(); 8956 8957 setFunctionHasBranchProtectedScope(); 8958 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 8959 NestedLoopCount, Clauses, AStmt, B); 8960 } 8961 8962 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 8963 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8964 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8965 if (!AStmt) 8966 return StmtError(); 8967 8968 auto *CS = cast<CapturedStmt>(AStmt); 8969 // 1.2.2 OpenMP Language Terminology 8970 // Structured block - An executable statement with a single entry at the 8971 // top and a single exit at the bottom. 8972 // The point of exit cannot be a branch out of the structured block. 8973 // longjmp() and throw() must not violate the entry/exit criteria. 8974 CS->getCapturedDecl()->setNothrow(); 8975 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8976 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8977 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8978 // 1.2.2 OpenMP Language Terminology 8979 // Structured block - An executable statement with a single entry at the 8980 // top and a single exit at the bottom. 8981 // The point of exit cannot be a branch out of the structured block. 8982 // longjmp() and throw() must not violate the entry/exit criteria. 8983 CS->getCapturedDecl()->setNothrow(); 8984 } 8985 8986 OMPLoopDirective::HelperExprs B; 8987 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8988 // define the nested loops number. 8989 unsigned NestedLoopCount = checkOpenMPLoop( 8990 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8991 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8992 VarsWithImplicitDSA, B); 8993 if (NestedLoopCount == 0) 8994 return StmtError(); 8995 8996 assert((CurContext->isDependentContext() || B.builtAll()) && 8997 "omp target parallel for simd loop exprs were not built"); 8998 8999 if (!CurContext->isDependentContext()) { 9000 // Finalize the clauses that need pre-built expressions for CodeGen. 9001 for (OMPClause *C : Clauses) { 9002 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9003 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9004 B.NumIterations, *this, CurScope, 9005 DSAStack)) 9006 return StmtError(); 9007 } 9008 } 9009 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9010 return StmtError(); 9011 9012 setFunctionHasBranchProtectedScope(); 9013 return OMPTargetParallelForSimdDirective::Create( 9014 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9015 } 9016 9017 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9018 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9019 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9020 if (!AStmt) 9021 return StmtError(); 9022 9023 auto *CS = cast<CapturedStmt>(AStmt); 9024 // 1.2.2 OpenMP Language Terminology 9025 // Structured block - An executable statement with a single entry at the 9026 // top and a single exit at the bottom. 9027 // The point of exit cannot be a branch out of the structured block. 9028 // longjmp() and throw() must not violate the entry/exit criteria. 9029 CS->getCapturedDecl()->setNothrow(); 9030 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9031 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9032 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9033 // 1.2.2 OpenMP Language Terminology 9034 // Structured block - An executable statement with a single entry at the 9035 // top and a single exit at the bottom. 9036 // The point of exit cannot be a branch out of the structured block. 9037 // longjmp() and throw() must not violate the entry/exit criteria. 9038 CS->getCapturedDecl()->setNothrow(); 9039 } 9040 9041 OMPLoopDirective::HelperExprs B; 9042 // In presence of clause 'collapse' with number of loops, it will define the 9043 // nested loops number. 9044 unsigned NestedLoopCount = 9045 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9046 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9047 VarsWithImplicitDSA, B); 9048 if (NestedLoopCount == 0) 9049 return StmtError(); 9050 9051 assert((CurContext->isDependentContext() || B.builtAll()) && 9052 "omp target simd loop exprs were not built"); 9053 9054 if (!CurContext->isDependentContext()) { 9055 // Finalize the clauses that need pre-built expressions for CodeGen. 9056 for (OMPClause *C : Clauses) { 9057 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9058 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9059 B.NumIterations, *this, CurScope, 9060 DSAStack)) 9061 return StmtError(); 9062 } 9063 } 9064 9065 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9066 return StmtError(); 9067 9068 setFunctionHasBranchProtectedScope(); 9069 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9070 NestedLoopCount, Clauses, AStmt, B); 9071 } 9072 9073 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9074 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9075 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9076 if (!AStmt) 9077 return StmtError(); 9078 9079 auto *CS = cast<CapturedStmt>(AStmt); 9080 // 1.2.2 OpenMP Language Terminology 9081 // Structured block - An executable statement with a single entry at the 9082 // top and a single exit at the bottom. 9083 // The point of exit cannot be a branch out of the structured block. 9084 // longjmp() and throw() must not violate the entry/exit criteria. 9085 CS->getCapturedDecl()->setNothrow(); 9086 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9087 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9088 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9089 // 1.2.2 OpenMP Language Terminology 9090 // Structured block - An executable statement with a single entry at the 9091 // top and a single exit at the bottom. 9092 // The point of exit cannot be a branch out of the structured block. 9093 // longjmp() and throw() must not violate the entry/exit criteria. 9094 CS->getCapturedDecl()->setNothrow(); 9095 } 9096 9097 OMPLoopDirective::HelperExprs B; 9098 // In presence of clause 'collapse' with number of loops, it will 9099 // define the nested loops number. 9100 unsigned NestedLoopCount = 9101 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9102 nullptr /*ordered not a clause on distribute*/, CS, *this, 9103 *DSAStack, VarsWithImplicitDSA, B); 9104 if (NestedLoopCount == 0) 9105 return StmtError(); 9106 9107 assert((CurContext->isDependentContext() || B.builtAll()) && 9108 "omp teams distribute loop exprs were not built"); 9109 9110 setFunctionHasBranchProtectedScope(); 9111 9112 DSAStack->setParentTeamsRegionLoc(StartLoc); 9113 9114 return OMPTeamsDistributeDirective::Create( 9115 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9116 } 9117 9118 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9119 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9120 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9121 if (!AStmt) 9122 return StmtError(); 9123 9124 auto *CS = cast<CapturedStmt>(AStmt); 9125 // 1.2.2 OpenMP Language Terminology 9126 // Structured block - An executable statement with a single entry at the 9127 // top and a single exit at the bottom. 9128 // The point of exit cannot be a branch out of the structured block. 9129 // longjmp() and throw() must not violate the entry/exit criteria. 9130 CS->getCapturedDecl()->setNothrow(); 9131 for (int ThisCaptureLevel = 9132 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9133 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9134 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9135 // 1.2.2 OpenMP Language Terminology 9136 // Structured block - An executable statement with a single entry at the 9137 // top and a single exit at the bottom. 9138 // The point of exit cannot be a branch out of the structured block. 9139 // longjmp() and throw() must not violate the entry/exit criteria. 9140 CS->getCapturedDecl()->setNothrow(); 9141 } 9142 9143 9144 OMPLoopDirective::HelperExprs B; 9145 // In presence of clause 'collapse' with number of loops, it will 9146 // define the nested loops number. 9147 unsigned NestedLoopCount = checkOpenMPLoop( 9148 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9149 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9150 VarsWithImplicitDSA, B); 9151 9152 if (NestedLoopCount == 0) 9153 return StmtError(); 9154 9155 assert((CurContext->isDependentContext() || B.builtAll()) && 9156 "omp teams distribute simd loop exprs were not built"); 9157 9158 if (!CurContext->isDependentContext()) { 9159 // Finalize the clauses that need pre-built expressions for CodeGen. 9160 for (OMPClause *C : Clauses) { 9161 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9162 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9163 B.NumIterations, *this, CurScope, 9164 DSAStack)) 9165 return StmtError(); 9166 } 9167 } 9168 9169 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9170 return StmtError(); 9171 9172 setFunctionHasBranchProtectedScope(); 9173 9174 DSAStack->setParentTeamsRegionLoc(StartLoc); 9175 9176 return OMPTeamsDistributeSimdDirective::Create( 9177 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9178 } 9179 9180 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9181 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9182 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9183 if (!AStmt) 9184 return StmtError(); 9185 9186 auto *CS = cast<CapturedStmt>(AStmt); 9187 // 1.2.2 OpenMP Language Terminology 9188 // Structured block - An executable statement with a single entry at the 9189 // top and a single exit at the bottom. 9190 // The point of exit cannot be a branch out of the structured block. 9191 // longjmp() and throw() must not violate the entry/exit criteria. 9192 CS->getCapturedDecl()->setNothrow(); 9193 9194 for (int ThisCaptureLevel = 9195 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9196 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9197 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9198 // 1.2.2 OpenMP Language Terminology 9199 // Structured block - An executable statement with a single entry at the 9200 // top and a single exit at the bottom. 9201 // The point of exit cannot be a branch out of the structured block. 9202 // longjmp() and throw() must not violate the entry/exit criteria. 9203 CS->getCapturedDecl()->setNothrow(); 9204 } 9205 9206 OMPLoopDirective::HelperExprs B; 9207 // In presence of clause 'collapse' with number of loops, it will 9208 // define the nested loops number. 9209 unsigned NestedLoopCount = checkOpenMPLoop( 9210 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9211 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9212 VarsWithImplicitDSA, B); 9213 9214 if (NestedLoopCount == 0) 9215 return StmtError(); 9216 9217 assert((CurContext->isDependentContext() || B.builtAll()) && 9218 "omp for loop exprs were not built"); 9219 9220 if (!CurContext->isDependentContext()) { 9221 // Finalize the clauses that need pre-built expressions for CodeGen. 9222 for (OMPClause *C : Clauses) { 9223 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9224 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9225 B.NumIterations, *this, CurScope, 9226 DSAStack)) 9227 return StmtError(); 9228 } 9229 } 9230 9231 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9232 return StmtError(); 9233 9234 setFunctionHasBranchProtectedScope(); 9235 9236 DSAStack->setParentTeamsRegionLoc(StartLoc); 9237 9238 return OMPTeamsDistributeParallelForSimdDirective::Create( 9239 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9240 } 9241 9242 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9243 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9244 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9245 if (!AStmt) 9246 return StmtError(); 9247 9248 auto *CS = cast<CapturedStmt>(AStmt); 9249 // 1.2.2 OpenMP Language Terminology 9250 // Structured block - An executable statement with a single entry at the 9251 // top and a single exit at the bottom. 9252 // The point of exit cannot be a branch out of the structured block. 9253 // longjmp() and throw() must not violate the entry/exit criteria. 9254 CS->getCapturedDecl()->setNothrow(); 9255 9256 for (int ThisCaptureLevel = 9257 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9258 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9259 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9260 // 1.2.2 OpenMP Language Terminology 9261 // Structured block - An executable statement with a single entry at the 9262 // top and a single exit at the bottom. 9263 // The point of exit cannot be a branch out of the structured block. 9264 // longjmp() and throw() must not violate the entry/exit criteria. 9265 CS->getCapturedDecl()->setNothrow(); 9266 } 9267 9268 OMPLoopDirective::HelperExprs B; 9269 // In presence of clause 'collapse' with number of loops, it will 9270 // define the nested loops number. 9271 unsigned NestedLoopCount = checkOpenMPLoop( 9272 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9273 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9274 VarsWithImplicitDSA, B); 9275 9276 if (NestedLoopCount == 0) 9277 return StmtError(); 9278 9279 assert((CurContext->isDependentContext() || B.builtAll()) && 9280 "omp for loop exprs were not built"); 9281 9282 setFunctionHasBranchProtectedScope(); 9283 9284 DSAStack->setParentTeamsRegionLoc(StartLoc); 9285 9286 return OMPTeamsDistributeParallelForDirective::Create( 9287 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9288 DSAStack->isCancelRegion()); 9289 } 9290 9291 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9292 Stmt *AStmt, 9293 SourceLocation StartLoc, 9294 SourceLocation EndLoc) { 9295 if (!AStmt) 9296 return StmtError(); 9297 9298 auto *CS = cast<CapturedStmt>(AStmt); 9299 // 1.2.2 OpenMP Language Terminology 9300 // Structured block - An executable statement with a single entry at the 9301 // top and a single exit at the bottom. 9302 // The point of exit cannot be a branch out of the structured block. 9303 // longjmp() and throw() must not violate the entry/exit criteria. 9304 CS->getCapturedDecl()->setNothrow(); 9305 9306 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9307 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9308 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9309 // 1.2.2 OpenMP Language Terminology 9310 // Structured block - An executable statement with a single entry at the 9311 // top and a single exit at the bottom. 9312 // The point of exit cannot be a branch out of the structured block. 9313 // longjmp() and throw() must not violate the entry/exit criteria. 9314 CS->getCapturedDecl()->setNothrow(); 9315 } 9316 setFunctionHasBranchProtectedScope(); 9317 9318 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9319 AStmt); 9320 } 9321 9322 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9323 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9324 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9325 if (!AStmt) 9326 return StmtError(); 9327 9328 auto *CS = cast<CapturedStmt>(AStmt); 9329 // 1.2.2 OpenMP Language Terminology 9330 // Structured block - An executable statement with a single entry at the 9331 // top and a single exit at the bottom. 9332 // The point of exit cannot be a branch out of the structured block. 9333 // longjmp() and throw() must not violate the entry/exit criteria. 9334 CS->getCapturedDecl()->setNothrow(); 9335 for (int ThisCaptureLevel = 9336 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9337 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9338 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9339 // 1.2.2 OpenMP Language Terminology 9340 // Structured block - An executable statement with a single entry at the 9341 // top and a single exit at the bottom. 9342 // The point of exit cannot be a branch out of the structured block. 9343 // longjmp() and throw() must not violate the entry/exit criteria. 9344 CS->getCapturedDecl()->setNothrow(); 9345 } 9346 9347 OMPLoopDirective::HelperExprs B; 9348 // In presence of clause 'collapse' with number of loops, it will 9349 // define the nested loops number. 9350 unsigned NestedLoopCount = checkOpenMPLoop( 9351 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9352 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9353 VarsWithImplicitDSA, B); 9354 if (NestedLoopCount == 0) 9355 return StmtError(); 9356 9357 assert((CurContext->isDependentContext() || B.builtAll()) && 9358 "omp target teams distribute loop exprs were not built"); 9359 9360 setFunctionHasBranchProtectedScope(); 9361 return OMPTargetTeamsDistributeDirective::Create( 9362 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9363 } 9364 9365 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9366 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9367 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9368 if (!AStmt) 9369 return StmtError(); 9370 9371 auto *CS = cast<CapturedStmt>(AStmt); 9372 // 1.2.2 OpenMP Language Terminology 9373 // Structured block - An executable statement with a single entry at the 9374 // top and a single exit at the bottom. 9375 // The point of exit cannot be a branch out of the structured block. 9376 // longjmp() and throw() must not violate the entry/exit criteria. 9377 CS->getCapturedDecl()->setNothrow(); 9378 for (int ThisCaptureLevel = 9379 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9380 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9381 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9382 // 1.2.2 OpenMP Language Terminology 9383 // Structured block - An executable statement with a single entry at the 9384 // top and a single exit at the bottom. 9385 // The point of exit cannot be a branch out of the structured block. 9386 // longjmp() and throw() must not violate the entry/exit criteria. 9387 CS->getCapturedDecl()->setNothrow(); 9388 } 9389 9390 OMPLoopDirective::HelperExprs B; 9391 // In presence of clause 'collapse' with number of loops, it will 9392 // define the nested loops number. 9393 unsigned NestedLoopCount = checkOpenMPLoop( 9394 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9395 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9396 VarsWithImplicitDSA, B); 9397 if (NestedLoopCount == 0) 9398 return StmtError(); 9399 9400 assert((CurContext->isDependentContext() || B.builtAll()) && 9401 "omp target teams distribute parallel for loop exprs were not built"); 9402 9403 if (!CurContext->isDependentContext()) { 9404 // Finalize the clauses that need pre-built expressions for CodeGen. 9405 for (OMPClause *C : Clauses) { 9406 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9407 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9408 B.NumIterations, *this, CurScope, 9409 DSAStack)) 9410 return StmtError(); 9411 } 9412 } 9413 9414 setFunctionHasBranchProtectedScope(); 9415 return OMPTargetTeamsDistributeParallelForDirective::Create( 9416 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9417 DSAStack->isCancelRegion()); 9418 } 9419 9420 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9421 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9422 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9423 if (!AStmt) 9424 return StmtError(); 9425 9426 auto *CS = cast<CapturedStmt>(AStmt); 9427 // 1.2.2 OpenMP Language Terminology 9428 // Structured block - An executable statement with a single entry at the 9429 // top and a single exit at the bottom. 9430 // The point of exit cannot be a branch out of the structured block. 9431 // longjmp() and throw() must not violate the entry/exit criteria. 9432 CS->getCapturedDecl()->setNothrow(); 9433 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9434 OMPD_target_teams_distribute_parallel_for_simd); 9435 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9436 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9437 // 1.2.2 OpenMP Language Terminology 9438 // Structured block - An executable statement with a single entry at the 9439 // top and a single exit at the bottom. 9440 // The point of exit cannot be a branch out of the structured block. 9441 // longjmp() and throw() must not violate the entry/exit criteria. 9442 CS->getCapturedDecl()->setNothrow(); 9443 } 9444 9445 OMPLoopDirective::HelperExprs B; 9446 // In presence of clause 'collapse' with number of loops, it will 9447 // define the nested loops number. 9448 unsigned NestedLoopCount = 9449 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9450 getCollapseNumberExpr(Clauses), 9451 nullptr /*ordered not a clause on distribute*/, CS, *this, 9452 *DSAStack, VarsWithImplicitDSA, B); 9453 if (NestedLoopCount == 0) 9454 return StmtError(); 9455 9456 assert((CurContext->isDependentContext() || B.builtAll()) && 9457 "omp target teams distribute parallel for simd loop exprs were not " 9458 "built"); 9459 9460 if (!CurContext->isDependentContext()) { 9461 // Finalize the clauses that need pre-built expressions for CodeGen. 9462 for (OMPClause *C : Clauses) { 9463 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9464 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9465 B.NumIterations, *this, CurScope, 9466 DSAStack)) 9467 return StmtError(); 9468 } 9469 } 9470 9471 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9472 return StmtError(); 9473 9474 setFunctionHasBranchProtectedScope(); 9475 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9476 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9477 } 9478 9479 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9480 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9481 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9482 if (!AStmt) 9483 return StmtError(); 9484 9485 auto *CS = cast<CapturedStmt>(AStmt); 9486 // 1.2.2 OpenMP Language Terminology 9487 // Structured block - An executable statement with a single entry at the 9488 // top and a single exit at the bottom. 9489 // The point of exit cannot be a branch out of the structured block. 9490 // longjmp() and throw() must not violate the entry/exit criteria. 9491 CS->getCapturedDecl()->setNothrow(); 9492 for (int ThisCaptureLevel = 9493 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9494 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9495 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9496 // 1.2.2 OpenMP Language Terminology 9497 // Structured block - An executable statement with a single entry at the 9498 // top and a single exit at the bottom. 9499 // The point of exit cannot be a branch out of the structured block. 9500 // longjmp() and throw() must not violate the entry/exit criteria. 9501 CS->getCapturedDecl()->setNothrow(); 9502 } 9503 9504 OMPLoopDirective::HelperExprs B; 9505 // In presence of clause 'collapse' with number of loops, it will 9506 // define the nested loops number. 9507 unsigned NestedLoopCount = checkOpenMPLoop( 9508 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9509 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9510 VarsWithImplicitDSA, B); 9511 if (NestedLoopCount == 0) 9512 return StmtError(); 9513 9514 assert((CurContext->isDependentContext() || B.builtAll()) && 9515 "omp target teams distribute simd loop exprs were not built"); 9516 9517 if (!CurContext->isDependentContext()) { 9518 // Finalize the clauses that need pre-built expressions for CodeGen. 9519 for (OMPClause *C : Clauses) { 9520 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9521 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9522 B.NumIterations, *this, CurScope, 9523 DSAStack)) 9524 return StmtError(); 9525 } 9526 } 9527 9528 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9529 return StmtError(); 9530 9531 setFunctionHasBranchProtectedScope(); 9532 return OMPTargetTeamsDistributeSimdDirective::Create( 9533 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9534 } 9535 9536 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9537 SourceLocation StartLoc, 9538 SourceLocation LParenLoc, 9539 SourceLocation EndLoc) { 9540 OMPClause *Res = nullptr; 9541 switch (Kind) { 9542 case OMPC_final: 9543 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9544 break; 9545 case OMPC_num_threads: 9546 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9547 break; 9548 case OMPC_safelen: 9549 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9550 break; 9551 case OMPC_simdlen: 9552 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9553 break; 9554 case OMPC_allocator: 9555 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9556 break; 9557 case OMPC_collapse: 9558 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9559 break; 9560 case OMPC_ordered: 9561 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9562 break; 9563 case OMPC_device: 9564 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9565 break; 9566 case OMPC_num_teams: 9567 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9568 break; 9569 case OMPC_thread_limit: 9570 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9571 break; 9572 case OMPC_priority: 9573 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9574 break; 9575 case OMPC_grainsize: 9576 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9577 break; 9578 case OMPC_num_tasks: 9579 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9580 break; 9581 case OMPC_hint: 9582 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9583 break; 9584 case OMPC_if: 9585 case OMPC_default: 9586 case OMPC_proc_bind: 9587 case OMPC_schedule: 9588 case OMPC_private: 9589 case OMPC_firstprivate: 9590 case OMPC_lastprivate: 9591 case OMPC_shared: 9592 case OMPC_reduction: 9593 case OMPC_task_reduction: 9594 case OMPC_in_reduction: 9595 case OMPC_linear: 9596 case OMPC_aligned: 9597 case OMPC_copyin: 9598 case OMPC_copyprivate: 9599 case OMPC_nowait: 9600 case OMPC_untied: 9601 case OMPC_mergeable: 9602 case OMPC_threadprivate: 9603 case OMPC_allocate: 9604 case OMPC_flush: 9605 case OMPC_read: 9606 case OMPC_write: 9607 case OMPC_update: 9608 case OMPC_capture: 9609 case OMPC_seq_cst: 9610 case OMPC_depend: 9611 case OMPC_threads: 9612 case OMPC_simd: 9613 case OMPC_map: 9614 case OMPC_nogroup: 9615 case OMPC_dist_schedule: 9616 case OMPC_defaultmap: 9617 case OMPC_unknown: 9618 case OMPC_uniform: 9619 case OMPC_to: 9620 case OMPC_from: 9621 case OMPC_use_device_ptr: 9622 case OMPC_is_device_ptr: 9623 case OMPC_unified_address: 9624 case OMPC_unified_shared_memory: 9625 case OMPC_reverse_offload: 9626 case OMPC_dynamic_allocators: 9627 case OMPC_atomic_default_mem_order: 9628 llvm_unreachable("Clause is not allowed."); 9629 } 9630 return Res; 9631 } 9632 9633 // An OpenMP directive such as 'target parallel' has two captured regions: 9634 // for the 'target' and 'parallel' respectively. This function returns 9635 // the region in which to capture expressions associated with a clause. 9636 // A return value of OMPD_unknown signifies that the expression should not 9637 // be captured. 9638 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9639 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9640 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9641 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9642 switch (CKind) { 9643 case OMPC_if: 9644 switch (DKind) { 9645 case OMPD_target_parallel: 9646 case OMPD_target_parallel_for: 9647 case OMPD_target_parallel_for_simd: 9648 // If this clause applies to the nested 'parallel' region, capture within 9649 // the 'target' region, otherwise do not capture. 9650 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9651 CaptureRegion = OMPD_target; 9652 break; 9653 case OMPD_target_teams_distribute_parallel_for: 9654 case OMPD_target_teams_distribute_parallel_for_simd: 9655 // If this clause applies to the nested 'parallel' region, capture within 9656 // the 'teams' region, otherwise do not capture. 9657 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9658 CaptureRegion = OMPD_teams; 9659 break; 9660 case OMPD_teams_distribute_parallel_for: 9661 case OMPD_teams_distribute_parallel_for_simd: 9662 CaptureRegion = OMPD_teams; 9663 break; 9664 case OMPD_target_update: 9665 case OMPD_target_enter_data: 9666 case OMPD_target_exit_data: 9667 CaptureRegion = OMPD_task; 9668 break; 9669 case OMPD_cancel: 9670 case OMPD_parallel: 9671 case OMPD_parallel_sections: 9672 case OMPD_parallel_for: 9673 case OMPD_parallel_for_simd: 9674 case OMPD_target: 9675 case OMPD_target_simd: 9676 case OMPD_target_teams: 9677 case OMPD_target_teams_distribute: 9678 case OMPD_target_teams_distribute_simd: 9679 case OMPD_distribute_parallel_for: 9680 case OMPD_distribute_parallel_for_simd: 9681 case OMPD_task: 9682 case OMPD_taskloop: 9683 case OMPD_taskloop_simd: 9684 case OMPD_target_data: 9685 // Do not capture if-clause expressions. 9686 break; 9687 case OMPD_threadprivate: 9688 case OMPD_allocate: 9689 case OMPD_taskyield: 9690 case OMPD_barrier: 9691 case OMPD_taskwait: 9692 case OMPD_cancellation_point: 9693 case OMPD_flush: 9694 case OMPD_declare_reduction: 9695 case OMPD_declare_mapper: 9696 case OMPD_declare_simd: 9697 case OMPD_declare_target: 9698 case OMPD_end_declare_target: 9699 case OMPD_teams: 9700 case OMPD_simd: 9701 case OMPD_for: 9702 case OMPD_for_simd: 9703 case OMPD_sections: 9704 case OMPD_section: 9705 case OMPD_single: 9706 case OMPD_master: 9707 case OMPD_critical: 9708 case OMPD_taskgroup: 9709 case OMPD_distribute: 9710 case OMPD_ordered: 9711 case OMPD_atomic: 9712 case OMPD_distribute_simd: 9713 case OMPD_teams_distribute: 9714 case OMPD_teams_distribute_simd: 9715 case OMPD_requires: 9716 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9717 case OMPD_unknown: 9718 llvm_unreachable("Unknown OpenMP directive"); 9719 } 9720 break; 9721 case OMPC_num_threads: 9722 switch (DKind) { 9723 case OMPD_target_parallel: 9724 case OMPD_target_parallel_for: 9725 case OMPD_target_parallel_for_simd: 9726 CaptureRegion = OMPD_target; 9727 break; 9728 case OMPD_teams_distribute_parallel_for: 9729 case OMPD_teams_distribute_parallel_for_simd: 9730 case OMPD_target_teams_distribute_parallel_for: 9731 case OMPD_target_teams_distribute_parallel_for_simd: 9732 CaptureRegion = OMPD_teams; 9733 break; 9734 case OMPD_parallel: 9735 case OMPD_parallel_sections: 9736 case OMPD_parallel_for: 9737 case OMPD_parallel_for_simd: 9738 case OMPD_distribute_parallel_for: 9739 case OMPD_distribute_parallel_for_simd: 9740 // Do not capture num_threads-clause expressions. 9741 break; 9742 case OMPD_target_data: 9743 case OMPD_target_enter_data: 9744 case OMPD_target_exit_data: 9745 case OMPD_target_update: 9746 case OMPD_target: 9747 case OMPD_target_simd: 9748 case OMPD_target_teams: 9749 case OMPD_target_teams_distribute: 9750 case OMPD_target_teams_distribute_simd: 9751 case OMPD_cancel: 9752 case OMPD_task: 9753 case OMPD_taskloop: 9754 case OMPD_taskloop_simd: 9755 case OMPD_threadprivate: 9756 case OMPD_allocate: 9757 case OMPD_taskyield: 9758 case OMPD_barrier: 9759 case OMPD_taskwait: 9760 case OMPD_cancellation_point: 9761 case OMPD_flush: 9762 case OMPD_declare_reduction: 9763 case OMPD_declare_mapper: 9764 case OMPD_declare_simd: 9765 case OMPD_declare_target: 9766 case OMPD_end_declare_target: 9767 case OMPD_teams: 9768 case OMPD_simd: 9769 case OMPD_for: 9770 case OMPD_for_simd: 9771 case OMPD_sections: 9772 case OMPD_section: 9773 case OMPD_single: 9774 case OMPD_master: 9775 case OMPD_critical: 9776 case OMPD_taskgroup: 9777 case OMPD_distribute: 9778 case OMPD_ordered: 9779 case OMPD_atomic: 9780 case OMPD_distribute_simd: 9781 case OMPD_teams_distribute: 9782 case OMPD_teams_distribute_simd: 9783 case OMPD_requires: 9784 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9785 case OMPD_unknown: 9786 llvm_unreachable("Unknown OpenMP directive"); 9787 } 9788 break; 9789 case OMPC_num_teams: 9790 switch (DKind) { 9791 case OMPD_target_teams: 9792 case OMPD_target_teams_distribute: 9793 case OMPD_target_teams_distribute_simd: 9794 case OMPD_target_teams_distribute_parallel_for: 9795 case OMPD_target_teams_distribute_parallel_for_simd: 9796 CaptureRegion = OMPD_target; 9797 break; 9798 case OMPD_teams_distribute_parallel_for: 9799 case OMPD_teams_distribute_parallel_for_simd: 9800 case OMPD_teams: 9801 case OMPD_teams_distribute: 9802 case OMPD_teams_distribute_simd: 9803 // Do not capture num_teams-clause expressions. 9804 break; 9805 case OMPD_distribute_parallel_for: 9806 case OMPD_distribute_parallel_for_simd: 9807 case OMPD_task: 9808 case OMPD_taskloop: 9809 case OMPD_taskloop_simd: 9810 case OMPD_target_data: 9811 case OMPD_target_enter_data: 9812 case OMPD_target_exit_data: 9813 case OMPD_target_update: 9814 case OMPD_cancel: 9815 case OMPD_parallel: 9816 case OMPD_parallel_sections: 9817 case OMPD_parallel_for: 9818 case OMPD_parallel_for_simd: 9819 case OMPD_target: 9820 case OMPD_target_simd: 9821 case OMPD_target_parallel: 9822 case OMPD_target_parallel_for: 9823 case OMPD_target_parallel_for_simd: 9824 case OMPD_threadprivate: 9825 case OMPD_allocate: 9826 case OMPD_taskyield: 9827 case OMPD_barrier: 9828 case OMPD_taskwait: 9829 case OMPD_cancellation_point: 9830 case OMPD_flush: 9831 case OMPD_declare_reduction: 9832 case OMPD_declare_mapper: 9833 case OMPD_declare_simd: 9834 case OMPD_declare_target: 9835 case OMPD_end_declare_target: 9836 case OMPD_simd: 9837 case OMPD_for: 9838 case OMPD_for_simd: 9839 case OMPD_sections: 9840 case OMPD_section: 9841 case OMPD_single: 9842 case OMPD_master: 9843 case OMPD_critical: 9844 case OMPD_taskgroup: 9845 case OMPD_distribute: 9846 case OMPD_ordered: 9847 case OMPD_atomic: 9848 case OMPD_distribute_simd: 9849 case OMPD_requires: 9850 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9851 case OMPD_unknown: 9852 llvm_unreachable("Unknown OpenMP directive"); 9853 } 9854 break; 9855 case OMPC_thread_limit: 9856 switch (DKind) { 9857 case OMPD_target_teams: 9858 case OMPD_target_teams_distribute: 9859 case OMPD_target_teams_distribute_simd: 9860 case OMPD_target_teams_distribute_parallel_for: 9861 case OMPD_target_teams_distribute_parallel_for_simd: 9862 CaptureRegion = OMPD_target; 9863 break; 9864 case OMPD_teams_distribute_parallel_for: 9865 case OMPD_teams_distribute_parallel_for_simd: 9866 case OMPD_teams: 9867 case OMPD_teams_distribute: 9868 case OMPD_teams_distribute_simd: 9869 // Do not capture thread_limit-clause expressions. 9870 break; 9871 case OMPD_distribute_parallel_for: 9872 case OMPD_distribute_parallel_for_simd: 9873 case OMPD_task: 9874 case OMPD_taskloop: 9875 case OMPD_taskloop_simd: 9876 case OMPD_target_data: 9877 case OMPD_target_enter_data: 9878 case OMPD_target_exit_data: 9879 case OMPD_target_update: 9880 case OMPD_cancel: 9881 case OMPD_parallel: 9882 case OMPD_parallel_sections: 9883 case OMPD_parallel_for: 9884 case OMPD_parallel_for_simd: 9885 case OMPD_target: 9886 case OMPD_target_simd: 9887 case OMPD_target_parallel: 9888 case OMPD_target_parallel_for: 9889 case OMPD_target_parallel_for_simd: 9890 case OMPD_threadprivate: 9891 case OMPD_allocate: 9892 case OMPD_taskyield: 9893 case OMPD_barrier: 9894 case OMPD_taskwait: 9895 case OMPD_cancellation_point: 9896 case OMPD_flush: 9897 case OMPD_declare_reduction: 9898 case OMPD_declare_mapper: 9899 case OMPD_declare_simd: 9900 case OMPD_declare_target: 9901 case OMPD_end_declare_target: 9902 case OMPD_simd: 9903 case OMPD_for: 9904 case OMPD_for_simd: 9905 case OMPD_sections: 9906 case OMPD_section: 9907 case OMPD_single: 9908 case OMPD_master: 9909 case OMPD_critical: 9910 case OMPD_taskgroup: 9911 case OMPD_distribute: 9912 case OMPD_ordered: 9913 case OMPD_atomic: 9914 case OMPD_distribute_simd: 9915 case OMPD_requires: 9916 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 9917 case OMPD_unknown: 9918 llvm_unreachable("Unknown OpenMP directive"); 9919 } 9920 break; 9921 case OMPC_schedule: 9922 switch (DKind) { 9923 case OMPD_parallel_for: 9924 case OMPD_parallel_for_simd: 9925 case OMPD_distribute_parallel_for: 9926 case OMPD_distribute_parallel_for_simd: 9927 case OMPD_teams_distribute_parallel_for: 9928 case OMPD_teams_distribute_parallel_for_simd: 9929 case OMPD_target_parallel_for: 9930 case OMPD_target_parallel_for_simd: 9931 case OMPD_target_teams_distribute_parallel_for: 9932 case OMPD_target_teams_distribute_parallel_for_simd: 9933 CaptureRegion = OMPD_parallel; 9934 break; 9935 case OMPD_for: 9936 case OMPD_for_simd: 9937 // Do not capture schedule-clause expressions. 9938 break; 9939 case OMPD_task: 9940 case OMPD_taskloop: 9941 case OMPD_taskloop_simd: 9942 case OMPD_target_data: 9943 case OMPD_target_enter_data: 9944 case OMPD_target_exit_data: 9945 case OMPD_target_update: 9946 case OMPD_teams: 9947 case OMPD_teams_distribute: 9948 case OMPD_teams_distribute_simd: 9949 case OMPD_target_teams_distribute: 9950 case OMPD_target_teams_distribute_simd: 9951 case OMPD_target: 9952 case OMPD_target_simd: 9953 case OMPD_target_parallel: 9954 case OMPD_cancel: 9955 case OMPD_parallel: 9956 case OMPD_parallel_sections: 9957 case OMPD_threadprivate: 9958 case OMPD_allocate: 9959 case OMPD_taskyield: 9960 case OMPD_barrier: 9961 case OMPD_taskwait: 9962 case OMPD_cancellation_point: 9963 case OMPD_flush: 9964 case OMPD_declare_reduction: 9965 case OMPD_declare_mapper: 9966 case OMPD_declare_simd: 9967 case OMPD_declare_target: 9968 case OMPD_end_declare_target: 9969 case OMPD_simd: 9970 case OMPD_sections: 9971 case OMPD_section: 9972 case OMPD_single: 9973 case OMPD_master: 9974 case OMPD_critical: 9975 case OMPD_taskgroup: 9976 case OMPD_distribute: 9977 case OMPD_ordered: 9978 case OMPD_atomic: 9979 case OMPD_distribute_simd: 9980 case OMPD_target_teams: 9981 case OMPD_requires: 9982 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9983 case OMPD_unknown: 9984 llvm_unreachable("Unknown OpenMP directive"); 9985 } 9986 break; 9987 case OMPC_dist_schedule: 9988 switch (DKind) { 9989 case OMPD_teams_distribute_parallel_for: 9990 case OMPD_teams_distribute_parallel_for_simd: 9991 case OMPD_teams_distribute: 9992 case OMPD_teams_distribute_simd: 9993 case OMPD_target_teams_distribute_parallel_for: 9994 case OMPD_target_teams_distribute_parallel_for_simd: 9995 case OMPD_target_teams_distribute: 9996 case OMPD_target_teams_distribute_simd: 9997 CaptureRegion = OMPD_teams; 9998 break; 9999 case OMPD_distribute_parallel_for: 10000 case OMPD_distribute_parallel_for_simd: 10001 case OMPD_distribute: 10002 case OMPD_distribute_simd: 10003 // Do not capture thread_limit-clause expressions. 10004 break; 10005 case OMPD_parallel_for: 10006 case OMPD_parallel_for_simd: 10007 case OMPD_target_parallel_for_simd: 10008 case OMPD_target_parallel_for: 10009 case OMPD_task: 10010 case OMPD_taskloop: 10011 case OMPD_taskloop_simd: 10012 case OMPD_target_data: 10013 case OMPD_target_enter_data: 10014 case OMPD_target_exit_data: 10015 case OMPD_target_update: 10016 case OMPD_teams: 10017 case OMPD_target: 10018 case OMPD_target_simd: 10019 case OMPD_target_parallel: 10020 case OMPD_cancel: 10021 case OMPD_parallel: 10022 case OMPD_parallel_sections: 10023 case OMPD_threadprivate: 10024 case OMPD_allocate: 10025 case OMPD_taskyield: 10026 case OMPD_barrier: 10027 case OMPD_taskwait: 10028 case OMPD_cancellation_point: 10029 case OMPD_flush: 10030 case OMPD_declare_reduction: 10031 case OMPD_declare_mapper: 10032 case OMPD_declare_simd: 10033 case OMPD_declare_target: 10034 case OMPD_end_declare_target: 10035 case OMPD_simd: 10036 case OMPD_for: 10037 case OMPD_for_simd: 10038 case OMPD_sections: 10039 case OMPD_section: 10040 case OMPD_single: 10041 case OMPD_master: 10042 case OMPD_critical: 10043 case OMPD_taskgroup: 10044 case OMPD_ordered: 10045 case OMPD_atomic: 10046 case OMPD_target_teams: 10047 case OMPD_requires: 10048 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10049 case OMPD_unknown: 10050 llvm_unreachable("Unknown OpenMP directive"); 10051 } 10052 break; 10053 case OMPC_device: 10054 switch (DKind) { 10055 case OMPD_target_update: 10056 case OMPD_target_enter_data: 10057 case OMPD_target_exit_data: 10058 case OMPD_target: 10059 case OMPD_target_simd: 10060 case OMPD_target_teams: 10061 case OMPD_target_parallel: 10062 case OMPD_target_teams_distribute: 10063 case OMPD_target_teams_distribute_simd: 10064 case OMPD_target_parallel_for: 10065 case OMPD_target_parallel_for_simd: 10066 case OMPD_target_teams_distribute_parallel_for: 10067 case OMPD_target_teams_distribute_parallel_for_simd: 10068 CaptureRegion = OMPD_task; 10069 break; 10070 case OMPD_target_data: 10071 // Do not capture device-clause expressions. 10072 break; 10073 case OMPD_teams_distribute_parallel_for: 10074 case OMPD_teams_distribute_parallel_for_simd: 10075 case OMPD_teams: 10076 case OMPD_teams_distribute: 10077 case OMPD_teams_distribute_simd: 10078 case OMPD_distribute_parallel_for: 10079 case OMPD_distribute_parallel_for_simd: 10080 case OMPD_task: 10081 case OMPD_taskloop: 10082 case OMPD_taskloop_simd: 10083 case OMPD_cancel: 10084 case OMPD_parallel: 10085 case OMPD_parallel_sections: 10086 case OMPD_parallel_for: 10087 case OMPD_parallel_for_simd: 10088 case OMPD_threadprivate: 10089 case OMPD_allocate: 10090 case OMPD_taskyield: 10091 case OMPD_barrier: 10092 case OMPD_taskwait: 10093 case OMPD_cancellation_point: 10094 case OMPD_flush: 10095 case OMPD_declare_reduction: 10096 case OMPD_declare_mapper: 10097 case OMPD_declare_simd: 10098 case OMPD_declare_target: 10099 case OMPD_end_declare_target: 10100 case OMPD_simd: 10101 case OMPD_for: 10102 case OMPD_for_simd: 10103 case OMPD_sections: 10104 case OMPD_section: 10105 case OMPD_single: 10106 case OMPD_master: 10107 case OMPD_critical: 10108 case OMPD_taskgroup: 10109 case OMPD_distribute: 10110 case OMPD_ordered: 10111 case OMPD_atomic: 10112 case OMPD_distribute_simd: 10113 case OMPD_requires: 10114 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10115 case OMPD_unknown: 10116 llvm_unreachable("Unknown OpenMP directive"); 10117 } 10118 break; 10119 case OMPC_firstprivate: 10120 case OMPC_lastprivate: 10121 case OMPC_reduction: 10122 case OMPC_task_reduction: 10123 case OMPC_in_reduction: 10124 case OMPC_linear: 10125 case OMPC_default: 10126 case OMPC_proc_bind: 10127 case OMPC_final: 10128 case OMPC_safelen: 10129 case OMPC_simdlen: 10130 case OMPC_allocator: 10131 case OMPC_collapse: 10132 case OMPC_private: 10133 case OMPC_shared: 10134 case OMPC_aligned: 10135 case OMPC_copyin: 10136 case OMPC_copyprivate: 10137 case OMPC_ordered: 10138 case OMPC_nowait: 10139 case OMPC_untied: 10140 case OMPC_mergeable: 10141 case OMPC_threadprivate: 10142 case OMPC_allocate: 10143 case OMPC_flush: 10144 case OMPC_read: 10145 case OMPC_write: 10146 case OMPC_update: 10147 case OMPC_capture: 10148 case OMPC_seq_cst: 10149 case OMPC_depend: 10150 case OMPC_threads: 10151 case OMPC_simd: 10152 case OMPC_map: 10153 case OMPC_priority: 10154 case OMPC_grainsize: 10155 case OMPC_nogroup: 10156 case OMPC_num_tasks: 10157 case OMPC_hint: 10158 case OMPC_defaultmap: 10159 case OMPC_unknown: 10160 case OMPC_uniform: 10161 case OMPC_to: 10162 case OMPC_from: 10163 case OMPC_use_device_ptr: 10164 case OMPC_is_device_ptr: 10165 case OMPC_unified_address: 10166 case OMPC_unified_shared_memory: 10167 case OMPC_reverse_offload: 10168 case OMPC_dynamic_allocators: 10169 case OMPC_atomic_default_mem_order: 10170 llvm_unreachable("Unexpected OpenMP clause."); 10171 } 10172 return CaptureRegion; 10173 } 10174 10175 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10176 Expr *Condition, SourceLocation StartLoc, 10177 SourceLocation LParenLoc, 10178 SourceLocation NameModifierLoc, 10179 SourceLocation ColonLoc, 10180 SourceLocation EndLoc) { 10181 Expr *ValExpr = Condition; 10182 Stmt *HelperValStmt = nullptr; 10183 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10184 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10185 !Condition->isInstantiationDependent() && 10186 !Condition->containsUnexpandedParameterPack()) { 10187 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10188 if (Val.isInvalid()) 10189 return nullptr; 10190 10191 ValExpr = Val.get(); 10192 10193 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10194 CaptureRegion = 10195 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10196 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10197 ValExpr = MakeFullExpr(ValExpr).get(); 10198 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10199 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10200 HelperValStmt = buildPreInits(Context, Captures); 10201 } 10202 } 10203 10204 return new (Context) 10205 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10206 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10207 } 10208 10209 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10210 SourceLocation StartLoc, 10211 SourceLocation LParenLoc, 10212 SourceLocation EndLoc) { 10213 Expr *ValExpr = Condition; 10214 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10215 !Condition->isInstantiationDependent() && 10216 !Condition->containsUnexpandedParameterPack()) { 10217 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10218 if (Val.isInvalid()) 10219 return nullptr; 10220 10221 ValExpr = MakeFullExpr(Val.get()).get(); 10222 } 10223 10224 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10225 } 10226 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10227 Expr *Op) { 10228 if (!Op) 10229 return ExprError(); 10230 10231 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10232 public: 10233 IntConvertDiagnoser() 10234 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10235 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10236 QualType T) override { 10237 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10238 } 10239 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10240 QualType T) override { 10241 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10242 } 10243 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10244 QualType T, 10245 QualType ConvTy) override { 10246 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10247 } 10248 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10249 QualType ConvTy) override { 10250 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10251 << ConvTy->isEnumeralType() << ConvTy; 10252 } 10253 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10254 QualType T) override { 10255 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10256 } 10257 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 10258 QualType ConvTy) override { 10259 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10260 << ConvTy->isEnumeralType() << ConvTy; 10261 } 10262 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 10263 QualType) override { 10264 llvm_unreachable("conversion functions are permitted"); 10265 } 10266 } ConvertDiagnoser; 10267 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 10268 } 10269 10270 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 10271 OpenMPClauseKind CKind, 10272 bool StrictlyPositive) { 10273 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 10274 !ValExpr->isInstantiationDependent()) { 10275 SourceLocation Loc = ValExpr->getExprLoc(); 10276 ExprResult Value = 10277 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 10278 if (Value.isInvalid()) 10279 return false; 10280 10281 ValExpr = Value.get(); 10282 // The expression must evaluate to a non-negative integer value. 10283 llvm::APSInt Result; 10284 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 10285 Result.isSigned() && 10286 !((!StrictlyPositive && Result.isNonNegative()) || 10287 (StrictlyPositive && Result.isStrictlyPositive()))) { 10288 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 10289 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10290 << ValExpr->getSourceRange(); 10291 return false; 10292 } 10293 } 10294 return true; 10295 } 10296 10297 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 10298 SourceLocation StartLoc, 10299 SourceLocation LParenLoc, 10300 SourceLocation EndLoc) { 10301 Expr *ValExpr = NumThreads; 10302 Stmt *HelperValStmt = nullptr; 10303 10304 // OpenMP [2.5, Restrictions] 10305 // The num_threads expression must evaluate to a positive integer value. 10306 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 10307 /*StrictlyPositive=*/true)) 10308 return nullptr; 10309 10310 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10311 OpenMPDirectiveKind CaptureRegion = 10312 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 10313 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10314 ValExpr = MakeFullExpr(ValExpr).get(); 10315 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10316 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10317 HelperValStmt = buildPreInits(Context, Captures); 10318 } 10319 10320 return new (Context) OMPNumThreadsClause( 10321 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 10322 } 10323 10324 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 10325 OpenMPClauseKind CKind, 10326 bool StrictlyPositive) { 10327 if (!E) 10328 return ExprError(); 10329 if (E->isValueDependent() || E->isTypeDependent() || 10330 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 10331 return E; 10332 llvm::APSInt Result; 10333 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 10334 if (ICE.isInvalid()) 10335 return ExprError(); 10336 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 10337 (!StrictlyPositive && !Result.isNonNegative())) { 10338 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 10339 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10340 << E->getSourceRange(); 10341 return ExprError(); 10342 } 10343 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 10344 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 10345 << E->getSourceRange(); 10346 return ExprError(); 10347 } 10348 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 10349 DSAStack->setAssociatedLoops(Result.getExtValue()); 10350 else if (CKind == OMPC_ordered) 10351 DSAStack->setAssociatedLoops(Result.getExtValue()); 10352 return ICE; 10353 } 10354 10355 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 10356 SourceLocation LParenLoc, 10357 SourceLocation EndLoc) { 10358 // OpenMP [2.8.1, simd construct, Description] 10359 // The parameter of the safelen clause must be a constant 10360 // positive integer expression. 10361 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10362 if (Safelen.isInvalid()) 10363 return nullptr; 10364 return new (Context) 10365 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10366 } 10367 10368 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10369 SourceLocation LParenLoc, 10370 SourceLocation EndLoc) { 10371 // OpenMP [2.8.1, simd construct, Description] 10372 // The parameter of the simdlen clause must be a constant 10373 // positive integer expression. 10374 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10375 if (Simdlen.isInvalid()) 10376 return nullptr; 10377 return new (Context) 10378 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10379 } 10380 10381 /// Tries to find omp_allocator_handle_t type. 10382 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10383 DSAStackTy *Stack) { 10384 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10385 if (!OMPAllocatorHandleT.isNull()) 10386 return true; 10387 // Build the predefined allocator expressions. 10388 bool ErrorFound = false; 10389 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10390 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10391 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10392 StringRef Allocator = 10393 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10394 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10395 auto *VD = dyn_cast_or_null<ValueDecl>( 10396 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10397 if (!VD) { 10398 ErrorFound = true; 10399 break; 10400 } 10401 QualType AllocatorType = 10402 VD->getType().getNonLValueExprType(S.getASTContext()); 10403 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10404 if (!Res.isUsable()) { 10405 ErrorFound = true; 10406 break; 10407 } 10408 if (OMPAllocatorHandleT.isNull()) 10409 OMPAllocatorHandleT = AllocatorType; 10410 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10411 ErrorFound = true; 10412 break; 10413 } 10414 Stack->setAllocator(AllocatorKind, Res.get()); 10415 } 10416 if (ErrorFound) { 10417 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10418 return false; 10419 } 10420 OMPAllocatorHandleT.addConst(); 10421 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10422 return true; 10423 } 10424 10425 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10426 SourceLocation LParenLoc, 10427 SourceLocation EndLoc) { 10428 // OpenMP [2.11.3, allocate Directive, Description] 10429 // allocator is an expression of omp_allocator_handle_t type. 10430 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10431 return nullptr; 10432 10433 ExprResult Allocator = DefaultLvalueConversion(A); 10434 if (Allocator.isInvalid()) 10435 return nullptr; 10436 Allocator = PerformImplicitConversion(Allocator.get(), 10437 DSAStack->getOMPAllocatorHandleT(), 10438 Sema::AA_Initializing, 10439 /*AllowExplicit=*/true); 10440 if (Allocator.isInvalid()) 10441 return nullptr; 10442 return new (Context) 10443 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10444 } 10445 10446 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10447 SourceLocation StartLoc, 10448 SourceLocation LParenLoc, 10449 SourceLocation EndLoc) { 10450 // OpenMP [2.7.1, loop construct, Description] 10451 // OpenMP [2.8.1, simd construct, Description] 10452 // OpenMP [2.9.6, distribute construct, Description] 10453 // The parameter of the collapse clause must be a constant 10454 // positive integer expression. 10455 ExprResult NumForLoopsResult = 10456 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10457 if (NumForLoopsResult.isInvalid()) 10458 return nullptr; 10459 return new (Context) 10460 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10461 } 10462 10463 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10464 SourceLocation EndLoc, 10465 SourceLocation LParenLoc, 10466 Expr *NumForLoops) { 10467 // OpenMP [2.7.1, loop construct, Description] 10468 // OpenMP [2.8.1, simd construct, Description] 10469 // OpenMP [2.9.6, distribute construct, Description] 10470 // The parameter of the ordered clause must be a constant 10471 // positive integer expression if any. 10472 if (NumForLoops && LParenLoc.isValid()) { 10473 ExprResult NumForLoopsResult = 10474 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10475 if (NumForLoopsResult.isInvalid()) 10476 return nullptr; 10477 NumForLoops = NumForLoopsResult.get(); 10478 } else { 10479 NumForLoops = nullptr; 10480 } 10481 auto *Clause = OMPOrderedClause::Create( 10482 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10483 StartLoc, LParenLoc, EndLoc); 10484 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10485 return Clause; 10486 } 10487 10488 OMPClause *Sema::ActOnOpenMPSimpleClause( 10489 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10490 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10491 OMPClause *Res = nullptr; 10492 switch (Kind) { 10493 case OMPC_default: 10494 Res = 10495 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10496 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10497 break; 10498 case OMPC_proc_bind: 10499 Res = ActOnOpenMPProcBindClause( 10500 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10501 LParenLoc, EndLoc); 10502 break; 10503 case OMPC_atomic_default_mem_order: 10504 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10505 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10506 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10507 break; 10508 case OMPC_if: 10509 case OMPC_final: 10510 case OMPC_num_threads: 10511 case OMPC_safelen: 10512 case OMPC_simdlen: 10513 case OMPC_allocator: 10514 case OMPC_collapse: 10515 case OMPC_schedule: 10516 case OMPC_private: 10517 case OMPC_firstprivate: 10518 case OMPC_lastprivate: 10519 case OMPC_shared: 10520 case OMPC_reduction: 10521 case OMPC_task_reduction: 10522 case OMPC_in_reduction: 10523 case OMPC_linear: 10524 case OMPC_aligned: 10525 case OMPC_copyin: 10526 case OMPC_copyprivate: 10527 case OMPC_ordered: 10528 case OMPC_nowait: 10529 case OMPC_untied: 10530 case OMPC_mergeable: 10531 case OMPC_threadprivate: 10532 case OMPC_allocate: 10533 case OMPC_flush: 10534 case OMPC_read: 10535 case OMPC_write: 10536 case OMPC_update: 10537 case OMPC_capture: 10538 case OMPC_seq_cst: 10539 case OMPC_depend: 10540 case OMPC_device: 10541 case OMPC_threads: 10542 case OMPC_simd: 10543 case OMPC_map: 10544 case OMPC_num_teams: 10545 case OMPC_thread_limit: 10546 case OMPC_priority: 10547 case OMPC_grainsize: 10548 case OMPC_nogroup: 10549 case OMPC_num_tasks: 10550 case OMPC_hint: 10551 case OMPC_dist_schedule: 10552 case OMPC_defaultmap: 10553 case OMPC_unknown: 10554 case OMPC_uniform: 10555 case OMPC_to: 10556 case OMPC_from: 10557 case OMPC_use_device_ptr: 10558 case OMPC_is_device_ptr: 10559 case OMPC_unified_address: 10560 case OMPC_unified_shared_memory: 10561 case OMPC_reverse_offload: 10562 case OMPC_dynamic_allocators: 10563 llvm_unreachable("Clause is not allowed."); 10564 } 10565 return Res; 10566 } 10567 10568 static std::string 10569 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10570 ArrayRef<unsigned> Exclude = llvm::None) { 10571 SmallString<256> Buffer; 10572 llvm::raw_svector_ostream Out(Buffer); 10573 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10574 unsigned Skipped = Exclude.size(); 10575 auto S = Exclude.begin(), E = Exclude.end(); 10576 for (unsigned I = First; I < Last; ++I) { 10577 if (std::find(S, E, I) != E) { 10578 --Skipped; 10579 continue; 10580 } 10581 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10582 if (I == Bound - Skipped) 10583 Out << " or "; 10584 else if (I != Bound + 1 - Skipped) 10585 Out << ", "; 10586 } 10587 return Out.str(); 10588 } 10589 10590 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10591 SourceLocation KindKwLoc, 10592 SourceLocation StartLoc, 10593 SourceLocation LParenLoc, 10594 SourceLocation EndLoc) { 10595 if (Kind == OMPC_DEFAULT_unknown) { 10596 static_assert(OMPC_DEFAULT_unknown > 0, 10597 "OMPC_DEFAULT_unknown not greater than 0"); 10598 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10599 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10600 /*Last=*/OMPC_DEFAULT_unknown) 10601 << getOpenMPClauseName(OMPC_default); 10602 return nullptr; 10603 } 10604 switch (Kind) { 10605 case OMPC_DEFAULT_none: 10606 DSAStack->setDefaultDSANone(KindKwLoc); 10607 break; 10608 case OMPC_DEFAULT_shared: 10609 DSAStack->setDefaultDSAShared(KindKwLoc); 10610 break; 10611 case OMPC_DEFAULT_unknown: 10612 llvm_unreachable("Clause kind is not allowed."); 10613 break; 10614 } 10615 return new (Context) 10616 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10617 } 10618 10619 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10620 SourceLocation KindKwLoc, 10621 SourceLocation StartLoc, 10622 SourceLocation LParenLoc, 10623 SourceLocation EndLoc) { 10624 if (Kind == OMPC_PROC_BIND_unknown) { 10625 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10626 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10627 /*Last=*/OMPC_PROC_BIND_unknown) 10628 << getOpenMPClauseName(OMPC_proc_bind); 10629 return nullptr; 10630 } 10631 return new (Context) 10632 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10633 } 10634 10635 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10636 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10637 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10638 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10639 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10640 << getListOfPossibleValues( 10641 OMPC_atomic_default_mem_order, /*First=*/0, 10642 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10643 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10644 return nullptr; 10645 } 10646 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10647 LParenLoc, EndLoc); 10648 } 10649 10650 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10651 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10652 SourceLocation StartLoc, SourceLocation LParenLoc, 10653 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10654 SourceLocation EndLoc) { 10655 OMPClause *Res = nullptr; 10656 switch (Kind) { 10657 case OMPC_schedule: 10658 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10659 assert(Argument.size() == NumberOfElements && 10660 ArgumentLoc.size() == NumberOfElements); 10661 Res = ActOnOpenMPScheduleClause( 10662 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10663 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10664 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10665 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10666 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10667 break; 10668 case OMPC_if: 10669 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10670 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10671 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10672 DelimLoc, EndLoc); 10673 break; 10674 case OMPC_dist_schedule: 10675 Res = ActOnOpenMPDistScheduleClause( 10676 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10677 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10678 break; 10679 case OMPC_defaultmap: 10680 enum { Modifier, DefaultmapKind }; 10681 Res = ActOnOpenMPDefaultmapClause( 10682 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10683 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10684 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10685 EndLoc); 10686 break; 10687 case OMPC_final: 10688 case OMPC_num_threads: 10689 case OMPC_safelen: 10690 case OMPC_simdlen: 10691 case OMPC_allocator: 10692 case OMPC_collapse: 10693 case OMPC_default: 10694 case OMPC_proc_bind: 10695 case OMPC_private: 10696 case OMPC_firstprivate: 10697 case OMPC_lastprivate: 10698 case OMPC_shared: 10699 case OMPC_reduction: 10700 case OMPC_task_reduction: 10701 case OMPC_in_reduction: 10702 case OMPC_linear: 10703 case OMPC_aligned: 10704 case OMPC_copyin: 10705 case OMPC_copyprivate: 10706 case OMPC_ordered: 10707 case OMPC_nowait: 10708 case OMPC_untied: 10709 case OMPC_mergeable: 10710 case OMPC_threadprivate: 10711 case OMPC_allocate: 10712 case OMPC_flush: 10713 case OMPC_read: 10714 case OMPC_write: 10715 case OMPC_update: 10716 case OMPC_capture: 10717 case OMPC_seq_cst: 10718 case OMPC_depend: 10719 case OMPC_device: 10720 case OMPC_threads: 10721 case OMPC_simd: 10722 case OMPC_map: 10723 case OMPC_num_teams: 10724 case OMPC_thread_limit: 10725 case OMPC_priority: 10726 case OMPC_grainsize: 10727 case OMPC_nogroup: 10728 case OMPC_num_tasks: 10729 case OMPC_hint: 10730 case OMPC_unknown: 10731 case OMPC_uniform: 10732 case OMPC_to: 10733 case OMPC_from: 10734 case OMPC_use_device_ptr: 10735 case OMPC_is_device_ptr: 10736 case OMPC_unified_address: 10737 case OMPC_unified_shared_memory: 10738 case OMPC_reverse_offload: 10739 case OMPC_dynamic_allocators: 10740 case OMPC_atomic_default_mem_order: 10741 llvm_unreachable("Clause is not allowed."); 10742 } 10743 return Res; 10744 } 10745 10746 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10747 OpenMPScheduleClauseModifier M2, 10748 SourceLocation M1Loc, SourceLocation M2Loc) { 10749 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10750 SmallVector<unsigned, 2> Excluded; 10751 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10752 Excluded.push_back(M2); 10753 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10754 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10755 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10756 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10757 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10758 << getListOfPossibleValues(OMPC_schedule, 10759 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10760 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10761 Excluded) 10762 << getOpenMPClauseName(OMPC_schedule); 10763 return true; 10764 } 10765 return false; 10766 } 10767 10768 OMPClause *Sema::ActOnOpenMPScheduleClause( 10769 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10770 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10771 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10772 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10773 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10774 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10775 return nullptr; 10776 // OpenMP, 2.7.1, Loop Construct, Restrictions 10777 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10778 // but not both. 10779 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10780 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10781 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10782 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10783 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10784 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10785 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10786 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10787 return nullptr; 10788 } 10789 if (Kind == OMPC_SCHEDULE_unknown) { 10790 std::string Values; 10791 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10792 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10793 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10794 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10795 Exclude); 10796 } else { 10797 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10798 /*Last=*/OMPC_SCHEDULE_unknown); 10799 } 10800 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10801 << Values << getOpenMPClauseName(OMPC_schedule); 10802 return nullptr; 10803 } 10804 // OpenMP, 2.7.1, Loop Construct, Restrictions 10805 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 10806 // schedule(guided). 10807 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 10808 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 10809 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 10810 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 10811 diag::err_omp_schedule_nonmonotonic_static); 10812 return nullptr; 10813 } 10814 Expr *ValExpr = ChunkSize; 10815 Stmt *HelperValStmt = nullptr; 10816 if (ChunkSize) { 10817 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10818 !ChunkSize->isInstantiationDependent() && 10819 !ChunkSize->containsUnexpandedParameterPack()) { 10820 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 10821 ExprResult Val = 10822 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10823 if (Val.isInvalid()) 10824 return nullptr; 10825 10826 ValExpr = Val.get(); 10827 10828 // OpenMP [2.7.1, Restrictions] 10829 // chunk_size must be a loop invariant integer expression with a positive 10830 // value. 10831 llvm::APSInt Result; 10832 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10833 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10834 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10835 << "schedule" << 1 << ChunkSize->getSourceRange(); 10836 return nullptr; 10837 } 10838 } else if (getOpenMPCaptureRegionForClause( 10839 DSAStack->getCurrentDirective(), OMPC_schedule) != 10840 OMPD_unknown && 10841 !CurContext->isDependentContext()) { 10842 ValExpr = MakeFullExpr(ValExpr).get(); 10843 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10844 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10845 HelperValStmt = buildPreInits(Context, Captures); 10846 } 10847 } 10848 } 10849 10850 return new (Context) 10851 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 10852 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 10853 } 10854 10855 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 10856 SourceLocation StartLoc, 10857 SourceLocation EndLoc) { 10858 OMPClause *Res = nullptr; 10859 switch (Kind) { 10860 case OMPC_ordered: 10861 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 10862 break; 10863 case OMPC_nowait: 10864 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 10865 break; 10866 case OMPC_untied: 10867 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 10868 break; 10869 case OMPC_mergeable: 10870 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 10871 break; 10872 case OMPC_read: 10873 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 10874 break; 10875 case OMPC_write: 10876 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 10877 break; 10878 case OMPC_update: 10879 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 10880 break; 10881 case OMPC_capture: 10882 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 10883 break; 10884 case OMPC_seq_cst: 10885 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 10886 break; 10887 case OMPC_threads: 10888 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 10889 break; 10890 case OMPC_simd: 10891 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 10892 break; 10893 case OMPC_nogroup: 10894 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 10895 break; 10896 case OMPC_unified_address: 10897 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 10898 break; 10899 case OMPC_unified_shared_memory: 10900 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10901 break; 10902 case OMPC_reverse_offload: 10903 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 10904 break; 10905 case OMPC_dynamic_allocators: 10906 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 10907 break; 10908 case OMPC_if: 10909 case OMPC_final: 10910 case OMPC_num_threads: 10911 case OMPC_safelen: 10912 case OMPC_simdlen: 10913 case OMPC_allocator: 10914 case OMPC_collapse: 10915 case OMPC_schedule: 10916 case OMPC_private: 10917 case OMPC_firstprivate: 10918 case OMPC_lastprivate: 10919 case OMPC_shared: 10920 case OMPC_reduction: 10921 case OMPC_task_reduction: 10922 case OMPC_in_reduction: 10923 case OMPC_linear: 10924 case OMPC_aligned: 10925 case OMPC_copyin: 10926 case OMPC_copyprivate: 10927 case OMPC_default: 10928 case OMPC_proc_bind: 10929 case OMPC_threadprivate: 10930 case OMPC_allocate: 10931 case OMPC_flush: 10932 case OMPC_depend: 10933 case OMPC_device: 10934 case OMPC_map: 10935 case OMPC_num_teams: 10936 case OMPC_thread_limit: 10937 case OMPC_priority: 10938 case OMPC_grainsize: 10939 case OMPC_num_tasks: 10940 case OMPC_hint: 10941 case OMPC_dist_schedule: 10942 case OMPC_defaultmap: 10943 case OMPC_unknown: 10944 case OMPC_uniform: 10945 case OMPC_to: 10946 case OMPC_from: 10947 case OMPC_use_device_ptr: 10948 case OMPC_is_device_ptr: 10949 case OMPC_atomic_default_mem_order: 10950 llvm_unreachable("Clause is not allowed."); 10951 } 10952 return Res; 10953 } 10954 10955 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 10956 SourceLocation EndLoc) { 10957 DSAStack->setNowaitRegion(); 10958 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 10959 } 10960 10961 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 10962 SourceLocation EndLoc) { 10963 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 10964 } 10965 10966 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 10967 SourceLocation EndLoc) { 10968 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10969 } 10970 10971 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10972 SourceLocation EndLoc) { 10973 return new (Context) OMPReadClause(StartLoc, EndLoc); 10974 } 10975 10976 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10977 SourceLocation EndLoc) { 10978 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10979 } 10980 10981 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10982 SourceLocation EndLoc) { 10983 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10984 } 10985 10986 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10987 SourceLocation EndLoc) { 10988 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10989 } 10990 10991 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10992 SourceLocation EndLoc) { 10993 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10994 } 10995 10996 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10997 SourceLocation EndLoc) { 10998 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10999 } 11000 11001 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11002 SourceLocation EndLoc) { 11003 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11004 } 11005 11006 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11007 SourceLocation EndLoc) { 11008 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11009 } 11010 11011 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11012 SourceLocation EndLoc) { 11013 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11014 } 11015 11016 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11017 SourceLocation EndLoc) { 11018 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11019 } 11020 11021 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11022 SourceLocation EndLoc) { 11023 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11024 } 11025 11026 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11027 SourceLocation EndLoc) { 11028 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11029 } 11030 11031 OMPClause *Sema::ActOnOpenMPVarListClause( 11032 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11033 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11034 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11035 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11036 OpenMPLinearClauseKind LinKind, 11037 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11038 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11039 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11040 SourceLocation StartLoc = Locs.StartLoc; 11041 SourceLocation LParenLoc = Locs.LParenLoc; 11042 SourceLocation EndLoc = Locs.EndLoc; 11043 OMPClause *Res = nullptr; 11044 switch (Kind) { 11045 case OMPC_private: 11046 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11047 break; 11048 case OMPC_firstprivate: 11049 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11050 break; 11051 case OMPC_lastprivate: 11052 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11053 break; 11054 case OMPC_shared: 11055 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11056 break; 11057 case OMPC_reduction: 11058 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11059 EndLoc, ReductionOrMapperIdScopeSpec, 11060 ReductionOrMapperId); 11061 break; 11062 case OMPC_task_reduction: 11063 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11064 EndLoc, ReductionOrMapperIdScopeSpec, 11065 ReductionOrMapperId); 11066 break; 11067 case OMPC_in_reduction: 11068 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11069 EndLoc, ReductionOrMapperIdScopeSpec, 11070 ReductionOrMapperId); 11071 break; 11072 case OMPC_linear: 11073 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11074 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11075 break; 11076 case OMPC_aligned: 11077 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11078 ColonLoc, EndLoc); 11079 break; 11080 case OMPC_copyin: 11081 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11082 break; 11083 case OMPC_copyprivate: 11084 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11085 break; 11086 case OMPC_flush: 11087 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11088 break; 11089 case OMPC_depend: 11090 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11091 StartLoc, LParenLoc, EndLoc); 11092 break; 11093 case OMPC_map: 11094 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11095 ReductionOrMapperIdScopeSpec, 11096 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11097 DepLinMapLoc, ColonLoc, VarList, Locs); 11098 break; 11099 case OMPC_to: 11100 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11101 ReductionOrMapperId, Locs); 11102 break; 11103 case OMPC_from: 11104 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11105 ReductionOrMapperId, Locs); 11106 break; 11107 case OMPC_use_device_ptr: 11108 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11109 break; 11110 case OMPC_is_device_ptr: 11111 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11112 break; 11113 case OMPC_allocate: 11114 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11115 ColonLoc, EndLoc); 11116 break; 11117 case OMPC_if: 11118 case OMPC_final: 11119 case OMPC_num_threads: 11120 case OMPC_safelen: 11121 case OMPC_simdlen: 11122 case OMPC_allocator: 11123 case OMPC_collapse: 11124 case OMPC_default: 11125 case OMPC_proc_bind: 11126 case OMPC_schedule: 11127 case OMPC_ordered: 11128 case OMPC_nowait: 11129 case OMPC_untied: 11130 case OMPC_mergeable: 11131 case OMPC_threadprivate: 11132 case OMPC_read: 11133 case OMPC_write: 11134 case OMPC_update: 11135 case OMPC_capture: 11136 case OMPC_seq_cst: 11137 case OMPC_device: 11138 case OMPC_threads: 11139 case OMPC_simd: 11140 case OMPC_num_teams: 11141 case OMPC_thread_limit: 11142 case OMPC_priority: 11143 case OMPC_grainsize: 11144 case OMPC_nogroup: 11145 case OMPC_num_tasks: 11146 case OMPC_hint: 11147 case OMPC_dist_schedule: 11148 case OMPC_defaultmap: 11149 case OMPC_unknown: 11150 case OMPC_uniform: 11151 case OMPC_unified_address: 11152 case OMPC_unified_shared_memory: 11153 case OMPC_reverse_offload: 11154 case OMPC_dynamic_allocators: 11155 case OMPC_atomic_default_mem_order: 11156 llvm_unreachable("Clause is not allowed."); 11157 } 11158 return Res; 11159 } 11160 11161 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11162 ExprObjectKind OK, SourceLocation Loc) { 11163 ExprResult Res = BuildDeclRefExpr( 11164 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11165 if (!Res.isUsable()) 11166 return ExprError(); 11167 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11168 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11169 if (!Res.isUsable()) 11170 return ExprError(); 11171 } 11172 if (VK != VK_LValue && Res.get()->isGLValue()) { 11173 Res = DefaultLvalueConversion(Res.get()); 11174 if (!Res.isUsable()) 11175 return ExprError(); 11176 } 11177 return Res; 11178 } 11179 11180 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11181 SourceLocation StartLoc, 11182 SourceLocation LParenLoc, 11183 SourceLocation EndLoc) { 11184 SmallVector<Expr *, 8> Vars; 11185 SmallVector<Expr *, 8> PrivateCopies; 11186 for (Expr *RefExpr : VarList) { 11187 assert(RefExpr && "NULL expr in OpenMP private clause."); 11188 SourceLocation ELoc; 11189 SourceRange ERange; 11190 Expr *SimpleRefExpr = RefExpr; 11191 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11192 if (Res.second) { 11193 // It will be analyzed later. 11194 Vars.push_back(RefExpr); 11195 PrivateCopies.push_back(nullptr); 11196 } 11197 ValueDecl *D = Res.first; 11198 if (!D) 11199 continue; 11200 11201 QualType Type = D->getType(); 11202 auto *VD = dyn_cast<VarDecl>(D); 11203 11204 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11205 // A variable that appears in a private clause must not have an incomplete 11206 // type or a reference type. 11207 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11208 continue; 11209 Type = Type.getNonReferenceType(); 11210 11211 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11212 // A variable that is privatized must not have a const-qualified type 11213 // unless it is of class type with a mutable member. This restriction does 11214 // not apply to the firstprivate clause. 11215 // 11216 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11217 // A variable that appears in a private clause must not have a 11218 // const-qualified type unless it is of class type with a mutable member. 11219 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11220 continue; 11221 11222 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11223 // in a Construct] 11224 // Variables with the predetermined data-sharing attributes may not be 11225 // listed in data-sharing attributes clauses, except for the cases 11226 // listed below. For these exceptions only, listing a predetermined 11227 // variable in a data-sharing attribute clause is allowed and overrides 11228 // the variable's predetermined data-sharing attributes. 11229 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11230 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11231 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11232 << getOpenMPClauseName(OMPC_private); 11233 reportOriginalDsa(*this, DSAStack, D, DVar); 11234 continue; 11235 } 11236 11237 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11238 // Variably modified types are not supported for tasks. 11239 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11240 isOpenMPTaskingDirective(CurrDir)) { 11241 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11242 << getOpenMPClauseName(OMPC_private) << Type 11243 << getOpenMPDirectiveName(CurrDir); 11244 bool IsDecl = 11245 !VD || 11246 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11247 Diag(D->getLocation(), 11248 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11249 << D; 11250 continue; 11251 } 11252 11253 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11254 // A list item cannot appear in both a map clause and a data-sharing 11255 // attribute clause on the same construct 11256 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11257 OpenMPClauseKind ConflictKind; 11258 if (DSAStack->checkMappableExprComponentListsForDecl( 11259 VD, /*CurrentRegionOnly=*/true, 11260 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 11261 OpenMPClauseKind WhereFoundClauseKind) -> bool { 11262 ConflictKind = WhereFoundClauseKind; 11263 return true; 11264 })) { 11265 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11266 << getOpenMPClauseName(OMPC_private) 11267 << getOpenMPClauseName(ConflictKind) 11268 << getOpenMPDirectiveName(CurrDir); 11269 reportOriginalDsa(*this, DSAStack, D, DVar); 11270 continue; 11271 } 11272 } 11273 11274 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 11275 // A variable of class type (or array thereof) that appears in a private 11276 // clause requires an accessible, unambiguous default constructor for the 11277 // class type. 11278 // Generate helper private variable and initialize it with the default 11279 // value. The address of the original variable is replaced by the address of 11280 // the new private variable in CodeGen. This new variable is not added to 11281 // IdResolver, so the code in the OpenMP region uses original variable for 11282 // proper diagnostics. 11283 Type = Type.getUnqualifiedType(); 11284 VarDecl *VDPrivate = 11285 buildVarDecl(*this, ELoc, Type, D->getName(), 11286 D->hasAttrs() ? &D->getAttrs() : nullptr, 11287 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11288 ActOnUninitializedDecl(VDPrivate); 11289 if (VDPrivate->isInvalidDecl()) 11290 continue; 11291 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11292 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11293 11294 DeclRefExpr *Ref = nullptr; 11295 if (!VD && !CurContext->isDependentContext()) 11296 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11297 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 11298 Vars.push_back((VD || CurContext->isDependentContext()) 11299 ? RefExpr->IgnoreParens() 11300 : Ref); 11301 PrivateCopies.push_back(VDPrivateRefExpr); 11302 } 11303 11304 if (Vars.empty()) 11305 return nullptr; 11306 11307 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11308 PrivateCopies); 11309 } 11310 11311 namespace { 11312 class DiagsUninitializedSeveretyRAII { 11313 private: 11314 DiagnosticsEngine &Diags; 11315 SourceLocation SavedLoc; 11316 bool IsIgnored = false; 11317 11318 public: 11319 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 11320 bool IsIgnored) 11321 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 11322 if (!IsIgnored) { 11323 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 11324 /*Map*/ diag::Severity::Ignored, Loc); 11325 } 11326 } 11327 ~DiagsUninitializedSeveretyRAII() { 11328 if (!IsIgnored) 11329 Diags.popMappings(SavedLoc); 11330 } 11331 }; 11332 } 11333 11334 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 11335 SourceLocation StartLoc, 11336 SourceLocation LParenLoc, 11337 SourceLocation EndLoc) { 11338 SmallVector<Expr *, 8> Vars; 11339 SmallVector<Expr *, 8> PrivateCopies; 11340 SmallVector<Expr *, 8> Inits; 11341 SmallVector<Decl *, 4> ExprCaptures; 11342 bool IsImplicitClause = 11343 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 11344 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 11345 11346 for (Expr *RefExpr : VarList) { 11347 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 11348 SourceLocation ELoc; 11349 SourceRange ERange; 11350 Expr *SimpleRefExpr = RefExpr; 11351 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11352 if (Res.second) { 11353 // It will be analyzed later. 11354 Vars.push_back(RefExpr); 11355 PrivateCopies.push_back(nullptr); 11356 Inits.push_back(nullptr); 11357 } 11358 ValueDecl *D = Res.first; 11359 if (!D) 11360 continue; 11361 11362 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11363 QualType Type = D->getType(); 11364 auto *VD = dyn_cast<VarDecl>(D); 11365 11366 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11367 // A variable that appears in a private clause must not have an incomplete 11368 // type or a reference type. 11369 if (RequireCompleteType(ELoc, Type, 11370 diag::err_omp_firstprivate_incomplete_type)) 11371 continue; 11372 Type = Type.getNonReferenceType(); 11373 11374 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11375 // A variable of class type (or array thereof) that appears in a private 11376 // clause requires an accessible, unambiguous copy constructor for the 11377 // class type. 11378 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11379 11380 // If an implicit firstprivate variable found it was checked already. 11381 DSAStackTy::DSAVarData TopDVar; 11382 if (!IsImplicitClause) { 11383 DSAStackTy::DSAVarData DVar = 11384 DSAStack->getTopDSA(D, /*FromParent=*/false); 11385 TopDVar = DVar; 11386 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11387 bool IsConstant = ElemType.isConstant(Context); 11388 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11389 // A list item that specifies a given variable may not appear in more 11390 // than one clause on the same directive, except that a variable may be 11391 // specified in both firstprivate and lastprivate clauses. 11392 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11393 // A list item may appear in a firstprivate or lastprivate clause but not 11394 // both. 11395 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11396 (isOpenMPDistributeDirective(CurrDir) || 11397 DVar.CKind != OMPC_lastprivate) && 11398 DVar.RefExpr) { 11399 Diag(ELoc, diag::err_omp_wrong_dsa) 11400 << getOpenMPClauseName(DVar.CKind) 11401 << getOpenMPClauseName(OMPC_firstprivate); 11402 reportOriginalDsa(*this, DSAStack, D, DVar); 11403 continue; 11404 } 11405 11406 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11407 // in a Construct] 11408 // Variables with the predetermined data-sharing attributes may not be 11409 // listed in data-sharing attributes clauses, except for the cases 11410 // listed below. For these exceptions only, listing a predetermined 11411 // variable in a data-sharing attribute clause is allowed and overrides 11412 // the variable's predetermined data-sharing attributes. 11413 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11414 // in a Construct, C/C++, p.2] 11415 // Variables with const-qualified type having no mutable member may be 11416 // listed in a firstprivate clause, even if they are static data members. 11417 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11418 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11419 Diag(ELoc, diag::err_omp_wrong_dsa) 11420 << getOpenMPClauseName(DVar.CKind) 11421 << getOpenMPClauseName(OMPC_firstprivate); 11422 reportOriginalDsa(*this, DSAStack, D, DVar); 11423 continue; 11424 } 11425 11426 // OpenMP [2.9.3.4, Restrictions, p.2] 11427 // A list item that is private within a parallel region must not appear 11428 // in a firstprivate clause on a worksharing construct if any of the 11429 // worksharing regions arising from the worksharing construct ever bind 11430 // to any of the parallel regions arising from the parallel construct. 11431 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11432 // A list item that is private within a teams region must not appear in a 11433 // firstprivate clause on a distribute construct if any of the distribute 11434 // regions arising from the distribute construct ever bind to any of the 11435 // teams regions arising from the teams construct. 11436 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11437 // A list item that appears in a reduction clause of a teams construct 11438 // must not appear in a firstprivate clause on a distribute construct if 11439 // any of the distribute regions arising from the distribute construct 11440 // ever bind to any of the teams regions arising from the teams construct. 11441 if ((isOpenMPWorksharingDirective(CurrDir) || 11442 isOpenMPDistributeDirective(CurrDir)) && 11443 !isOpenMPParallelDirective(CurrDir) && 11444 !isOpenMPTeamsDirective(CurrDir)) { 11445 DVar = DSAStack->getImplicitDSA(D, true); 11446 if (DVar.CKind != OMPC_shared && 11447 (isOpenMPParallelDirective(DVar.DKind) || 11448 isOpenMPTeamsDirective(DVar.DKind) || 11449 DVar.DKind == OMPD_unknown)) { 11450 Diag(ELoc, diag::err_omp_required_access) 11451 << getOpenMPClauseName(OMPC_firstprivate) 11452 << getOpenMPClauseName(OMPC_shared); 11453 reportOriginalDsa(*this, DSAStack, D, DVar); 11454 continue; 11455 } 11456 } 11457 // OpenMP [2.9.3.4, Restrictions, p.3] 11458 // A list item that appears in a reduction clause of a parallel construct 11459 // must not appear in a firstprivate clause on a worksharing or task 11460 // construct if any of the worksharing or task regions arising from the 11461 // worksharing or task construct ever bind to any of the parallel regions 11462 // arising from the parallel construct. 11463 // OpenMP [2.9.3.4, Restrictions, p.4] 11464 // A list item that appears in a reduction clause in worksharing 11465 // construct must not appear in a firstprivate clause in a task construct 11466 // encountered during execution of any of the worksharing regions arising 11467 // from the worksharing construct. 11468 if (isOpenMPTaskingDirective(CurrDir)) { 11469 DVar = DSAStack->hasInnermostDSA( 11470 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11471 [](OpenMPDirectiveKind K) { 11472 return isOpenMPParallelDirective(K) || 11473 isOpenMPWorksharingDirective(K) || 11474 isOpenMPTeamsDirective(K); 11475 }, 11476 /*FromParent=*/true); 11477 if (DVar.CKind == OMPC_reduction && 11478 (isOpenMPParallelDirective(DVar.DKind) || 11479 isOpenMPWorksharingDirective(DVar.DKind) || 11480 isOpenMPTeamsDirective(DVar.DKind))) { 11481 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11482 << getOpenMPDirectiveName(DVar.DKind); 11483 reportOriginalDsa(*this, DSAStack, D, DVar); 11484 continue; 11485 } 11486 } 11487 11488 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11489 // A list item cannot appear in both a map clause and a data-sharing 11490 // attribute clause on the same construct 11491 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11492 OpenMPClauseKind ConflictKind; 11493 if (DSAStack->checkMappableExprComponentListsForDecl( 11494 VD, /*CurrentRegionOnly=*/true, 11495 [&ConflictKind]( 11496 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11497 OpenMPClauseKind WhereFoundClauseKind) { 11498 ConflictKind = WhereFoundClauseKind; 11499 return true; 11500 })) { 11501 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11502 << getOpenMPClauseName(OMPC_firstprivate) 11503 << getOpenMPClauseName(ConflictKind) 11504 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11505 reportOriginalDsa(*this, DSAStack, D, DVar); 11506 continue; 11507 } 11508 } 11509 } 11510 11511 // Variably modified types are not supported for tasks. 11512 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11513 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11514 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11515 << getOpenMPClauseName(OMPC_firstprivate) << Type 11516 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11517 bool IsDecl = 11518 !VD || 11519 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11520 Diag(D->getLocation(), 11521 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11522 << D; 11523 continue; 11524 } 11525 11526 Type = Type.getUnqualifiedType(); 11527 VarDecl *VDPrivate = 11528 buildVarDecl(*this, ELoc, Type, D->getName(), 11529 D->hasAttrs() ? &D->getAttrs() : nullptr, 11530 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11531 // Generate helper private variable and initialize it with the value of the 11532 // original variable. The address of the original variable is replaced by 11533 // the address of the new private variable in the CodeGen. This new variable 11534 // is not added to IdResolver, so the code in the OpenMP region uses 11535 // original variable for proper diagnostics and variable capturing. 11536 Expr *VDInitRefExpr = nullptr; 11537 // For arrays generate initializer for single element and replace it by the 11538 // original array element in CodeGen. 11539 if (Type->isArrayType()) { 11540 VarDecl *VDInit = 11541 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11542 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11543 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11544 ElemType = ElemType.getUnqualifiedType(); 11545 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11546 ".firstprivate.temp"); 11547 InitializedEntity Entity = 11548 InitializedEntity::InitializeVariable(VDInitTemp); 11549 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11550 11551 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11552 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11553 if (Result.isInvalid()) 11554 VDPrivate->setInvalidDecl(); 11555 else 11556 VDPrivate->setInit(Result.getAs<Expr>()); 11557 // Remove temp variable declaration. 11558 Context.Deallocate(VDInitTemp); 11559 } else { 11560 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11561 ".firstprivate.temp"); 11562 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11563 RefExpr->getExprLoc()); 11564 AddInitializerToDecl(VDPrivate, 11565 DefaultLvalueConversion(VDInitRefExpr).get(), 11566 /*DirectInit=*/false); 11567 } 11568 if (VDPrivate->isInvalidDecl()) { 11569 if (IsImplicitClause) { 11570 Diag(RefExpr->getExprLoc(), 11571 diag::note_omp_task_predetermined_firstprivate_here); 11572 } 11573 continue; 11574 } 11575 CurContext->addDecl(VDPrivate); 11576 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11577 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11578 RefExpr->getExprLoc()); 11579 DeclRefExpr *Ref = nullptr; 11580 if (!VD && !CurContext->isDependentContext()) { 11581 if (TopDVar.CKind == OMPC_lastprivate) { 11582 Ref = TopDVar.PrivateCopy; 11583 } else { 11584 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11585 if (!isOpenMPCapturedDecl(D)) 11586 ExprCaptures.push_back(Ref->getDecl()); 11587 } 11588 } 11589 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11590 Vars.push_back((VD || CurContext->isDependentContext()) 11591 ? RefExpr->IgnoreParens() 11592 : Ref); 11593 PrivateCopies.push_back(VDPrivateRefExpr); 11594 Inits.push_back(VDInitRefExpr); 11595 } 11596 11597 if (Vars.empty()) 11598 return nullptr; 11599 11600 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11601 Vars, PrivateCopies, Inits, 11602 buildPreInits(Context, ExprCaptures)); 11603 } 11604 11605 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11606 SourceLocation StartLoc, 11607 SourceLocation LParenLoc, 11608 SourceLocation EndLoc) { 11609 SmallVector<Expr *, 8> Vars; 11610 SmallVector<Expr *, 8> SrcExprs; 11611 SmallVector<Expr *, 8> DstExprs; 11612 SmallVector<Expr *, 8> AssignmentOps; 11613 SmallVector<Decl *, 4> ExprCaptures; 11614 SmallVector<Expr *, 4> ExprPostUpdates; 11615 for (Expr *RefExpr : VarList) { 11616 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11617 SourceLocation ELoc; 11618 SourceRange ERange; 11619 Expr *SimpleRefExpr = RefExpr; 11620 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11621 if (Res.second) { 11622 // It will be analyzed later. 11623 Vars.push_back(RefExpr); 11624 SrcExprs.push_back(nullptr); 11625 DstExprs.push_back(nullptr); 11626 AssignmentOps.push_back(nullptr); 11627 } 11628 ValueDecl *D = Res.first; 11629 if (!D) 11630 continue; 11631 11632 QualType Type = D->getType(); 11633 auto *VD = dyn_cast<VarDecl>(D); 11634 11635 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11636 // A variable that appears in a lastprivate clause must not have an 11637 // incomplete type or a reference type. 11638 if (RequireCompleteType(ELoc, Type, 11639 diag::err_omp_lastprivate_incomplete_type)) 11640 continue; 11641 Type = Type.getNonReferenceType(); 11642 11643 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11644 // A variable that is privatized must not have a const-qualified type 11645 // unless it is of class type with a mutable member. This restriction does 11646 // not apply to the firstprivate clause. 11647 // 11648 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11649 // A variable that appears in a lastprivate clause must not have a 11650 // const-qualified type unless it is of class type with a mutable member. 11651 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11652 continue; 11653 11654 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11655 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11656 // in a Construct] 11657 // Variables with the predetermined data-sharing attributes may not be 11658 // listed in data-sharing attributes clauses, except for the cases 11659 // listed below. 11660 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11661 // A list item may appear in a firstprivate or lastprivate clause but not 11662 // both. 11663 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11664 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11665 (isOpenMPDistributeDirective(CurrDir) || 11666 DVar.CKind != OMPC_firstprivate) && 11667 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11668 Diag(ELoc, diag::err_omp_wrong_dsa) 11669 << getOpenMPClauseName(DVar.CKind) 11670 << getOpenMPClauseName(OMPC_lastprivate); 11671 reportOriginalDsa(*this, DSAStack, D, DVar); 11672 continue; 11673 } 11674 11675 // OpenMP [2.14.3.5, Restrictions, p.2] 11676 // A list item that is private within a parallel region, or that appears in 11677 // the reduction clause of a parallel construct, must not appear in a 11678 // lastprivate clause on a worksharing construct if any of the corresponding 11679 // worksharing regions ever binds to any of the corresponding parallel 11680 // regions. 11681 DSAStackTy::DSAVarData TopDVar = DVar; 11682 if (isOpenMPWorksharingDirective(CurrDir) && 11683 !isOpenMPParallelDirective(CurrDir) && 11684 !isOpenMPTeamsDirective(CurrDir)) { 11685 DVar = DSAStack->getImplicitDSA(D, true); 11686 if (DVar.CKind != OMPC_shared) { 11687 Diag(ELoc, diag::err_omp_required_access) 11688 << getOpenMPClauseName(OMPC_lastprivate) 11689 << getOpenMPClauseName(OMPC_shared); 11690 reportOriginalDsa(*this, DSAStack, D, DVar); 11691 continue; 11692 } 11693 } 11694 11695 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11696 // A variable of class type (or array thereof) that appears in a 11697 // lastprivate clause requires an accessible, unambiguous default 11698 // constructor for the class type, unless the list item is also specified 11699 // in a firstprivate clause. 11700 // A variable of class type (or array thereof) that appears in a 11701 // lastprivate clause requires an accessible, unambiguous copy assignment 11702 // operator for the class type. 11703 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11704 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11705 Type.getUnqualifiedType(), ".lastprivate.src", 11706 D->hasAttrs() ? &D->getAttrs() : nullptr); 11707 DeclRefExpr *PseudoSrcExpr = 11708 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11709 VarDecl *DstVD = 11710 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11711 D->hasAttrs() ? &D->getAttrs() : nullptr); 11712 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11713 // For arrays generate assignment operation for single element and replace 11714 // it by the original array element in CodeGen. 11715 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11716 PseudoDstExpr, PseudoSrcExpr); 11717 if (AssignmentOp.isInvalid()) 11718 continue; 11719 AssignmentOp = 11720 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11721 if (AssignmentOp.isInvalid()) 11722 continue; 11723 11724 DeclRefExpr *Ref = nullptr; 11725 if (!VD && !CurContext->isDependentContext()) { 11726 if (TopDVar.CKind == OMPC_firstprivate) { 11727 Ref = TopDVar.PrivateCopy; 11728 } else { 11729 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11730 if (!isOpenMPCapturedDecl(D)) 11731 ExprCaptures.push_back(Ref->getDecl()); 11732 } 11733 if (TopDVar.CKind == OMPC_firstprivate || 11734 (!isOpenMPCapturedDecl(D) && 11735 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11736 ExprResult RefRes = DefaultLvalueConversion(Ref); 11737 if (!RefRes.isUsable()) 11738 continue; 11739 ExprResult PostUpdateRes = 11740 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11741 RefRes.get()); 11742 if (!PostUpdateRes.isUsable()) 11743 continue; 11744 ExprPostUpdates.push_back( 11745 IgnoredValueConversions(PostUpdateRes.get()).get()); 11746 } 11747 } 11748 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11749 Vars.push_back((VD || CurContext->isDependentContext()) 11750 ? RefExpr->IgnoreParens() 11751 : Ref); 11752 SrcExprs.push_back(PseudoSrcExpr); 11753 DstExprs.push_back(PseudoDstExpr); 11754 AssignmentOps.push_back(AssignmentOp.get()); 11755 } 11756 11757 if (Vars.empty()) 11758 return nullptr; 11759 11760 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11761 Vars, SrcExprs, DstExprs, AssignmentOps, 11762 buildPreInits(Context, ExprCaptures), 11763 buildPostUpdate(*this, ExprPostUpdates)); 11764 } 11765 11766 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11767 SourceLocation StartLoc, 11768 SourceLocation LParenLoc, 11769 SourceLocation EndLoc) { 11770 SmallVector<Expr *, 8> Vars; 11771 for (Expr *RefExpr : VarList) { 11772 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11773 SourceLocation ELoc; 11774 SourceRange ERange; 11775 Expr *SimpleRefExpr = RefExpr; 11776 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11777 if (Res.second) { 11778 // It will be analyzed later. 11779 Vars.push_back(RefExpr); 11780 } 11781 ValueDecl *D = Res.first; 11782 if (!D) 11783 continue; 11784 11785 auto *VD = dyn_cast<VarDecl>(D); 11786 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11787 // in a Construct] 11788 // Variables with the predetermined data-sharing attributes may not be 11789 // listed in data-sharing attributes clauses, except for the cases 11790 // listed below. For these exceptions only, listing a predetermined 11791 // variable in a data-sharing attribute clause is allowed and overrides 11792 // the variable's predetermined data-sharing attributes. 11793 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11794 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 11795 DVar.RefExpr) { 11796 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11797 << getOpenMPClauseName(OMPC_shared); 11798 reportOriginalDsa(*this, DSAStack, D, DVar); 11799 continue; 11800 } 11801 11802 DeclRefExpr *Ref = nullptr; 11803 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 11804 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11805 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 11806 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 11807 ? RefExpr->IgnoreParens() 11808 : Ref); 11809 } 11810 11811 if (Vars.empty()) 11812 return nullptr; 11813 11814 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 11815 } 11816 11817 namespace { 11818 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 11819 DSAStackTy *Stack; 11820 11821 public: 11822 bool VisitDeclRefExpr(DeclRefExpr *E) { 11823 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 11824 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 11825 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 11826 return false; 11827 if (DVar.CKind != OMPC_unknown) 11828 return true; 11829 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 11830 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 11831 /*FromParent=*/true); 11832 return DVarPrivate.CKind != OMPC_unknown; 11833 } 11834 return false; 11835 } 11836 bool VisitStmt(Stmt *S) { 11837 for (Stmt *Child : S->children()) { 11838 if (Child && Visit(Child)) 11839 return true; 11840 } 11841 return false; 11842 } 11843 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 11844 }; 11845 } // namespace 11846 11847 namespace { 11848 // Transform MemberExpression for specified FieldDecl of current class to 11849 // DeclRefExpr to specified OMPCapturedExprDecl. 11850 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 11851 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 11852 ValueDecl *Field = nullptr; 11853 DeclRefExpr *CapturedExpr = nullptr; 11854 11855 public: 11856 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 11857 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 11858 11859 ExprResult TransformMemberExpr(MemberExpr *E) { 11860 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 11861 E->getMemberDecl() == Field) { 11862 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 11863 return CapturedExpr; 11864 } 11865 return BaseTransform::TransformMemberExpr(E); 11866 } 11867 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 11868 }; 11869 } // namespace 11870 11871 template <typename T, typename U> 11872 static T filterLookupForUDReductionAndMapper( 11873 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 11874 for (U &Set : Lookups) { 11875 for (auto *D : Set) { 11876 if (T Res = Gen(cast<ValueDecl>(D))) 11877 return Res; 11878 } 11879 } 11880 return T(); 11881 } 11882 11883 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 11884 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 11885 11886 for (auto RD : D->redecls()) { 11887 // Don't bother with extra checks if we already know this one isn't visible. 11888 if (RD == D) 11889 continue; 11890 11891 auto ND = cast<NamedDecl>(RD); 11892 if (LookupResult::isVisible(SemaRef, ND)) 11893 return ND; 11894 } 11895 11896 return nullptr; 11897 } 11898 11899 static void 11900 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 11901 SourceLocation Loc, QualType Ty, 11902 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 11903 // Find all of the associated namespaces and classes based on the 11904 // arguments we have. 11905 Sema::AssociatedNamespaceSet AssociatedNamespaces; 11906 Sema::AssociatedClassSet AssociatedClasses; 11907 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 11908 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 11909 AssociatedClasses); 11910 11911 // C++ [basic.lookup.argdep]p3: 11912 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11913 // and let Y be the lookup set produced by argument dependent 11914 // lookup (defined as follows). If X contains [...] then Y is 11915 // empty. Otherwise Y is the set of declarations found in the 11916 // namespaces associated with the argument types as described 11917 // below. The set of declarations found by the lookup of the name 11918 // is the union of X and Y. 11919 // 11920 // Here, we compute Y and add its members to the overloaded 11921 // candidate set. 11922 for (auto *NS : AssociatedNamespaces) { 11923 // When considering an associated namespace, the lookup is the 11924 // same as the lookup performed when the associated namespace is 11925 // used as a qualifier (3.4.3.2) except that: 11926 // 11927 // -- Any using-directives in the associated namespace are 11928 // ignored. 11929 // 11930 // -- Any namespace-scope friend functions declared in 11931 // associated classes are visible within their respective 11932 // namespaces even if they are not visible during an ordinary 11933 // lookup (11.4). 11934 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11935 for (auto *D : R) { 11936 auto *Underlying = D; 11937 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11938 Underlying = USD->getTargetDecl(); 11939 11940 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11941 !isa<OMPDeclareMapperDecl>(Underlying)) 11942 continue; 11943 11944 if (!SemaRef.isVisible(D)) { 11945 D = findAcceptableDecl(SemaRef, D); 11946 if (!D) 11947 continue; 11948 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11949 Underlying = USD->getTargetDecl(); 11950 } 11951 Lookups.emplace_back(); 11952 Lookups.back().addDecl(Underlying); 11953 } 11954 } 11955 } 11956 11957 static ExprResult 11958 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11959 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11960 const DeclarationNameInfo &ReductionId, QualType Ty, 11961 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11962 if (ReductionIdScopeSpec.isInvalid()) 11963 return ExprError(); 11964 SmallVector<UnresolvedSet<8>, 4> Lookups; 11965 if (S) { 11966 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11967 Lookup.suppressDiagnostics(); 11968 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11969 NamedDecl *D = Lookup.getRepresentativeDecl(); 11970 do { 11971 S = S->getParent(); 11972 } while (S && !S->isDeclScope(D)); 11973 if (S) 11974 S = S->getParent(); 11975 Lookups.emplace_back(); 11976 Lookups.back().append(Lookup.begin(), Lookup.end()); 11977 Lookup.clear(); 11978 } 11979 } else if (auto *ULE = 11980 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11981 Lookups.push_back(UnresolvedSet<8>()); 11982 Decl *PrevD = nullptr; 11983 for (NamedDecl *D : ULE->decls()) { 11984 if (D == PrevD) 11985 Lookups.push_back(UnresolvedSet<8>()); 11986 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11987 Lookups.back().addDecl(DRD); 11988 PrevD = D; 11989 } 11990 } 11991 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11992 Ty->isInstantiationDependentType() || 11993 Ty->containsUnexpandedParameterPack() || 11994 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11995 return !D->isInvalidDecl() && 11996 (D->getType()->isDependentType() || 11997 D->getType()->isInstantiationDependentType() || 11998 D->getType()->containsUnexpandedParameterPack()); 11999 })) { 12000 UnresolvedSet<8> ResSet; 12001 for (const UnresolvedSet<8> &Set : Lookups) { 12002 if (Set.empty()) 12003 continue; 12004 ResSet.append(Set.begin(), Set.end()); 12005 // The last item marks the end of all declarations at the specified scope. 12006 ResSet.addDecl(Set[Set.size() - 1]); 12007 } 12008 return UnresolvedLookupExpr::Create( 12009 SemaRef.Context, /*NamingClass=*/nullptr, 12010 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12011 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12012 } 12013 // Lookup inside the classes. 12014 // C++ [over.match.oper]p3: 12015 // For a unary operator @ with an operand of a type whose 12016 // cv-unqualified version is T1, and for a binary operator @ with 12017 // a left operand of a type whose cv-unqualified version is T1 and 12018 // a right operand of a type whose cv-unqualified version is T2, 12019 // three sets of candidate functions, designated member 12020 // candidates, non-member candidates and built-in candidates, are 12021 // constructed as follows: 12022 // -- If T1 is a complete class type or a class currently being 12023 // defined, the set of member candidates is the result of the 12024 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12025 // the set of member candidates is empty. 12026 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12027 Lookup.suppressDiagnostics(); 12028 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12029 // Complete the type if it can be completed. 12030 // If the type is neither complete nor being defined, bail out now. 12031 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12032 TyRec->getDecl()->getDefinition()) { 12033 Lookup.clear(); 12034 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12035 if (Lookup.empty()) { 12036 Lookups.emplace_back(); 12037 Lookups.back().append(Lookup.begin(), Lookup.end()); 12038 } 12039 } 12040 } 12041 // Perform ADL. 12042 if (SemaRef.getLangOpts().CPlusPlus) 12043 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12044 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12045 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12046 if (!D->isInvalidDecl() && 12047 SemaRef.Context.hasSameType(D->getType(), Ty)) 12048 return D; 12049 return nullptr; 12050 })) 12051 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12052 VK_LValue, Loc); 12053 if (SemaRef.getLangOpts().CPlusPlus) { 12054 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12055 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12056 if (!D->isInvalidDecl() && 12057 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12058 !Ty.isMoreQualifiedThan(D->getType())) 12059 return D; 12060 return nullptr; 12061 })) { 12062 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12063 /*DetectVirtual=*/false); 12064 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12065 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12066 VD->getType().getUnqualifiedType()))) { 12067 if (SemaRef.CheckBaseClassAccess( 12068 Loc, VD->getType(), Ty, Paths.front(), 12069 /*DiagID=*/0) != Sema::AR_inaccessible) { 12070 SemaRef.BuildBasePathArray(Paths, BasePath); 12071 return SemaRef.BuildDeclRefExpr( 12072 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12073 } 12074 } 12075 } 12076 } 12077 } 12078 if (ReductionIdScopeSpec.isSet()) { 12079 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12080 return ExprError(); 12081 } 12082 return ExprEmpty(); 12083 } 12084 12085 namespace { 12086 /// Data for the reduction-based clauses. 12087 struct ReductionData { 12088 /// List of original reduction items. 12089 SmallVector<Expr *, 8> Vars; 12090 /// List of private copies of the reduction items. 12091 SmallVector<Expr *, 8> Privates; 12092 /// LHS expressions for the reduction_op expressions. 12093 SmallVector<Expr *, 8> LHSs; 12094 /// RHS expressions for the reduction_op expressions. 12095 SmallVector<Expr *, 8> RHSs; 12096 /// Reduction operation expression. 12097 SmallVector<Expr *, 8> ReductionOps; 12098 /// Taskgroup descriptors for the corresponding reduction items in 12099 /// in_reduction clauses. 12100 SmallVector<Expr *, 8> TaskgroupDescriptors; 12101 /// List of captures for clause. 12102 SmallVector<Decl *, 4> ExprCaptures; 12103 /// List of postupdate expressions. 12104 SmallVector<Expr *, 4> ExprPostUpdates; 12105 ReductionData() = delete; 12106 /// Reserves required memory for the reduction data. 12107 ReductionData(unsigned Size) { 12108 Vars.reserve(Size); 12109 Privates.reserve(Size); 12110 LHSs.reserve(Size); 12111 RHSs.reserve(Size); 12112 ReductionOps.reserve(Size); 12113 TaskgroupDescriptors.reserve(Size); 12114 ExprCaptures.reserve(Size); 12115 ExprPostUpdates.reserve(Size); 12116 } 12117 /// Stores reduction item and reduction operation only (required for dependent 12118 /// reduction item). 12119 void push(Expr *Item, Expr *ReductionOp) { 12120 Vars.emplace_back(Item); 12121 Privates.emplace_back(nullptr); 12122 LHSs.emplace_back(nullptr); 12123 RHSs.emplace_back(nullptr); 12124 ReductionOps.emplace_back(ReductionOp); 12125 TaskgroupDescriptors.emplace_back(nullptr); 12126 } 12127 /// Stores reduction data. 12128 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12129 Expr *TaskgroupDescriptor) { 12130 Vars.emplace_back(Item); 12131 Privates.emplace_back(Private); 12132 LHSs.emplace_back(LHS); 12133 RHSs.emplace_back(RHS); 12134 ReductionOps.emplace_back(ReductionOp); 12135 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12136 } 12137 }; 12138 } // namespace 12139 12140 static bool checkOMPArraySectionConstantForReduction( 12141 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12142 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12143 const Expr *Length = OASE->getLength(); 12144 if (Length == nullptr) { 12145 // For array sections of the form [1:] or [:], we would need to analyze 12146 // the lower bound... 12147 if (OASE->getColonLoc().isValid()) 12148 return false; 12149 12150 // This is an array subscript which has implicit length 1! 12151 SingleElement = true; 12152 ArraySizes.push_back(llvm::APSInt::get(1)); 12153 } else { 12154 Expr::EvalResult Result; 12155 if (!Length->EvaluateAsInt(Result, Context)) 12156 return false; 12157 12158 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12159 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12160 ArraySizes.push_back(ConstantLengthValue); 12161 } 12162 12163 // Get the base of this array section and walk up from there. 12164 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12165 12166 // We require length = 1 for all array sections except the right-most to 12167 // guarantee that the memory region is contiguous and has no holes in it. 12168 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12169 Length = TempOASE->getLength(); 12170 if (Length == nullptr) { 12171 // For array sections of the form [1:] or [:], we would need to analyze 12172 // the lower bound... 12173 if (OASE->getColonLoc().isValid()) 12174 return false; 12175 12176 // This is an array subscript which has implicit length 1! 12177 ArraySizes.push_back(llvm::APSInt::get(1)); 12178 } else { 12179 Expr::EvalResult Result; 12180 if (!Length->EvaluateAsInt(Result, Context)) 12181 return false; 12182 12183 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12184 if (ConstantLengthValue.getSExtValue() != 1) 12185 return false; 12186 12187 ArraySizes.push_back(ConstantLengthValue); 12188 } 12189 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12190 } 12191 12192 // If we have a single element, we don't need to add the implicit lengths. 12193 if (!SingleElement) { 12194 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12195 // Has implicit length 1! 12196 ArraySizes.push_back(llvm::APSInt::get(1)); 12197 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12198 } 12199 } 12200 12201 // This array section can be privatized as a single value or as a constant 12202 // sized array. 12203 return true; 12204 } 12205 12206 static bool actOnOMPReductionKindClause( 12207 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12208 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12209 SourceLocation ColonLoc, SourceLocation EndLoc, 12210 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12211 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12212 DeclarationName DN = ReductionId.getName(); 12213 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12214 BinaryOperatorKind BOK = BO_Comma; 12215 12216 ASTContext &Context = S.Context; 12217 // OpenMP [2.14.3.6, reduction clause] 12218 // C 12219 // reduction-identifier is either an identifier or one of the following 12220 // operators: +, -, *, &, |, ^, && and || 12221 // C++ 12222 // reduction-identifier is either an id-expression or one of the following 12223 // operators: +, -, *, &, |, ^, && and || 12224 switch (OOK) { 12225 case OO_Plus: 12226 case OO_Minus: 12227 BOK = BO_Add; 12228 break; 12229 case OO_Star: 12230 BOK = BO_Mul; 12231 break; 12232 case OO_Amp: 12233 BOK = BO_And; 12234 break; 12235 case OO_Pipe: 12236 BOK = BO_Or; 12237 break; 12238 case OO_Caret: 12239 BOK = BO_Xor; 12240 break; 12241 case OO_AmpAmp: 12242 BOK = BO_LAnd; 12243 break; 12244 case OO_PipePipe: 12245 BOK = BO_LOr; 12246 break; 12247 case OO_New: 12248 case OO_Delete: 12249 case OO_Array_New: 12250 case OO_Array_Delete: 12251 case OO_Slash: 12252 case OO_Percent: 12253 case OO_Tilde: 12254 case OO_Exclaim: 12255 case OO_Equal: 12256 case OO_Less: 12257 case OO_Greater: 12258 case OO_LessEqual: 12259 case OO_GreaterEqual: 12260 case OO_PlusEqual: 12261 case OO_MinusEqual: 12262 case OO_StarEqual: 12263 case OO_SlashEqual: 12264 case OO_PercentEqual: 12265 case OO_CaretEqual: 12266 case OO_AmpEqual: 12267 case OO_PipeEqual: 12268 case OO_LessLess: 12269 case OO_GreaterGreater: 12270 case OO_LessLessEqual: 12271 case OO_GreaterGreaterEqual: 12272 case OO_EqualEqual: 12273 case OO_ExclaimEqual: 12274 case OO_Spaceship: 12275 case OO_PlusPlus: 12276 case OO_MinusMinus: 12277 case OO_Comma: 12278 case OO_ArrowStar: 12279 case OO_Arrow: 12280 case OO_Call: 12281 case OO_Subscript: 12282 case OO_Conditional: 12283 case OO_Coawait: 12284 case NUM_OVERLOADED_OPERATORS: 12285 llvm_unreachable("Unexpected reduction identifier"); 12286 case OO_None: 12287 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 12288 if (II->isStr("max")) 12289 BOK = BO_GT; 12290 else if (II->isStr("min")) 12291 BOK = BO_LT; 12292 } 12293 break; 12294 } 12295 SourceRange ReductionIdRange; 12296 if (ReductionIdScopeSpec.isValid()) 12297 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 12298 else 12299 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 12300 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 12301 12302 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 12303 bool FirstIter = true; 12304 for (Expr *RefExpr : VarList) { 12305 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 12306 // OpenMP [2.1, C/C++] 12307 // A list item is a variable or array section, subject to the restrictions 12308 // specified in Section 2.4 on page 42 and in each of the sections 12309 // describing clauses and directives for which a list appears. 12310 // OpenMP [2.14.3.3, Restrictions, p.1] 12311 // A variable that is part of another variable (as an array or 12312 // structure element) cannot appear in a private clause. 12313 if (!FirstIter && IR != ER) 12314 ++IR; 12315 FirstIter = false; 12316 SourceLocation ELoc; 12317 SourceRange ERange; 12318 Expr *SimpleRefExpr = RefExpr; 12319 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 12320 /*AllowArraySection=*/true); 12321 if (Res.second) { 12322 // Try to find 'declare reduction' corresponding construct before using 12323 // builtin/overloaded operators. 12324 QualType Type = Context.DependentTy; 12325 CXXCastPath BasePath; 12326 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12327 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12328 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12329 Expr *ReductionOp = nullptr; 12330 if (S.CurContext->isDependentContext() && 12331 (DeclareReductionRef.isUnset() || 12332 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 12333 ReductionOp = DeclareReductionRef.get(); 12334 // It will be analyzed later. 12335 RD.push(RefExpr, ReductionOp); 12336 } 12337 ValueDecl *D = Res.first; 12338 if (!D) 12339 continue; 12340 12341 Expr *TaskgroupDescriptor = nullptr; 12342 QualType Type; 12343 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 12344 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 12345 if (ASE) { 12346 Type = ASE->getType().getNonReferenceType(); 12347 } else if (OASE) { 12348 QualType BaseType = 12349 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 12350 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 12351 Type = ATy->getElementType(); 12352 else 12353 Type = BaseType->getPointeeType(); 12354 Type = Type.getNonReferenceType(); 12355 } else { 12356 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 12357 } 12358 auto *VD = dyn_cast<VarDecl>(D); 12359 12360 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12361 // A variable that appears in a private clause must not have an incomplete 12362 // type or a reference type. 12363 if (S.RequireCompleteType(ELoc, D->getType(), 12364 diag::err_omp_reduction_incomplete_type)) 12365 continue; 12366 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12367 // A list item that appears in a reduction clause must not be 12368 // const-qualified. 12369 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12370 /*AcceptIfMutable*/ false, ASE || OASE)) 12371 continue; 12372 12373 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12374 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12375 // If a list-item is a reference type then it must bind to the same object 12376 // for all threads of the team. 12377 if (!ASE && !OASE) { 12378 if (VD) { 12379 VarDecl *VDDef = VD->getDefinition(); 12380 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12381 DSARefChecker Check(Stack); 12382 if (Check.Visit(VDDef->getInit())) { 12383 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12384 << getOpenMPClauseName(ClauseKind) << ERange; 12385 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12386 continue; 12387 } 12388 } 12389 } 12390 12391 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12392 // in a Construct] 12393 // Variables with the predetermined data-sharing attributes may not be 12394 // listed in data-sharing attributes clauses, except for the cases 12395 // listed below. For these exceptions only, listing a predetermined 12396 // variable in a data-sharing attribute clause is allowed and overrides 12397 // the variable's predetermined data-sharing attributes. 12398 // OpenMP [2.14.3.6, Restrictions, p.3] 12399 // Any number of reduction clauses can be specified on the directive, 12400 // but a list item can appear only once in the reduction clauses for that 12401 // directive. 12402 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12403 if (DVar.CKind == OMPC_reduction) { 12404 S.Diag(ELoc, diag::err_omp_once_referenced) 12405 << getOpenMPClauseName(ClauseKind); 12406 if (DVar.RefExpr) 12407 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12408 continue; 12409 } 12410 if (DVar.CKind != OMPC_unknown) { 12411 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12412 << getOpenMPClauseName(DVar.CKind) 12413 << getOpenMPClauseName(OMPC_reduction); 12414 reportOriginalDsa(S, Stack, D, DVar); 12415 continue; 12416 } 12417 12418 // OpenMP [2.14.3.6, Restrictions, p.1] 12419 // A list item that appears in a reduction clause of a worksharing 12420 // construct must be shared in the parallel regions to which any of the 12421 // worksharing regions arising from the worksharing construct bind. 12422 if (isOpenMPWorksharingDirective(CurrDir) && 12423 !isOpenMPParallelDirective(CurrDir) && 12424 !isOpenMPTeamsDirective(CurrDir)) { 12425 DVar = Stack->getImplicitDSA(D, true); 12426 if (DVar.CKind != OMPC_shared) { 12427 S.Diag(ELoc, diag::err_omp_required_access) 12428 << getOpenMPClauseName(OMPC_reduction) 12429 << getOpenMPClauseName(OMPC_shared); 12430 reportOriginalDsa(S, Stack, D, DVar); 12431 continue; 12432 } 12433 } 12434 } 12435 12436 // Try to find 'declare reduction' corresponding construct before using 12437 // builtin/overloaded operators. 12438 CXXCastPath BasePath; 12439 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12440 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12441 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12442 if (DeclareReductionRef.isInvalid()) 12443 continue; 12444 if (S.CurContext->isDependentContext() && 12445 (DeclareReductionRef.isUnset() || 12446 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12447 RD.push(RefExpr, DeclareReductionRef.get()); 12448 continue; 12449 } 12450 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12451 // Not allowed reduction identifier is found. 12452 S.Diag(ReductionId.getBeginLoc(), 12453 diag::err_omp_unknown_reduction_identifier) 12454 << Type << ReductionIdRange; 12455 continue; 12456 } 12457 12458 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12459 // The type of a list item that appears in a reduction clause must be valid 12460 // for the reduction-identifier. For a max or min reduction in C, the type 12461 // of the list item must be an allowed arithmetic data type: char, int, 12462 // float, double, or _Bool, possibly modified with long, short, signed, or 12463 // unsigned. For a max or min reduction in C++, the type of the list item 12464 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12465 // double, or bool, possibly modified with long, short, signed, or unsigned. 12466 if (DeclareReductionRef.isUnset()) { 12467 if ((BOK == BO_GT || BOK == BO_LT) && 12468 !(Type->isScalarType() || 12469 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12470 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12471 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12472 if (!ASE && !OASE) { 12473 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12474 VarDecl::DeclarationOnly; 12475 S.Diag(D->getLocation(), 12476 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12477 << D; 12478 } 12479 continue; 12480 } 12481 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12482 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12483 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12484 << getOpenMPClauseName(ClauseKind); 12485 if (!ASE && !OASE) { 12486 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12487 VarDecl::DeclarationOnly; 12488 S.Diag(D->getLocation(), 12489 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12490 << D; 12491 } 12492 continue; 12493 } 12494 } 12495 12496 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12497 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12498 D->hasAttrs() ? &D->getAttrs() : nullptr); 12499 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12500 D->hasAttrs() ? &D->getAttrs() : nullptr); 12501 QualType PrivateTy = Type; 12502 12503 // Try if we can determine constant lengths for all array sections and avoid 12504 // the VLA. 12505 bool ConstantLengthOASE = false; 12506 if (OASE) { 12507 bool SingleElement; 12508 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12509 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12510 Context, OASE, SingleElement, ArraySizes); 12511 12512 // If we don't have a single element, we must emit a constant array type. 12513 if (ConstantLengthOASE && !SingleElement) { 12514 for (llvm::APSInt &Size : ArraySizes) 12515 PrivateTy = Context.getConstantArrayType( 12516 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12517 } 12518 } 12519 12520 if ((OASE && !ConstantLengthOASE) || 12521 (!OASE && !ASE && 12522 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12523 if (!Context.getTargetInfo().isVLASupported()) { 12524 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 12525 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12526 S.Diag(ELoc, diag::note_vla_unsupported); 12527 } else { 12528 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12529 S.targetDiag(ELoc, diag::note_vla_unsupported); 12530 } 12531 continue; 12532 } 12533 // For arrays/array sections only: 12534 // Create pseudo array type for private copy. The size for this array will 12535 // be generated during codegen. 12536 // For array subscripts or single variables Private Ty is the same as Type 12537 // (type of the variable or single array element). 12538 PrivateTy = Context.getVariableArrayType( 12539 Type, 12540 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12541 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12542 } else if (!ASE && !OASE && 12543 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12544 PrivateTy = D->getType().getNonReferenceType(); 12545 } 12546 // Private copy. 12547 VarDecl *PrivateVD = 12548 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12549 D->hasAttrs() ? &D->getAttrs() : nullptr, 12550 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12551 // Add initializer for private variable. 12552 Expr *Init = nullptr; 12553 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12554 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12555 if (DeclareReductionRef.isUsable()) { 12556 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12557 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12558 if (DRD->getInitializer()) { 12559 Init = DRDRef; 12560 RHSVD->setInit(DRDRef); 12561 RHSVD->setInitStyle(VarDecl::CallInit); 12562 } 12563 } else { 12564 switch (BOK) { 12565 case BO_Add: 12566 case BO_Xor: 12567 case BO_Or: 12568 case BO_LOr: 12569 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12570 if (Type->isScalarType() || Type->isAnyComplexType()) 12571 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12572 break; 12573 case BO_Mul: 12574 case BO_LAnd: 12575 if (Type->isScalarType() || Type->isAnyComplexType()) { 12576 // '*' and '&&' reduction ops - initializer is '1'. 12577 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12578 } 12579 break; 12580 case BO_And: { 12581 // '&' reduction op - initializer is '~0'. 12582 QualType OrigType = Type; 12583 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12584 Type = ComplexTy->getElementType(); 12585 if (Type->isRealFloatingType()) { 12586 llvm::APFloat InitValue = 12587 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12588 /*isIEEE=*/true); 12589 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12590 Type, ELoc); 12591 } else if (Type->isScalarType()) { 12592 uint64_t Size = Context.getTypeSize(Type); 12593 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12594 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12595 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12596 } 12597 if (Init && OrigType->isAnyComplexType()) { 12598 // Init = 0xFFFF + 0xFFFFi; 12599 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12600 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12601 } 12602 Type = OrigType; 12603 break; 12604 } 12605 case BO_LT: 12606 case BO_GT: { 12607 // 'min' reduction op - initializer is 'Largest representable number in 12608 // the reduction list item type'. 12609 // 'max' reduction op - initializer is 'Least representable number in 12610 // the reduction list item type'. 12611 if (Type->isIntegerType() || Type->isPointerType()) { 12612 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12613 uint64_t Size = Context.getTypeSize(Type); 12614 QualType IntTy = 12615 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12616 llvm::APInt InitValue = 12617 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12618 : llvm::APInt::getMinValue(Size) 12619 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12620 : llvm::APInt::getMaxValue(Size); 12621 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12622 if (Type->isPointerType()) { 12623 // Cast to pointer type. 12624 ExprResult CastExpr = S.BuildCStyleCastExpr( 12625 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12626 if (CastExpr.isInvalid()) 12627 continue; 12628 Init = CastExpr.get(); 12629 } 12630 } else if (Type->isRealFloatingType()) { 12631 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12632 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12633 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12634 Type, ELoc); 12635 } 12636 break; 12637 } 12638 case BO_PtrMemD: 12639 case BO_PtrMemI: 12640 case BO_MulAssign: 12641 case BO_Div: 12642 case BO_Rem: 12643 case BO_Sub: 12644 case BO_Shl: 12645 case BO_Shr: 12646 case BO_LE: 12647 case BO_GE: 12648 case BO_EQ: 12649 case BO_NE: 12650 case BO_Cmp: 12651 case BO_AndAssign: 12652 case BO_XorAssign: 12653 case BO_OrAssign: 12654 case BO_Assign: 12655 case BO_AddAssign: 12656 case BO_SubAssign: 12657 case BO_DivAssign: 12658 case BO_RemAssign: 12659 case BO_ShlAssign: 12660 case BO_ShrAssign: 12661 case BO_Comma: 12662 llvm_unreachable("Unexpected reduction operation"); 12663 } 12664 } 12665 if (Init && DeclareReductionRef.isUnset()) 12666 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12667 else if (!Init) 12668 S.ActOnUninitializedDecl(RHSVD); 12669 if (RHSVD->isInvalidDecl()) 12670 continue; 12671 if (!RHSVD->hasInit() && 12672 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12673 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12674 << Type << ReductionIdRange; 12675 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12676 VarDecl::DeclarationOnly; 12677 S.Diag(D->getLocation(), 12678 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12679 << D; 12680 continue; 12681 } 12682 // Store initializer for single element in private copy. Will be used during 12683 // codegen. 12684 PrivateVD->setInit(RHSVD->getInit()); 12685 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12686 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12687 ExprResult ReductionOp; 12688 if (DeclareReductionRef.isUsable()) { 12689 QualType RedTy = DeclareReductionRef.get()->getType(); 12690 QualType PtrRedTy = Context.getPointerType(RedTy); 12691 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12692 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12693 if (!BasePath.empty()) { 12694 LHS = S.DefaultLvalueConversion(LHS.get()); 12695 RHS = S.DefaultLvalueConversion(RHS.get()); 12696 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12697 CK_UncheckedDerivedToBase, LHS.get(), 12698 &BasePath, LHS.get()->getValueKind()); 12699 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12700 CK_UncheckedDerivedToBase, RHS.get(), 12701 &BasePath, RHS.get()->getValueKind()); 12702 } 12703 FunctionProtoType::ExtProtoInfo EPI; 12704 QualType Params[] = {PtrRedTy, PtrRedTy}; 12705 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12706 auto *OVE = new (Context) OpaqueValueExpr( 12707 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12708 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12709 Expr *Args[] = {LHS.get(), RHS.get()}; 12710 ReductionOp = 12711 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12712 } else { 12713 ReductionOp = S.BuildBinOp( 12714 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12715 if (ReductionOp.isUsable()) { 12716 if (BOK != BO_LT && BOK != BO_GT) { 12717 ReductionOp = 12718 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12719 BO_Assign, LHSDRE, ReductionOp.get()); 12720 } else { 12721 auto *ConditionalOp = new (Context) 12722 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12723 Type, VK_LValue, OK_Ordinary); 12724 ReductionOp = 12725 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12726 BO_Assign, LHSDRE, ConditionalOp); 12727 } 12728 if (ReductionOp.isUsable()) 12729 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12730 /*DiscardedValue*/ false); 12731 } 12732 if (!ReductionOp.isUsable()) 12733 continue; 12734 } 12735 12736 // OpenMP [2.15.4.6, Restrictions, p.2] 12737 // A list item that appears in an in_reduction clause of a task construct 12738 // must appear in a task_reduction clause of a construct associated with a 12739 // taskgroup region that includes the participating task in its taskgroup 12740 // set. The construct associated with the innermost region that meets this 12741 // condition must specify the same reduction-identifier as the in_reduction 12742 // clause. 12743 if (ClauseKind == OMPC_in_reduction) { 12744 SourceRange ParentSR; 12745 BinaryOperatorKind ParentBOK; 12746 const Expr *ParentReductionOp; 12747 Expr *ParentBOKTD, *ParentReductionOpTD; 12748 DSAStackTy::DSAVarData ParentBOKDSA = 12749 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12750 ParentBOKTD); 12751 DSAStackTy::DSAVarData ParentReductionOpDSA = 12752 Stack->getTopMostTaskgroupReductionData( 12753 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12754 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12755 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12756 if (!IsParentBOK && !IsParentReductionOp) { 12757 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12758 continue; 12759 } 12760 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12761 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12762 IsParentReductionOp) { 12763 bool EmitError = true; 12764 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12765 llvm::FoldingSetNodeID RedId, ParentRedId; 12766 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12767 DeclareReductionRef.get()->Profile(RedId, Context, 12768 /*Canonical=*/true); 12769 EmitError = RedId != ParentRedId; 12770 } 12771 if (EmitError) { 12772 S.Diag(ReductionId.getBeginLoc(), 12773 diag::err_omp_reduction_identifier_mismatch) 12774 << ReductionIdRange << RefExpr->getSourceRange(); 12775 S.Diag(ParentSR.getBegin(), 12776 diag::note_omp_previous_reduction_identifier) 12777 << ParentSR 12778 << (IsParentBOK ? ParentBOKDSA.RefExpr 12779 : ParentReductionOpDSA.RefExpr) 12780 ->getSourceRange(); 12781 continue; 12782 } 12783 } 12784 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12785 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12786 } 12787 12788 DeclRefExpr *Ref = nullptr; 12789 Expr *VarsExpr = RefExpr->IgnoreParens(); 12790 if (!VD && !S.CurContext->isDependentContext()) { 12791 if (ASE || OASE) { 12792 TransformExprToCaptures RebuildToCapture(S, D); 12793 VarsExpr = 12794 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 12795 Ref = RebuildToCapture.getCapturedExpr(); 12796 } else { 12797 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 12798 } 12799 if (!S.isOpenMPCapturedDecl(D)) { 12800 RD.ExprCaptures.emplace_back(Ref->getDecl()); 12801 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12802 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 12803 if (!RefRes.isUsable()) 12804 continue; 12805 ExprResult PostUpdateRes = 12806 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12807 RefRes.get()); 12808 if (!PostUpdateRes.isUsable()) 12809 continue; 12810 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 12811 Stack->getCurrentDirective() == OMPD_taskgroup) { 12812 S.Diag(RefExpr->getExprLoc(), 12813 diag::err_omp_reduction_non_addressable_expression) 12814 << RefExpr->getSourceRange(); 12815 continue; 12816 } 12817 RD.ExprPostUpdates.emplace_back( 12818 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 12819 } 12820 } 12821 } 12822 // All reduction items are still marked as reduction (to do not increase 12823 // code base size). 12824 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 12825 if (CurrDir == OMPD_taskgroup) { 12826 if (DeclareReductionRef.isUsable()) 12827 Stack->addTaskgroupReductionData(D, ReductionIdRange, 12828 DeclareReductionRef.get()); 12829 else 12830 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 12831 } 12832 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 12833 TaskgroupDescriptor); 12834 } 12835 return RD.Vars.empty(); 12836 } 12837 12838 OMPClause *Sema::ActOnOpenMPReductionClause( 12839 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12840 SourceLocation ColonLoc, SourceLocation EndLoc, 12841 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12842 ArrayRef<Expr *> UnresolvedReductions) { 12843 ReductionData RD(VarList.size()); 12844 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 12845 StartLoc, LParenLoc, ColonLoc, EndLoc, 12846 ReductionIdScopeSpec, ReductionId, 12847 UnresolvedReductions, RD)) 12848 return nullptr; 12849 12850 return OMPReductionClause::Create( 12851 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12852 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12853 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12854 buildPreInits(Context, RD.ExprCaptures), 12855 buildPostUpdate(*this, RD.ExprPostUpdates)); 12856 } 12857 12858 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 12859 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12860 SourceLocation ColonLoc, SourceLocation EndLoc, 12861 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12862 ArrayRef<Expr *> UnresolvedReductions) { 12863 ReductionData RD(VarList.size()); 12864 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 12865 StartLoc, LParenLoc, ColonLoc, EndLoc, 12866 ReductionIdScopeSpec, ReductionId, 12867 UnresolvedReductions, RD)) 12868 return nullptr; 12869 12870 return OMPTaskReductionClause::Create( 12871 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12872 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12873 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12874 buildPreInits(Context, RD.ExprCaptures), 12875 buildPostUpdate(*this, RD.ExprPostUpdates)); 12876 } 12877 12878 OMPClause *Sema::ActOnOpenMPInReductionClause( 12879 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12880 SourceLocation ColonLoc, SourceLocation EndLoc, 12881 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12882 ArrayRef<Expr *> UnresolvedReductions) { 12883 ReductionData RD(VarList.size()); 12884 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 12885 StartLoc, LParenLoc, ColonLoc, EndLoc, 12886 ReductionIdScopeSpec, ReductionId, 12887 UnresolvedReductions, RD)) 12888 return nullptr; 12889 12890 return OMPInReductionClause::Create( 12891 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12892 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12893 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 12894 buildPreInits(Context, RD.ExprCaptures), 12895 buildPostUpdate(*this, RD.ExprPostUpdates)); 12896 } 12897 12898 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 12899 SourceLocation LinLoc) { 12900 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 12901 LinKind == OMPC_LINEAR_unknown) { 12902 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 12903 return true; 12904 } 12905 return false; 12906 } 12907 12908 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 12909 OpenMPLinearClauseKind LinKind, 12910 QualType Type) { 12911 const auto *VD = dyn_cast_or_null<VarDecl>(D); 12912 // A variable must not have an incomplete type or a reference type. 12913 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 12914 return true; 12915 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 12916 !Type->isReferenceType()) { 12917 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12918 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12919 return true; 12920 } 12921 Type = Type.getNonReferenceType(); 12922 12923 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12924 // A variable that is privatized must not have a const-qualified type 12925 // unless it is of class type with a mutable member. This restriction does 12926 // not apply to the firstprivate clause. 12927 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12928 return true; 12929 12930 // A list item must be of integral or pointer type. 12931 Type = Type.getUnqualifiedType().getCanonicalType(); 12932 const auto *Ty = Type.getTypePtrOrNull(); 12933 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12934 !Ty->isPointerType())) { 12935 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12936 if (D) { 12937 bool IsDecl = 12938 !VD || 12939 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12940 Diag(D->getLocation(), 12941 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12942 << D; 12943 } 12944 return true; 12945 } 12946 return false; 12947 } 12948 12949 OMPClause *Sema::ActOnOpenMPLinearClause( 12950 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12951 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12952 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12953 SmallVector<Expr *, 8> Vars; 12954 SmallVector<Expr *, 8> Privates; 12955 SmallVector<Expr *, 8> Inits; 12956 SmallVector<Decl *, 4> ExprCaptures; 12957 SmallVector<Expr *, 4> ExprPostUpdates; 12958 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12959 LinKind = OMPC_LINEAR_val; 12960 for (Expr *RefExpr : VarList) { 12961 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12962 SourceLocation ELoc; 12963 SourceRange ERange; 12964 Expr *SimpleRefExpr = RefExpr; 12965 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12966 if (Res.second) { 12967 // It will be analyzed later. 12968 Vars.push_back(RefExpr); 12969 Privates.push_back(nullptr); 12970 Inits.push_back(nullptr); 12971 } 12972 ValueDecl *D = Res.first; 12973 if (!D) 12974 continue; 12975 12976 QualType Type = D->getType(); 12977 auto *VD = dyn_cast<VarDecl>(D); 12978 12979 // OpenMP [2.14.3.7, linear clause] 12980 // A list-item cannot appear in more than one linear clause. 12981 // A list-item that appears in a linear clause cannot appear in any 12982 // other data-sharing attribute clause. 12983 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12984 if (DVar.RefExpr) { 12985 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12986 << getOpenMPClauseName(OMPC_linear); 12987 reportOriginalDsa(*this, DSAStack, D, DVar); 12988 continue; 12989 } 12990 12991 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12992 continue; 12993 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12994 12995 // Build private copy of original var. 12996 VarDecl *Private = 12997 buildVarDecl(*this, ELoc, Type, D->getName(), 12998 D->hasAttrs() ? &D->getAttrs() : nullptr, 12999 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13000 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13001 // Build var to save initial value. 13002 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13003 Expr *InitExpr; 13004 DeclRefExpr *Ref = nullptr; 13005 if (!VD && !CurContext->isDependentContext()) { 13006 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13007 if (!isOpenMPCapturedDecl(D)) { 13008 ExprCaptures.push_back(Ref->getDecl()); 13009 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13010 ExprResult RefRes = DefaultLvalueConversion(Ref); 13011 if (!RefRes.isUsable()) 13012 continue; 13013 ExprResult PostUpdateRes = 13014 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13015 SimpleRefExpr, RefRes.get()); 13016 if (!PostUpdateRes.isUsable()) 13017 continue; 13018 ExprPostUpdates.push_back( 13019 IgnoredValueConversions(PostUpdateRes.get()).get()); 13020 } 13021 } 13022 } 13023 if (LinKind == OMPC_LINEAR_uval) 13024 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13025 else 13026 InitExpr = VD ? SimpleRefExpr : Ref; 13027 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13028 /*DirectInit=*/false); 13029 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13030 13031 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13032 Vars.push_back((VD || CurContext->isDependentContext()) 13033 ? RefExpr->IgnoreParens() 13034 : Ref); 13035 Privates.push_back(PrivateRef); 13036 Inits.push_back(InitRef); 13037 } 13038 13039 if (Vars.empty()) 13040 return nullptr; 13041 13042 Expr *StepExpr = Step; 13043 Expr *CalcStepExpr = nullptr; 13044 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13045 !Step->isInstantiationDependent() && 13046 !Step->containsUnexpandedParameterPack()) { 13047 SourceLocation StepLoc = Step->getBeginLoc(); 13048 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13049 if (Val.isInvalid()) 13050 return nullptr; 13051 StepExpr = Val.get(); 13052 13053 // Build var to save the step value. 13054 VarDecl *SaveVar = 13055 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13056 ExprResult SaveRef = 13057 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13058 ExprResult CalcStep = 13059 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13060 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13061 13062 // Warn about zero linear step (it would be probably better specified as 13063 // making corresponding variables 'const'). 13064 llvm::APSInt Result; 13065 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13066 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13067 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13068 << (Vars.size() > 1); 13069 if (!IsConstant && CalcStep.isUsable()) { 13070 // Calculate the step beforehand instead of doing this on each iteration. 13071 // (This is not used if the number of iterations may be kfold-ed). 13072 CalcStepExpr = CalcStep.get(); 13073 } 13074 } 13075 13076 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13077 ColonLoc, EndLoc, Vars, Privates, Inits, 13078 StepExpr, CalcStepExpr, 13079 buildPreInits(Context, ExprCaptures), 13080 buildPostUpdate(*this, ExprPostUpdates)); 13081 } 13082 13083 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13084 Expr *NumIterations, Sema &SemaRef, 13085 Scope *S, DSAStackTy *Stack) { 13086 // Walk the vars and build update/final expressions for the CodeGen. 13087 SmallVector<Expr *, 8> Updates; 13088 SmallVector<Expr *, 8> Finals; 13089 SmallVector<Expr *, 8> UsedExprs; 13090 Expr *Step = Clause.getStep(); 13091 Expr *CalcStep = Clause.getCalcStep(); 13092 // OpenMP [2.14.3.7, linear clause] 13093 // If linear-step is not specified it is assumed to be 1. 13094 if (!Step) 13095 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13096 else if (CalcStep) 13097 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13098 bool HasErrors = false; 13099 auto CurInit = Clause.inits().begin(); 13100 auto CurPrivate = Clause.privates().begin(); 13101 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13102 for (Expr *RefExpr : Clause.varlists()) { 13103 SourceLocation ELoc; 13104 SourceRange ERange; 13105 Expr *SimpleRefExpr = RefExpr; 13106 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13107 ValueDecl *D = Res.first; 13108 if (Res.second || !D) { 13109 Updates.push_back(nullptr); 13110 Finals.push_back(nullptr); 13111 HasErrors = true; 13112 continue; 13113 } 13114 auto &&Info = Stack->isLoopControlVariable(D); 13115 // OpenMP [2.15.11, distribute simd Construct] 13116 // A list item may not appear in a linear clause, unless it is the loop 13117 // iteration variable. 13118 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13119 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13120 SemaRef.Diag(ELoc, 13121 diag::err_omp_linear_distribute_var_non_loop_iteration); 13122 Updates.push_back(nullptr); 13123 Finals.push_back(nullptr); 13124 HasErrors = true; 13125 continue; 13126 } 13127 Expr *InitExpr = *CurInit; 13128 13129 // Build privatized reference to the current linear var. 13130 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13131 Expr *CapturedRef; 13132 if (LinKind == OMPC_LINEAR_uval) 13133 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13134 else 13135 CapturedRef = 13136 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13137 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13138 /*RefersToCapture=*/true); 13139 13140 // Build update: Var = InitExpr + IV * Step 13141 ExprResult Update; 13142 if (!Info.first) 13143 Update = buildCounterUpdate( 13144 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13145 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13146 else 13147 Update = *CurPrivate; 13148 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13149 /*DiscardedValue*/ false); 13150 13151 // Build final: Var = InitExpr + NumIterations * Step 13152 ExprResult Final; 13153 if (!Info.first) 13154 Final = 13155 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13156 InitExpr, NumIterations, Step, /*Subtract=*/false, 13157 /*IsNonRectangularLB=*/false); 13158 else 13159 Final = *CurPrivate; 13160 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13161 /*DiscardedValue*/ false); 13162 13163 if (!Update.isUsable() || !Final.isUsable()) { 13164 Updates.push_back(nullptr); 13165 Finals.push_back(nullptr); 13166 UsedExprs.push_back(nullptr); 13167 HasErrors = true; 13168 } else { 13169 Updates.push_back(Update.get()); 13170 Finals.push_back(Final.get()); 13171 if (!Info.first) 13172 UsedExprs.push_back(SimpleRefExpr); 13173 } 13174 ++CurInit; 13175 ++CurPrivate; 13176 } 13177 if (Expr *S = Clause.getStep()) 13178 UsedExprs.push_back(S); 13179 // Fill the remaining part with the nullptr. 13180 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13181 Clause.setUpdates(Updates); 13182 Clause.setFinals(Finals); 13183 Clause.setUsedExprs(UsedExprs); 13184 return HasErrors; 13185 } 13186 13187 OMPClause *Sema::ActOnOpenMPAlignedClause( 13188 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13189 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13190 SmallVector<Expr *, 8> Vars; 13191 for (Expr *RefExpr : VarList) { 13192 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13193 SourceLocation ELoc; 13194 SourceRange ERange; 13195 Expr *SimpleRefExpr = RefExpr; 13196 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13197 if (Res.second) { 13198 // It will be analyzed later. 13199 Vars.push_back(RefExpr); 13200 } 13201 ValueDecl *D = Res.first; 13202 if (!D) 13203 continue; 13204 13205 QualType QType = D->getType(); 13206 auto *VD = dyn_cast<VarDecl>(D); 13207 13208 // OpenMP [2.8.1, simd construct, Restrictions] 13209 // The type of list items appearing in the aligned clause must be 13210 // array, pointer, reference to array, or reference to pointer. 13211 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13212 const Type *Ty = QType.getTypePtrOrNull(); 13213 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13214 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13215 << QType << getLangOpts().CPlusPlus << ERange; 13216 bool IsDecl = 13217 !VD || 13218 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13219 Diag(D->getLocation(), 13220 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13221 << D; 13222 continue; 13223 } 13224 13225 // OpenMP [2.8.1, simd construct, Restrictions] 13226 // A list-item cannot appear in more than one aligned clause. 13227 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 13228 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 13229 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 13230 << getOpenMPClauseName(OMPC_aligned); 13231 continue; 13232 } 13233 13234 DeclRefExpr *Ref = nullptr; 13235 if (!VD && isOpenMPCapturedDecl(D)) 13236 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13237 Vars.push_back(DefaultFunctionArrayConversion( 13238 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 13239 .get()); 13240 } 13241 13242 // OpenMP [2.8.1, simd construct, Description] 13243 // The parameter of the aligned clause, alignment, must be a constant 13244 // positive integer expression. 13245 // If no optional parameter is specified, implementation-defined default 13246 // alignments for SIMD instructions on the target platforms are assumed. 13247 if (Alignment != nullptr) { 13248 ExprResult AlignResult = 13249 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 13250 if (AlignResult.isInvalid()) 13251 return nullptr; 13252 Alignment = AlignResult.get(); 13253 } 13254 if (Vars.empty()) 13255 return nullptr; 13256 13257 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 13258 EndLoc, Vars, Alignment); 13259 } 13260 13261 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 13262 SourceLocation StartLoc, 13263 SourceLocation LParenLoc, 13264 SourceLocation EndLoc) { 13265 SmallVector<Expr *, 8> Vars; 13266 SmallVector<Expr *, 8> SrcExprs; 13267 SmallVector<Expr *, 8> DstExprs; 13268 SmallVector<Expr *, 8> AssignmentOps; 13269 for (Expr *RefExpr : VarList) { 13270 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 13271 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13272 // It will be analyzed later. 13273 Vars.push_back(RefExpr); 13274 SrcExprs.push_back(nullptr); 13275 DstExprs.push_back(nullptr); 13276 AssignmentOps.push_back(nullptr); 13277 continue; 13278 } 13279 13280 SourceLocation ELoc = RefExpr->getExprLoc(); 13281 // OpenMP [2.1, C/C++] 13282 // A list item is a variable name. 13283 // OpenMP [2.14.4.1, Restrictions, p.1] 13284 // A list item that appears in a copyin clause must be threadprivate. 13285 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 13286 if (!DE || !isa<VarDecl>(DE->getDecl())) { 13287 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 13288 << 0 << RefExpr->getSourceRange(); 13289 continue; 13290 } 13291 13292 Decl *D = DE->getDecl(); 13293 auto *VD = cast<VarDecl>(D); 13294 13295 QualType Type = VD->getType(); 13296 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 13297 // It will be analyzed later. 13298 Vars.push_back(DE); 13299 SrcExprs.push_back(nullptr); 13300 DstExprs.push_back(nullptr); 13301 AssignmentOps.push_back(nullptr); 13302 continue; 13303 } 13304 13305 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 13306 // A list item that appears in a copyin clause must be threadprivate. 13307 if (!DSAStack->isThreadPrivate(VD)) { 13308 Diag(ELoc, diag::err_omp_required_access) 13309 << getOpenMPClauseName(OMPC_copyin) 13310 << getOpenMPDirectiveName(OMPD_threadprivate); 13311 continue; 13312 } 13313 13314 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13315 // A variable of class type (or array thereof) that appears in a 13316 // copyin clause requires an accessible, unambiguous copy assignment 13317 // operator for the class type. 13318 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13319 VarDecl *SrcVD = 13320 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 13321 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13322 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 13323 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 13324 VarDecl *DstVD = 13325 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 13326 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13327 DeclRefExpr *PseudoDstExpr = 13328 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 13329 // For arrays generate assignment operation for single element and replace 13330 // it by the original array element in CodeGen. 13331 ExprResult AssignmentOp = 13332 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 13333 PseudoSrcExpr); 13334 if (AssignmentOp.isInvalid()) 13335 continue; 13336 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 13337 /*DiscardedValue*/ false); 13338 if (AssignmentOp.isInvalid()) 13339 continue; 13340 13341 DSAStack->addDSA(VD, DE, OMPC_copyin); 13342 Vars.push_back(DE); 13343 SrcExprs.push_back(PseudoSrcExpr); 13344 DstExprs.push_back(PseudoDstExpr); 13345 AssignmentOps.push_back(AssignmentOp.get()); 13346 } 13347 13348 if (Vars.empty()) 13349 return nullptr; 13350 13351 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13352 SrcExprs, DstExprs, AssignmentOps); 13353 } 13354 13355 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 13356 SourceLocation StartLoc, 13357 SourceLocation LParenLoc, 13358 SourceLocation EndLoc) { 13359 SmallVector<Expr *, 8> Vars; 13360 SmallVector<Expr *, 8> SrcExprs; 13361 SmallVector<Expr *, 8> DstExprs; 13362 SmallVector<Expr *, 8> AssignmentOps; 13363 for (Expr *RefExpr : VarList) { 13364 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13365 SourceLocation ELoc; 13366 SourceRange ERange; 13367 Expr *SimpleRefExpr = RefExpr; 13368 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13369 if (Res.second) { 13370 // It will be analyzed later. 13371 Vars.push_back(RefExpr); 13372 SrcExprs.push_back(nullptr); 13373 DstExprs.push_back(nullptr); 13374 AssignmentOps.push_back(nullptr); 13375 } 13376 ValueDecl *D = Res.first; 13377 if (!D) 13378 continue; 13379 13380 QualType Type = D->getType(); 13381 auto *VD = dyn_cast<VarDecl>(D); 13382 13383 // OpenMP [2.14.4.2, Restrictions, p.2] 13384 // A list item that appears in a copyprivate clause may not appear in a 13385 // private or firstprivate clause on the single construct. 13386 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13387 DSAStackTy::DSAVarData DVar = 13388 DSAStack->getTopDSA(D, /*FromParent=*/false); 13389 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13390 DVar.RefExpr) { 13391 Diag(ELoc, diag::err_omp_wrong_dsa) 13392 << getOpenMPClauseName(DVar.CKind) 13393 << getOpenMPClauseName(OMPC_copyprivate); 13394 reportOriginalDsa(*this, DSAStack, D, DVar); 13395 continue; 13396 } 13397 13398 // OpenMP [2.11.4.2, Restrictions, p.1] 13399 // All list items that appear in a copyprivate clause must be either 13400 // threadprivate or private in the enclosing context. 13401 if (DVar.CKind == OMPC_unknown) { 13402 DVar = DSAStack->getImplicitDSA(D, false); 13403 if (DVar.CKind == OMPC_shared) { 13404 Diag(ELoc, diag::err_omp_required_access) 13405 << getOpenMPClauseName(OMPC_copyprivate) 13406 << "threadprivate or private in the enclosing context"; 13407 reportOriginalDsa(*this, DSAStack, D, DVar); 13408 continue; 13409 } 13410 } 13411 } 13412 13413 // Variably modified types are not supported. 13414 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13415 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13416 << getOpenMPClauseName(OMPC_copyprivate) << Type 13417 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13418 bool IsDecl = 13419 !VD || 13420 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13421 Diag(D->getLocation(), 13422 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13423 << D; 13424 continue; 13425 } 13426 13427 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13428 // A variable of class type (or array thereof) that appears in a 13429 // copyin clause requires an accessible, unambiguous copy assignment 13430 // operator for the class type. 13431 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13432 .getUnqualifiedType(); 13433 VarDecl *SrcVD = 13434 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13435 D->hasAttrs() ? &D->getAttrs() : nullptr); 13436 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13437 VarDecl *DstVD = 13438 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13439 D->hasAttrs() ? &D->getAttrs() : nullptr); 13440 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13441 ExprResult AssignmentOp = BuildBinOp( 13442 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13443 if (AssignmentOp.isInvalid()) 13444 continue; 13445 AssignmentOp = 13446 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13447 if (AssignmentOp.isInvalid()) 13448 continue; 13449 13450 // No need to mark vars as copyprivate, they are already threadprivate or 13451 // implicitly private. 13452 assert(VD || isOpenMPCapturedDecl(D)); 13453 Vars.push_back( 13454 VD ? RefExpr->IgnoreParens() 13455 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13456 SrcExprs.push_back(PseudoSrcExpr); 13457 DstExprs.push_back(PseudoDstExpr); 13458 AssignmentOps.push_back(AssignmentOp.get()); 13459 } 13460 13461 if (Vars.empty()) 13462 return nullptr; 13463 13464 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13465 Vars, SrcExprs, DstExprs, AssignmentOps); 13466 } 13467 13468 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13469 SourceLocation StartLoc, 13470 SourceLocation LParenLoc, 13471 SourceLocation EndLoc) { 13472 if (VarList.empty()) 13473 return nullptr; 13474 13475 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13476 } 13477 13478 OMPClause * 13479 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13480 SourceLocation DepLoc, SourceLocation ColonLoc, 13481 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13482 SourceLocation LParenLoc, SourceLocation EndLoc) { 13483 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13484 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13485 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13486 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13487 return nullptr; 13488 } 13489 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13490 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13491 DepKind == OMPC_DEPEND_sink)) { 13492 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13493 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13494 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13495 /*Last=*/OMPC_DEPEND_unknown, Except) 13496 << getOpenMPClauseName(OMPC_depend); 13497 return nullptr; 13498 } 13499 SmallVector<Expr *, 8> Vars; 13500 DSAStackTy::OperatorOffsetTy OpsOffs; 13501 llvm::APSInt DepCounter(/*BitWidth=*/32); 13502 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13503 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13504 if (const Expr *OrderedCountExpr = 13505 DSAStack->getParentOrderedRegionParam().first) { 13506 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13507 TotalDepCount.setIsUnsigned(/*Val=*/true); 13508 } 13509 } 13510 for (Expr *RefExpr : VarList) { 13511 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13512 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13513 // It will be analyzed later. 13514 Vars.push_back(RefExpr); 13515 continue; 13516 } 13517 13518 SourceLocation ELoc = RefExpr->getExprLoc(); 13519 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13520 if (DepKind == OMPC_DEPEND_sink) { 13521 if (DSAStack->getParentOrderedRegionParam().first && 13522 DepCounter >= TotalDepCount) { 13523 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13524 continue; 13525 } 13526 ++DepCounter; 13527 // OpenMP [2.13.9, Summary] 13528 // depend(dependence-type : vec), where dependence-type is: 13529 // 'sink' and where vec is the iteration vector, which has the form: 13530 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13531 // where n is the value specified by the ordered clause in the loop 13532 // directive, xi denotes the loop iteration variable of the i-th nested 13533 // loop associated with the loop directive, and di is a constant 13534 // non-negative integer. 13535 if (CurContext->isDependentContext()) { 13536 // It will be analyzed later. 13537 Vars.push_back(RefExpr); 13538 continue; 13539 } 13540 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13541 OverloadedOperatorKind OOK = OO_None; 13542 SourceLocation OOLoc; 13543 Expr *LHS = SimpleExpr; 13544 Expr *RHS = nullptr; 13545 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13546 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13547 OOLoc = BO->getOperatorLoc(); 13548 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13549 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13550 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13551 OOK = OCE->getOperator(); 13552 OOLoc = OCE->getOperatorLoc(); 13553 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13554 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13555 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13556 OOK = MCE->getMethodDecl() 13557 ->getNameInfo() 13558 .getName() 13559 .getCXXOverloadedOperator(); 13560 OOLoc = MCE->getCallee()->getExprLoc(); 13561 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13562 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13563 } 13564 SourceLocation ELoc; 13565 SourceRange ERange; 13566 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13567 if (Res.second) { 13568 // It will be analyzed later. 13569 Vars.push_back(RefExpr); 13570 } 13571 ValueDecl *D = Res.first; 13572 if (!D) 13573 continue; 13574 13575 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13576 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13577 continue; 13578 } 13579 if (RHS) { 13580 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13581 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13582 if (RHSRes.isInvalid()) 13583 continue; 13584 } 13585 if (!CurContext->isDependentContext() && 13586 DSAStack->getParentOrderedRegionParam().first && 13587 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13588 const ValueDecl *VD = 13589 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13590 if (VD) 13591 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13592 << 1 << VD; 13593 else 13594 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13595 continue; 13596 } 13597 OpsOffs.emplace_back(RHS, OOK); 13598 } else { 13599 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13600 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13601 (ASE && 13602 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13603 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13604 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13605 << RefExpr->getSourceRange(); 13606 continue; 13607 } 13608 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 13609 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 13610 ExprResult Res = 13611 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 13612 getDiagnostics().setSuppressAllDiagnostics(Suppress); 13613 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13614 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13615 << RefExpr->getSourceRange(); 13616 continue; 13617 } 13618 } 13619 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13620 } 13621 13622 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13623 TotalDepCount > VarList.size() && 13624 DSAStack->getParentOrderedRegionParam().first && 13625 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13626 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13627 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13628 } 13629 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13630 Vars.empty()) 13631 return nullptr; 13632 13633 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13634 DepKind, DepLoc, ColonLoc, Vars, 13635 TotalDepCount.getZExtValue()); 13636 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13637 DSAStack->isParentOrderedRegion()) 13638 DSAStack->addDoacrossDependClause(C, OpsOffs); 13639 return C; 13640 } 13641 13642 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13643 SourceLocation LParenLoc, 13644 SourceLocation EndLoc) { 13645 Expr *ValExpr = Device; 13646 Stmt *HelperValStmt = nullptr; 13647 13648 // OpenMP [2.9.1, Restrictions] 13649 // The device expression must evaluate to a non-negative integer value. 13650 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13651 /*StrictlyPositive=*/false)) 13652 return nullptr; 13653 13654 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13655 OpenMPDirectiveKind CaptureRegion = 13656 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13657 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13658 ValExpr = MakeFullExpr(ValExpr).get(); 13659 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13660 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13661 HelperValStmt = buildPreInits(Context, Captures); 13662 } 13663 13664 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13665 StartLoc, LParenLoc, EndLoc); 13666 } 13667 13668 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13669 DSAStackTy *Stack, QualType QTy, 13670 bool FullCheck = true) { 13671 NamedDecl *ND; 13672 if (QTy->isIncompleteType(&ND)) { 13673 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13674 return false; 13675 } 13676 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13677 !QTy.isTrivialType(SemaRef.Context)) 13678 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13679 return true; 13680 } 13681 13682 /// Return true if it can be proven that the provided array expression 13683 /// (array section or array subscript) does NOT specify the whole size of the 13684 /// array whose base type is \a BaseQTy. 13685 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13686 const Expr *E, 13687 QualType BaseQTy) { 13688 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13689 13690 // If this is an array subscript, it refers to the whole size if the size of 13691 // the dimension is constant and equals 1. Also, an array section assumes the 13692 // format of an array subscript if no colon is used. 13693 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13694 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13695 return ATy->getSize().getSExtValue() != 1; 13696 // Size can't be evaluated statically. 13697 return false; 13698 } 13699 13700 assert(OASE && "Expecting array section if not an array subscript."); 13701 const Expr *LowerBound = OASE->getLowerBound(); 13702 const Expr *Length = OASE->getLength(); 13703 13704 // If there is a lower bound that does not evaluates to zero, we are not 13705 // covering the whole dimension. 13706 if (LowerBound) { 13707 Expr::EvalResult Result; 13708 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13709 return false; // Can't get the integer value as a constant. 13710 13711 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13712 if (ConstLowerBound.getSExtValue()) 13713 return true; 13714 } 13715 13716 // If we don't have a length we covering the whole dimension. 13717 if (!Length) 13718 return false; 13719 13720 // If the base is a pointer, we don't have a way to get the size of the 13721 // pointee. 13722 if (BaseQTy->isPointerType()) 13723 return false; 13724 13725 // We can only check if the length is the same as the size of the dimension 13726 // if we have a constant array. 13727 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13728 if (!CATy) 13729 return false; 13730 13731 Expr::EvalResult Result; 13732 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13733 return false; // Can't get the integer value as a constant. 13734 13735 llvm::APSInt ConstLength = Result.Val.getInt(); 13736 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13737 } 13738 13739 // Return true if it can be proven that the provided array expression (array 13740 // section or array subscript) does NOT specify a single element of the array 13741 // whose base type is \a BaseQTy. 13742 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13743 const Expr *E, 13744 QualType BaseQTy) { 13745 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13746 13747 // An array subscript always refer to a single element. Also, an array section 13748 // assumes the format of an array subscript if no colon is used. 13749 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13750 return false; 13751 13752 assert(OASE && "Expecting array section if not an array subscript."); 13753 const Expr *Length = OASE->getLength(); 13754 13755 // If we don't have a length we have to check if the array has unitary size 13756 // for this dimension. Also, we should always expect a length if the base type 13757 // is pointer. 13758 if (!Length) { 13759 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13760 return ATy->getSize().getSExtValue() != 1; 13761 // We cannot assume anything. 13762 return false; 13763 } 13764 13765 // Check if the length evaluates to 1. 13766 Expr::EvalResult Result; 13767 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13768 return false; // Can't get the integer value as a constant. 13769 13770 llvm::APSInt ConstLength = Result.Val.getInt(); 13771 return ConstLength.getSExtValue() != 1; 13772 } 13773 13774 // Return the expression of the base of the mappable expression or null if it 13775 // cannot be determined and do all the necessary checks to see if the expression 13776 // is valid as a standalone mappable expression. In the process, record all the 13777 // components of the expression. 13778 static const Expr *checkMapClauseExpressionBase( 13779 Sema &SemaRef, Expr *E, 13780 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13781 OpenMPClauseKind CKind, bool NoDiagnose) { 13782 SourceLocation ELoc = E->getExprLoc(); 13783 SourceRange ERange = E->getSourceRange(); 13784 13785 // The base of elements of list in a map clause have to be either: 13786 // - a reference to variable or field. 13787 // - a member expression. 13788 // - an array expression. 13789 // 13790 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 13791 // reference to 'r'. 13792 // 13793 // If we have: 13794 // 13795 // struct SS { 13796 // Bla S; 13797 // foo() { 13798 // #pragma omp target map (S.Arr[:12]); 13799 // } 13800 // } 13801 // 13802 // We want to retrieve the member expression 'this->S'; 13803 13804 const Expr *RelevantExpr = nullptr; 13805 13806 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 13807 // If a list item is an array section, it must specify contiguous storage. 13808 // 13809 // For this restriction it is sufficient that we make sure only references 13810 // to variables or fields and array expressions, and that no array sections 13811 // exist except in the rightmost expression (unless they cover the whole 13812 // dimension of the array). E.g. these would be invalid: 13813 // 13814 // r.ArrS[3:5].Arr[6:7] 13815 // 13816 // r.ArrS[3:5].x 13817 // 13818 // but these would be valid: 13819 // r.ArrS[3].Arr[6:7] 13820 // 13821 // r.ArrS[3].x 13822 13823 bool AllowUnitySizeArraySection = true; 13824 bool AllowWholeSizeArraySection = true; 13825 13826 while (!RelevantExpr) { 13827 E = E->IgnoreParenImpCasts(); 13828 13829 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 13830 if (!isa<VarDecl>(CurE->getDecl())) 13831 return nullptr; 13832 13833 RelevantExpr = CurE; 13834 13835 // If we got a reference to a declaration, we should not expect any array 13836 // section before that. 13837 AllowUnitySizeArraySection = false; 13838 AllowWholeSizeArraySection = false; 13839 13840 // Record the component. 13841 CurComponents.emplace_back(CurE, CurE->getDecl()); 13842 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 13843 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 13844 13845 if (isa<CXXThisExpr>(BaseE)) 13846 // We found a base expression: this->Val. 13847 RelevantExpr = CurE; 13848 else 13849 E = BaseE; 13850 13851 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 13852 if (!NoDiagnose) { 13853 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 13854 << CurE->getSourceRange(); 13855 return nullptr; 13856 } 13857 if (RelevantExpr) 13858 return nullptr; 13859 continue; 13860 } 13861 13862 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 13863 13864 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 13865 // A bit-field cannot appear in a map clause. 13866 // 13867 if (FD->isBitField()) { 13868 if (!NoDiagnose) { 13869 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 13870 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 13871 return nullptr; 13872 } 13873 if (RelevantExpr) 13874 return nullptr; 13875 continue; 13876 } 13877 13878 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13879 // If the type of a list item is a reference to a type T then the type 13880 // will be considered to be T for all purposes of this clause. 13881 QualType CurType = BaseE->getType().getNonReferenceType(); 13882 13883 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 13884 // A list item cannot be a variable that is a member of a structure with 13885 // a union type. 13886 // 13887 if (CurType->isUnionType()) { 13888 if (!NoDiagnose) { 13889 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 13890 << CurE->getSourceRange(); 13891 return nullptr; 13892 } 13893 continue; 13894 } 13895 13896 // If we got a member expression, we should not expect any array section 13897 // before that: 13898 // 13899 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 13900 // If a list item is an element of a structure, only the rightmost symbol 13901 // of the variable reference can be an array section. 13902 // 13903 AllowUnitySizeArraySection = false; 13904 AllowWholeSizeArraySection = false; 13905 13906 // Record the component. 13907 CurComponents.emplace_back(CurE, FD); 13908 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 13909 E = CurE->getBase()->IgnoreParenImpCasts(); 13910 13911 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 13912 if (!NoDiagnose) { 13913 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13914 << 0 << CurE->getSourceRange(); 13915 return nullptr; 13916 } 13917 continue; 13918 } 13919 13920 // If we got an array subscript that express the whole dimension we 13921 // can have any array expressions before. If it only expressing part of 13922 // the dimension, we can only have unitary-size array expressions. 13923 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 13924 E->getType())) 13925 AllowWholeSizeArraySection = false; 13926 13927 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13928 Expr::EvalResult Result; 13929 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13930 if (!Result.Val.getInt().isNullValue()) { 13931 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13932 diag::err_omp_invalid_map_this_expr); 13933 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13934 diag::note_omp_invalid_subscript_on_this_ptr_map); 13935 } 13936 } 13937 RelevantExpr = TE; 13938 } 13939 13940 // Record the component - we don't have any declaration associated. 13941 CurComponents.emplace_back(CurE, nullptr); 13942 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13943 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13944 E = CurE->getBase()->IgnoreParenImpCasts(); 13945 13946 QualType CurType = 13947 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13948 13949 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13950 // If the type of a list item is a reference to a type T then the type 13951 // will be considered to be T for all purposes of this clause. 13952 if (CurType->isReferenceType()) 13953 CurType = CurType->getPointeeType(); 13954 13955 bool IsPointer = CurType->isAnyPointerType(); 13956 13957 if (!IsPointer && !CurType->isArrayType()) { 13958 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13959 << 0 << CurE->getSourceRange(); 13960 return nullptr; 13961 } 13962 13963 bool NotWhole = 13964 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13965 bool NotUnity = 13966 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13967 13968 if (AllowWholeSizeArraySection) { 13969 // Any array section is currently allowed. Allowing a whole size array 13970 // section implies allowing a unity array section as well. 13971 // 13972 // If this array section refers to the whole dimension we can still 13973 // accept other array sections before this one, except if the base is a 13974 // pointer. Otherwise, only unitary sections are accepted. 13975 if (NotWhole || IsPointer) 13976 AllowWholeSizeArraySection = false; 13977 } else if (AllowUnitySizeArraySection && NotUnity) { 13978 // A unity or whole array section is not allowed and that is not 13979 // compatible with the properties of the current array section. 13980 SemaRef.Diag( 13981 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13982 << CurE->getSourceRange(); 13983 return nullptr; 13984 } 13985 13986 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13987 Expr::EvalResult ResultR; 13988 Expr::EvalResult ResultL; 13989 if (CurE->getLength()->EvaluateAsInt(ResultR, 13990 SemaRef.getASTContext())) { 13991 if (!ResultR.Val.getInt().isOneValue()) { 13992 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13993 diag::err_omp_invalid_map_this_expr); 13994 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13995 diag::note_omp_invalid_length_on_this_ptr_mapping); 13996 } 13997 } 13998 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 13999 ResultL, SemaRef.getASTContext())) { 14000 if (!ResultL.Val.getInt().isNullValue()) { 14001 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14002 diag::err_omp_invalid_map_this_expr); 14003 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14004 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14005 } 14006 } 14007 RelevantExpr = TE; 14008 } 14009 14010 // Record the component - we don't have any declaration associated. 14011 CurComponents.emplace_back(CurE, nullptr); 14012 } else { 14013 if (!NoDiagnose) { 14014 // If nothing else worked, this is not a valid map clause expression. 14015 SemaRef.Diag( 14016 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14017 << ERange; 14018 } 14019 return nullptr; 14020 } 14021 } 14022 14023 return RelevantExpr; 14024 } 14025 14026 // Return true if expression E associated with value VD has conflicts with other 14027 // map information. 14028 static bool checkMapConflicts( 14029 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14030 bool CurrentRegionOnly, 14031 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14032 OpenMPClauseKind CKind) { 14033 assert(VD && E); 14034 SourceLocation ELoc = E->getExprLoc(); 14035 SourceRange ERange = E->getSourceRange(); 14036 14037 // In order to easily check the conflicts we need to match each component of 14038 // the expression under test with the components of the expressions that are 14039 // already in the stack. 14040 14041 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14042 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14043 "Map clause expression with unexpected base!"); 14044 14045 // Variables to help detecting enclosing problems in data environment nests. 14046 bool IsEnclosedByDataEnvironmentExpr = false; 14047 const Expr *EnclosingExpr = nullptr; 14048 14049 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14050 VD, CurrentRegionOnly, 14051 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14052 ERange, CKind, &EnclosingExpr, 14053 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14054 StackComponents, 14055 OpenMPClauseKind) { 14056 assert(!StackComponents.empty() && 14057 "Map clause expression with no components!"); 14058 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14059 "Map clause expression with unexpected base!"); 14060 (void)VD; 14061 14062 // The whole expression in the stack. 14063 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14064 14065 // Expressions must start from the same base. Here we detect at which 14066 // point both expressions diverge from each other and see if we can 14067 // detect if the memory referred to both expressions is contiguous and 14068 // do not overlap. 14069 auto CI = CurComponents.rbegin(); 14070 auto CE = CurComponents.rend(); 14071 auto SI = StackComponents.rbegin(); 14072 auto SE = StackComponents.rend(); 14073 for (; CI != CE && SI != SE; ++CI, ++SI) { 14074 14075 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14076 // At most one list item can be an array item derived from a given 14077 // variable in map clauses of the same construct. 14078 if (CurrentRegionOnly && 14079 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14080 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14081 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14082 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14083 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14084 diag::err_omp_multiple_array_items_in_map_clause) 14085 << CI->getAssociatedExpression()->getSourceRange(); 14086 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14087 diag::note_used_here) 14088 << SI->getAssociatedExpression()->getSourceRange(); 14089 return true; 14090 } 14091 14092 // Do both expressions have the same kind? 14093 if (CI->getAssociatedExpression()->getStmtClass() != 14094 SI->getAssociatedExpression()->getStmtClass()) 14095 break; 14096 14097 // Are we dealing with different variables/fields? 14098 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14099 break; 14100 } 14101 // Check if the extra components of the expressions in the enclosing 14102 // data environment are redundant for the current base declaration. 14103 // If they are, the maps completely overlap, which is legal. 14104 for (; SI != SE; ++SI) { 14105 QualType Type; 14106 if (const auto *ASE = 14107 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14108 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14109 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14110 SI->getAssociatedExpression())) { 14111 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14112 Type = 14113 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14114 } 14115 if (Type.isNull() || Type->isAnyPointerType() || 14116 checkArrayExpressionDoesNotReferToWholeSize( 14117 SemaRef, SI->getAssociatedExpression(), Type)) 14118 break; 14119 } 14120 14121 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14122 // List items of map clauses in the same construct must not share 14123 // original storage. 14124 // 14125 // If the expressions are exactly the same or one is a subset of the 14126 // other, it means they are sharing storage. 14127 if (CI == CE && SI == SE) { 14128 if (CurrentRegionOnly) { 14129 if (CKind == OMPC_map) { 14130 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14131 } else { 14132 assert(CKind == OMPC_to || CKind == OMPC_from); 14133 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14134 << ERange; 14135 } 14136 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14137 << RE->getSourceRange(); 14138 return true; 14139 } 14140 // If we find the same expression in the enclosing data environment, 14141 // that is legal. 14142 IsEnclosedByDataEnvironmentExpr = true; 14143 return false; 14144 } 14145 14146 QualType DerivedType = 14147 std::prev(CI)->getAssociatedDeclaration()->getType(); 14148 SourceLocation DerivedLoc = 14149 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14150 14151 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14152 // If the type of a list item is a reference to a type T then the type 14153 // will be considered to be T for all purposes of this clause. 14154 DerivedType = DerivedType.getNonReferenceType(); 14155 14156 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14157 // A variable for which the type is pointer and an array section 14158 // derived from that variable must not appear as list items of map 14159 // clauses of the same construct. 14160 // 14161 // Also, cover one of the cases in: 14162 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14163 // If any part of the original storage of a list item has corresponding 14164 // storage in the device data environment, all of the original storage 14165 // must have corresponding storage in the device data environment. 14166 // 14167 if (DerivedType->isAnyPointerType()) { 14168 if (CI == CE || SI == SE) { 14169 SemaRef.Diag( 14170 DerivedLoc, 14171 diag::err_omp_pointer_mapped_along_with_derived_section) 14172 << DerivedLoc; 14173 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14174 << RE->getSourceRange(); 14175 return true; 14176 } 14177 if (CI->getAssociatedExpression()->getStmtClass() != 14178 SI->getAssociatedExpression()->getStmtClass() || 14179 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14180 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14181 assert(CI != CE && SI != SE); 14182 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14183 << DerivedLoc; 14184 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14185 << RE->getSourceRange(); 14186 return true; 14187 } 14188 } 14189 14190 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14191 // List items of map clauses in the same construct must not share 14192 // original storage. 14193 // 14194 // An expression is a subset of the other. 14195 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14196 if (CKind == OMPC_map) { 14197 if (CI != CE || SI != SE) { 14198 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14199 // a pointer. 14200 auto Begin = 14201 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14202 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14203 auto It = Begin; 14204 while (It != End && !It->getAssociatedDeclaration()) 14205 std::advance(It, 1); 14206 assert(It != End && 14207 "Expected at least one component with the declaration."); 14208 if (It != Begin && It->getAssociatedDeclaration() 14209 ->getType() 14210 .getCanonicalType() 14211 ->isAnyPointerType()) { 14212 IsEnclosedByDataEnvironmentExpr = false; 14213 EnclosingExpr = nullptr; 14214 return false; 14215 } 14216 } 14217 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14218 } else { 14219 assert(CKind == OMPC_to || CKind == OMPC_from); 14220 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14221 << ERange; 14222 } 14223 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14224 << RE->getSourceRange(); 14225 return true; 14226 } 14227 14228 // The current expression uses the same base as other expression in the 14229 // data environment but does not contain it completely. 14230 if (!CurrentRegionOnly && SI != SE) 14231 EnclosingExpr = RE; 14232 14233 // The current expression is a subset of the expression in the data 14234 // environment. 14235 IsEnclosedByDataEnvironmentExpr |= 14236 (!CurrentRegionOnly && CI != CE && SI == SE); 14237 14238 return false; 14239 }); 14240 14241 if (CurrentRegionOnly) 14242 return FoundError; 14243 14244 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14245 // If any part of the original storage of a list item has corresponding 14246 // storage in the device data environment, all of the original storage must 14247 // have corresponding storage in the device data environment. 14248 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 14249 // If a list item is an element of a structure, and a different element of 14250 // the structure has a corresponding list item in the device data environment 14251 // prior to a task encountering the construct associated with the map clause, 14252 // then the list item must also have a corresponding list item in the device 14253 // data environment prior to the task encountering the construct. 14254 // 14255 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 14256 SemaRef.Diag(ELoc, 14257 diag::err_omp_original_storage_is_shared_and_does_not_contain) 14258 << ERange; 14259 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 14260 << EnclosingExpr->getSourceRange(); 14261 return true; 14262 } 14263 14264 return FoundError; 14265 } 14266 14267 // Look up the user-defined mapper given the mapper name and mapped type, and 14268 // build a reference to it. 14269 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 14270 CXXScopeSpec &MapperIdScopeSpec, 14271 const DeclarationNameInfo &MapperId, 14272 QualType Type, 14273 Expr *UnresolvedMapper) { 14274 if (MapperIdScopeSpec.isInvalid()) 14275 return ExprError(); 14276 // Find all user-defined mappers with the given MapperId. 14277 SmallVector<UnresolvedSet<8>, 4> Lookups; 14278 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 14279 Lookup.suppressDiagnostics(); 14280 if (S) { 14281 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 14282 NamedDecl *D = Lookup.getRepresentativeDecl(); 14283 while (S && !S->isDeclScope(D)) 14284 S = S->getParent(); 14285 if (S) 14286 S = S->getParent(); 14287 Lookups.emplace_back(); 14288 Lookups.back().append(Lookup.begin(), Lookup.end()); 14289 Lookup.clear(); 14290 } 14291 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 14292 // Extract the user-defined mappers with the given MapperId. 14293 Lookups.push_back(UnresolvedSet<8>()); 14294 for (NamedDecl *D : ULE->decls()) { 14295 auto *DMD = cast<OMPDeclareMapperDecl>(D); 14296 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 14297 Lookups.back().addDecl(DMD); 14298 } 14299 } 14300 // Defer the lookup for dependent types. The results will be passed through 14301 // UnresolvedMapper on instantiation. 14302 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 14303 Type->isInstantiationDependentType() || 14304 Type->containsUnexpandedParameterPack() || 14305 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14306 return !D->isInvalidDecl() && 14307 (D->getType()->isDependentType() || 14308 D->getType()->isInstantiationDependentType() || 14309 D->getType()->containsUnexpandedParameterPack()); 14310 })) { 14311 UnresolvedSet<8> URS; 14312 for (const UnresolvedSet<8> &Set : Lookups) { 14313 if (Set.empty()) 14314 continue; 14315 URS.append(Set.begin(), Set.end()); 14316 } 14317 return UnresolvedLookupExpr::Create( 14318 SemaRef.Context, /*NamingClass=*/nullptr, 14319 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 14320 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 14321 } 14322 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14323 // The type must be of struct, union or class type in C and C++ 14324 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 14325 return ExprEmpty(); 14326 SourceLocation Loc = MapperId.getLoc(); 14327 // Perform argument dependent lookup. 14328 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 14329 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 14330 // Return the first user-defined mapper with the desired type. 14331 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14332 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 14333 if (!D->isInvalidDecl() && 14334 SemaRef.Context.hasSameType(D->getType(), Type)) 14335 return D; 14336 return nullptr; 14337 })) 14338 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14339 // Find the first user-defined mapper with a type derived from the desired 14340 // type. 14341 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14342 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 14343 if (!D->isInvalidDecl() && 14344 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 14345 !Type.isMoreQualifiedThan(D->getType())) 14346 return D; 14347 return nullptr; 14348 })) { 14349 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14350 /*DetectVirtual=*/false); 14351 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 14352 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14353 VD->getType().getUnqualifiedType()))) { 14354 if (SemaRef.CheckBaseClassAccess( 14355 Loc, VD->getType(), Type, Paths.front(), 14356 /*DiagID=*/0) != Sema::AR_inaccessible) { 14357 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14358 } 14359 } 14360 } 14361 } 14362 // Report error if a mapper is specified, but cannot be found. 14363 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 14364 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 14365 << Type << MapperId.getName(); 14366 return ExprError(); 14367 } 14368 return ExprEmpty(); 14369 } 14370 14371 namespace { 14372 // Utility struct that gathers all the related lists associated with a mappable 14373 // expression. 14374 struct MappableVarListInfo { 14375 // The list of expressions. 14376 ArrayRef<Expr *> VarList; 14377 // The list of processed expressions. 14378 SmallVector<Expr *, 16> ProcessedVarList; 14379 // The mappble components for each expression. 14380 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14381 // The base declaration of the variable. 14382 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14383 // The reference to the user-defined mapper associated with every expression. 14384 SmallVector<Expr *, 16> UDMapperList; 14385 14386 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14387 // We have a list of components and base declarations for each entry in the 14388 // variable list. 14389 VarComponents.reserve(VarList.size()); 14390 VarBaseDeclarations.reserve(VarList.size()); 14391 } 14392 }; 14393 } 14394 14395 // Check the validity of the provided variable list for the provided clause kind 14396 // \a CKind. In the check process the valid expressions, mappable expression 14397 // components, variables, and user-defined mappers are extracted and used to 14398 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14399 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14400 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14401 static void checkMappableExpressionList( 14402 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14403 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14404 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14405 ArrayRef<Expr *> UnresolvedMappers, 14406 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14407 bool IsMapTypeImplicit = false) { 14408 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14409 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14410 "Unexpected clause kind with mappable expressions!"); 14411 14412 // If the identifier of user-defined mapper is not specified, it is "default". 14413 // We do not change the actual name in this clause to distinguish whether a 14414 // mapper is specified explicitly, i.e., it is not explicitly specified when 14415 // MapperId.getName() is empty. 14416 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14417 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14418 MapperId.setName(DeclNames.getIdentifier( 14419 &SemaRef.getASTContext().Idents.get("default"))); 14420 } 14421 14422 // Iterators to find the current unresolved mapper expression. 14423 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14424 bool UpdateUMIt = false; 14425 Expr *UnresolvedMapper = nullptr; 14426 14427 // Keep track of the mappable components and base declarations in this clause. 14428 // Each entry in the list is going to have a list of components associated. We 14429 // record each set of the components so that we can build the clause later on. 14430 // In the end we should have the same amount of declarations and component 14431 // lists. 14432 14433 for (Expr *RE : MVLI.VarList) { 14434 assert(RE && "Null expr in omp to/from/map clause"); 14435 SourceLocation ELoc = RE->getExprLoc(); 14436 14437 // Find the current unresolved mapper expression. 14438 if (UpdateUMIt && UMIt != UMEnd) { 14439 UMIt++; 14440 assert( 14441 UMIt != UMEnd && 14442 "Expect the size of UnresolvedMappers to match with that of VarList"); 14443 } 14444 UpdateUMIt = true; 14445 if (UMIt != UMEnd) 14446 UnresolvedMapper = *UMIt; 14447 14448 const Expr *VE = RE->IgnoreParenLValueCasts(); 14449 14450 if (VE->isValueDependent() || VE->isTypeDependent() || 14451 VE->isInstantiationDependent() || 14452 VE->containsUnexpandedParameterPack()) { 14453 // Try to find the associated user-defined mapper. 14454 ExprResult ER = buildUserDefinedMapperRef( 14455 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14456 VE->getType().getCanonicalType(), UnresolvedMapper); 14457 if (ER.isInvalid()) 14458 continue; 14459 MVLI.UDMapperList.push_back(ER.get()); 14460 // We can only analyze this information once the missing information is 14461 // resolved. 14462 MVLI.ProcessedVarList.push_back(RE); 14463 continue; 14464 } 14465 14466 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14467 14468 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14469 SemaRef.Diag(ELoc, 14470 diag::err_omp_expected_named_var_member_or_array_expression) 14471 << RE->getSourceRange(); 14472 continue; 14473 } 14474 14475 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14476 ValueDecl *CurDeclaration = nullptr; 14477 14478 // Obtain the array or member expression bases if required. Also, fill the 14479 // components array with all the components identified in the process. 14480 const Expr *BE = checkMapClauseExpressionBase( 14481 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14482 if (!BE) 14483 continue; 14484 14485 assert(!CurComponents.empty() && 14486 "Invalid mappable expression information."); 14487 14488 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14489 // Add store "this" pointer to class in DSAStackTy for future checking 14490 DSAS->addMappedClassesQualTypes(TE->getType()); 14491 // Try to find the associated user-defined mapper. 14492 ExprResult ER = buildUserDefinedMapperRef( 14493 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14494 VE->getType().getCanonicalType(), UnresolvedMapper); 14495 if (ER.isInvalid()) 14496 continue; 14497 MVLI.UDMapperList.push_back(ER.get()); 14498 // Skip restriction checking for variable or field declarations 14499 MVLI.ProcessedVarList.push_back(RE); 14500 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14501 MVLI.VarComponents.back().append(CurComponents.begin(), 14502 CurComponents.end()); 14503 MVLI.VarBaseDeclarations.push_back(nullptr); 14504 continue; 14505 } 14506 14507 // For the following checks, we rely on the base declaration which is 14508 // expected to be associated with the last component. The declaration is 14509 // expected to be a variable or a field (if 'this' is being mapped). 14510 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14511 assert(CurDeclaration && "Null decl on map clause."); 14512 assert( 14513 CurDeclaration->isCanonicalDecl() && 14514 "Expecting components to have associated only canonical declarations."); 14515 14516 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14517 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14518 14519 assert((VD || FD) && "Only variables or fields are expected here!"); 14520 (void)FD; 14521 14522 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14523 // threadprivate variables cannot appear in a map clause. 14524 // OpenMP 4.5 [2.10.5, target update Construct] 14525 // threadprivate variables cannot appear in a from clause. 14526 if (VD && DSAS->isThreadPrivate(VD)) { 14527 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14528 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14529 << getOpenMPClauseName(CKind); 14530 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14531 continue; 14532 } 14533 14534 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14535 // A list item cannot appear in both a map clause and a data-sharing 14536 // attribute clause on the same construct. 14537 14538 // Check conflicts with other map clause expressions. We check the conflicts 14539 // with the current construct separately from the enclosing data 14540 // environment, because the restrictions are different. We only have to 14541 // check conflicts across regions for the map clauses. 14542 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14543 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14544 break; 14545 if (CKind == OMPC_map && 14546 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14547 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14548 break; 14549 14550 // OpenMP 4.5 [2.10.5, target update Construct] 14551 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14552 // If the type of a list item is a reference to a type T then the type will 14553 // be considered to be T for all purposes of this clause. 14554 auto I = llvm::find_if( 14555 CurComponents, 14556 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14557 return MC.getAssociatedDeclaration(); 14558 }); 14559 assert(I != CurComponents.end() && "Null decl on map clause."); 14560 QualType Type = 14561 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14562 14563 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14564 // A list item in a to or from clause must have a mappable type. 14565 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14566 // A list item must have a mappable type. 14567 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14568 DSAS, Type)) 14569 continue; 14570 14571 if (CKind == OMPC_map) { 14572 // target enter data 14573 // OpenMP [2.10.2, Restrictions, p. 99] 14574 // A map-type must be specified in all map clauses and must be either 14575 // to or alloc. 14576 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14577 if (DKind == OMPD_target_enter_data && 14578 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14579 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14580 << (IsMapTypeImplicit ? 1 : 0) 14581 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14582 << getOpenMPDirectiveName(DKind); 14583 continue; 14584 } 14585 14586 // target exit_data 14587 // OpenMP [2.10.3, Restrictions, p. 102] 14588 // A map-type must be specified in all map clauses and must be either 14589 // from, release, or delete. 14590 if (DKind == OMPD_target_exit_data && 14591 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14592 MapType == OMPC_MAP_delete)) { 14593 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14594 << (IsMapTypeImplicit ? 1 : 0) 14595 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14596 << getOpenMPDirectiveName(DKind); 14597 continue; 14598 } 14599 14600 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14601 // A list item cannot appear in both a map clause and a data-sharing 14602 // attribute clause on the same construct 14603 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 14604 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14605 if (isOpenMPPrivate(DVar.CKind)) { 14606 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14607 << getOpenMPClauseName(DVar.CKind) 14608 << getOpenMPClauseName(OMPC_map) 14609 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14610 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14611 continue; 14612 } 14613 } 14614 } 14615 14616 // Try to find the associated user-defined mapper. 14617 ExprResult ER = buildUserDefinedMapperRef( 14618 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14619 Type.getCanonicalType(), UnresolvedMapper); 14620 if (ER.isInvalid()) 14621 continue; 14622 MVLI.UDMapperList.push_back(ER.get()); 14623 14624 // Save the current expression. 14625 MVLI.ProcessedVarList.push_back(RE); 14626 14627 // Store the components in the stack so that they can be used to check 14628 // against other clauses later on. 14629 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14630 /*WhereFoundClauseKind=*/OMPC_map); 14631 14632 // Save the components and declaration to create the clause. For purposes of 14633 // the clause creation, any component list that has has base 'this' uses 14634 // null as base declaration. 14635 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14636 MVLI.VarComponents.back().append(CurComponents.begin(), 14637 CurComponents.end()); 14638 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14639 : CurDeclaration); 14640 } 14641 } 14642 14643 OMPClause *Sema::ActOnOpenMPMapClause( 14644 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14645 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14646 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14647 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14648 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14649 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14650 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14651 OMPC_MAP_MODIFIER_unknown, 14652 OMPC_MAP_MODIFIER_unknown}; 14653 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14654 14655 // Process map-type-modifiers, flag errors for duplicate modifiers. 14656 unsigned Count = 0; 14657 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14658 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14659 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14660 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14661 continue; 14662 } 14663 assert(Count < OMPMapClause::NumberOfModifiers && 14664 "Modifiers exceed the allowed number of map type modifiers"); 14665 Modifiers[Count] = MapTypeModifiers[I]; 14666 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14667 ++Count; 14668 } 14669 14670 MappableVarListInfo MVLI(VarList); 14671 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14672 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14673 MapType, IsMapTypeImplicit); 14674 14675 // We need to produce a map clause even if we don't have variables so that 14676 // other diagnostics related with non-existing map clauses are accurate. 14677 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14678 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14679 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14680 MapperIdScopeSpec.getWithLocInContext(Context), 14681 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14682 } 14683 14684 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14685 TypeResult ParsedType) { 14686 assert(ParsedType.isUsable()); 14687 14688 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14689 if (ReductionType.isNull()) 14690 return QualType(); 14691 14692 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14693 // A type name in a declare reduction directive cannot be a function type, an 14694 // array type, a reference type, or a type qualified with const, volatile or 14695 // restrict. 14696 if (ReductionType.hasQualifiers()) { 14697 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14698 return QualType(); 14699 } 14700 14701 if (ReductionType->isFunctionType()) { 14702 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14703 return QualType(); 14704 } 14705 if (ReductionType->isReferenceType()) { 14706 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14707 return QualType(); 14708 } 14709 if (ReductionType->isArrayType()) { 14710 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14711 return QualType(); 14712 } 14713 return ReductionType; 14714 } 14715 14716 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14717 Scope *S, DeclContext *DC, DeclarationName Name, 14718 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14719 AccessSpecifier AS, Decl *PrevDeclInScope) { 14720 SmallVector<Decl *, 8> Decls; 14721 Decls.reserve(ReductionTypes.size()); 14722 14723 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14724 forRedeclarationInCurContext()); 14725 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14726 // A reduction-identifier may not be re-declared in the current scope for the 14727 // same type or for a type that is compatible according to the base language 14728 // rules. 14729 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14730 OMPDeclareReductionDecl *PrevDRD = nullptr; 14731 bool InCompoundScope = true; 14732 if (S != nullptr) { 14733 // Find previous declaration with the same name not referenced in other 14734 // declarations. 14735 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14736 InCompoundScope = 14737 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14738 LookupName(Lookup, S); 14739 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14740 /*AllowInlineNamespace=*/false); 14741 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14742 LookupResult::Filter Filter = Lookup.makeFilter(); 14743 while (Filter.hasNext()) { 14744 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14745 if (InCompoundScope) { 14746 auto I = UsedAsPrevious.find(PrevDecl); 14747 if (I == UsedAsPrevious.end()) 14748 UsedAsPrevious[PrevDecl] = false; 14749 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14750 UsedAsPrevious[D] = true; 14751 } 14752 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14753 PrevDecl->getLocation(); 14754 } 14755 Filter.done(); 14756 if (InCompoundScope) { 14757 for (const auto &PrevData : UsedAsPrevious) { 14758 if (!PrevData.second) { 14759 PrevDRD = PrevData.first; 14760 break; 14761 } 14762 } 14763 } 14764 } else if (PrevDeclInScope != nullptr) { 14765 auto *PrevDRDInScope = PrevDRD = 14766 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14767 do { 14768 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14769 PrevDRDInScope->getLocation(); 14770 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14771 } while (PrevDRDInScope != nullptr); 14772 } 14773 for (const auto &TyData : ReductionTypes) { 14774 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14775 bool Invalid = false; 14776 if (I != PreviousRedeclTypes.end()) { 14777 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14778 << TyData.first; 14779 Diag(I->second, diag::note_previous_definition); 14780 Invalid = true; 14781 } 14782 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 14783 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 14784 Name, TyData.first, PrevDRD); 14785 DC->addDecl(DRD); 14786 DRD->setAccess(AS); 14787 Decls.push_back(DRD); 14788 if (Invalid) 14789 DRD->setInvalidDecl(); 14790 else 14791 PrevDRD = DRD; 14792 } 14793 14794 return DeclGroupPtrTy::make( 14795 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 14796 } 14797 14798 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 14799 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14800 14801 // Enter new function scope. 14802 PushFunctionScope(); 14803 setFunctionHasBranchProtectedScope(); 14804 getCurFunction()->setHasOMPDeclareReductionCombiner(); 14805 14806 if (S != nullptr) 14807 PushDeclContext(S, DRD); 14808 else 14809 CurContext = DRD; 14810 14811 PushExpressionEvaluationContext( 14812 ExpressionEvaluationContext::PotentiallyEvaluated); 14813 14814 QualType ReductionType = DRD->getType(); 14815 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 14816 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 14817 // uses semantics of argument handles by value, but it should be passed by 14818 // reference. C lang does not support references, so pass all parameters as 14819 // pointers. 14820 // Create 'T omp_in;' variable. 14821 VarDecl *OmpInParm = 14822 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 14823 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 14824 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 14825 // uses semantics of argument handles by value, but it should be passed by 14826 // reference. C lang does not support references, so pass all parameters as 14827 // pointers. 14828 // Create 'T omp_out;' variable. 14829 VarDecl *OmpOutParm = 14830 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 14831 if (S != nullptr) { 14832 PushOnScopeChains(OmpInParm, S); 14833 PushOnScopeChains(OmpOutParm, S); 14834 } else { 14835 DRD->addDecl(OmpInParm); 14836 DRD->addDecl(OmpOutParm); 14837 } 14838 Expr *InE = 14839 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 14840 Expr *OutE = 14841 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 14842 DRD->setCombinerData(InE, OutE); 14843 } 14844 14845 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 14846 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14847 DiscardCleanupsInEvaluationContext(); 14848 PopExpressionEvaluationContext(); 14849 14850 PopDeclContext(); 14851 PopFunctionScopeInfo(); 14852 14853 if (Combiner != nullptr) 14854 DRD->setCombiner(Combiner); 14855 else 14856 DRD->setInvalidDecl(); 14857 } 14858 14859 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 14860 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14861 14862 // Enter new function scope. 14863 PushFunctionScope(); 14864 setFunctionHasBranchProtectedScope(); 14865 14866 if (S != nullptr) 14867 PushDeclContext(S, DRD); 14868 else 14869 CurContext = DRD; 14870 14871 PushExpressionEvaluationContext( 14872 ExpressionEvaluationContext::PotentiallyEvaluated); 14873 14874 QualType ReductionType = DRD->getType(); 14875 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 14876 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 14877 // uses semantics of argument handles by value, but it should be passed by 14878 // reference. C lang does not support references, so pass all parameters as 14879 // pointers. 14880 // Create 'T omp_priv;' variable. 14881 VarDecl *OmpPrivParm = 14882 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 14883 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 14884 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 14885 // uses semantics of argument handles by value, but it should be passed by 14886 // reference. C lang does not support references, so pass all parameters as 14887 // pointers. 14888 // Create 'T omp_orig;' variable. 14889 VarDecl *OmpOrigParm = 14890 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 14891 if (S != nullptr) { 14892 PushOnScopeChains(OmpPrivParm, S); 14893 PushOnScopeChains(OmpOrigParm, S); 14894 } else { 14895 DRD->addDecl(OmpPrivParm); 14896 DRD->addDecl(OmpOrigParm); 14897 } 14898 Expr *OrigE = 14899 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 14900 Expr *PrivE = 14901 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 14902 DRD->setInitializerData(OrigE, PrivE); 14903 return OmpPrivParm; 14904 } 14905 14906 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 14907 VarDecl *OmpPrivParm) { 14908 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14909 DiscardCleanupsInEvaluationContext(); 14910 PopExpressionEvaluationContext(); 14911 14912 PopDeclContext(); 14913 PopFunctionScopeInfo(); 14914 14915 if (Initializer != nullptr) { 14916 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 14917 } else if (OmpPrivParm->hasInit()) { 14918 DRD->setInitializer(OmpPrivParm->getInit(), 14919 OmpPrivParm->isDirectInit() 14920 ? OMPDeclareReductionDecl::DirectInit 14921 : OMPDeclareReductionDecl::CopyInit); 14922 } else { 14923 DRD->setInvalidDecl(); 14924 } 14925 } 14926 14927 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14928 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14929 for (Decl *D : DeclReductions.get()) { 14930 if (IsValid) { 14931 if (S) 14932 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14933 /*AddToContext=*/false); 14934 } else { 14935 D->setInvalidDecl(); 14936 } 14937 } 14938 return DeclReductions; 14939 } 14940 14941 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14942 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14943 QualType T = TInfo->getType(); 14944 if (D.isInvalidType()) 14945 return true; 14946 14947 if (getLangOpts().CPlusPlus) { 14948 // Check that there are no default arguments (C++ only). 14949 CheckExtraCXXDefaultArguments(D); 14950 } 14951 14952 return CreateParsedType(T, TInfo); 14953 } 14954 14955 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14956 TypeResult ParsedType) { 14957 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14958 14959 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14960 assert(!MapperType.isNull() && "Expect valid mapper type"); 14961 14962 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14963 // The type must be of struct, union or class type in C and C++ 14964 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14965 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14966 return QualType(); 14967 } 14968 return MapperType; 14969 } 14970 14971 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14972 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14973 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14974 Decl *PrevDeclInScope) { 14975 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14976 forRedeclarationInCurContext()); 14977 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14978 // A mapper-identifier may not be redeclared in the current scope for the 14979 // same type or for a type that is compatible according to the base language 14980 // rules. 14981 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14982 OMPDeclareMapperDecl *PrevDMD = nullptr; 14983 bool InCompoundScope = true; 14984 if (S != nullptr) { 14985 // Find previous declaration with the same name not referenced in other 14986 // declarations. 14987 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14988 InCompoundScope = 14989 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14990 LookupName(Lookup, S); 14991 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14992 /*AllowInlineNamespace=*/false); 14993 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14994 LookupResult::Filter Filter = Lookup.makeFilter(); 14995 while (Filter.hasNext()) { 14996 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14997 if (InCompoundScope) { 14998 auto I = UsedAsPrevious.find(PrevDecl); 14999 if (I == UsedAsPrevious.end()) 15000 UsedAsPrevious[PrevDecl] = false; 15001 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15002 UsedAsPrevious[D] = true; 15003 } 15004 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15005 PrevDecl->getLocation(); 15006 } 15007 Filter.done(); 15008 if (InCompoundScope) { 15009 for (const auto &PrevData : UsedAsPrevious) { 15010 if (!PrevData.second) { 15011 PrevDMD = PrevData.first; 15012 break; 15013 } 15014 } 15015 } 15016 } else if (PrevDeclInScope) { 15017 auto *PrevDMDInScope = PrevDMD = 15018 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15019 do { 15020 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15021 PrevDMDInScope->getLocation(); 15022 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15023 } while (PrevDMDInScope != nullptr); 15024 } 15025 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15026 bool Invalid = false; 15027 if (I != PreviousRedeclTypes.end()) { 15028 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15029 << MapperType << Name; 15030 Diag(I->second, diag::note_previous_definition); 15031 Invalid = true; 15032 } 15033 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15034 MapperType, VN, PrevDMD); 15035 DC->addDecl(DMD); 15036 DMD->setAccess(AS); 15037 if (Invalid) 15038 DMD->setInvalidDecl(); 15039 15040 // Enter new function scope. 15041 PushFunctionScope(); 15042 setFunctionHasBranchProtectedScope(); 15043 15044 CurContext = DMD; 15045 15046 return DMD; 15047 } 15048 15049 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15050 Scope *S, 15051 QualType MapperType, 15052 SourceLocation StartLoc, 15053 DeclarationName VN) { 15054 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15055 if (S) 15056 PushOnScopeChains(VD, S); 15057 else 15058 DMD->addDecl(VD); 15059 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15060 DMD->setMapperVarRef(MapperVarRefExpr); 15061 } 15062 15063 Sema::DeclGroupPtrTy 15064 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15065 ArrayRef<OMPClause *> ClauseList) { 15066 PopDeclContext(); 15067 PopFunctionScopeInfo(); 15068 15069 if (D) { 15070 if (S) 15071 PushOnScopeChains(D, S, /*AddToContext=*/false); 15072 D->CreateClauses(Context, ClauseList); 15073 } 15074 15075 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15076 } 15077 15078 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15079 SourceLocation StartLoc, 15080 SourceLocation LParenLoc, 15081 SourceLocation EndLoc) { 15082 Expr *ValExpr = NumTeams; 15083 Stmt *HelperValStmt = nullptr; 15084 15085 // OpenMP [teams Constrcut, Restrictions] 15086 // The num_teams expression must evaluate to a positive integer value. 15087 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15088 /*StrictlyPositive=*/true)) 15089 return nullptr; 15090 15091 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15092 OpenMPDirectiveKind CaptureRegion = 15093 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15094 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15095 ValExpr = MakeFullExpr(ValExpr).get(); 15096 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15097 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15098 HelperValStmt = buildPreInits(Context, Captures); 15099 } 15100 15101 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15102 StartLoc, LParenLoc, EndLoc); 15103 } 15104 15105 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15106 SourceLocation StartLoc, 15107 SourceLocation LParenLoc, 15108 SourceLocation EndLoc) { 15109 Expr *ValExpr = ThreadLimit; 15110 Stmt *HelperValStmt = nullptr; 15111 15112 // OpenMP [teams Constrcut, Restrictions] 15113 // The thread_limit expression must evaluate to a positive integer value. 15114 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15115 /*StrictlyPositive=*/true)) 15116 return nullptr; 15117 15118 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15119 OpenMPDirectiveKind CaptureRegion = 15120 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15121 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15122 ValExpr = MakeFullExpr(ValExpr).get(); 15123 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15124 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15125 HelperValStmt = buildPreInits(Context, Captures); 15126 } 15127 15128 return new (Context) OMPThreadLimitClause( 15129 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15130 } 15131 15132 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15133 SourceLocation StartLoc, 15134 SourceLocation LParenLoc, 15135 SourceLocation EndLoc) { 15136 Expr *ValExpr = Priority; 15137 15138 // OpenMP [2.9.1, task Constrcut] 15139 // The priority-value is a non-negative numerical scalar expression. 15140 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15141 /*StrictlyPositive=*/false)) 15142 return nullptr; 15143 15144 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15145 } 15146 15147 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15148 SourceLocation StartLoc, 15149 SourceLocation LParenLoc, 15150 SourceLocation EndLoc) { 15151 Expr *ValExpr = Grainsize; 15152 15153 // OpenMP [2.9.2, taskloop Constrcut] 15154 // The parameter of the grainsize clause must be a positive integer 15155 // expression. 15156 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 15157 /*StrictlyPositive=*/true)) 15158 return nullptr; 15159 15160 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15161 } 15162 15163 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15164 SourceLocation StartLoc, 15165 SourceLocation LParenLoc, 15166 SourceLocation EndLoc) { 15167 Expr *ValExpr = NumTasks; 15168 15169 // OpenMP [2.9.2, taskloop Constrcut] 15170 // The parameter of the num_tasks clause must be a positive integer 15171 // expression. 15172 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 15173 /*StrictlyPositive=*/true)) 15174 return nullptr; 15175 15176 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15177 } 15178 15179 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15180 SourceLocation LParenLoc, 15181 SourceLocation EndLoc) { 15182 // OpenMP [2.13.2, critical construct, Description] 15183 // ... where hint-expression is an integer constant expression that evaluates 15184 // to a valid lock hint. 15185 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15186 if (HintExpr.isInvalid()) 15187 return nullptr; 15188 return new (Context) 15189 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 15190 } 15191 15192 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 15193 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 15194 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 15195 SourceLocation EndLoc) { 15196 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 15197 std::string Values; 15198 Values += "'"; 15199 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 15200 Values += "'"; 15201 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 15202 << Values << getOpenMPClauseName(OMPC_dist_schedule); 15203 return nullptr; 15204 } 15205 Expr *ValExpr = ChunkSize; 15206 Stmt *HelperValStmt = nullptr; 15207 if (ChunkSize) { 15208 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 15209 !ChunkSize->isInstantiationDependent() && 15210 !ChunkSize->containsUnexpandedParameterPack()) { 15211 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 15212 ExprResult Val = 15213 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 15214 if (Val.isInvalid()) 15215 return nullptr; 15216 15217 ValExpr = Val.get(); 15218 15219 // OpenMP [2.7.1, Restrictions] 15220 // chunk_size must be a loop invariant integer expression with a positive 15221 // value. 15222 llvm::APSInt Result; 15223 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 15224 if (Result.isSigned() && !Result.isStrictlyPositive()) { 15225 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 15226 << "dist_schedule" << ChunkSize->getSourceRange(); 15227 return nullptr; 15228 } 15229 } else if (getOpenMPCaptureRegionForClause( 15230 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 15231 OMPD_unknown && 15232 !CurContext->isDependentContext()) { 15233 ValExpr = MakeFullExpr(ValExpr).get(); 15234 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15235 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15236 HelperValStmt = buildPreInits(Context, Captures); 15237 } 15238 } 15239 } 15240 15241 return new (Context) 15242 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 15243 Kind, ValExpr, HelperValStmt); 15244 } 15245 15246 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 15247 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 15248 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 15249 SourceLocation KindLoc, SourceLocation EndLoc) { 15250 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 15251 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 15252 std::string Value; 15253 SourceLocation Loc; 15254 Value += "'"; 15255 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 15256 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15257 OMPC_DEFAULTMAP_MODIFIER_tofrom); 15258 Loc = MLoc; 15259 } else { 15260 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15261 OMPC_DEFAULTMAP_scalar); 15262 Loc = KindLoc; 15263 } 15264 Value += "'"; 15265 Diag(Loc, diag::err_omp_unexpected_clause_value) 15266 << Value << getOpenMPClauseName(OMPC_defaultmap); 15267 return nullptr; 15268 } 15269 DSAStack->setDefaultDMAToFromScalar(StartLoc); 15270 15271 return new (Context) 15272 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 15273 } 15274 15275 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 15276 DeclContext *CurLexicalContext = getCurLexicalContext(); 15277 if (!CurLexicalContext->isFileContext() && 15278 !CurLexicalContext->isExternCContext() && 15279 !CurLexicalContext->isExternCXXContext() && 15280 !isa<CXXRecordDecl>(CurLexicalContext) && 15281 !isa<ClassTemplateDecl>(CurLexicalContext) && 15282 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 15283 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 15284 Diag(Loc, diag::err_omp_region_not_file_context); 15285 return false; 15286 } 15287 ++DeclareTargetNestingLevel; 15288 return true; 15289 } 15290 15291 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 15292 assert(DeclareTargetNestingLevel > 0 && 15293 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 15294 --DeclareTargetNestingLevel; 15295 } 15296 15297 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 15298 CXXScopeSpec &ScopeSpec, 15299 const DeclarationNameInfo &Id, 15300 OMPDeclareTargetDeclAttr::MapTypeTy MT, 15301 NamedDeclSetType &SameDirectiveDecls) { 15302 LookupResult Lookup(*this, Id, LookupOrdinaryName); 15303 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 15304 15305 if (Lookup.isAmbiguous()) 15306 return; 15307 Lookup.suppressDiagnostics(); 15308 15309 if (!Lookup.isSingleResult()) { 15310 VarOrFuncDeclFilterCCC CCC(*this); 15311 if (TypoCorrection Corrected = 15312 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 15313 CTK_ErrorRecovery)) { 15314 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 15315 << Id.getName()); 15316 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 15317 return; 15318 } 15319 15320 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 15321 return; 15322 } 15323 15324 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 15325 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 15326 isa<FunctionTemplateDecl>(ND)) { 15327 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 15328 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 15329 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15330 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 15331 cast<ValueDecl>(ND)); 15332 if (!Res) { 15333 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 15334 ND->addAttr(A); 15335 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15336 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 15337 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 15338 } else if (*Res != MT) { 15339 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 15340 << Id.getName(); 15341 } 15342 } else { 15343 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 15344 } 15345 } 15346 15347 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 15348 Sema &SemaRef, Decl *D) { 15349 if (!D || !isa<VarDecl>(D)) 15350 return; 15351 auto *VD = cast<VarDecl>(D); 15352 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 15353 return; 15354 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 15355 SemaRef.Diag(SL, diag::note_used_here) << SR; 15356 } 15357 15358 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 15359 Sema &SemaRef, DSAStackTy *Stack, 15360 ValueDecl *VD) { 15361 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 15362 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 15363 /*FullCheck=*/false); 15364 } 15365 15366 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 15367 SourceLocation IdLoc) { 15368 if (!D || D->isInvalidDecl()) 15369 return; 15370 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 15371 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15372 if (auto *VD = dyn_cast<VarDecl>(D)) { 15373 // Only global variables can be marked as declare target. 15374 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15375 !VD->isStaticDataMember()) 15376 return; 15377 // 2.10.6: threadprivate variable cannot appear in a declare target 15378 // directive. 15379 if (DSAStack->isThreadPrivate(VD)) { 15380 Diag(SL, diag::err_omp_threadprivate_in_target); 15381 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15382 return; 15383 } 15384 } 15385 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 15386 D = FTD->getTemplatedDecl(); 15387 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 15388 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15389 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 15390 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 15391 assert(IdLoc.isValid() && "Source location is expected"); 15392 Diag(IdLoc, diag::err_omp_function_in_link_clause); 15393 Diag(FD->getLocation(), diag::note_defined_here) << FD; 15394 return; 15395 } 15396 } 15397 if (auto *VD = dyn_cast<ValueDecl>(D)) { 15398 // Problem if any with var declared with incomplete type will be reported 15399 // as normal, so no need to check it here. 15400 if ((E || !VD->getType()->isIncompleteType()) && 15401 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 15402 return; 15403 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 15404 // Checking declaration inside declare target region. 15405 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 15406 isa<FunctionTemplateDecl>(D)) { 15407 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 15408 Context, OMPDeclareTargetDeclAttr::MT_To); 15409 D->addAttr(A); 15410 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15411 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 15412 } 15413 return; 15414 } 15415 } 15416 if (!E) 15417 return; 15418 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15419 } 15420 15421 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15422 CXXScopeSpec &MapperIdScopeSpec, 15423 DeclarationNameInfo &MapperId, 15424 const OMPVarListLocTy &Locs, 15425 ArrayRef<Expr *> UnresolvedMappers) { 15426 MappableVarListInfo MVLI(VarList); 15427 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15428 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15429 if (MVLI.ProcessedVarList.empty()) 15430 return nullptr; 15431 15432 return OMPToClause::Create( 15433 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15434 MVLI.VarComponents, MVLI.UDMapperList, 15435 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15436 } 15437 15438 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15439 CXXScopeSpec &MapperIdScopeSpec, 15440 DeclarationNameInfo &MapperId, 15441 const OMPVarListLocTy &Locs, 15442 ArrayRef<Expr *> UnresolvedMappers) { 15443 MappableVarListInfo MVLI(VarList); 15444 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15445 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15446 if (MVLI.ProcessedVarList.empty()) 15447 return nullptr; 15448 15449 return OMPFromClause::Create( 15450 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15451 MVLI.VarComponents, MVLI.UDMapperList, 15452 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15453 } 15454 15455 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15456 const OMPVarListLocTy &Locs) { 15457 MappableVarListInfo MVLI(VarList); 15458 SmallVector<Expr *, 8> PrivateCopies; 15459 SmallVector<Expr *, 8> Inits; 15460 15461 for (Expr *RefExpr : VarList) { 15462 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15463 SourceLocation ELoc; 15464 SourceRange ERange; 15465 Expr *SimpleRefExpr = RefExpr; 15466 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15467 if (Res.second) { 15468 // It will be analyzed later. 15469 MVLI.ProcessedVarList.push_back(RefExpr); 15470 PrivateCopies.push_back(nullptr); 15471 Inits.push_back(nullptr); 15472 } 15473 ValueDecl *D = Res.first; 15474 if (!D) 15475 continue; 15476 15477 QualType Type = D->getType(); 15478 Type = Type.getNonReferenceType().getUnqualifiedType(); 15479 15480 auto *VD = dyn_cast<VarDecl>(D); 15481 15482 // Item should be a pointer or reference to pointer. 15483 if (!Type->isPointerType()) { 15484 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15485 << 0 << RefExpr->getSourceRange(); 15486 continue; 15487 } 15488 15489 // Build the private variable and the expression that refers to it. 15490 auto VDPrivate = 15491 buildVarDecl(*this, ELoc, Type, D->getName(), 15492 D->hasAttrs() ? &D->getAttrs() : nullptr, 15493 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15494 if (VDPrivate->isInvalidDecl()) 15495 continue; 15496 15497 CurContext->addDecl(VDPrivate); 15498 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15499 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15500 15501 // Add temporary variable to initialize the private copy of the pointer. 15502 VarDecl *VDInit = 15503 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15504 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15505 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15506 AddInitializerToDecl(VDPrivate, 15507 DefaultLvalueConversion(VDInitRefExpr).get(), 15508 /*DirectInit=*/false); 15509 15510 // If required, build a capture to implement the privatization initialized 15511 // with the current list item value. 15512 DeclRefExpr *Ref = nullptr; 15513 if (!VD) 15514 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15515 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15516 PrivateCopies.push_back(VDPrivateRefExpr); 15517 Inits.push_back(VDInitRefExpr); 15518 15519 // We need to add a data sharing attribute for this variable to make sure it 15520 // is correctly captured. A variable that shows up in a use_device_ptr has 15521 // similar properties of a first private variable. 15522 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15523 15524 // Create a mappable component for the list item. List items in this clause 15525 // only need a component. 15526 MVLI.VarBaseDeclarations.push_back(D); 15527 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15528 MVLI.VarComponents.back().push_back( 15529 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15530 } 15531 15532 if (MVLI.ProcessedVarList.empty()) 15533 return nullptr; 15534 15535 return OMPUseDevicePtrClause::Create( 15536 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15537 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15538 } 15539 15540 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15541 const OMPVarListLocTy &Locs) { 15542 MappableVarListInfo MVLI(VarList); 15543 for (Expr *RefExpr : VarList) { 15544 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15545 SourceLocation ELoc; 15546 SourceRange ERange; 15547 Expr *SimpleRefExpr = RefExpr; 15548 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15549 if (Res.second) { 15550 // It will be analyzed later. 15551 MVLI.ProcessedVarList.push_back(RefExpr); 15552 } 15553 ValueDecl *D = Res.first; 15554 if (!D) 15555 continue; 15556 15557 QualType Type = D->getType(); 15558 // item should be a pointer or array or reference to pointer or array 15559 if (!Type.getNonReferenceType()->isPointerType() && 15560 !Type.getNonReferenceType()->isArrayType()) { 15561 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15562 << 0 << RefExpr->getSourceRange(); 15563 continue; 15564 } 15565 15566 // Check if the declaration in the clause does not show up in any data 15567 // sharing attribute. 15568 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15569 if (isOpenMPPrivate(DVar.CKind)) { 15570 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15571 << getOpenMPClauseName(DVar.CKind) 15572 << getOpenMPClauseName(OMPC_is_device_ptr) 15573 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15574 reportOriginalDsa(*this, DSAStack, D, DVar); 15575 continue; 15576 } 15577 15578 const Expr *ConflictExpr; 15579 if (DSAStack->checkMappableExprComponentListsForDecl( 15580 D, /*CurrentRegionOnly=*/true, 15581 [&ConflictExpr]( 15582 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15583 OpenMPClauseKind) -> bool { 15584 ConflictExpr = R.front().getAssociatedExpression(); 15585 return true; 15586 })) { 15587 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15588 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15589 << ConflictExpr->getSourceRange(); 15590 continue; 15591 } 15592 15593 // Store the components in the stack so that they can be used to check 15594 // against other clauses later on. 15595 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15596 DSAStack->addMappableExpressionComponents( 15597 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15598 15599 // Record the expression we've just processed. 15600 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15601 15602 // Create a mappable component for the list item. List items in this clause 15603 // only need a component. We use a null declaration to signal fields in 15604 // 'this'. 15605 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15606 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15607 "Unexpected device pointer expression!"); 15608 MVLI.VarBaseDeclarations.push_back( 15609 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15610 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15611 MVLI.VarComponents.back().push_back(MC); 15612 } 15613 15614 if (MVLI.ProcessedVarList.empty()) 15615 return nullptr; 15616 15617 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15618 MVLI.VarBaseDeclarations, 15619 MVLI.VarComponents); 15620 } 15621 15622 OMPClause *Sema::ActOnOpenMPAllocateClause( 15623 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15624 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15625 if (Allocator) { 15626 // OpenMP [2.11.4 allocate Clause, Description] 15627 // allocator is an expression of omp_allocator_handle_t type. 15628 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15629 return nullptr; 15630 15631 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15632 if (AllocatorRes.isInvalid()) 15633 return nullptr; 15634 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15635 DSAStack->getOMPAllocatorHandleT(), 15636 Sema::AA_Initializing, 15637 /*AllowExplicit=*/true); 15638 if (AllocatorRes.isInvalid()) 15639 return nullptr; 15640 Allocator = AllocatorRes.get(); 15641 } else { 15642 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15643 // allocate clauses that appear on a target construct or on constructs in a 15644 // target region must specify an allocator expression unless a requires 15645 // directive with the dynamic_allocators clause is present in the same 15646 // compilation unit. 15647 if (LangOpts.OpenMPIsDevice && 15648 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15649 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15650 } 15651 // Analyze and build list of variables. 15652 SmallVector<Expr *, 8> Vars; 15653 for (Expr *RefExpr : VarList) { 15654 assert(RefExpr && "NULL expr in OpenMP private clause."); 15655 SourceLocation ELoc; 15656 SourceRange ERange; 15657 Expr *SimpleRefExpr = RefExpr; 15658 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15659 if (Res.second) { 15660 // It will be analyzed later. 15661 Vars.push_back(RefExpr); 15662 } 15663 ValueDecl *D = Res.first; 15664 if (!D) 15665 continue; 15666 15667 auto *VD = dyn_cast<VarDecl>(D); 15668 DeclRefExpr *Ref = nullptr; 15669 if (!VD && !CurContext->isDependentContext()) 15670 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15671 Vars.push_back((VD || CurContext->isDependentContext()) 15672 ? RefExpr->IgnoreParens() 15673 : Ref); 15674 } 15675 15676 if (Vars.empty()) 15677 return nullptr; 15678 15679 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15680 ColonLoc, EndLoc, Vars); 15681 } 15682