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 const Decl *PossiblyLoopCounter = nullptr; 143 bool NowaitRegion = false; 144 bool CancelRegion = false; 145 bool LoopStart = false; 146 bool BodyComplete = false; 147 SourceLocation InnerTeamsRegionLoc; 148 /// Reference to the taskgroup task_reduction reference expression. 149 Expr *TaskgroupReductionRef = nullptr; 150 llvm::DenseSet<QualType> MappedClassesQualTypes; 151 /// List of globals marked as declare target link in this target region 152 /// (isOpenMPTargetExecutionDirective(Directive) == true). 153 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 154 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 155 Scope *CurScope, SourceLocation Loc) 156 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 157 ConstructLoc(Loc) {} 158 SharingMapTy() = default; 159 }; 160 161 using StackTy = SmallVector<SharingMapTy, 4>; 162 163 /// Stack of used declaration and their data-sharing attributes. 164 DeclSAMapTy Threadprivates; 165 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 166 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 167 /// true, if check for DSA must be from parent directive, false, if 168 /// from current directive. 169 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 170 Sema &SemaRef; 171 bool ForceCapturing = false; 172 /// true if all the vaiables in the target executable directives must be 173 /// captured by reference. 174 bool ForceCaptureByReferenceInTargetExecutable = false; 175 CriticalsWithHintsTy Criticals; 176 unsigned IgnoredStackElements = 0; 177 178 /// Iterators over the stack iterate in order from innermost to outermost 179 /// directive. 180 using const_iterator = StackTy::const_reverse_iterator; 181 const_iterator begin() const { 182 return Stack.empty() ? const_iterator() 183 : Stack.back().first.rbegin() + IgnoredStackElements; 184 } 185 const_iterator end() const { 186 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 187 } 188 using iterator = StackTy::reverse_iterator; 189 iterator begin() { 190 return Stack.empty() ? iterator() 191 : Stack.back().first.rbegin() + IgnoredStackElements; 192 } 193 iterator end() { 194 return Stack.empty() ? iterator() : Stack.back().first.rend(); 195 } 196 197 // Convenience operations to get at the elements of the stack. 198 199 bool isStackEmpty() const { 200 return Stack.empty() || 201 Stack.back().second != CurrentNonCapturingFunctionScope || 202 Stack.back().first.size() <= IgnoredStackElements; 203 } 204 size_t getStackSize() const { 205 return isStackEmpty() ? 0 206 : Stack.back().first.size() - IgnoredStackElements; 207 } 208 209 SharingMapTy *getTopOfStackOrNull() { 210 size_t Size = getStackSize(); 211 if (Size == 0) 212 return nullptr; 213 return &Stack.back().first[Size - 1]; 214 } 215 const SharingMapTy *getTopOfStackOrNull() const { 216 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 217 } 218 SharingMapTy &getTopOfStack() { 219 assert(!isStackEmpty() && "no current directive"); 220 return *getTopOfStackOrNull(); 221 } 222 const SharingMapTy &getTopOfStack() const { 223 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 224 } 225 226 SharingMapTy *getSecondOnStackOrNull() { 227 size_t Size = getStackSize(); 228 if (Size <= 1) 229 return nullptr; 230 return &Stack.back().first[Size - 2]; 231 } 232 const SharingMapTy *getSecondOnStackOrNull() const { 233 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 234 } 235 236 /// Get the stack element at a certain level (previously returned by 237 /// \c getNestingLevel). 238 /// 239 /// Note that nesting levels count from outermost to innermost, and this is 240 /// the reverse of our iteration order where new inner levels are pushed at 241 /// the front of the stack. 242 SharingMapTy &getStackElemAtLevel(unsigned Level) { 243 assert(Level < getStackSize() && "no such stack element"); 244 return Stack.back().first[Level]; 245 } 246 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 247 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 248 } 249 250 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 251 252 /// Checks if the variable is a local for OpenMP region. 253 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 254 255 /// Vector of previously declared requires directives 256 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 257 /// omp_allocator_handle_t type. 258 QualType OMPAllocatorHandleT; 259 /// Expression for the predefined allocators. 260 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 261 nullptr}; 262 /// Vector of previously encountered target directives 263 SmallVector<SourceLocation, 2> TargetLocations; 264 265 public: 266 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 267 268 /// Sets omp_allocator_handle_t type. 269 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 270 /// Gets omp_allocator_handle_t type. 271 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 272 /// Sets the given default allocator. 273 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 274 Expr *Allocator) { 275 OMPPredefinedAllocators[AllocatorKind] = Allocator; 276 } 277 /// Returns the specified default allocator. 278 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 279 return OMPPredefinedAllocators[AllocatorKind]; 280 } 281 282 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 283 OpenMPClauseKind getClauseParsingMode() const { 284 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 285 return ClauseKindMode; 286 } 287 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 288 289 bool isBodyComplete() const { 290 const SharingMapTy *Top = getTopOfStackOrNull(); 291 return Top && Top->BodyComplete; 292 } 293 void setBodyComplete() { 294 getTopOfStack().BodyComplete = true; 295 } 296 297 bool isForceVarCapturing() const { return ForceCapturing; } 298 void setForceVarCapturing(bool V) { ForceCapturing = V; } 299 300 void setForceCaptureByReferenceInTargetExecutable(bool V) { 301 ForceCaptureByReferenceInTargetExecutable = V; 302 } 303 bool isForceCaptureByReferenceInTargetExecutable() const { 304 return ForceCaptureByReferenceInTargetExecutable; 305 } 306 307 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 308 Scope *CurScope, SourceLocation Loc) { 309 assert(!IgnoredStackElements && 310 "cannot change stack while ignoring elements"); 311 if (Stack.empty() || 312 Stack.back().second != CurrentNonCapturingFunctionScope) 313 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 314 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 315 Stack.back().first.back().DefaultAttrLoc = Loc; 316 } 317 318 void pop() { 319 assert(!IgnoredStackElements && 320 "cannot change stack while ignoring elements"); 321 assert(!Stack.back().first.empty() && 322 "Data-sharing attributes stack is empty!"); 323 Stack.back().first.pop_back(); 324 } 325 326 /// RAII object to temporarily leave the scope of a directive when we want to 327 /// logically operate in its parent. 328 class ParentDirectiveScope { 329 DSAStackTy &Self; 330 bool Active; 331 public: 332 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 333 : Self(Self), Active(false) { 334 if (Activate) 335 enable(); 336 } 337 ~ParentDirectiveScope() { disable(); } 338 void disable() { 339 if (Active) { 340 --Self.IgnoredStackElements; 341 Active = false; 342 } 343 } 344 void enable() { 345 if (!Active) { 346 ++Self.IgnoredStackElements; 347 Active = true; 348 } 349 } 350 }; 351 352 /// Marks that we're started loop parsing. 353 void loopInit() { 354 assert(isOpenMPLoopDirective(getCurrentDirective()) && 355 "Expected loop-based directive."); 356 getTopOfStack().LoopStart = true; 357 } 358 /// Start capturing of the variables in the loop context. 359 void loopStart() { 360 assert(isOpenMPLoopDirective(getCurrentDirective()) && 361 "Expected loop-based directive."); 362 getTopOfStack().LoopStart = false; 363 } 364 /// true, if variables are captured, false otherwise. 365 bool isLoopStarted() const { 366 assert(isOpenMPLoopDirective(getCurrentDirective()) && 367 "Expected loop-based directive."); 368 return !getTopOfStack().LoopStart; 369 } 370 /// Marks (or clears) declaration as possibly loop counter. 371 void resetPossibleLoopCounter(const Decl *D = nullptr) { 372 getTopOfStack().PossiblyLoopCounter = 373 D ? D->getCanonicalDecl() : D; 374 } 375 /// Gets the possible loop counter decl. 376 const Decl *getPossiblyLoopCunter() const { 377 return getTopOfStack().PossiblyLoopCounter; 378 } 379 /// Start new OpenMP region stack in new non-capturing function. 380 void pushFunction() { 381 assert(!IgnoredStackElements && 382 "cannot change stack while ignoring elements"); 383 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 384 assert(!isa<CapturingScopeInfo>(CurFnScope)); 385 CurrentNonCapturingFunctionScope = CurFnScope; 386 } 387 /// Pop region stack for non-capturing function. 388 void popFunction(const FunctionScopeInfo *OldFSI) { 389 assert(!IgnoredStackElements && 390 "cannot change stack while ignoring elements"); 391 if (!Stack.empty() && Stack.back().second == OldFSI) { 392 assert(Stack.back().first.empty()); 393 Stack.pop_back(); 394 } 395 CurrentNonCapturingFunctionScope = nullptr; 396 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 397 if (!isa<CapturingScopeInfo>(FSI)) { 398 CurrentNonCapturingFunctionScope = FSI; 399 break; 400 } 401 } 402 } 403 404 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 405 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 406 } 407 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 408 getCriticalWithHint(const DeclarationNameInfo &Name) const { 409 auto I = Criticals.find(Name.getAsString()); 410 if (I != Criticals.end()) 411 return I->second; 412 return std::make_pair(nullptr, llvm::APSInt()); 413 } 414 /// If 'aligned' declaration for given variable \a D was not seen yet, 415 /// add it and return NULL; otherwise return previous occurrence's expression 416 /// for diagnostics. 417 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 418 419 /// Register specified variable as loop control variable. 420 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 421 /// Check if the specified variable is a loop control variable for 422 /// current region. 423 /// \return The index of the loop control variable in the list of associated 424 /// for-loops (from outer to inner). 425 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 426 /// Check if the specified variable is a loop control variable for 427 /// parent region. 428 /// \return The index of the loop control variable in the list of associated 429 /// for-loops (from outer to inner). 430 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 431 /// Get the loop control variable for the I-th loop (or nullptr) in 432 /// parent directive. 433 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 434 435 /// Adds explicit data sharing attribute to the specified declaration. 436 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 437 DeclRefExpr *PrivateCopy = nullptr); 438 439 /// Adds additional information for the reduction items with the reduction id 440 /// represented as an operator. 441 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 442 BinaryOperatorKind BOK); 443 /// Adds additional information for the reduction items with the reduction id 444 /// represented as reduction identifier. 445 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 446 const Expr *ReductionRef); 447 /// Returns the location and reduction operation from the innermost parent 448 /// region for the given \p D. 449 const DSAVarData 450 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 451 BinaryOperatorKind &BOK, 452 Expr *&TaskgroupDescriptor) const; 453 /// Returns the location and reduction operation from the innermost parent 454 /// region for the given \p D. 455 const DSAVarData 456 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 457 const Expr *&ReductionRef, 458 Expr *&TaskgroupDescriptor) const; 459 /// Return reduction reference expression for the current taskgroup. 460 Expr *getTaskgroupReductionRef() const { 461 assert(getTopOfStack().Directive == OMPD_taskgroup && 462 "taskgroup reference expression requested for non taskgroup " 463 "directive."); 464 return getTopOfStack().TaskgroupReductionRef; 465 } 466 /// Checks if the given \p VD declaration is actually a taskgroup reduction 467 /// descriptor variable at the \p Level of OpenMP regions. 468 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 469 return getStackElemAtLevel(Level).TaskgroupReductionRef && 470 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 471 ->getDecl() == VD; 472 } 473 474 /// Returns data sharing attributes from top of the stack for the 475 /// specified declaration. 476 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 477 /// Returns data-sharing attributes for the specified declaration. 478 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 479 /// Checks if the specified variables has data-sharing attributes which 480 /// match specified \a CPred predicate in any directive which matches \a DPred 481 /// predicate. 482 const DSAVarData 483 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 484 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 485 bool FromParent) const; 486 /// Checks if the specified variables has data-sharing attributes which 487 /// match specified \a CPred predicate in any innermost directive which 488 /// matches \a DPred predicate. 489 const DSAVarData 490 hasInnermostDSA(ValueDecl *D, 491 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 492 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 493 bool FromParent) const; 494 /// Checks if the specified variables has explicit data-sharing 495 /// attributes which match specified \a CPred predicate at the specified 496 /// OpenMP region. 497 bool hasExplicitDSA(const ValueDecl *D, 498 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 499 unsigned Level, bool NotLastprivate = false) const; 500 501 /// Returns true if the directive at level \Level matches in the 502 /// specified \a DPred predicate. 503 bool hasExplicitDirective( 504 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 505 unsigned Level) const; 506 507 /// Finds a directive which matches specified \a DPred predicate. 508 bool hasDirective( 509 const llvm::function_ref<bool( 510 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 511 DPred, 512 bool FromParent) const; 513 514 /// Returns currently analyzed directive. 515 OpenMPDirectiveKind getCurrentDirective() const { 516 const SharingMapTy *Top = getTopOfStackOrNull(); 517 return Top ? Top->Directive : OMPD_unknown; 518 } 519 /// Returns directive kind at specified level. 520 OpenMPDirectiveKind getDirective(unsigned Level) const { 521 assert(!isStackEmpty() && "No directive at specified level."); 522 return getStackElemAtLevel(Level).Directive; 523 } 524 /// Returns parent directive. 525 OpenMPDirectiveKind getParentDirective() const { 526 const SharingMapTy *Parent = getSecondOnStackOrNull(); 527 return Parent ? Parent->Directive : OMPD_unknown; 528 } 529 530 /// Add requires decl to internal vector 531 void addRequiresDecl(OMPRequiresDecl *RD) { 532 RequiresDecls.push_back(RD); 533 } 534 535 /// Checks if the defined 'requires' directive has specified type of clause. 536 template <typename ClauseType> 537 bool hasRequiresDeclWithClause() { 538 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 539 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 540 return isa<ClauseType>(C); 541 }); 542 }); 543 } 544 545 /// Checks for a duplicate clause amongst previously declared requires 546 /// directives 547 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 548 bool IsDuplicate = false; 549 for (OMPClause *CNew : ClauseList) { 550 for (const OMPRequiresDecl *D : RequiresDecls) { 551 for (const OMPClause *CPrev : D->clauselists()) { 552 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 553 SemaRef.Diag(CNew->getBeginLoc(), 554 diag::err_omp_requires_clause_redeclaration) 555 << getOpenMPClauseName(CNew->getClauseKind()); 556 SemaRef.Diag(CPrev->getBeginLoc(), 557 diag::note_omp_requires_previous_clause) 558 << getOpenMPClauseName(CPrev->getClauseKind()); 559 IsDuplicate = true; 560 } 561 } 562 } 563 } 564 return IsDuplicate; 565 } 566 567 /// Add location of previously encountered target to internal vector 568 void addTargetDirLocation(SourceLocation LocStart) { 569 TargetLocations.push_back(LocStart); 570 } 571 572 // Return previously encountered target region locations. 573 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 574 return TargetLocations; 575 } 576 577 /// Set default data sharing attribute to none. 578 void setDefaultDSANone(SourceLocation Loc) { 579 getTopOfStack().DefaultAttr = DSA_none; 580 getTopOfStack().DefaultAttrLoc = Loc; 581 } 582 /// Set default data sharing attribute to shared. 583 void setDefaultDSAShared(SourceLocation Loc) { 584 getTopOfStack().DefaultAttr = DSA_shared; 585 getTopOfStack().DefaultAttrLoc = Loc; 586 } 587 /// Set default data mapping attribute to 'tofrom:scalar'. 588 void setDefaultDMAToFromScalar(SourceLocation Loc) { 589 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 590 getTopOfStack().DefaultMapAttrLoc = Loc; 591 } 592 593 DefaultDataSharingAttributes getDefaultDSA() const { 594 return isStackEmpty() ? DSA_unspecified 595 : getTopOfStack().DefaultAttr; 596 } 597 SourceLocation getDefaultDSALocation() const { 598 return isStackEmpty() ? SourceLocation() 599 : getTopOfStack().DefaultAttrLoc; 600 } 601 DefaultMapAttributes getDefaultDMA() const { 602 return isStackEmpty() ? DMA_unspecified 603 : getTopOfStack().DefaultMapAttr; 604 } 605 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 606 return getStackElemAtLevel(Level).DefaultMapAttr; 607 } 608 SourceLocation getDefaultDMALocation() const { 609 return isStackEmpty() ? SourceLocation() 610 : getTopOfStack().DefaultMapAttrLoc; 611 } 612 613 /// Checks if the specified variable is a threadprivate. 614 bool isThreadPrivate(VarDecl *D) { 615 const DSAVarData DVar = getTopDSA(D, false); 616 return isOpenMPThreadPrivate(DVar.CKind); 617 } 618 619 /// Marks current region as ordered (it has an 'ordered' clause). 620 void setOrderedRegion(bool IsOrdered, const Expr *Param, 621 OMPOrderedClause *Clause) { 622 if (IsOrdered) 623 getTopOfStack().OrderedRegion.emplace(Param, Clause); 624 else 625 getTopOfStack().OrderedRegion.reset(); 626 } 627 /// Returns true, if region is ordered (has associated 'ordered' clause), 628 /// false - otherwise. 629 bool isOrderedRegion() const { 630 if (const SharingMapTy *Top = getTopOfStackOrNull()) 631 return Top->OrderedRegion.hasValue(); 632 return false; 633 } 634 /// Returns optional parameter for the ordered region. 635 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 636 if (const SharingMapTy *Top = getTopOfStackOrNull()) 637 if (Top->OrderedRegion.hasValue()) 638 return Top->OrderedRegion.getValue(); 639 return std::make_pair(nullptr, nullptr); 640 } 641 /// Returns true, if parent region is ordered (has associated 642 /// 'ordered' clause), false - otherwise. 643 bool isParentOrderedRegion() const { 644 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 645 return Parent->OrderedRegion.hasValue(); 646 return false; 647 } 648 /// Returns optional parameter for the ordered region. 649 std::pair<const Expr *, OMPOrderedClause *> 650 getParentOrderedRegionParam() const { 651 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 652 if (Parent->OrderedRegion.hasValue()) 653 return Parent->OrderedRegion.getValue(); 654 return std::make_pair(nullptr, nullptr); 655 } 656 /// Marks current region as nowait (it has a 'nowait' clause). 657 void setNowaitRegion(bool IsNowait = true) { 658 getTopOfStack().NowaitRegion = IsNowait; 659 } 660 /// Returns true, if parent region is nowait (has associated 661 /// 'nowait' clause), false - otherwise. 662 bool isParentNowaitRegion() const { 663 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 664 return Parent->NowaitRegion; 665 return false; 666 } 667 /// Marks parent region as cancel region. 668 void setParentCancelRegion(bool Cancel = true) { 669 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 670 Parent->CancelRegion |= Cancel; 671 } 672 /// Return true if current region has inner cancel construct. 673 bool isCancelRegion() const { 674 const SharingMapTy *Top = getTopOfStackOrNull(); 675 return Top ? Top->CancelRegion : false; 676 } 677 678 /// Set collapse value for the region. 679 void setAssociatedLoops(unsigned Val) { 680 getTopOfStack().AssociatedLoops = Val; 681 } 682 /// Return collapse value for region. 683 unsigned getAssociatedLoops() const { 684 const SharingMapTy *Top = getTopOfStackOrNull(); 685 return Top ? Top->AssociatedLoops : 0; 686 } 687 688 /// Marks current target region as one with closely nested teams 689 /// region. 690 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 691 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 692 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 693 } 694 /// Returns true, if current region has closely nested teams region. 695 bool hasInnerTeamsRegion() const { 696 return getInnerTeamsRegionLoc().isValid(); 697 } 698 /// Returns location of the nested teams region (if any). 699 SourceLocation getInnerTeamsRegionLoc() const { 700 const SharingMapTy *Top = getTopOfStackOrNull(); 701 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 702 } 703 704 Scope *getCurScope() const { 705 const SharingMapTy *Top = getTopOfStackOrNull(); 706 return Top ? Top->CurScope : nullptr; 707 } 708 SourceLocation getConstructLoc() const { 709 const SharingMapTy *Top = getTopOfStackOrNull(); 710 return Top ? Top->ConstructLoc : SourceLocation(); 711 } 712 713 /// Do the check specified in \a Check to all component lists and return true 714 /// if any issue is found. 715 bool checkMappableExprComponentListsForDecl( 716 const ValueDecl *VD, bool CurrentRegionOnly, 717 const llvm::function_ref< 718 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 719 OpenMPClauseKind)> 720 Check) const { 721 if (isStackEmpty()) 722 return false; 723 auto SI = begin(); 724 auto SE = end(); 725 726 if (SI == SE) 727 return false; 728 729 if (CurrentRegionOnly) 730 SE = std::next(SI); 731 else 732 std::advance(SI, 1); 733 734 for (; SI != SE; ++SI) { 735 auto MI = SI->MappedExprComponents.find(VD); 736 if (MI != SI->MappedExprComponents.end()) 737 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 738 MI->second.Components) 739 if (Check(L, MI->second.Kind)) 740 return true; 741 } 742 return false; 743 } 744 745 /// Do the check specified in \a Check to all component lists at a given level 746 /// and return true if any issue is found. 747 bool checkMappableExprComponentListsForDeclAtLevel( 748 const ValueDecl *VD, unsigned Level, 749 const llvm::function_ref< 750 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 751 OpenMPClauseKind)> 752 Check) const { 753 if (getStackSize() <= Level) 754 return false; 755 756 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 757 auto MI = StackElem.MappedExprComponents.find(VD); 758 if (MI != StackElem.MappedExprComponents.end()) 759 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 760 MI->second.Components) 761 if (Check(L, MI->second.Kind)) 762 return true; 763 return false; 764 } 765 766 /// Create a new mappable expression component list associated with a given 767 /// declaration and initialize it with the provided list of components. 768 void addMappableExpressionComponents( 769 const ValueDecl *VD, 770 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 771 OpenMPClauseKind WhereFoundClauseKind) { 772 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 773 // Create new entry and append the new components there. 774 MEC.Components.resize(MEC.Components.size() + 1); 775 MEC.Components.back().append(Components.begin(), Components.end()); 776 MEC.Kind = WhereFoundClauseKind; 777 } 778 779 unsigned getNestingLevel() const { 780 assert(!isStackEmpty()); 781 return getStackSize() - 1; 782 } 783 void addDoacrossDependClause(OMPDependClause *C, 784 const OperatorOffsetTy &OpsOffs) { 785 SharingMapTy *Parent = getSecondOnStackOrNull(); 786 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 787 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 788 } 789 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 790 getDoacrossDependClauses() const { 791 const SharingMapTy &StackElem = getTopOfStack(); 792 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 793 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 794 return llvm::make_range(Ref.begin(), Ref.end()); 795 } 796 return llvm::make_range(StackElem.DoacrossDepends.end(), 797 StackElem.DoacrossDepends.end()); 798 } 799 800 // Store types of classes which have been explicitly mapped 801 void addMappedClassesQualTypes(QualType QT) { 802 SharingMapTy &StackElem = getTopOfStack(); 803 StackElem.MappedClassesQualTypes.insert(QT); 804 } 805 806 // Return set of mapped classes types 807 bool isClassPreviouslyMapped(QualType QT) const { 808 const SharingMapTy &StackElem = getTopOfStack(); 809 return StackElem.MappedClassesQualTypes.count(QT) != 0; 810 } 811 812 /// Adds global declare target to the parent target region. 813 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 814 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 815 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 816 "Expected declare target link global."); 817 for (auto &Elem : *this) { 818 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 819 Elem.DeclareTargetLinkVarDecls.push_back(E); 820 return; 821 } 822 } 823 } 824 825 /// Returns the list of globals with declare target link if current directive 826 /// is target. 827 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 828 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 829 "Expected target executable directive."); 830 return getTopOfStack().DeclareTargetLinkVarDecls; 831 } 832 }; 833 834 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 835 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 836 } 837 838 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 839 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 840 DKind == OMPD_unknown; 841 } 842 843 } // namespace 844 845 static const Expr *getExprAsWritten(const Expr *E) { 846 if (const auto *FE = dyn_cast<FullExpr>(E)) 847 E = FE->getSubExpr(); 848 849 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 850 E = MTE->GetTemporaryExpr(); 851 852 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 853 E = Binder->getSubExpr(); 854 855 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 856 E = ICE->getSubExprAsWritten(); 857 return E->IgnoreParens(); 858 } 859 860 static Expr *getExprAsWritten(Expr *E) { 861 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 862 } 863 864 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 865 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 866 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 867 D = ME->getMemberDecl(); 868 const auto *VD = dyn_cast<VarDecl>(D); 869 const auto *FD = dyn_cast<FieldDecl>(D); 870 if (VD != nullptr) { 871 VD = VD->getCanonicalDecl(); 872 D = VD; 873 } else { 874 assert(FD); 875 FD = FD->getCanonicalDecl(); 876 D = FD; 877 } 878 return D; 879 } 880 881 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 882 return const_cast<ValueDecl *>( 883 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 884 } 885 886 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 887 ValueDecl *D) const { 888 D = getCanonicalDecl(D); 889 auto *VD = dyn_cast<VarDecl>(D); 890 const auto *FD = dyn_cast<FieldDecl>(D); 891 DSAVarData DVar; 892 if (Iter == end()) { 893 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 894 // in a region but not in construct] 895 // File-scope or namespace-scope variables referenced in called routines 896 // in the region are shared unless they appear in a threadprivate 897 // directive. 898 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 899 DVar.CKind = OMPC_shared; 900 901 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 902 // in a region but not in construct] 903 // Variables with static storage duration that are declared in called 904 // routines in the region are shared. 905 if (VD && VD->hasGlobalStorage()) 906 DVar.CKind = OMPC_shared; 907 908 // Non-static data members are shared by default. 909 if (FD) 910 DVar.CKind = OMPC_shared; 911 912 return DVar; 913 } 914 915 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 916 // in a Construct, C/C++, predetermined, p.1] 917 // Variables with automatic storage duration that are declared in a scope 918 // inside the construct are private. 919 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 920 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 921 DVar.CKind = OMPC_private; 922 return DVar; 923 } 924 925 DVar.DKind = Iter->Directive; 926 // Explicitly specified attributes and local variables with predetermined 927 // attributes. 928 if (Iter->SharingMap.count(D)) { 929 const DSAInfo &Data = Iter->SharingMap.lookup(D); 930 DVar.RefExpr = Data.RefExpr.getPointer(); 931 DVar.PrivateCopy = Data.PrivateCopy; 932 DVar.CKind = Data.Attributes; 933 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 934 return DVar; 935 } 936 937 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 938 // in a Construct, C/C++, implicitly determined, p.1] 939 // In a parallel or task construct, the data-sharing attributes of these 940 // variables are determined by the default clause, if present. 941 switch (Iter->DefaultAttr) { 942 case DSA_shared: 943 DVar.CKind = OMPC_shared; 944 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 945 return DVar; 946 case DSA_none: 947 return DVar; 948 case DSA_unspecified: 949 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 950 // in a Construct, implicitly determined, p.2] 951 // In a parallel construct, if no default clause is present, these 952 // variables are shared. 953 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 954 if (isOpenMPParallelDirective(DVar.DKind) || 955 isOpenMPTeamsDirective(DVar.DKind)) { 956 DVar.CKind = OMPC_shared; 957 return DVar; 958 } 959 960 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 961 // in a Construct, implicitly determined, p.4] 962 // In a task construct, if no default clause is present, a variable that in 963 // the enclosing context is determined to be shared by all implicit tasks 964 // bound to the current team is shared. 965 if (isOpenMPTaskingDirective(DVar.DKind)) { 966 DSAVarData DVarTemp; 967 const_iterator I = Iter, E = end(); 968 do { 969 ++I; 970 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 971 // Referenced in a Construct, implicitly determined, p.6] 972 // In a task construct, if no default clause is present, a variable 973 // whose data-sharing attribute is not determined by the rules above is 974 // firstprivate. 975 DVarTemp = getDSA(I, D); 976 if (DVarTemp.CKind != OMPC_shared) { 977 DVar.RefExpr = nullptr; 978 DVar.CKind = OMPC_firstprivate; 979 return DVar; 980 } 981 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 982 DVar.CKind = 983 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 984 return DVar; 985 } 986 } 987 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 988 // in a Construct, implicitly determined, p.3] 989 // For constructs other than task, if no default clause is present, these 990 // variables inherit their data-sharing attributes from the enclosing 991 // context. 992 return getDSA(++Iter, D); 993 } 994 995 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 996 const Expr *NewDE) { 997 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 998 D = getCanonicalDecl(D); 999 SharingMapTy &StackElem = getTopOfStack(); 1000 auto It = StackElem.AlignedMap.find(D); 1001 if (It == StackElem.AlignedMap.end()) { 1002 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1003 StackElem.AlignedMap[D] = NewDE; 1004 return nullptr; 1005 } 1006 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1007 return It->second; 1008 } 1009 1010 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1011 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1012 D = getCanonicalDecl(D); 1013 SharingMapTy &StackElem = getTopOfStack(); 1014 StackElem.LCVMap.try_emplace( 1015 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1016 } 1017 1018 const DSAStackTy::LCDeclInfo 1019 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1020 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1021 D = getCanonicalDecl(D); 1022 const SharingMapTy &StackElem = getTopOfStack(); 1023 auto It = StackElem.LCVMap.find(D); 1024 if (It != StackElem.LCVMap.end()) 1025 return It->second; 1026 return {0, nullptr}; 1027 } 1028 1029 const DSAStackTy::LCDeclInfo 1030 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1031 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1032 assert(Parent && "Data-sharing attributes stack is empty"); 1033 D = getCanonicalDecl(D); 1034 auto It = Parent->LCVMap.find(D); 1035 if (It != Parent->LCVMap.end()) 1036 return It->second; 1037 return {0, nullptr}; 1038 } 1039 1040 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1041 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1042 assert(Parent && "Data-sharing attributes stack is empty"); 1043 if (Parent->LCVMap.size() < I) 1044 return nullptr; 1045 for (const auto &Pair : Parent->LCVMap) 1046 if (Pair.second.first == I) 1047 return Pair.first; 1048 return nullptr; 1049 } 1050 1051 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1052 DeclRefExpr *PrivateCopy) { 1053 D = getCanonicalDecl(D); 1054 if (A == OMPC_threadprivate) { 1055 DSAInfo &Data = Threadprivates[D]; 1056 Data.Attributes = A; 1057 Data.RefExpr.setPointer(E); 1058 Data.PrivateCopy = nullptr; 1059 } else { 1060 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1061 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1062 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1063 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1064 (isLoopControlVariable(D).first && A == OMPC_private)); 1065 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1066 Data.RefExpr.setInt(/*IntVal=*/true); 1067 return; 1068 } 1069 const bool IsLastprivate = 1070 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1071 Data.Attributes = A; 1072 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1073 Data.PrivateCopy = PrivateCopy; 1074 if (PrivateCopy) { 1075 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1076 Data.Attributes = A; 1077 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1078 Data.PrivateCopy = nullptr; 1079 } 1080 } 1081 } 1082 1083 /// Build a variable declaration for OpenMP loop iteration variable. 1084 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1085 StringRef Name, const AttrVec *Attrs = nullptr, 1086 DeclRefExpr *OrigRef = nullptr) { 1087 DeclContext *DC = SemaRef.CurContext; 1088 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1089 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1090 auto *Decl = 1091 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1092 if (Attrs) { 1093 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1094 I != E; ++I) 1095 Decl->addAttr(*I); 1096 } 1097 Decl->setImplicit(); 1098 if (OrigRef) { 1099 Decl->addAttr( 1100 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1101 } 1102 return Decl; 1103 } 1104 1105 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1106 SourceLocation Loc, 1107 bool RefersToCapture = false) { 1108 D->setReferenced(); 1109 D->markUsed(S.Context); 1110 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1111 SourceLocation(), D, RefersToCapture, Loc, Ty, 1112 VK_LValue); 1113 } 1114 1115 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1116 BinaryOperatorKind BOK) { 1117 D = getCanonicalDecl(D); 1118 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1119 assert( 1120 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1121 "Additional reduction info may be specified only for reduction items."); 1122 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1123 assert(ReductionData.ReductionRange.isInvalid() && 1124 getTopOfStack().Directive == OMPD_taskgroup && 1125 "Additional reduction info may be specified only once for reduction " 1126 "items."); 1127 ReductionData.set(BOK, SR); 1128 Expr *&TaskgroupReductionRef = 1129 getTopOfStack().TaskgroupReductionRef; 1130 if (!TaskgroupReductionRef) { 1131 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1132 SemaRef.Context.VoidPtrTy, ".task_red."); 1133 TaskgroupReductionRef = 1134 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1135 } 1136 } 1137 1138 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1139 const Expr *ReductionRef) { 1140 D = getCanonicalDecl(D); 1141 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1142 assert( 1143 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1144 "Additional reduction info may be specified only for reduction items."); 1145 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1146 assert(ReductionData.ReductionRange.isInvalid() && 1147 getTopOfStack().Directive == OMPD_taskgroup && 1148 "Additional reduction info may be specified only once for reduction " 1149 "items."); 1150 ReductionData.set(ReductionRef, SR); 1151 Expr *&TaskgroupReductionRef = 1152 getTopOfStack().TaskgroupReductionRef; 1153 if (!TaskgroupReductionRef) { 1154 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1155 SemaRef.Context.VoidPtrTy, ".task_red."); 1156 TaskgroupReductionRef = 1157 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1158 } 1159 } 1160 1161 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1162 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1163 Expr *&TaskgroupDescriptor) const { 1164 D = getCanonicalDecl(D); 1165 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1166 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1167 const DSAInfo &Data = I->SharingMap.lookup(D); 1168 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1169 continue; 1170 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1171 if (!ReductionData.ReductionOp || 1172 ReductionData.ReductionOp.is<const Expr *>()) 1173 return DSAVarData(); 1174 SR = ReductionData.ReductionRange; 1175 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1176 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1177 "expression for the descriptor is not " 1178 "set."); 1179 TaskgroupDescriptor = I->TaskgroupReductionRef; 1180 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1181 Data.PrivateCopy, I->DefaultAttrLoc); 1182 } 1183 return DSAVarData(); 1184 } 1185 1186 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1187 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1188 Expr *&TaskgroupDescriptor) const { 1189 D = getCanonicalDecl(D); 1190 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1191 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1192 const DSAInfo &Data = I->SharingMap.lookup(D); 1193 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1194 continue; 1195 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1196 if (!ReductionData.ReductionOp || 1197 !ReductionData.ReductionOp.is<const Expr *>()) 1198 return DSAVarData(); 1199 SR = ReductionData.ReductionRange; 1200 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1201 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1202 "expression for the descriptor is not " 1203 "set."); 1204 TaskgroupDescriptor = I->TaskgroupReductionRef; 1205 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1206 Data.PrivateCopy, I->DefaultAttrLoc); 1207 } 1208 return DSAVarData(); 1209 } 1210 1211 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1212 D = D->getCanonicalDecl(); 1213 for (const_iterator E = end(); I != E; ++I) { 1214 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1215 isOpenMPTargetExecutionDirective(I->Directive)) { 1216 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1217 Scope *CurScope = getCurScope(); 1218 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1219 CurScope = CurScope->getParent(); 1220 return CurScope != TopScope; 1221 } 1222 } 1223 return false; 1224 } 1225 1226 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1227 bool AcceptIfMutable = true, 1228 bool *IsClassType = nullptr) { 1229 ASTContext &Context = SemaRef.getASTContext(); 1230 Type = Type.getNonReferenceType().getCanonicalType(); 1231 bool IsConstant = Type.isConstant(Context); 1232 Type = Context.getBaseElementType(Type); 1233 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1234 ? Type->getAsCXXRecordDecl() 1235 : nullptr; 1236 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1237 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1238 RD = CTD->getTemplatedDecl(); 1239 if (IsClassType) 1240 *IsClassType = RD; 1241 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1242 RD->hasDefinition() && RD->hasMutableFields()); 1243 } 1244 1245 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1246 QualType Type, OpenMPClauseKind CKind, 1247 SourceLocation ELoc, 1248 bool AcceptIfMutable = true, 1249 bool ListItemNotVar = false) { 1250 ASTContext &Context = SemaRef.getASTContext(); 1251 bool IsClassType; 1252 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1253 unsigned Diag = ListItemNotVar 1254 ? diag::err_omp_const_list_item 1255 : IsClassType ? diag::err_omp_const_not_mutable_variable 1256 : diag::err_omp_const_variable; 1257 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1258 if (!ListItemNotVar && D) { 1259 const VarDecl *VD = dyn_cast<VarDecl>(D); 1260 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1261 VarDecl::DeclarationOnly; 1262 SemaRef.Diag(D->getLocation(), 1263 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1264 << D; 1265 } 1266 return true; 1267 } 1268 return false; 1269 } 1270 1271 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1272 bool FromParent) { 1273 D = getCanonicalDecl(D); 1274 DSAVarData DVar; 1275 1276 auto *VD = dyn_cast<VarDecl>(D); 1277 auto TI = Threadprivates.find(D); 1278 if (TI != Threadprivates.end()) { 1279 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1280 DVar.CKind = OMPC_threadprivate; 1281 return DVar; 1282 } 1283 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1284 DVar.RefExpr = buildDeclRefExpr( 1285 SemaRef, VD, D->getType().getNonReferenceType(), 1286 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1287 DVar.CKind = OMPC_threadprivate; 1288 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1289 return DVar; 1290 } 1291 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1292 // in a Construct, C/C++, predetermined, p.1] 1293 // Variables appearing in threadprivate directives are threadprivate. 1294 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1295 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1296 SemaRef.getLangOpts().OpenMPUseTLS && 1297 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1298 (VD && VD->getStorageClass() == SC_Register && 1299 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1300 DVar.RefExpr = buildDeclRefExpr( 1301 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1302 DVar.CKind = OMPC_threadprivate; 1303 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1304 return DVar; 1305 } 1306 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1307 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1308 !isLoopControlVariable(D).first) { 1309 const_iterator IterTarget = 1310 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1311 return isOpenMPTargetExecutionDirective(Data.Directive); 1312 }); 1313 if (IterTarget != end()) { 1314 const_iterator ParentIterTarget = IterTarget + 1; 1315 for (const_iterator Iter = begin(); 1316 Iter != ParentIterTarget; ++Iter) { 1317 if (isOpenMPLocal(VD, Iter)) { 1318 DVar.RefExpr = 1319 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1320 D->getLocation()); 1321 DVar.CKind = OMPC_threadprivate; 1322 return DVar; 1323 } 1324 } 1325 if (!isClauseParsingMode() || IterTarget != begin()) { 1326 auto DSAIter = IterTarget->SharingMap.find(D); 1327 if (DSAIter != IterTarget->SharingMap.end() && 1328 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1329 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1330 DVar.CKind = OMPC_threadprivate; 1331 return DVar; 1332 } 1333 const_iterator End = end(); 1334 if (!SemaRef.isOpenMPCapturedByRef( 1335 D, std::distance(ParentIterTarget, End))) { 1336 DVar.RefExpr = 1337 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1338 IterTarget->ConstructLoc); 1339 DVar.CKind = OMPC_threadprivate; 1340 return DVar; 1341 } 1342 } 1343 } 1344 } 1345 1346 if (isStackEmpty()) 1347 // Not in OpenMP execution region and top scope was already checked. 1348 return DVar; 1349 1350 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1351 // in a Construct, C/C++, predetermined, p.4] 1352 // Static data members are shared. 1353 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1354 // in a Construct, C/C++, predetermined, p.7] 1355 // Variables with static storage duration that are declared in a scope 1356 // inside the construct are shared. 1357 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1358 if (VD && VD->isStaticDataMember()) { 1359 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1360 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1361 return DVar; 1362 1363 DVar.CKind = OMPC_shared; 1364 return DVar; 1365 } 1366 1367 // The predetermined shared attribute for const-qualified types having no 1368 // mutable members was removed after OpenMP 3.1. 1369 if (SemaRef.LangOpts.OpenMP <= 31) { 1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1371 // in a Construct, C/C++, predetermined, p.6] 1372 // Variables with const qualified type having no mutable member are 1373 // shared. 1374 if (isConstNotMutableType(SemaRef, D->getType())) { 1375 // Variables with const-qualified type having no mutable member may be 1376 // listed in a firstprivate clause, even if they are static data members. 1377 DSAVarData DVarTemp = hasInnermostDSA( 1378 D, 1379 [](OpenMPClauseKind C) { 1380 return C == OMPC_firstprivate || C == OMPC_shared; 1381 }, 1382 MatchesAlways, FromParent); 1383 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1384 return DVarTemp; 1385 1386 DVar.CKind = OMPC_shared; 1387 return DVar; 1388 } 1389 } 1390 1391 // Explicitly specified attributes and local variables with predetermined 1392 // attributes. 1393 const_iterator I = begin(); 1394 const_iterator EndI = end(); 1395 if (FromParent && I != EndI) 1396 ++I; 1397 auto It = I->SharingMap.find(D); 1398 if (It != I->SharingMap.end()) { 1399 const DSAInfo &Data = It->getSecond(); 1400 DVar.RefExpr = Data.RefExpr.getPointer(); 1401 DVar.PrivateCopy = Data.PrivateCopy; 1402 DVar.CKind = Data.Attributes; 1403 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1404 DVar.DKind = I->Directive; 1405 } 1406 1407 return DVar; 1408 } 1409 1410 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1411 bool FromParent) const { 1412 if (isStackEmpty()) { 1413 const_iterator I; 1414 return getDSA(I, D); 1415 } 1416 D = getCanonicalDecl(D); 1417 const_iterator StartI = begin(); 1418 const_iterator EndI = end(); 1419 if (FromParent && StartI != EndI) 1420 ++StartI; 1421 return getDSA(StartI, D); 1422 } 1423 1424 const DSAStackTy::DSAVarData 1425 DSAStackTy::hasDSA(ValueDecl *D, 1426 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1427 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1428 bool FromParent) const { 1429 if (isStackEmpty()) 1430 return {}; 1431 D = getCanonicalDecl(D); 1432 const_iterator I = begin(); 1433 const_iterator EndI = end(); 1434 if (FromParent && I != EndI) 1435 ++I; 1436 for (; I != EndI; ++I) { 1437 if (!DPred(I->Directive) && 1438 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1439 continue; 1440 const_iterator NewI = I; 1441 DSAVarData DVar = getDSA(NewI, D); 1442 if (I == NewI && CPred(DVar.CKind)) 1443 return DVar; 1444 } 1445 return {}; 1446 } 1447 1448 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1449 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1450 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1451 bool FromParent) const { 1452 if (isStackEmpty()) 1453 return {}; 1454 D = getCanonicalDecl(D); 1455 const_iterator StartI = begin(); 1456 const_iterator EndI = end(); 1457 if (FromParent && StartI != EndI) 1458 ++StartI; 1459 if (StartI == EndI || !DPred(StartI->Directive)) 1460 return {}; 1461 const_iterator NewI = StartI; 1462 DSAVarData DVar = getDSA(NewI, D); 1463 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1464 } 1465 1466 bool DSAStackTy::hasExplicitDSA( 1467 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1468 unsigned Level, bool NotLastprivate) const { 1469 if (getStackSize() <= Level) 1470 return false; 1471 D = getCanonicalDecl(D); 1472 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1473 auto I = StackElem.SharingMap.find(D); 1474 if (I != StackElem.SharingMap.end() && 1475 I->getSecond().RefExpr.getPointer() && 1476 CPred(I->getSecond().Attributes) && 1477 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1478 return true; 1479 // Check predetermined rules for the loop control variables. 1480 auto LI = StackElem.LCVMap.find(D); 1481 if (LI != StackElem.LCVMap.end()) 1482 return CPred(OMPC_private); 1483 return false; 1484 } 1485 1486 bool DSAStackTy::hasExplicitDirective( 1487 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1488 unsigned Level) const { 1489 if (getStackSize() <= Level) 1490 return false; 1491 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1492 return DPred(StackElem.Directive); 1493 } 1494 1495 bool DSAStackTy::hasDirective( 1496 const llvm::function_ref<bool(OpenMPDirectiveKind, 1497 const DeclarationNameInfo &, SourceLocation)> 1498 DPred, 1499 bool FromParent) const { 1500 // We look only in the enclosing region. 1501 size_t Skip = FromParent ? 2 : 1; 1502 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1503 I != E; ++I) { 1504 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1505 return true; 1506 } 1507 return false; 1508 } 1509 1510 void Sema::InitDataSharingAttributesStack() { 1511 VarDataSharingAttributesStack = new DSAStackTy(*this); 1512 } 1513 1514 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1515 1516 void Sema::pushOpenMPFunctionRegion() { 1517 DSAStack->pushFunction(); 1518 } 1519 1520 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1521 DSAStack->popFunction(OldFSI); 1522 } 1523 1524 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1525 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1526 "Expected OpenMP device compilation."); 1527 return !S.isInOpenMPTargetExecutionDirective() && 1528 !S.isInOpenMPDeclareTargetContext(); 1529 } 1530 1531 /// Do we know that we will eventually codegen the given function? 1532 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1533 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1534 "Expected OpenMP device compilation."); 1535 // Templates are emitted when they're instantiated. 1536 if (FD->isDependentContext()) 1537 return false; 1538 1539 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1540 FD->getCanonicalDecl())) 1541 return true; 1542 1543 // Otherwise, the function is known-emitted if it's in our set of 1544 // known-emitted functions. 1545 return S.DeviceKnownEmittedFns.count(FD) > 0; 1546 } 1547 1548 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1549 unsigned DiagID) { 1550 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1551 "Expected OpenMP device compilation."); 1552 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1553 !isKnownEmitted(*this, getCurFunctionDecl())) 1554 ? DeviceDiagBuilder::K_Deferred 1555 : DeviceDiagBuilder::K_Immediate, 1556 Loc, DiagID, getCurFunctionDecl(), *this); 1557 } 1558 1559 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1560 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1561 "Expected OpenMP device compilation."); 1562 assert(Callee && "Callee may not be null."); 1563 FunctionDecl *Caller = getCurFunctionDecl(); 1564 1565 // If the caller is known-emitted, mark the callee as known-emitted. 1566 // Otherwise, mark the call in our call graph so we can traverse it later. 1567 if (!isOpenMPDeviceDelayedContext(*this) || 1568 (Caller && isKnownEmitted(*this, Caller))) 1569 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1570 else if (Caller) 1571 DeviceCallGraph[Caller].insert({Callee, Loc}); 1572 } 1573 1574 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1575 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1576 "OpenMP device compilation mode is expected."); 1577 QualType Ty = E->getType(); 1578 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1579 ((Ty->isFloat128Type() || 1580 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1581 !Context.getTargetInfo().hasFloat128Type()) || 1582 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1583 !Context.getTargetInfo().hasInt128Type())) 1584 targetDiag(E->getExprLoc(), diag::err_type_unsupported) 1585 << Ty << E->getSourceRange(); 1586 } 1587 1588 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1589 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1590 1591 ASTContext &Ctx = getASTContext(); 1592 bool IsByRef = true; 1593 1594 // Find the directive that is associated with the provided scope. 1595 D = cast<ValueDecl>(D->getCanonicalDecl()); 1596 QualType Ty = D->getType(); 1597 1598 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1599 // This table summarizes how a given variable should be passed to the device 1600 // given its type and the clauses where it appears. This table is based on 1601 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1602 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1603 // 1604 // ========================================================================= 1605 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1606 // | |(tofrom:scalar)| | pvt | | | | 1607 // ========================================================================= 1608 // | scl | | | | - | | bycopy| 1609 // | scl | | - | x | - | - | bycopy| 1610 // | scl | | x | - | - | - | null | 1611 // | scl | x | | | - | | byref | 1612 // | scl | x | - | x | - | - | bycopy| 1613 // | scl | x | x | - | - | - | null | 1614 // | scl | | - | - | - | x | byref | 1615 // | scl | x | - | - | - | x | byref | 1616 // 1617 // | agg | n.a. | | | - | | byref | 1618 // | agg | n.a. | - | x | - | - | byref | 1619 // | agg | n.a. | x | - | - | - | null | 1620 // | agg | n.a. | - | - | - | x | byref | 1621 // | agg | n.a. | - | - | - | x[] | byref | 1622 // 1623 // | ptr | n.a. | | | - | | bycopy| 1624 // | ptr | n.a. | - | x | - | - | bycopy| 1625 // | ptr | n.a. | x | - | - | - | null | 1626 // | ptr | n.a. | - | - | - | x | byref | 1627 // | ptr | n.a. | - | - | - | x[] | bycopy| 1628 // | ptr | n.a. | - | - | x | | bycopy| 1629 // | ptr | n.a. | - | - | x | x | bycopy| 1630 // | ptr | n.a. | - | - | x | x[] | bycopy| 1631 // ========================================================================= 1632 // Legend: 1633 // scl - scalar 1634 // ptr - pointer 1635 // agg - aggregate 1636 // x - applies 1637 // - - invalid in this combination 1638 // [] - mapped with an array section 1639 // byref - should be mapped by reference 1640 // byval - should be mapped by value 1641 // null - initialize a local variable to null on the device 1642 // 1643 // Observations: 1644 // - All scalar declarations that show up in a map clause have to be passed 1645 // by reference, because they may have been mapped in the enclosing data 1646 // environment. 1647 // - If the scalar value does not fit the size of uintptr, it has to be 1648 // passed by reference, regardless the result in the table above. 1649 // - For pointers mapped by value that have either an implicit map or an 1650 // array section, the runtime library may pass the NULL value to the 1651 // device instead of the value passed to it by the compiler. 1652 1653 if (Ty->isReferenceType()) 1654 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1655 1656 // Locate map clauses and see if the variable being captured is referred to 1657 // in any of those clauses. Here we only care about variables, not fields, 1658 // because fields are part of aggregates. 1659 bool IsVariableUsedInMapClause = false; 1660 bool IsVariableAssociatedWithSection = false; 1661 1662 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1663 D, Level, 1664 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1665 OMPClauseMappableExprCommon::MappableExprComponentListRef 1666 MapExprComponents, 1667 OpenMPClauseKind WhereFoundClauseKind) { 1668 // Only the map clause information influences how a variable is 1669 // captured. E.g. is_device_ptr does not require changing the default 1670 // behavior. 1671 if (WhereFoundClauseKind != OMPC_map) 1672 return false; 1673 1674 auto EI = MapExprComponents.rbegin(); 1675 auto EE = MapExprComponents.rend(); 1676 1677 assert(EI != EE && "Invalid map expression!"); 1678 1679 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1680 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1681 1682 ++EI; 1683 if (EI == EE) 1684 return false; 1685 1686 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1687 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1688 isa<MemberExpr>(EI->getAssociatedExpression())) { 1689 IsVariableAssociatedWithSection = true; 1690 // There is nothing more we need to know about this variable. 1691 return true; 1692 } 1693 1694 // Keep looking for more map info. 1695 return false; 1696 }); 1697 1698 if (IsVariableUsedInMapClause) { 1699 // If variable is identified in a map clause it is always captured by 1700 // reference except if it is a pointer that is dereferenced somehow. 1701 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1702 } else { 1703 // By default, all the data that has a scalar type is mapped by copy 1704 // (except for reduction variables). 1705 IsByRef = 1706 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1707 !Ty->isAnyPointerType()) || 1708 !Ty->isScalarType() || 1709 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1710 DSAStack->hasExplicitDSA( 1711 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1712 } 1713 } 1714 1715 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1716 IsByRef = 1717 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1718 !Ty->isAnyPointerType()) || 1719 !DSAStack->hasExplicitDSA( 1720 D, 1721 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1722 Level, /*NotLastprivate=*/true)) && 1723 // If the variable is artificial and must be captured by value - try to 1724 // capture by value. 1725 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1726 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1727 } 1728 1729 // When passing data by copy, we need to make sure it fits the uintptr size 1730 // and alignment, because the runtime library only deals with uintptr types. 1731 // If it does not fit the uintptr size, we need to pass the data by reference 1732 // instead. 1733 if (!IsByRef && 1734 (Ctx.getTypeSizeInChars(Ty) > 1735 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1736 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1737 IsByRef = true; 1738 } 1739 1740 return IsByRef; 1741 } 1742 1743 unsigned Sema::getOpenMPNestingLevel() const { 1744 assert(getLangOpts().OpenMP); 1745 return DSAStack->getNestingLevel(); 1746 } 1747 1748 bool Sema::isInOpenMPTargetExecutionDirective() const { 1749 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1750 !DSAStack->isClauseParsingMode()) || 1751 DSAStack->hasDirective( 1752 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1753 SourceLocation) -> bool { 1754 return isOpenMPTargetExecutionDirective(K); 1755 }, 1756 false); 1757 } 1758 1759 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1760 unsigned StopAt) { 1761 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1762 D = getCanonicalDecl(D); 1763 1764 // If we want to determine whether the variable should be captured from the 1765 // perspective of the current capturing scope, and we've already left all the 1766 // capturing scopes of the top directive on the stack, check from the 1767 // perspective of its parent directive (if any) instead. 1768 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1769 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1770 1771 // If we are attempting to capture a global variable in a directive with 1772 // 'target' we return true so that this global is also mapped to the device. 1773 // 1774 auto *VD = dyn_cast<VarDecl>(D); 1775 if (VD && !VD->hasLocalStorage() && 1776 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1777 if (isInOpenMPDeclareTargetContext()) { 1778 // Try to mark variable as declare target if it is used in capturing 1779 // regions. 1780 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1781 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1782 return nullptr; 1783 } else if (isInOpenMPTargetExecutionDirective()) { 1784 // If the declaration is enclosed in a 'declare target' directive, 1785 // then it should not be captured. 1786 // 1787 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1788 return nullptr; 1789 return VD; 1790 } 1791 } 1792 // Capture variables captured by reference in lambdas for target-based 1793 // directives. 1794 // FIXME: Triggering capture from here is completely inappropriate. 1795 if (VD && !DSAStack->isClauseParsingMode()) { 1796 if (const auto *RD = VD->getType() 1797 .getCanonicalType() 1798 .getNonReferenceType() 1799 ->getAsCXXRecordDecl()) { 1800 bool SavedForceCaptureByReferenceInTargetExecutable = 1801 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1802 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1803 InParentDirectiveRAII.disable(); 1804 if (RD->isLambda()) { 1805 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1806 FieldDecl *ThisCapture; 1807 RD->getCaptureFields(Captures, ThisCapture); 1808 for (const LambdaCapture &LC : RD->captures()) { 1809 if (LC.getCaptureKind() == LCK_ByRef) { 1810 VarDecl *VD = LC.getCapturedVar(); 1811 DeclContext *VDC = VD->getDeclContext(); 1812 if (!VDC->Encloses(CurContext)) 1813 continue; 1814 DSAStackTy::DSAVarData DVarPrivate = 1815 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1816 // Do not capture already captured variables. 1817 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1818 DVarPrivate.CKind == OMPC_unknown && 1819 !DSAStack->checkMappableExprComponentListsForDecl( 1820 D, /*CurrentRegionOnly=*/true, 1821 [](OMPClauseMappableExprCommon:: 1822 MappableExprComponentListRef, 1823 OpenMPClauseKind) { return true; })) 1824 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1825 } else if (LC.getCaptureKind() == LCK_This) { 1826 QualType ThisTy = getCurrentThisType(); 1827 if (!ThisTy.isNull() && 1828 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1829 CheckCXXThisCapture(LC.getLocation()); 1830 } 1831 } 1832 } 1833 if (CheckScopeInfo && DSAStack->isBodyComplete()) 1834 InParentDirectiveRAII.enable(); 1835 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1836 SavedForceCaptureByReferenceInTargetExecutable); 1837 } 1838 } 1839 1840 if (CheckScopeInfo) { 1841 bool OpenMPFound = false; 1842 for (unsigned I = StopAt + 1; I > 0; --I) { 1843 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1844 if(!isa<CapturingScopeInfo>(FSI)) 1845 return nullptr; 1846 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1847 if (RSI->CapRegionKind == CR_OpenMP) { 1848 OpenMPFound = true; 1849 break; 1850 } 1851 } 1852 if (!OpenMPFound) 1853 return nullptr; 1854 } 1855 1856 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1857 (!DSAStack->isClauseParsingMode() || 1858 DSAStack->getParentDirective() != OMPD_unknown)) { 1859 auto &&Info = DSAStack->isLoopControlVariable(D); 1860 if (Info.first || 1861 (VD && VD->hasLocalStorage() && 1862 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1863 (VD && DSAStack->isForceVarCapturing())) 1864 return VD ? VD : Info.second; 1865 DSAStackTy::DSAVarData DVarPrivate = 1866 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1867 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1868 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1869 // Threadprivate variables must not be captured. 1870 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1871 return nullptr; 1872 // The variable is not private or it is the variable in the directive with 1873 // default(none) clause and not used in any clause. 1874 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1875 [](OpenMPDirectiveKind) { return true; }, 1876 DSAStack->isClauseParsingMode()); 1877 if (DVarPrivate.CKind != OMPC_unknown || 1878 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1879 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1880 } 1881 return nullptr; 1882 } 1883 1884 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1885 unsigned Level) const { 1886 SmallVector<OpenMPDirectiveKind, 4> Regions; 1887 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1888 FunctionScopesIndex -= Regions.size(); 1889 } 1890 1891 void Sema::startOpenMPLoop() { 1892 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1893 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1894 DSAStack->loopInit(); 1895 } 1896 1897 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1898 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1899 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1900 if (DSAStack->getAssociatedLoops() > 0 && 1901 !DSAStack->isLoopStarted()) { 1902 DSAStack->resetPossibleLoopCounter(D); 1903 DSAStack->loopStart(); 1904 return true; 1905 } 1906 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1907 DSAStack->isLoopControlVariable(D).first) && 1908 !DSAStack->hasExplicitDSA( 1909 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1910 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1911 return true; 1912 } 1913 return DSAStack->hasExplicitDSA( 1914 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1915 (DSAStack->isClauseParsingMode() && 1916 DSAStack->getClauseParsingMode() == OMPC_private) || 1917 // Consider taskgroup reduction descriptor variable a private to avoid 1918 // possible capture in the region. 1919 (DSAStack->hasExplicitDirective( 1920 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1921 Level) && 1922 DSAStack->isTaskgroupReductionRef(D, Level)); 1923 } 1924 1925 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1926 unsigned Level) { 1927 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1928 D = getCanonicalDecl(D); 1929 OpenMPClauseKind OMPC = OMPC_unknown; 1930 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1931 const unsigned NewLevel = I - 1; 1932 if (DSAStack->hasExplicitDSA(D, 1933 [&OMPC](const OpenMPClauseKind K) { 1934 if (isOpenMPPrivate(K)) { 1935 OMPC = K; 1936 return true; 1937 } 1938 return false; 1939 }, 1940 NewLevel)) 1941 break; 1942 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1943 D, NewLevel, 1944 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1945 OpenMPClauseKind) { return true; })) { 1946 OMPC = OMPC_map; 1947 break; 1948 } 1949 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1950 NewLevel)) { 1951 OMPC = OMPC_map; 1952 if (D->getType()->isScalarType() && 1953 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1954 DefaultMapAttributes::DMA_tofrom_scalar) 1955 OMPC = OMPC_firstprivate; 1956 break; 1957 } 1958 } 1959 if (OMPC != OMPC_unknown) 1960 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1961 } 1962 1963 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1964 unsigned Level) const { 1965 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1966 // Return true if the current level is no longer enclosed in a target region. 1967 1968 const auto *VD = dyn_cast<VarDecl>(D); 1969 return VD && !VD->hasLocalStorage() && 1970 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1971 Level); 1972 } 1973 1974 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1975 1976 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1977 const DeclarationNameInfo &DirName, 1978 Scope *CurScope, SourceLocation Loc) { 1979 DSAStack->push(DKind, DirName, CurScope, Loc); 1980 PushExpressionEvaluationContext( 1981 ExpressionEvaluationContext::PotentiallyEvaluated); 1982 } 1983 1984 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1985 DSAStack->setClauseParsingMode(K); 1986 } 1987 1988 void Sema::EndOpenMPClause() { 1989 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1990 } 1991 1992 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 1993 ArrayRef<OMPClause *> Clauses); 1994 1995 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1996 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1997 // A variable of class type (or array thereof) that appears in a lastprivate 1998 // clause requires an accessible, unambiguous default constructor for the 1999 // class type, unless the list item is also specified in a firstprivate 2000 // clause. 2001 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2002 for (OMPClause *C : D->clauses()) { 2003 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2004 SmallVector<Expr *, 8> PrivateCopies; 2005 for (Expr *DE : Clause->varlists()) { 2006 if (DE->isValueDependent() || DE->isTypeDependent()) { 2007 PrivateCopies.push_back(nullptr); 2008 continue; 2009 } 2010 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2011 auto *VD = cast<VarDecl>(DRE->getDecl()); 2012 QualType Type = VD->getType().getNonReferenceType(); 2013 const DSAStackTy::DSAVarData DVar = 2014 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2015 if (DVar.CKind == OMPC_lastprivate) { 2016 // Generate helper private variable and initialize it with the 2017 // default value. The address of the original variable is replaced 2018 // by the address of the new private variable in CodeGen. This new 2019 // variable is not added to IdResolver, so the code in the OpenMP 2020 // region uses original variable for proper diagnostics. 2021 VarDecl *VDPrivate = buildVarDecl( 2022 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2023 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2024 ActOnUninitializedDecl(VDPrivate); 2025 if (VDPrivate->isInvalidDecl()) { 2026 PrivateCopies.push_back(nullptr); 2027 continue; 2028 } 2029 PrivateCopies.push_back(buildDeclRefExpr( 2030 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2031 } else { 2032 // The variable is also a firstprivate, so initialization sequence 2033 // for private copy is generated already. 2034 PrivateCopies.push_back(nullptr); 2035 } 2036 } 2037 Clause->setPrivateCopies(PrivateCopies); 2038 } 2039 } 2040 // Check allocate clauses. 2041 if (!CurContext->isDependentContext()) 2042 checkAllocateClauses(*this, DSAStack, D->clauses()); 2043 } 2044 2045 DSAStack->pop(); 2046 DiscardCleanupsInEvaluationContext(); 2047 PopExpressionEvaluationContext(); 2048 } 2049 2050 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2051 Expr *NumIterations, Sema &SemaRef, 2052 Scope *S, DSAStackTy *Stack); 2053 2054 namespace { 2055 2056 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2057 private: 2058 Sema &SemaRef; 2059 2060 public: 2061 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2062 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2063 NamedDecl *ND = Candidate.getCorrectionDecl(); 2064 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2065 return VD->hasGlobalStorage() && 2066 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2067 SemaRef.getCurScope()); 2068 } 2069 return false; 2070 } 2071 2072 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2073 return llvm::make_unique<VarDeclFilterCCC>(*this); 2074 } 2075 2076 }; 2077 2078 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2079 private: 2080 Sema &SemaRef; 2081 2082 public: 2083 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2084 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2085 NamedDecl *ND = Candidate.getCorrectionDecl(); 2086 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2087 isa<FunctionDecl>(ND))) { 2088 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2089 SemaRef.getCurScope()); 2090 } 2091 return false; 2092 } 2093 2094 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2095 return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this); 2096 } 2097 }; 2098 2099 } // namespace 2100 2101 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2102 CXXScopeSpec &ScopeSpec, 2103 const DeclarationNameInfo &Id, 2104 OpenMPDirectiveKind Kind) { 2105 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2106 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2107 2108 if (Lookup.isAmbiguous()) 2109 return ExprError(); 2110 2111 VarDecl *VD; 2112 if (!Lookup.isSingleResult()) { 2113 VarDeclFilterCCC CCC(*this); 2114 if (TypoCorrection Corrected = 2115 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2116 CTK_ErrorRecovery)) { 2117 diagnoseTypo(Corrected, 2118 PDiag(Lookup.empty() 2119 ? diag::err_undeclared_var_use_suggest 2120 : diag::err_omp_expected_var_arg_suggest) 2121 << Id.getName()); 2122 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2123 } else { 2124 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2125 : diag::err_omp_expected_var_arg) 2126 << Id.getName(); 2127 return ExprError(); 2128 } 2129 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2130 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2131 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2132 return ExprError(); 2133 } 2134 Lookup.suppressDiagnostics(); 2135 2136 // OpenMP [2.9.2, Syntax, C/C++] 2137 // Variables must be file-scope, namespace-scope, or static block-scope. 2138 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2139 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2140 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2141 bool IsDecl = 2142 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2143 Diag(VD->getLocation(), 2144 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2145 << VD; 2146 return ExprError(); 2147 } 2148 2149 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2150 NamedDecl *ND = CanonicalVD; 2151 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2152 // A threadprivate directive for file-scope variables must appear outside 2153 // any definition or declaration. 2154 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2155 !getCurLexicalContext()->isTranslationUnit()) { 2156 Diag(Id.getLoc(), diag::err_omp_var_scope) 2157 << getOpenMPDirectiveName(Kind) << VD; 2158 bool IsDecl = 2159 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2160 Diag(VD->getLocation(), 2161 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2162 << VD; 2163 return ExprError(); 2164 } 2165 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2166 // A threadprivate directive for static class member variables must appear 2167 // in the class definition, in the same scope in which the member 2168 // variables are declared. 2169 if (CanonicalVD->isStaticDataMember() && 2170 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2171 Diag(Id.getLoc(), diag::err_omp_var_scope) 2172 << getOpenMPDirectiveName(Kind) << VD; 2173 bool IsDecl = 2174 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2175 Diag(VD->getLocation(), 2176 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2177 << VD; 2178 return ExprError(); 2179 } 2180 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2181 // A threadprivate directive for namespace-scope variables must appear 2182 // outside any definition or declaration other than the namespace 2183 // definition itself. 2184 if (CanonicalVD->getDeclContext()->isNamespace() && 2185 (!getCurLexicalContext()->isFileContext() || 2186 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2187 Diag(Id.getLoc(), diag::err_omp_var_scope) 2188 << getOpenMPDirectiveName(Kind) << VD; 2189 bool IsDecl = 2190 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2191 Diag(VD->getLocation(), 2192 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2193 << VD; 2194 return ExprError(); 2195 } 2196 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2197 // A threadprivate directive for static block-scope variables must appear 2198 // in the scope of the variable and not in a nested scope. 2199 if (CanonicalVD->isLocalVarDecl() && CurScope && 2200 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2201 Diag(Id.getLoc(), diag::err_omp_var_scope) 2202 << getOpenMPDirectiveName(Kind) << VD; 2203 bool IsDecl = 2204 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2205 Diag(VD->getLocation(), 2206 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2207 << VD; 2208 return ExprError(); 2209 } 2210 2211 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2212 // A threadprivate directive must lexically precede all references to any 2213 // of the variables in its list. 2214 if (Kind == OMPD_threadprivate && VD->isUsed() && 2215 !DSAStack->isThreadPrivate(VD)) { 2216 Diag(Id.getLoc(), diag::err_omp_var_used) 2217 << getOpenMPDirectiveName(Kind) << VD; 2218 return ExprError(); 2219 } 2220 2221 QualType ExprType = VD->getType().getNonReferenceType(); 2222 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2223 SourceLocation(), VD, 2224 /*RefersToEnclosingVariableOrCapture=*/false, 2225 Id.getLoc(), ExprType, VK_LValue); 2226 } 2227 2228 Sema::DeclGroupPtrTy 2229 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2230 ArrayRef<Expr *> VarList) { 2231 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2232 CurContext->addDecl(D); 2233 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2234 } 2235 return nullptr; 2236 } 2237 2238 namespace { 2239 class LocalVarRefChecker final 2240 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2241 Sema &SemaRef; 2242 2243 public: 2244 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2245 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2246 if (VD->hasLocalStorage()) { 2247 SemaRef.Diag(E->getBeginLoc(), 2248 diag::err_omp_local_var_in_threadprivate_init) 2249 << E->getSourceRange(); 2250 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2251 << VD << VD->getSourceRange(); 2252 return true; 2253 } 2254 } 2255 return false; 2256 } 2257 bool VisitStmt(const Stmt *S) { 2258 for (const Stmt *Child : S->children()) { 2259 if (Child && Visit(Child)) 2260 return true; 2261 } 2262 return false; 2263 } 2264 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2265 }; 2266 } // namespace 2267 2268 OMPThreadPrivateDecl * 2269 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2270 SmallVector<Expr *, 8> Vars; 2271 for (Expr *RefExpr : VarList) { 2272 auto *DE = cast<DeclRefExpr>(RefExpr); 2273 auto *VD = cast<VarDecl>(DE->getDecl()); 2274 SourceLocation ILoc = DE->getExprLoc(); 2275 2276 // Mark variable as used. 2277 VD->setReferenced(); 2278 VD->markUsed(Context); 2279 2280 QualType QType = VD->getType(); 2281 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2282 // It will be analyzed later. 2283 Vars.push_back(DE); 2284 continue; 2285 } 2286 2287 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2288 // A threadprivate variable must not have an incomplete type. 2289 if (RequireCompleteType(ILoc, VD->getType(), 2290 diag::err_omp_threadprivate_incomplete_type)) { 2291 continue; 2292 } 2293 2294 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2295 // A threadprivate variable must not have a reference type. 2296 if (VD->getType()->isReferenceType()) { 2297 Diag(ILoc, diag::err_omp_ref_type_arg) 2298 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2299 bool IsDecl = 2300 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2301 Diag(VD->getLocation(), 2302 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2303 << VD; 2304 continue; 2305 } 2306 2307 // Check if this is a TLS variable. If TLS is not being supported, produce 2308 // the corresponding diagnostic. 2309 if ((VD->getTLSKind() != VarDecl::TLS_None && 2310 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2311 getLangOpts().OpenMPUseTLS && 2312 getASTContext().getTargetInfo().isTLSSupported())) || 2313 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2314 !VD->isLocalVarDecl())) { 2315 Diag(ILoc, diag::err_omp_var_thread_local) 2316 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2317 bool IsDecl = 2318 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2319 Diag(VD->getLocation(), 2320 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2321 << VD; 2322 continue; 2323 } 2324 2325 // Check if initial value of threadprivate variable reference variable with 2326 // local storage (it is not supported by runtime). 2327 if (const Expr *Init = VD->getAnyInitializer()) { 2328 LocalVarRefChecker Checker(*this); 2329 if (Checker.Visit(Init)) 2330 continue; 2331 } 2332 2333 Vars.push_back(RefExpr); 2334 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2335 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2336 Context, SourceRange(Loc, Loc))); 2337 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2338 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2339 } 2340 OMPThreadPrivateDecl *D = nullptr; 2341 if (!Vars.empty()) { 2342 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2343 Vars); 2344 D->setAccess(AS_public); 2345 } 2346 return D; 2347 } 2348 2349 static OMPAllocateDeclAttr::AllocatorTypeTy 2350 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2351 if (!Allocator) 2352 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2353 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2354 Allocator->isInstantiationDependent() || 2355 Allocator->containsUnexpandedParameterPack()) 2356 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2357 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2358 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2359 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2360 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2361 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2362 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2363 llvm::FoldingSetNodeID AEId, DAEId; 2364 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2365 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2366 if (AEId == DAEId) { 2367 AllocatorKindRes = AllocatorKind; 2368 break; 2369 } 2370 } 2371 return AllocatorKindRes; 2372 } 2373 2374 static bool checkPreviousOMPAllocateAttribute( 2375 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2376 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2377 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2378 return false; 2379 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2380 Expr *PrevAllocator = A->getAllocator(); 2381 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2382 getAllocatorKind(S, Stack, PrevAllocator); 2383 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2384 if (AllocatorsMatch && 2385 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2386 Allocator && PrevAllocator) { 2387 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2388 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2389 llvm::FoldingSetNodeID AEId, PAEId; 2390 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2391 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2392 AllocatorsMatch = AEId == PAEId; 2393 } 2394 if (!AllocatorsMatch) { 2395 SmallString<256> AllocatorBuffer; 2396 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2397 if (Allocator) 2398 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2399 SmallString<256> PrevAllocatorBuffer; 2400 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2401 if (PrevAllocator) 2402 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2403 S.getPrintingPolicy()); 2404 2405 SourceLocation AllocatorLoc = 2406 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2407 SourceRange AllocatorRange = 2408 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2409 SourceLocation PrevAllocatorLoc = 2410 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2411 SourceRange PrevAllocatorRange = 2412 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2413 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2414 << (Allocator ? 1 : 0) << AllocatorStream.str() 2415 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2416 << AllocatorRange; 2417 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2418 << PrevAllocatorRange; 2419 return true; 2420 } 2421 return false; 2422 } 2423 2424 static void 2425 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2426 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2427 Expr *Allocator, SourceRange SR) { 2428 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2429 return; 2430 if (Allocator && 2431 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2432 Allocator->isInstantiationDependent() || 2433 Allocator->containsUnexpandedParameterPack())) 2434 return; 2435 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2436 Allocator, SR); 2437 VD->addAttr(A); 2438 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2439 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2440 } 2441 2442 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2443 SourceLocation Loc, ArrayRef<Expr *> VarList, 2444 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2445 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2446 Expr *Allocator = nullptr; 2447 if (Clauses.empty()) { 2448 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2449 // allocate directives that appear in a target region must specify an 2450 // allocator clause unless a requires directive with the dynamic_allocators 2451 // clause is present in the same compilation unit. 2452 if (LangOpts.OpenMPIsDevice && 2453 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2454 targetDiag(Loc, diag::err_expected_allocator_clause); 2455 } else { 2456 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2457 } 2458 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2459 getAllocatorKind(*this, DSAStack, Allocator); 2460 SmallVector<Expr *, 8> Vars; 2461 for (Expr *RefExpr : VarList) { 2462 auto *DE = cast<DeclRefExpr>(RefExpr); 2463 auto *VD = cast<VarDecl>(DE->getDecl()); 2464 2465 // Check if this is a TLS variable or global register. 2466 if (VD->getTLSKind() != VarDecl::TLS_None || 2467 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2468 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2469 !VD->isLocalVarDecl())) 2470 continue; 2471 2472 // If the used several times in the allocate directive, the same allocator 2473 // must be used. 2474 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2475 AllocatorKind, Allocator)) 2476 continue; 2477 2478 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2479 // If a list item has a static storage type, the allocator expression in the 2480 // allocator clause must be a constant expression that evaluates to one of 2481 // the predefined memory allocator values. 2482 if (Allocator && VD->hasGlobalStorage()) { 2483 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2484 Diag(Allocator->getExprLoc(), 2485 diag::err_omp_expected_predefined_allocator) 2486 << Allocator->getSourceRange(); 2487 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2488 VarDecl::DeclarationOnly; 2489 Diag(VD->getLocation(), 2490 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2491 << VD; 2492 continue; 2493 } 2494 } 2495 2496 Vars.push_back(RefExpr); 2497 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2498 DE->getSourceRange()); 2499 } 2500 if (Vars.empty()) 2501 return nullptr; 2502 if (!Owner) 2503 Owner = getCurLexicalContext(); 2504 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2505 D->setAccess(AS_public); 2506 Owner->addDecl(D); 2507 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2508 } 2509 2510 Sema::DeclGroupPtrTy 2511 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2512 ArrayRef<OMPClause *> ClauseList) { 2513 OMPRequiresDecl *D = nullptr; 2514 if (!CurContext->isFileContext()) { 2515 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2516 } else { 2517 D = CheckOMPRequiresDecl(Loc, ClauseList); 2518 if (D) { 2519 CurContext->addDecl(D); 2520 DSAStack->addRequiresDecl(D); 2521 } 2522 } 2523 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2524 } 2525 2526 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2527 ArrayRef<OMPClause *> ClauseList) { 2528 /// For target specific clauses, the requires directive cannot be 2529 /// specified after the handling of any of the target regions in the 2530 /// current compilation unit. 2531 ArrayRef<SourceLocation> TargetLocations = 2532 DSAStack->getEncounteredTargetLocs(); 2533 if (!TargetLocations.empty()) { 2534 for (const OMPClause *CNew : ClauseList) { 2535 // Check if any of the requires clauses affect target regions. 2536 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2537 isa<OMPUnifiedAddressClause>(CNew) || 2538 isa<OMPReverseOffloadClause>(CNew) || 2539 isa<OMPDynamicAllocatorsClause>(CNew)) { 2540 Diag(Loc, diag::err_omp_target_before_requires) 2541 << getOpenMPClauseName(CNew->getClauseKind()); 2542 for (SourceLocation TargetLoc : TargetLocations) { 2543 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2544 } 2545 } 2546 } 2547 } 2548 2549 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2550 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2551 ClauseList); 2552 return nullptr; 2553 } 2554 2555 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2556 const ValueDecl *D, 2557 const DSAStackTy::DSAVarData &DVar, 2558 bool IsLoopIterVar = false) { 2559 if (DVar.RefExpr) { 2560 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2561 << getOpenMPClauseName(DVar.CKind); 2562 return; 2563 } 2564 enum { 2565 PDSA_StaticMemberShared, 2566 PDSA_StaticLocalVarShared, 2567 PDSA_LoopIterVarPrivate, 2568 PDSA_LoopIterVarLinear, 2569 PDSA_LoopIterVarLastprivate, 2570 PDSA_ConstVarShared, 2571 PDSA_GlobalVarShared, 2572 PDSA_TaskVarFirstprivate, 2573 PDSA_LocalVarPrivate, 2574 PDSA_Implicit 2575 } Reason = PDSA_Implicit; 2576 bool ReportHint = false; 2577 auto ReportLoc = D->getLocation(); 2578 auto *VD = dyn_cast<VarDecl>(D); 2579 if (IsLoopIterVar) { 2580 if (DVar.CKind == OMPC_private) 2581 Reason = PDSA_LoopIterVarPrivate; 2582 else if (DVar.CKind == OMPC_lastprivate) 2583 Reason = PDSA_LoopIterVarLastprivate; 2584 else 2585 Reason = PDSA_LoopIterVarLinear; 2586 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2587 DVar.CKind == OMPC_firstprivate) { 2588 Reason = PDSA_TaskVarFirstprivate; 2589 ReportLoc = DVar.ImplicitDSALoc; 2590 } else if (VD && VD->isStaticLocal()) 2591 Reason = PDSA_StaticLocalVarShared; 2592 else if (VD && VD->isStaticDataMember()) 2593 Reason = PDSA_StaticMemberShared; 2594 else if (VD && VD->isFileVarDecl()) 2595 Reason = PDSA_GlobalVarShared; 2596 else if (D->getType().isConstant(SemaRef.getASTContext())) 2597 Reason = PDSA_ConstVarShared; 2598 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2599 ReportHint = true; 2600 Reason = PDSA_LocalVarPrivate; 2601 } 2602 if (Reason != PDSA_Implicit) { 2603 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2604 << Reason << ReportHint 2605 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2606 } else if (DVar.ImplicitDSALoc.isValid()) { 2607 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2608 << getOpenMPClauseName(DVar.CKind); 2609 } 2610 } 2611 2612 namespace { 2613 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2614 DSAStackTy *Stack; 2615 Sema &SemaRef; 2616 bool ErrorFound = false; 2617 CapturedStmt *CS = nullptr; 2618 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2619 llvm::SmallVector<Expr *, 4> ImplicitMap; 2620 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2621 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2622 2623 void VisitSubCaptures(OMPExecutableDirective *S) { 2624 // Check implicitly captured variables. 2625 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2626 return; 2627 for (const CapturedStmt::Capture &Cap : 2628 S->getInnermostCapturedStmt()->captures()) { 2629 if (!Cap.capturesVariable()) 2630 continue; 2631 VarDecl *VD = Cap.getCapturedVar(); 2632 // Do not try to map the variable if it or its sub-component was mapped 2633 // already. 2634 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2635 Stack->checkMappableExprComponentListsForDecl( 2636 VD, /*CurrentRegionOnly=*/true, 2637 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2638 OpenMPClauseKind) { return true; })) 2639 continue; 2640 DeclRefExpr *DRE = buildDeclRefExpr( 2641 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2642 Cap.getLocation(), /*RefersToCapture=*/true); 2643 Visit(DRE); 2644 } 2645 } 2646 2647 public: 2648 void VisitDeclRefExpr(DeclRefExpr *E) { 2649 if (E->isTypeDependent() || E->isValueDependent() || 2650 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2651 return; 2652 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2653 // Check the datasharing rules for the expressions in the clauses. 2654 if (!CS) { 2655 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2656 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2657 Visit(CED->getInit()); 2658 return; 2659 } 2660 } 2661 VD = VD->getCanonicalDecl(); 2662 // Skip internally declared variables. 2663 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2664 return; 2665 2666 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2667 // Check if the variable has explicit DSA set and stop analysis if it so. 2668 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2669 return; 2670 2671 // Skip internally declared static variables. 2672 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2673 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2674 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2675 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2676 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2677 return; 2678 2679 SourceLocation ELoc = E->getExprLoc(); 2680 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2681 // The default(none) clause requires that each variable that is referenced 2682 // in the construct, and does not have a predetermined data-sharing 2683 // attribute, must have its data-sharing attribute explicitly determined 2684 // by being listed in a data-sharing attribute clause. 2685 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2686 isImplicitOrExplicitTaskingRegion(DKind) && 2687 VarsWithInheritedDSA.count(VD) == 0) { 2688 VarsWithInheritedDSA[VD] = E; 2689 return; 2690 } 2691 2692 if (isOpenMPTargetExecutionDirective(DKind) && 2693 !Stack->isLoopControlVariable(VD).first) { 2694 if (!Stack->checkMappableExprComponentListsForDecl( 2695 VD, /*CurrentRegionOnly=*/true, 2696 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2697 StackComponents, 2698 OpenMPClauseKind) { 2699 // Variable is used if it has been marked as an array, array 2700 // section or the variable iself. 2701 return StackComponents.size() == 1 || 2702 std::all_of( 2703 std::next(StackComponents.rbegin()), 2704 StackComponents.rend(), 2705 [](const OMPClauseMappableExprCommon:: 2706 MappableComponent &MC) { 2707 return MC.getAssociatedDeclaration() == 2708 nullptr && 2709 (isa<OMPArraySectionExpr>( 2710 MC.getAssociatedExpression()) || 2711 isa<ArraySubscriptExpr>( 2712 MC.getAssociatedExpression())); 2713 }); 2714 })) { 2715 bool IsFirstprivate = false; 2716 // By default lambdas are captured as firstprivates. 2717 if (const auto *RD = 2718 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2719 IsFirstprivate = RD->isLambda(); 2720 IsFirstprivate = 2721 IsFirstprivate || 2722 (VD->getType().getNonReferenceType()->isScalarType() && 2723 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2724 if (IsFirstprivate) 2725 ImplicitFirstprivate.emplace_back(E); 2726 else 2727 ImplicitMap.emplace_back(E); 2728 return; 2729 } 2730 } 2731 2732 // OpenMP [2.9.3.6, Restrictions, p.2] 2733 // A list item that appears in a reduction clause of the innermost 2734 // enclosing worksharing or parallel construct may not be accessed in an 2735 // explicit task. 2736 DVar = Stack->hasInnermostDSA( 2737 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2738 [](OpenMPDirectiveKind K) { 2739 return isOpenMPParallelDirective(K) || 2740 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2741 }, 2742 /*FromParent=*/true); 2743 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2744 ErrorFound = true; 2745 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2746 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2747 return; 2748 } 2749 2750 // Define implicit data-sharing attributes for task. 2751 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2752 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2753 !Stack->isLoopControlVariable(VD).first) { 2754 ImplicitFirstprivate.push_back(E); 2755 return; 2756 } 2757 2758 // Store implicitly used globals with declare target link for parent 2759 // target. 2760 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2761 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2762 Stack->addToParentTargetRegionLinkGlobals(E); 2763 return; 2764 } 2765 } 2766 } 2767 void VisitMemberExpr(MemberExpr *E) { 2768 if (E->isTypeDependent() || E->isValueDependent() || 2769 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2770 return; 2771 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2772 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2773 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2774 if (!FD) 2775 return; 2776 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2777 // Check if the variable has explicit DSA set and stop analysis if it 2778 // so. 2779 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2780 return; 2781 2782 if (isOpenMPTargetExecutionDirective(DKind) && 2783 !Stack->isLoopControlVariable(FD).first && 2784 !Stack->checkMappableExprComponentListsForDecl( 2785 FD, /*CurrentRegionOnly=*/true, 2786 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2787 StackComponents, 2788 OpenMPClauseKind) { 2789 return isa<CXXThisExpr>( 2790 cast<MemberExpr>( 2791 StackComponents.back().getAssociatedExpression()) 2792 ->getBase() 2793 ->IgnoreParens()); 2794 })) { 2795 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2796 // A bit-field cannot appear in a map clause. 2797 // 2798 if (FD->isBitField()) 2799 return; 2800 2801 // Check to see if the member expression is referencing a class that 2802 // has already been explicitly mapped 2803 if (Stack->isClassPreviouslyMapped(TE->getType())) 2804 return; 2805 2806 ImplicitMap.emplace_back(E); 2807 return; 2808 } 2809 2810 SourceLocation ELoc = E->getExprLoc(); 2811 // OpenMP [2.9.3.6, Restrictions, p.2] 2812 // A list item that appears in a reduction clause of the innermost 2813 // enclosing worksharing or parallel construct may not be accessed in 2814 // an explicit task. 2815 DVar = Stack->hasInnermostDSA( 2816 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2817 [](OpenMPDirectiveKind K) { 2818 return isOpenMPParallelDirective(K) || 2819 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2820 }, 2821 /*FromParent=*/true); 2822 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2823 ErrorFound = true; 2824 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2825 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2826 return; 2827 } 2828 2829 // Define implicit data-sharing attributes for task. 2830 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2831 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2832 !Stack->isLoopControlVariable(FD).first) { 2833 // Check if there is a captured expression for the current field in the 2834 // region. Do not mark it as firstprivate unless there is no captured 2835 // expression. 2836 // TODO: try to make it firstprivate. 2837 if (DVar.CKind != OMPC_unknown) 2838 ImplicitFirstprivate.push_back(E); 2839 } 2840 return; 2841 } 2842 if (isOpenMPTargetExecutionDirective(DKind)) { 2843 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2844 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2845 /*NoDiagnose=*/true)) 2846 return; 2847 const auto *VD = cast<ValueDecl>( 2848 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2849 if (!Stack->checkMappableExprComponentListsForDecl( 2850 VD, /*CurrentRegionOnly=*/true, 2851 [&CurComponents]( 2852 OMPClauseMappableExprCommon::MappableExprComponentListRef 2853 StackComponents, 2854 OpenMPClauseKind) { 2855 auto CCI = CurComponents.rbegin(); 2856 auto CCE = CurComponents.rend(); 2857 for (const auto &SC : llvm::reverse(StackComponents)) { 2858 // Do both expressions have the same kind? 2859 if (CCI->getAssociatedExpression()->getStmtClass() != 2860 SC.getAssociatedExpression()->getStmtClass()) 2861 if (!(isa<OMPArraySectionExpr>( 2862 SC.getAssociatedExpression()) && 2863 isa<ArraySubscriptExpr>( 2864 CCI->getAssociatedExpression()))) 2865 return false; 2866 2867 const Decl *CCD = CCI->getAssociatedDeclaration(); 2868 const Decl *SCD = SC.getAssociatedDeclaration(); 2869 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2870 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2871 if (SCD != CCD) 2872 return false; 2873 std::advance(CCI, 1); 2874 if (CCI == CCE) 2875 break; 2876 } 2877 return true; 2878 })) { 2879 Visit(E->getBase()); 2880 } 2881 } else { 2882 Visit(E->getBase()); 2883 } 2884 } 2885 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2886 for (OMPClause *C : S->clauses()) { 2887 // Skip analysis of arguments of implicitly defined firstprivate clause 2888 // for task|target directives. 2889 // Skip analysis of arguments of implicitly defined map clause for target 2890 // directives. 2891 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2892 C->isImplicit())) { 2893 for (Stmt *CC : C->children()) { 2894 if (CC) 2895 Visit(CC); 2896 } 2897 } 2898 } 2899 // Check implicitly captured variables. 2900 VisitSubCaptures(S); 2901 } 2902 void VisitStmt(Stmt *S) { 2903 for (Stmt *C : S->children()) { 2904 if (C) { 2905 // Check implicitly captured variables in the task-based directives to 2906 // check if they must be firstprivatized. 2907 Visit(C); 2908 } 2909 } 2910 } 2911 2912 bool isErrorFound() const { return ErrorFound; } 2913 ArrayRef<Expr *> getImplicitFirstprivate() const { 2914 return ImplicitFirstprivate; 2915 } 2916 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2917 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2918 return VarsWithInheritedDSA; 2919 } 2920 2921 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2922 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2923 // Process declare target link variables for the target directives. 2924 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2925 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2926 Visit(E); 2927 } 2928 } 2929 }; 2930 } // namespace 2931 2932 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2933 switch (DKind) { 2934 case OMPD_parallel: 2935 case OMPD_parallel_for: 2936 case OMPD_parallel_for_simd: 2937 case OMPD_parallel_sections: 2938 case OMPD_teams: 2939 case OMPD_teams_distribute: 2940 case OMPD_teams_distribute_simd: { 2941 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2942 QualType KmpInt32PtrTy = 2943 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2944 Sema::CapturedParamNameType Params[] = { 2945 std::make_pair(".global_tid.", KmpInt32PtrTy), 2946 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2947 std::make_pair(StringRef(), QualType()) // __context with shared vars 2948 }; 2949 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2950 Params); 2951 break; 2952 } 2953 case OMPD_target_teams: 2954 case OMPD_target_parallel: 2955 case OMPD_target_parallel_for: 2956 case OMPD_target_parallel_for_simd: 2957 case OMPD_target_teams_distribute: 2958 case OMPD_target_teams_distribute_simd: { 2959 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2960 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2961 QualType KmpInt32PtrTy = 2962 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2963 QualType Args[] = {VoidPtrTy}; 2964 FunctionProtoType::ExtProtoInfo EPI; 2965 EPI.Variadic = true; 2966 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2967 Sema::CapturedParamNameType Params[] = { 2968 std::make_pair(".global_tid.", KmpInt32Ty), 2969 std::make_pair(".part_id.", KmpInt32PtrTy), 2970 std::make_pair(".privates.", VoidPtrTy), 2971 std::make_pair( 2972 ".copy_fn.", 2973 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2974 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2975 std::make_pair(StringRef(), QualType()) // __context with shared vars 2976 }; 2977 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2978 Params); 2979 // Mark this captured region as inlined, because we don't use outlined 2980 // function directly. 2981 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2982 AlwaysInlineAttr::CreateImplicit( 2983 Context, AlwaysInlineAttr::Keyword_forceinline)); 2984 Sema::CapturedParamNameType ParamsTarget[] = { 2985 std::make_pair(StringRef(), QualType()) // __context with shared vars 2986 }; 2987 // Start a captured region for 'target' with no implicit parameters. 2988 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2989 ParamsTarget); 2990 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2991 std::make_pair(".global_tid.", KmpInt32PtrTy), 2992 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2993 std::make_pair(StringRef(), QualType()) // __context with shared vars 2994 }; 2995 // Start a captured region for 'teams' or 'parallel'. Both regions have 2996 // the same implicit parameters. 2997 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2998 ParamsTeamsOrParallel); 2999 break; 3000 } 3001 case OMPD_target: 3002 case OMPD_target_simd: { 3003 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3004 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3005 QualType KmpInt32PtrTy = 3006 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3007 QualType Args[] = {VoidPtrTy}; 3008 FunctionProtoType::ExtProtoInfo EPI; 3009 EPI.Variadic = true; 3010 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3011 Sema::CapturedParamNameType Params[] = { 3012 std::make_pair(".global_tid.", KmpInt32Ty), 3013 std::make_pair(".part_id.", KmpInt32PtrTy), 3014 std::make_pair(".privates.", VoidPtrTy), 3015 std::make_pair( 3016 ".copy_fn.", 3017 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3018 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3019 std::make_pair(StringRef(), QualType()) // __context with shared vars 3020 }; 3021 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3022 Params); 3023 // Mark this captured region as inlined, because we don't use outlined 3024 // function directly. 3025 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3026 AlwaysInlineAttr::CreateImplicit( 3027 Context, AlwaysInlineAttr::Keyword_forceinline)); 3028 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3029 std::make_pair(StringRef(), QualType())); 3030 break; 3031 } 3032 case OMPD_simd: 3033 case OMPD_for: 3034 case OMPD_for_simd: 3035 case OMPD_sections: 3036 case OMPD_section: 3037 case OMPD_single: 3038 case OMPD_master: 3039 case OMPD_critical: 3040 case OMPD_taskgroup: 3041 case OMPD_distribute: 3042 case OMPD_distribute_simd: 3043 case OMPD_ordered: 3044 case OMPD_atomic: 3045 case OMPD_target_data: { 3046 Sema::CapturedParamNameType Params[] = { 3047 std::make_pair(StringRef(), QualType()) // __context with shared vars 3048 }; 3049 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3050 Params); 3051 break; 3052 } 3053 case OMPD_task: { 3054 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3055 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3056 QualType KmpInt32PtrTy = 3057 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3058 QualType Args[] = {VoidPtrTy}; 3059 FunctionProtoType::ExtProtoInfo EPI; 3060 EPI.Variadic = true; 3061 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3062 Sema::CapturedParamNameType Params[] = { 3063 std::make_pair(".global_tid.", KmpInt32Ty), 3064 std::make_pair(".part_id.", KmpInt32PtrTy), 3065 std::make_pair(".privates.", VoidPtrTy), 3066 std::make_pair( 3067 ".copy_fn.", 3068 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3069 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3070 std::make_pair(StringRef(), QualType()) // __context with shared vars 3071 }; 3072 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3073 Params); 3074 // Mark this captured region as inlined, because we don't use outlined 3075 // function directly. 3076 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3077 AlwaysInlineAttr::CreateImplicit( 3078 Context, AlwaysInlineAttr::Keyword_forceinline)); 3079 break; 3080 } 3081 case OMPD_taskloop: 3082 case OMPD_taskloop_simd: { 3083 QualType KmpInt32Ty = 3084 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3085 .withConst(); 3086 QualType KmpUInt64Ty = 3087 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3088 .withConst(); 3089 QualType KmpInt64Ty = 3090 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3091 .withConst(); 3092 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3093 QualType KmpInt32PtrTy = 3094 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3095 QualType Args[] = {VoidPtrTy}; 3096 FunctionProtoType::ExtProtoInfo EPI; 3097 EPI.Variadic = true; 3098 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3099 Sema::CapturedParamNameType Params[] = { 3100 std::make_pair(".global_tid.", KmpInt32Ty), 3101 std::make_pair(".part_id.", KmpInt32PtrTy), 3102 std::make_pair(".privates.", VoidPtrTy), 3103 std::make_pair( 3104 ".copy_fn.", 3105 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3106 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3107 std::make_pair(".lb.", KmpUInt64Ty), 3108 std::make_pair(".ub.", KmpUInt64Ty), 3109 std::make_pair(".st.", KmpInt64Ty), 3110 std::make_pair(".liter.", KmpInt32Ty), 3111 std::make_pair(".reductions.", VoidPtrTy), 3112 std::make_pair(StringRef(), QualType()) // __context with shared vars 3113 }; 3114 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3115 Params); 3116 // Mark this captured region as inlined, because we don't use outlined 3117 // function directly. 3118 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3119 AlwaysInlineAttr::CreateImplicit( 3120 Context, AlwaysInlineAttr::Keyword_forceinline)); 3121 break; 3122 } 3123 case OMPD_distribute_parallel_for_simd: 3124 case OMPD_distribute_parallel_for: { 3125 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3126 QualType KmpInt32PtrTy = 3127 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3128 Sema::CapturedParamNameType Params[] = { 3129 std::make_pair(".global_tid.", KmpInt32PtrTy), 3130 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3131 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3132 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3133 std::make_pair(StringRef(), QualType()) // __context with shared vars 3134 }; 3135 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3136 Params); 3137 break; 3138 } 3139 case OMPD_target_teams_distribute_parallel_for: 3140 case OMPD_target_teams_distribute_parallel_for_simd: { 3141 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3142 QualType KmpInt32PtrTy = 3143 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3144 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3145 3146 QualType Args[] = {VoidPtrTy}; 3147 FunctionProtoType::ExtProtoInfo EPI; 3148 EPI.Variadic = true; 3149 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3150 Sema::CapturedParamNameType Params[] = { 3151 std::make_pair(".global_tid.", KmpInt32Ty), 3152 std::make_pair(".part_id.", KmpInt32PtrTy), 3153 std::make_pair(".privates.", VoidPtrTy), 3154 std::make_pair( 3155 ".copy_fn.", 3156 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3157 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3158 std::make_pair(StringRef(), QualType()) // __context with shared vars 3159 }; 3160 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3161 Params); 3162 // Mark this captured region as inlined, because we don't use outlined 3163 // function directly. 3164 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3165 AlwaysInlineAttr::CreateImplicit( 3166 Context, AlwaysInlineAttr::Keyword_forceinline)); 3167 Sema::CapturedParamNameType ParamsTarget[] = { 3168 std::make_pair(StringRef(), QualType()) // __context with shared vars 3169 }; 3170 // Start a captured region for 'target' with no implicit parameters. 3171 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3172 ParamsTarget); 3173 3174 Sema::CapturedParamNameType ParamsTeams[] = { 3175 std::make_pair(".global_tid.", KmpInt32PtrTy), 3176 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3177 std::make_pair(StringRef(), QualType()) // __context with shared vars 3178 }; 3179 // Start a captured region for 'target' with no implicit parameters. 3180 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3181 ParamsTeams); 3182 3183 Sema::CapturedParamNameType ParamsParallel[] = { 3184 std::make_pair(".global_tid.", KmpInt32PtrTy), 3185 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3186 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3187 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3188 std::make_pair(StringRef(), QualType()) // __context with shared vars 3189 }; 3190 // Start a captured region for 'teams' or 'parallel'. Both regions have 3191 // the same implicit parameters. 3192 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3193 ParamsParallel); 3194 break; 3195 } 3196 3197 case OMPD_teams_distribute_parallel_for: 3198 case OMPD_teams_distribute_parallel_for_simd: { 3199 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3200 QualType KmpInt32PtrTy = 3201 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3202 3203 Sema::CapturedParamNameType ParamsTeams[] = { 3204 std::make_pair(".global_tid.", KmpInt32PtrTy), 3205 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3206 std::make_pair(StringRef(), QualType()) // __context with shared vars 3207 }; 3208 // Start a captured region for 'target' with no implicit parameters. 3209 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3210 ParamsTeams); 3211 3212 Sema::CapturedParamNameType ParamsParallel[] = { 3213 std::make_pair(".global_tid.", KmpInt32PtrTy), 3214 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3215 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3216 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3217 std::make_pair(StringRef(), QualType()) // __context with shared vars 3218 }; 3219 // Start a captured region for 'teams' or 'parallel'. Both regions have 3220 // the same implicit parameters. 3221 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3222 ParamsParallel); 3223 break; 3224 } 3225 case OMPD_target_update: 3226 case OMPD_target_enter_data: 3227 case OMPD_target_exit_data: { 3228 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3229 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3230 QualType KmpInt32PtrTy = 3231 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3232 QualType Args[] = {VoidPtrTy}; 3233 FunctionProtoType::ExtProtoInfo EPI; 3234 EPI.Variadic = true; 3235 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3236 Sema::CapturedParamNameType Params[] = { 3237 std::make_pair(".global_tid.", KmpInt32Ty), 3238 std::make_pair(".part_id.", KmpInt32PtrTy), 3239 std::make_pair(".privates.", VoidPtrTy), 3240 std::make_pair( 3241 ".copy_fn.", 3242 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3243 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3244 std::make_pair(StringRef(), QualType()) // __context with shared vars 3245 }; 3246 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3247 Params); 3248 // Mark this captured region as inlined, because we don't use outlined 3249 // function directly. 3250 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3251 AlwaysInlineAttr::CreateImplicit( 3252 Context, AlwaysInlineAttr::Keyword_forceinline)); 3253 break; 3254 } 3255 case OMPD_threadprivate: 3256 case OMPD_allocate: 3257 case OMPD_taskyield: 3258 case OMPD_barrier: 3259 case OMPD_taskwait: 3260 case OMPD_cancellation_point: 3261 case OMPD_cancel: 3262 case OMPD_flush: 3263 case OMPD_declare_reduction: 3264 case OMPD_declare_mapper: 3265 case OMPD_declare_simd: 3266 case OMPD_declare_target: 3267 case OMPD_end_declare_target: 3268 case OMPD_requires: 3269 llvm_unreachable("OpenMP Directive is not allowed"); 3270 case OMPD_unknown: 3271 llvm_unreachable("Unknown OpenMP directive"); 3272 } 3273 } 3274 3275 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3276 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3277 getOpenMPCaptureRegions(CaptureRegions, DKind); 3278 return CaptureRegions.size(); 3279 } 3280 3281 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3282 Expr *CaptureExpr, bool WithInit, 3283 bool AsExpression) { 3284 assert(CaptureExpr); 3285 ASTContext &C = S.getASTContext(); 3286 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3287 QualType Ty = Init->getType(); 3288 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3289 if (S.getLangOpts().CPlusPlus) { 3290 Ty = C.getLValueReferenceType(Ty); 3291 } else { 3292 Ty = C.getPointerType(Ty); 3293 ExprResult Res = 3294 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3295 if (!Res.isUsable()) 3296 return nullptr; 3297 Init = Res.get(); 3298 } 3299 WithInit = true; 3300 } 3301 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3302 CaptureExpr->getBeginLoc()); 3303 if (!WithInit) 3304 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3305 S.CurContext->addHiddenDecl(CED); 3306 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3307 return CED; 3308 } 3309 3310 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3311 bool WithInit) { 3312 OMPCapturedExprDecl *CD; 3313 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3314 CD = cast<OMPCapturedExprDecl>(VD); 3315 else 3316 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3317 /*AsExpression=*/false); 3318 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3319 CaptureExpr->getExprLoc()); 3320 } 3321 3322 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3323 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3324 if (!Ref) { 3325 OMPCapturedExprDecl *CD = buildCaptureDecl( 3326 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3327 /*WithInit=*/true, /*AsExpression=*/true); 3328 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3329 CaptureExpr->getExprLoc()); 3330 } 3331 ExprResult Res = Ref; 3332 if (!S.getLangOpts().CPlusPlus && 3333 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3334 Ref->getType()->isPointerType()) { 3335 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3336 if (!Res.isUsable()) 3337 return ExprError(); 3338 } 3339 return S.DefaultLvalueConversion(Res.get()); 3340 } 3341 3342 namespace { 3343 // OpenMP directives parsed in this section are represented as a 3344 // CapturedStatement with an associated statement. If a syntax error 3345 // is detected during the parsing of the associated statement, the 3346 // compiler must abort processing and close the CapturedStatement. 3347 // 3348 // Combined directives such as 'target parallel' have more than one 3349 // nested CapturedStatements. This RAII ensures that we unwind out 3350 // of all the nested CapturedStatements when an error is found. 3351 class CaptureRegionUnwinderRAII { 3352 private: 3353 Sema &S; 3354 bool &ErrorFound; 3355 OpenMPDirectiveKind DKind = OMPD_unknown; 3356 3357 public: 3358 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3359 OpenMPDirectiveKind DKind) 3360 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3361 ~CaptureRegionUnwinderRAII() { 3362 if (ErrorFound) { 3363 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3364 while (--ThisCaptureLevel >= 0) 3365 S.ActOnCapturedRegionError(); 3366 } 3367 } 3368 }; 3369 } // namespace 3370 3371 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3372 ArrayRef<OMPClause *> Clauses) { 3373 bool ErrorFound = false; 3374 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3375 *this, ErrorFound, DSAStack->getCurrentDirective()); 3376 if (!S.isUsable()) { 3377 ErrorFound = true; 3378 return StmtError(); 3379 } 3380 3381 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3382 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3383 OMPOrderedClause *OC = nullptr; 3384 OMPScheduleClause *SC = nullptr; 3385 SmallVector<const OMPLinearClause *, 4> LCs; 3386 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3387 // This is required for proper codegen. 3388 for (OMPClause *Clause : Clauses) { 3389 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3390 Clause->getClauseKind() == OMPC_in_reduction) { 3391 // Capture taskgroup task_reduction descriptors inside the tasking regions 3392 // with the corresponding in_reduction items. 3393 auto *IRC = cast<OMPInReductionClause>(Clause); 3394 for (Expr *E : IRC->taskgroup_descriptors()) 3395 if (E) 3396 MarkDeclarationsReferencedInExpr(E); 3397 } 3398 if (isOpenMPPrivate(Clause->getClauseKind()) || 3399 Clause->getClauseKind() == OMPC_copyprivate || 3400 (getLangOpts().OpenMPUseTLS && 3401 getASTContext().getTargetInfo().isTLSSupported() && 3402 Clause->getClauseKind() == OMPC_copyin)) { 3403 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3404 // Mark all variables in private list clauses as used in inner region. 3405 for (Stmt *VarRef : Clause->children()) { 3406 if (auto *E = cast_or_null<Expr>(VarRef)) { 3407 MarkDeclarationsReferencedInExpr(E); 3408 } 3409 } 3410 DSAStack->setForceVarCapturing(/*V=*/false); 3411 } else if (CaptureRegions.size() > 1 || 3412 CaptureRegions.back() != OMPD_unknown) { 3413 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3414 PICs.push_back(C); 3415 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3416 if (Expr *E = C->getPostUpdateExpr()) 3417 MarkDeclarationsReferencedInExpr(E); 3418 } 3419 } 3420 if (Clause->getClauseKind() == OMPC_schedule) 3421 SC = cast<OMPScheduleClause>(Clause); 3422 else if (Clause->getClauseKind() == OMPC_ordered) 3423 OC = cast<OMPOrderedClause>(Clause); 3424 else if (Clause->getClauseKind() == OMPC_linear) 3425 LCs.push_back(cast<OMPLinearClause>(Clause)); 3426 } 3427 // OpenMP, 2.7.1 Loop Construct, Restrictions 3428 // The nonmonotonic modifier cannot be specified if an ordered clause is 3429 // specified. 3430 if (SC && 3431 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3432 SC->getSecondScheduleModifier() == 3433 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3434 OC) { 3435 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3436 ? SC->getFirstScheduleModifierLoc() 3437 : SC->getSecondScheduleModifierLoc(), 3438 diag::err_omp_schedule_nonmonotonic_ordered) 3439 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3440 ErrorFound = true; 3441 } 3442 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3443 for (const OMPLinearClause *C : LCs) { 3444 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3445 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3446 } 3447 ErrorFound = true; 3448 } 3449 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3450 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3451 OC->getNumForLoops()) { 3452 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3453 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3454 ErrorFound = true; 3455 } 3456 if (ErrorFound) { 3457 return StmtError(); 3458 } 3459 StmtResult SR = S; 3460 unsigned CompletedRegions = 0; 3461 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3462 // Mark all variables in private list clauses as used in inner region. 3463 // Required for proper codegen of combined directives. 3464 // TODO: add processing for other clauses. 3465 if (ThisCaptureRegion != OMPD_unknown) { 3466 for (const clang::OMPClauseWithPreInit *C : PICs) { 3467 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3468 // Find the particular capture region for the clause if the 3469 // directive is a combined one with multiple capture regions. 3470 // If the directive is not a combined one, the capture region 3471 // associated with the clause is OMPD_unknown and is generated 3472 // only once. 3473 if (CaptureRegion == ThisCaptureRegion || 3474 CaptureRegion == OMPD_unknown) { 3475 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3476 for (Decl *D : DS->decls()) 3477 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3478 } 3479 } 3480 } 3481 } 3482 if (++CompletedRegions == CaptureRegions.size()) 3483 DSAStack->setBodyComplete(); 3484 SR = ActOnCapturedRegionEnd(SR.get()); 3485 } 3486 return SR; 3487 } 3488 3489 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3490 OpenMPDirectiveKind CancelRegion, 3491 SourceLocation StartLoc) { 3492 // CancelRegion is only needed for cancel and cancellation_point. 3493 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3494 return false; 3495 3496 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3497 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3498 return false; 3499 3500 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3501 << getOpenMPDirectiveName(CancelRegion); 3502 return true; 3503 } 3504 3505 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3506 OpenMPDirectiveKind CurrentRegion, 3507 const DeclarationNameInfo &CurrentName, 3508 OpenMPDirectiveKind CancelRegion, 3509 SourceLocation StartLoc) { 3510 if (Stack->getCurScope()) { 3511 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3512 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3513 bool NestingProhibited = false; 3514 bool CloseNesting = true; 3515 bool OrphanSeen = false; 3516 enum { 3517 NoRecommend, 3518 ShouldBeInParallelRegion, 3519 ShouldBeInOrderedRegion, 3520 ShouldBeInTargetRegion, 3521 ShouldBeInTeamsRegion 3522 } Recommend = NoRecommend; 3523 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3524 // OpenMP [2.16, Nesting of Regions] 3525 // OpenMP constructs may not be nested inside a simd region. 3526 // OpenMP [2.8.1,simd Construct, Restrictions] 3527 // An ordered construct with the simd clause is the only OpenMP 3528 // construct that can appear in the simd region. 3529 // Allowing a SIMD construct nested in another SIMD construct is an 3530 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3531 // message. 3532 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3533 ? diag::err_omp_prohibited_region_simd 3534 : diag::warn_omp_nesting_simd); 3535 return CurrentRegion != OMPD_simd; 3536 } 3537 if (ParentRegion == OMPD_atomic) { 3538 // OpenMP [2.16, Nesting of Regions] 3539 // OpenMP constructs may not be nested inside an atomic region. 3540 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3541 return true; 3542 } 3543 if (CurrentRegion == OMPD_section) { 3544 // OpenMP [2.7.2, sections Construct, Restrictions] 3545 // Orphaned section directives are prohibited. That is, the section 3546 // directives must appear within the sections construct and must not be 3547 // encountered elsewhere in the sections region. 3548 if (ParentRegion != OMPD_sections && 3549 ParentRegion != OMPD_parallel_sections) { 3550 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3551 << (ParentRegion != OMPD_unknown) 3552 << getOpenMPDirectiveName(ParentRegion); 3553 return true; 3554 } 3555 return false; 3556 } 3557 // Allow some constructs (except teams and cancellation constructs) to be 3558 // orphaned (they could be used in functions, called from OpenMP regions 3559 // with the required preconditions). 3560 if (ParentRegion == OMPD_unknown && 3561 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3562 CurrentRegion != OMPD_cancellation_point && 3563 CurrentRegion != OMPD_cancel) 3564 return false; 3565 if (CurrentRegion == OMPD_cancellation_point || 3566 CurrentRegion == OMPD_cancel) { 3567 // OpenMP [2.16, Nesting of Regions] 3568 // A cancellation point construct for which construct-type-clause is 3569 // taskgroup must be nested inside a task construct. A cancellation 3570 // point construct for which construct-type-clause is not taskgroup must 3571 // be closely nested inside an OpenMP construct that matches the type 3572 // specified in construct-type-clause. 3573 // A cancel construct for which construct-type-clause is taskgroup must be 3574 // nested inside a task construct. A cancel construct for which 3575 // construct-type-clause is not taskgroup must be closely nested inside an 3576 // OpenMP construct that matches the type specified in 3577 // construct-type-clause. 3578 NestingProhibited = 3579 !((CancelRegion == OMPD_parallel && 3580 (ParentRegion == OMPD_parallel || 3581 ParentRegion == OMPD_target_parallel)) || 3582 (CancelRegion == OMPD_for && 3583 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3584 ParentRegion == OMPD_target_parallel_for || 3585 ParentRegion == OMPD_distribute_parallel_for || 3586 ParentRegion == OMPD_teams_distribute_parallel_for || 3587 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3588 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3589 (CancelRegion == OMPD_sections && 3590 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3591 ParentRegion == OMPD_parallel_sections))); 3592 OrphanSeen = ParentRegion == OMPD_unknown; 3593 } else if (CurrentRegion == OMPD_master) { 3594 // OpenMP [2.16, Nesting of Regions] 3595 // A master region may not be closely nested inside a worksharing, 3596 // atomic, or explicit task region. 3597 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3598 isOpenMPTaskingDirective(ParentRegion); 3599 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3600 // OpenMP [2.16, Nesting of Regions] 3601 // A critical region may not be nested (closely or otherwise) inside a 3602 // critical region with the same name. Note that this restriction is not 3603 // sufficient to prevent deadlock. 3604 SourceLocation PreviousCriticalLoc; 3605 bool DeadLock = Stack->hasDirective( 3606 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3607 const DeclarationNameInfo &DNI, 3608 SourceLocation Loc) { 3609 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3610 PreviousCriticalLoc = Loc; 3611 return true; 3612 } 3613 return false; 3614 }, 3615 false /* skip top directive */); 3616 if (DeadLock) { 3617 SemaRef.Diag(StartLoc, 3618 diag::err_omp_prohibited_region_critical_same_name) 3619 << CurrentName.getName(); 3620 if (PreviousCriticalLoc.isValid()) 3621 SemaRef.Diag(PreviousCriticalLoc, 3622 diag::note_omp_previous_critical_region); 3623 return true; 3624 } 3625 } else if (CurrentRegion == OMPD_barrier) { 3626 // OpenMP [2.16, Nesting of Regions] 3627 // A barrier region may not be closely nested inside a worksharing, 3628 // explicit task, critical, ordered, atomic, or master region. 3629 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3630 isOpenMPTaskingDirective(ParentRegion) || 3631 ParentRegion == OMPD_master || 3632 ParentRegion == OMPD_critical || 3633 ParentRegion == OMPD_ordered; 3634 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3635 !isOpenMPParallelDirective(CurrentRegion) && 3636 !isOpenMPTeamsDirective(CurrentRegion)) { 3637 // OpenMP [2.16, Nesting of Regions] 3638 // A worksharing region may not be closely nested inside a worksharing, 3639 // explicit task, critical, ordered, atomic, or master region. 3640 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3641 isOpenMPTaskingDirective(ParentRegion) || 3642 ParentRegion == OMPD_master || 3643 ParentRegion == OMPD_critical || 3644 ParentRegion == OMPD_ordered; 3645 Recommend = ShouldBeInParallelRegion; 3646 } else if (CurrentRegion == OMPD_ordered) { 3647 // OpenMP [2.16, Nesting of Regions] 3648 // An ordered region may not be closely nested inside a critical, 3649 // atomic, or explicit task region. 3650 // An ordered region must be closely nested inside a loop region (or 3651 // parallel loop region) with an ordered clause. 3652 // OpenMP [2.8.1,simd Construct, Restrictions] 3653 // An ordered construct with the simd clause is the only OpenMP construct 3654 // that can appear in the simd region. 3655 NestingProhibited = ParentRegion == OMPD_critical || 3656 isOpenMPTaskingDirective(ParentRegion) || 3657 !(isOpenMPSimdDirective(ParentRegion) || 3658 Stack->isParentOrderedRegion()); 3659 Recommend = ShouldBeInOrderedRegion; 3660 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3661 // OpenMP [2.16, Nesting of Regions] 3662 // If specified, a teams construct must be contained within a target 3663 // construct. 3664 NestingProhibited = ParentRegion != OMPD_target; 3665 OrphanSeen = ParentRegion == OMPD_unknown; 3666 Recommend = ShouldBeInTargetRegion; 3667 } 3668 if (!NestingProhibited && 3669 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3670 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3671 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3672 // OpenMP [2.16, Nesting of Regions] 3673 // distribute, parallel, parallel sections, parallel workshare, and the 3674 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3675 // constructs that can be closely nested in the teams region. 3676 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3677 !isOpenMPDistributeDirective(CurrentRegion); 3678 Recommend = ShouldBeInParallelRegion; 3679 } 3680 if (!NestingProhibited && 3681 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3682 // OpenMP 4.5 [2.17 Nesting of Regions] 3683 // The region associated with the distribute construct must be strictly 3684 // nested inside a teams region 3685 NestingProhibited = 3686 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3687 Recommend = ShouldBeInTeamsRegion; 3688 } 3689 if (!NestingProhibited && 3690 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3691 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3692 // OpenMP 4.5 [2.17 Nesting of Regions] 3693 // If a target, target update, target data, target enter data, or 3694 // target exit data construct is encountered during execution of a 3695 // target region, the behavior is unspecified. 3696 NestingProhibited = Stack->hasDirective( 3697 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3698 SourceLocation) { 3699 if (isOpenMPTargetExecutionDirective(K)) { 3700 OffendingRegion = K; 3701 return true; 3702 } 3703 return false; 3704 }, 3705 false /* don't skip top directive */); 3706 CloseNesting = false; 3707 } 3708 if (NestingProhibited) { 3709 if (OrphanSeen) { 3710 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3711 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3712 } else { 3713 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3714 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3715 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3716 } 3717 return true; 3718 } 3719 } 3720 return false; 3721 } 3722 3723 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3724 ArrayRef<OMPClause *> Clauses, 3725 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3726 bool ErrorFound = false; 3727 unsigned NamedModifiersNumber = 0; 3728 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3729 OMPD_unknown + 1); 3730 SmallVector<SourceLocation, 4> NameModifierLoc; 3731 for (const OMPClause *C : Clauses) { 3732 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3733 // At most one if clause without a directive-name-modifier can appear on 3734 // the directive. 3735 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3736 if (FoundNameModifiers[CurNM]) { 3737 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3738 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3739 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3740 ErrorFound = true; 3741 } else if (CurNM != OMPD_unknown) { 3742 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3743 ++NamedModifiersNumber; 3744 } 3745 FoundNameModifiers[CurNM] = IC; 3746 if (CurNM == OMPD_unknown) 3747 continue; 3748 // Check if the specified name modifier is allowed for the current 3749 // directive. 3750 // At most one if clause with the particular directive-name-modifier can 3751 // appear on the directive. 3752 bool MatchFound = false; 3753 for (auto NM : AllowedNameModifiers) { 3754 if (CurNM == NM) { 3755 MatchFound = true; 3756 break; 3757 } 3758 } 3759 if (!MatchFound) { 3760 S.Diag(IC->getNameModifierLoc(), 3761 diag::err_omp_wrong_if_directive_name_modifier) 3762 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3763 ErrorFound = true; 3764 } 3765 } 3766 } 3767 // If any if clause on the directive includes a directive-name-modifier then 3768 // all if clauses on the directive must include a directive-name-modifier. 3769 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3770 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3771 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3772 diag::err_omp_no_more_if_clause); 3773 } else { 3774 std::string Values; 3775 std::string Sep(", "); 3776 unsigned AllowedCnt = 0; 3777 unsigned TotalAllowedNum = 3778 AllowedNameModifiers.size() - NamedModifiersNumber; 3779 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3780 ++Cnt) { 3781 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3782 if (!FoundNameModifiers[NM]) { 3783 Values += "'"; 3784 Values += getOpenMPDirectiveName(NM); 3785 Values += "'"; 3786 if (AllowedCnt + 2 == TotalAllowedNum) 3787 Values += " or "; 3788 else if (AllowedCnt + 1 != TotalAllowedNum) 3789 Values += Sep; 3790 ++AllowedCnt; 3791 } 3792 } 3793 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3794 diag::err_omp_unnamed_if_clause) 3795 << (TotalAllowedNum > 1) << Values; 3796 } 3797 for (SourceLocation Loc : NameModifierLoc) { 3798 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3799 } 3800 ErrorFound = true; 3801 } 3802 return ErrorFound; 3803 } 3804 3805 static std::pair<ValueDecl *, bool> 3806 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 3807 SourceRange &ERange, bool AllowArraySection = false) { 3808 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 3809 RefExpr->containsUnexpandedParameterPack()) 3810 return std::make_pair(nullptr, true); 3811 3812 // OpenMP [3.1, C/C++] 3813 // A list item is a variable name. 3814 // OpenMP [2.9.3.3, Restrictions, p.1] 3815 // A variable that is part of another variable (as an array or 3816 // structure element) cannot appear in a private clause. 3817 RefExpr = RefExpr->IgnoreParens(); 3818 enum { 3819 NoArrayExpr = -1, 3820 ArraySubscript = 0, 3821 OMPArraySection = 1 3822 } IsArrayExpr = NoArrayExpr; 3823 if (AllowArraySection) { 3824 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 3825 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 3826 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3827 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3828 RefExpr = Base; 3829 IsArrayExpr = ArraySubscript; 3830 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 3831 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 3832 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 3833 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 3834 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3835 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3836 RefExpr = Base; 3837 IsArrayExpr = OMPArraySection; 3838 } 3839 } 3840 ELoc = RefExpr->getExprLoc(); 3841 ERange = RefExpr->getSourceRange(); 3842 RefExpr = RefExpr->IgnoreParenImpCasts(); 3843 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 3844 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 3845 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 3846 (S.getCurrentThisType().isNull() || !ME || 3847 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 3848 !isa<FieldDecl>(ME->getMemberDecl()))) { 3849 if (IsArrayExpr != NoArrayExpr) { 3850 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 3851 << ERange; 3852 } else { 3853 S.Diag(ELoc, 3854 AllowArraySection 3855 ? diag::err_omp_expected_var_name_member_expr_or_array_item 3856 : diag::err_omp_expected_var_name_member_expr) 3857 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 3858 } 3859 return std::make_pair(nullptr, false); 3860 } 3861 return std::make_pair( 3862 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 3863 } 3864 3865 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 3866 ArrayRef<OMPClause *> Clauses) { 3867 assert(!S.CurContext->isDependentContext() && 3868 "Expected non-dependent context."); 3869 auto AllocateRange = 3870 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 3871 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 3872 DeclToCopy; 3873 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 3874 return isOpenMPPrivate(C->getClauseKind()); 3875 }); 3876 for (OMPClause *Cl : PrivateRange) { 3877 MutableArrayRef<Expr *>::iterator I, It, Et; 3878 if (Cl->getClauseKind() == OMPC_private) { 3879 auto *PC = cast<OMPPrivateClause>(Cl); 3880 I = PC->private_copies().begin(); 3881 It = PC->varlist_begin(); 3882 Et = PC->varlist_end(); 3883 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 3884 auto *PC = cast<OMPFirstprivateClause>(Cl); 3885 I = PC->private_copies().begin(); 3886 It = PC->varlist_begin(); 3887 Et = PC->varlist_end(); 3888 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 3889 auto *PC = cast<OMPLastprivateClause>(Cl); 3890 I = PC->private_copies().begin(); 3891 It = PC->varlist_begin(); 3892 Et = PC->varlist_end(); 3893 } else if (Cl->getClauseKind() == OMPC_linear) { 3894 auto *PC = cast<OMPLinearClause>(Cl); 3895 I = PC->privates().begin(); 3896 It = PC->varlist_begin(); 3897 Et = PC->varlist_end(); 3898 } else if (Cl->getClauseKind() == OMPC_reduction) { 3899 auto *PC = cast<OMPReductionClause>(Cl); 3900 I = PC->privates().begin(); 3901 It = PC->varlist_begin(); 3902 Et = PC->varlist_end(); 3903 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 3904 auto *PC = cast<OMPTaskReductionClause>(Cl); 3905 I = PC->privates().begin(); 3906 It = PC->varlist_begin(); 3907 Et = PC->varlist_end(); 3908 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 3909 auto *PC = cast<OMPInReductionClause>(Cl); 3910 I = PC->privates().begin(); 3911 It = PC->varlist_begin(); 3912 Et = PC->varlist_end(); 3913 } else { 3914 llvm_unreachable("Expected private clause."); 3915 } 3916 for (Expr *E : llvm::make_range(It, Et)) { 3917 if (!*I) { 3918 ++I; 3919 continue; 3920 } 3921 SourceLocation ELoc; 3922 SourceRange ERange; 3923 Expr *SimpleRefExpr = E; 3924 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 3925 /*AllowArraySection=*/true); 3926 DeclToCopy.try_emplace(Res.first, 3927 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 3928 ++I; 3929 } 3930 } 3931 for (OMPClause *C : AllocateRange) { 3932 auto *AC = cast<OMPAllocateClause>(C); 3933 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3934 getAllocatorKind(S, Stack, AC->getAllocator()); 3935 // OpenMP, 2.11.4 allocate Clause, Restrictions. 3936 // For task, taskloop or target directives, allocation requests to memory 3937 // allocators with the trait access set to thread result in unspecified 3938 // behavior. 3939 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 3940 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 3941 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 3942 S.Diag(AC->getAllocator()->getExprLoc(), 3943 diag::warn_omp_allocate_thread_on_task_target_directive) 3944 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3945 } 3946 for (Expr *E : AC->varlists()) { 3947 SourceLocation ELoc; 3948 SourceRange ERange; 3949 Expr *SimpleRefExpr = E; 3950 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 3951 ValueDecl *VD = Res.first; 3952 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 3953 if (!isOpenMPPrivate(Data.CKind)) { 3954 S.Diag(E->getExprLoc(), 3955 diag::err_omp_expected_private_copy_for_allocate); 3956 continue; 3957 } 3958 VarDecl *PrivateVD = DeclToCopy[VD]; 3959 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 3960 AllocatorKind, AC->getAllocator())) 3961 continue; 3962 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 3963 E->getSourceRange()); 3964 } 3965 } 3966 } 3967 3968 StmtResult Sema::ActOnOpenMPExecutableDirective( 3969 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3970 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3971 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3972 StmtResult Res = StmtError(); 3973 // First check CancelRegion which is then used in checkNestingOfRegions. 3974 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3975 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3976 StartLoc)) 3977 return StmtError(); 3978 3979 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3980 VarsWithInheritedDSAType VarsWithInheritedDSA; 3981 bool ErrorFound = false; 3982 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3983 if (AStmt && !CurContext->isDependentContext()) { 3984 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3985 3986 // Check default data sharing attributes for referenced variables. 3987 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3988 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3989 Stmt *S = AStmt; 3990 while (--ThisCaptureLevel >= 0) 3991 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3992 DSAChecker.Visit(S); 3993 if (DSAChecker.isErrorFound()) 3994 return StmtError(); 3995 // Generate list of implicitly defined firstprivate variables. 3996 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3997 3998 SmallVector<Expr *, 4> ImplicitFirstprivates( 3999 DSAChecker.getImplicitFirstprivate().begin(), 4000 DSAChecker.getImplicitFirstprivate().end()); 4001 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4002 DSAChecker.getImplicitMap().end()); 4003 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4004 for (OMPClause *C : Clauses) { 4005 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4006 for (Expr *E : IRC->taskgroup_descriptors()) 4007 if (E) 4008 ImplicitFirstprivates.emplace_back(E); 4009 } 4010 } 4011 if (!ImplicitFirstprivates.empty()) { 4012 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4013 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4014 SourceLocation())) { 4015 ClausesWithImplicit.push_back(Implicit); 4016 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4017 ImplicitFirstprivates.size(); 4018 } else { 4019 ErrorFound = true; 4020 } 4021 } 4022 if (!ImplicitMaps.empty()) { 4023 CXXScopeSpec MapperIdScopeSpec; 4024 DeclarationNameInfo MapperId; 4025 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4026 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4027 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4028 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4029 ClausesWithImplicit.emplace_back(Implicit); 4030 ErrorFound |= 4031 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4032 } else { 4033 ErrorFound = true; 4034 } 4035 } 4036 } 4037 4038 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4039 switch (Kind) { 4040 case OMPD_parallel: 4041 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4042 EndLoc); 4043 AllowedNameModifiers.push_back(OMPD_parallel); 4044 break; 4045 case OMPD_simd: 4046 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4047 VarsWithInheritedDSA); 4048 break; 4049 case OMPD_for: 4050 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4051 VarsWithInheritedDSA); 4052 break; 4053 case OMPD_for_simd: 4054 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4055 EndLoc, VarsWithInheritedDSA); 4056 break; 4057 case OMPD_sections: 4058 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4059 EndLoc); 4060 break; 4061 case OMPD_section: 4062 assert(ClausesWithImplicit.empty() && 4063 "No clauses are allowed for 'omp section' directive"); 4064 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4065 break; 4066 case OMPD_single: 4067 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4068 EndLoc); 4069 break; 4070 case OMPD_master: 4071 assert(ClausesWithImplicit.empty() && 4072 "No clauses are allowed for 'omp master' directive"); 4073 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4074 break; 4075 case OMPD_critical: 4076 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4077 StartLoc, EndLoc); 4078 break; 4079 case OMPD_parallel_for: 4080 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4081 EndLoc, VarsWithInheritedDSA); 4082 AllowedNameModifiers.push_back(OMPD_parallel); 4083 break; 4084 case OMPD_parallel_for_simd: 4085 Res = ActOnOpenMPParallelForSimdDirective( 4086 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4087 AllowedNameModifiers.push_back(OMPD_parallel); 4088 break; 4089 case OMPD_parallel_sections: 4090 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4091 StartLoc, EndLoc); 4092 AllowedNameModifiers.push_back(OMPD_parallel); 4093 break; 4094 case OMPD_task: 4095 Res = 4096 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4097 AllowedNameModifiers.push_back(OMPD_task); 4098 break; 4099 case OMPD_taskyield: 4100 assert(ClausesWithImplicit.empty() && 4101 "No clauses are allowed for 'omp taskyield' directive"); 4102 assert(AStmt == nullptr && 4103 "No associated statement allowed for 'omp taskyield' directive"); 4104 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4105 break; 4106 case OMPD_barrier: 4107 assert(ClausesWithImplicit.empty() && 4108 "No clauses are allowed for 'omp barrier' directive"); 4109 assert(AStmt == nullptr && 4110 "No associated statement allowed for 'omp barrier' directive"); 4111 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4112 break; 4113 case OMPD_taskwait: 4114 assert(ClausesWithImplicit.empty() && 4115 "No clauses are allowed for 'omp taskwait' directive"); 4116 assert(AStmt == nullptr && 4117 "No associated statement allowed for 'omp taskwait' directive"); 4118 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4119 break; 4120 case OMPD_taskgroup: 4121 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4122 EndLoc); 4123 break; 4124 case OMPD_flush: 4125 assert(AStmt == nullptr && 4126 "No associated statement allowed for 'omp flush' directive"); 4127 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4128 break; 4129 case OMPD_ordered: 4130 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4131 EndLoc); 4132 break; 4133 case OMPD_atomic: 4134 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4135 EndLoc); 4136 break; 4137 case OMPD_teams: 4138 Res = 4139 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4140 break; 4141 case OMPD_target: 4142 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4143 EndLoc); 4144 AllowedNameModifiers.push_back(OMPD_target); 4145 break; 4146 case OMPD_target_parallel: 4147 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4148 StartLoc, EndLoc); 4149 AllowedNameModifiers.push_back(OMPD_target); 4150 AllowedNameModifiers.push_back(OMPD_parallel); 4151 break; 4152 case OMPD_target_parallel_for: 4153 Res = ActOnOpenMPTargetParallelForDirective( 4154 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4155 AllowedNameModifiers.push_back(OMPD_target); 4156 AllowedNameModifiers.push_back(OMPD_parallel); 4157 break; 4158 case OMPD_cancellation_point: 4159 assert(ClausesWithImplicit.empty() && 4160 "No clauses are allowed for 'omp cancellation point' directive"); 4161 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4162 "cancellation point' directive"); 4163 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4164 break; 4165 case OMPD_cancel: 4166 assert(AStmt == nullptr && 4167 "No associated statement allowed for 'omp cancel' directive"); 4168 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4169 CancelRegion); 4170 AllowedNameModifiers.push_back(OMPD_cancel); 4171 break; 4172 case OMPD_target_data: 4173 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4174 EndLoc); 4175 AllowedNameModifiers.push_back(OMPD_target_data); 4176 break; 4177 case OMPD_target_enter_data: 4178 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4179 EndLoc, AStmt); 4180 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4181 break; 4182 case OMPD_target_exit_data: 4183 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4184 EndLoc, AStmt); 4185 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4186 break; 4187 case OMPD_taskloop: 4188 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4189 EndLoc, VarsWithInheritedDSA); 4190 AllowedNameModifiers.push_back(OMPD_taskloop); 4191 break; 4192 case OMPD_taskloop_simd: 4193 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4194 EndLoc, VarsWithInheritedDSA); 4195 AllowedNameModifiers.push_back(OMPD_taskloop); 4196 break; 4197 case OMPD_distribute: 4198 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4199 EndLoc, VarsWithInheritedDSA); 4200 break; 4201 case OMPD_target_update: 4202 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4203 EndLoc, AStmt); 4204 AllowedNameModifiers.push_back(OMPD_target_update); 4205 break; 4206 case OMPD_distribute_parallel_for: 4207 Res = ActOnOpenMPDistributeParallelForDirective( 4208 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4209 AllowedNameModifiers.push_back(OMPD_parallel); 4210 break; 4211 case OMPD_distribute_parallel_for_simd: 4212 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4213 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4214 AllowedNameModifiers.push_back(OMPD_parallel); 4215 break; 4216 case OMPD_distribute_simd: 4217 Res = ActOnOpenMPDistributeSimdDirective( 4218 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4219 break; 4220 case OMPD_target_parallel_for_simd: 4221 Res = ActOnOpenMPTargetParallelForSimdDirective( 4222 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4223 AllowedNameModifiers.push_back(OMPD_target); 4224 AllowedNameModifiers.push_back(OMPD_parallel); 4225 break; 4226 case OMPD_target_simd: 4227 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4228 EndLoc, VarsWithInheritedDSA); 4229 AllowedNameModifiers.push_back(OMPD_target); 4230 break; 4231 case OMPD_teams_distribute: 4232 Res = ActOnOpenMPTeamsDistributeDirective( 4233 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4234 break; 4235 case OMPD_teams_distribute_simd: 4236 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4237 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4238 break; 4239 case OMPD_teams_distribute_parallel_for_simd: 4240 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4241 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4242 AllowedNameModifiers.push_back(OMPD_parallel); 4243 break; 4244 case OMPD_teams_distribute_parallel_for: 4245 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4246 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4247 AllowedNameModifiers.push_back(OMPD_parallel); 4248 break; 4249 case OMPD_target_teams: 4250 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4251 EndLoc); 4252 AllowedNameModifiers.push_back(OMPD_target); 4253 break; 4254 case OMPD_target_teams_distribute: 4255 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4256 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4257 AllowedNameModifiers.push_back(OMPD_target); 4258 break; 4259 case OMPD_target_teams_distribute_parallel_for: 4260 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4261 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4262 AllowedNameModifiers.push_back(OMPD_target); 4263 AllowedNameModifiers.push_back(OMPD_parallel); 4264 break; 4265 case OMPD_target_teams_distribute_parallel_for_simd: 4266 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4267 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4268 AllowedNameModifiers.push_back(OMPD_target); 4269 AllowedNameModifiers.push_back(OMPD_parallel); 4270 break; 4271 case OMPD_target_teams_distribute_simd: 4272 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4273 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4274 AllowedNameModifiers.push_back(OMPD_target); 4275 break; 4276 case OMPD_declare_target: 4277 case OMPD_end_declare_target: 4278 case OMPD_threadprivate: 4279 case OMPD_allocate: 4280 case OMPD_declare_reduction: 4281 case OMPD_declare_mapper: 4282 case OMPD_declare_simd: 4283 case OMPD_requires: 4284 llvm_unreachable("OpenMP Directive is not allowed"); 4285 case OMPD_unknown: 4286 llvm_unreachable("Unknown OpenMP directive"); 4287 } 4288 4289 ErrorFound = Res.isInvalid() || ErrorFound; 4290 4291 // Check variables in the clauses if default(none) was specified. 4292 if (DSAStack->getDefaultDSA() == DSA_none) { 4293 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4294 for (OMPClause *C : Clauses) { 4295 switch (C->getClauseKind()) { 4296 case OMPC_num_threads: 4297 case OMPC_dist_schedule: 4298 // Do not analyse if no parent teams directive. 4299 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4300 break; 4301 continue; 4302 case OMPC_if: 4303 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4304 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4305 break; 4306 continue; 4307 case OMPC_schedule: 4308 break; 4309 case OMPC_ordered: 4310 case OMPC_device: 4311 case OMPC_num_teams: 4312 case OMPC_thread_limit: 4313 case OMPC_priority: 4314 case OMPC_grainsize: 4315 case OMPC_num_tasks: 4316 case OMPC_hint: 4317 case OMPC_collapse: 4318 case OMPC_safelen: 4319 case OMPC_simdlen: 4320 case OMPC_final: 4321 case OMPC_default: 4322 case OMPC_proc_bind: 4323 case OMPC_private: 4324 case OMPC_firstprivate: 4325 case OMPC_lastprivate: 4326 case OMPC_shared: 4327 case OMPC_reduction: 4328 case OMPC_task_reduction: 4329 case OMPC_in_reduction: 4330 case OMPC_linear: 4331 case OMPC_aligned: 4332 case OMPC_copyin: 4333 case OMPC_copyprivate: 4334 case OMPC_nowait: 4335 case OMPC_untied: 4336 case OMPC_mergeable: 4337 case OMPC_allocate: 4338 case OMPC_read: 4339 case OMPC_write: 4340 case OMPC_update: 4341 case OMPC_capture: 4342 case OMPC_seq_cst: 4343 case OMPC_depend: 4344 case OMPC_threads: 4345 case OMPC_simd: 4346 case OMPC_map: 4347 case OMPC_nogroup: 4348 case OMPC_defaultmap: 4349 case OMPC_to: 4350 case OMPC_from: 4351 case OMPC_use_device_ptr: 4352 case OMPC_is_device_ptr: 4353 continue; 4354 case OMPC_allocator: 4355 case OMPC_flush: 4356 case OMPC_threadprivate: 4357 case OMPC_uniform: 4358 case OMPC_unknown: 4359 case OMPC_unified_address: 4360 case OMPC_unified_shared_memory: 4361 case OMPC_reverse_offload: 4362 case OMPC_dynamic_allocators: 4363 case OMPC_atomic_default_mem_order: 4364 llvm_unreachable("Unexpected clause"); 4365 } 4366 for (Stmt *CC : C->children()) { 4367 if (CC) 4368 DSAChecker.Visit(CC); 4369 } 4370 } 4371 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4372 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4373 } 4374 for (const auto &P : VarsWithInheritedDSA) { 4375 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4376 << P.first << P.second->getSourceRange(); 4377 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4378 } 4379 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 4380 4381 if (!AllowedNameModifiers.empty()) 4382 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4383 ErrorFound; 4384 4385 if (ErrorFound) 4386 return StmtError(); 4387 4388 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4389 Res.getAs<OMPExecutableDirective>() 4390 ->getStructuredBlock() 4391 ->setIsOMPStructuredBlock(true); 4392 } 4393 4394 if (!CurContext->isDependentContext() && 4395 isOpenMPTargetExecutionDirective(Kind) && 4396 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4397 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4398 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4399 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4400 // Register target to DSA Stack. 4401 DSAStack->addTargetDirLocation(StartLoc); 4402 } 4403 4404 return Res; 4405 } 4406 4407 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4408 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4409 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4410 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4411 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4412 assert(Aligneds.size() == Alignments.size()); 4413 assert(Linears.size() == LinModifiers.size()); 4414 assert(Linears.size() == Steps.size()); 4415 if (!DG || DG.get().isNull()) 4416 return DeclGroupPtrTy(); 4417 4418 if (!DG.get().isSingleDecl()) { 4419 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4420 return DG; 4421 } 4422 Decl *ADecl = DG.get().getSingleDecl(); 4423 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4424 ADecl = FTD->getTemplatedDecl(); 4425 4426 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4427 if (!FD) { 4428 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4429 return DeclGroupPtrTy(); 4430 } 4431 4432 // OpenMP [2.8.2, declare simd construct, Description] 4433 // The parameter of the simdlen clause must be a constant positive integer 4434 // expression. 4435 ExprResult SL; 4436 if (Simdlen) 4437 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4438 // OpenMP [2.8.2, declare simd construct, Description] 4439 // The special this pointer can be used as if was one of the arguments to the 4440 // function in any of the linear, aligned, or uniform clauses. 4441 // The uniform clause declares one or more arguments to have an invariant 4442 // value for all concurrent invocations of the function in the execution of a 4443 // single SIMD loop. 4444 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4445 const Expr *UniformedLinearThis = nullptr; 4446 for (const Expr *E : Uniforms) { 4447 E = E->IgnoreParenImpCasts(); 4448 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4449 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4450 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4451 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4452 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4453 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4454 continue; 4455 } 4456 if (isa<CXXThisExpr>(E)) { 4457 UniformedLinearThis = E; 4458 continue; 4459 } 4460 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4461 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4462 } 4463 // OpenMP [2.8.2, declare simd construct, Description] 4464 // The aligned clause declares that the object to which each list item points 4465 // is aligned to the number of bytes expressed in the optional parameter of 4466 // the aligned clause. 4467 // The special this pointer can be used as if was one of the arguments to the 4468 // function in any of the linear, aligned, or uniform clauses. 4469 // The type of list items appearing in the aligned clause must be array, 4470 // pointer, reference to array, or reference to pointer. 4471 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4472 const Expr *AlignedThis = nullptr; 4473 for (const Expr *E : Aligneds) { 4474 E = E->IgnoreParenImpCasts(); 4475 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4476 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4477 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4478 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4479 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4480 ->getCanonicalDecl() == CanonPVD) { 4481 // OpenMP [2.8.1, simd construct, Restrictions] 4482 // A list-item cannot appear in more than one aligned clause. 4483 if (AlignedArgs.count(CanonPVD) > 0) { 4484 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4485 << 1 << E->getSourceRange(); 4486 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4487 diag::note_omp_explicit_dsa) 4488 << getOpenMPClauseName(OMPC_aligned); 4489 continue; 4490 } 4491 AlignedArgs[CanonPVD] = E; 4492 QualType QTy = PVD->getType() 4493 .getNonReferenceType() 4494 .getUnqualifiedType() 4495 .getCanonicalType(); 4496 const Type *Ty = QTy.getTypePtrOrNull(); 4497 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4498 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4499 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4500 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4501 } 4502 continue; 4503 } 4504 } 4505 if (isa<CXXThisExpr>(E)) { 4506 if (AlignedThis) { 4507 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4508 << 2 << E->getSourceRange(); 4509 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4510 << getOpenMPClauseName(OMPC_aligned); 4511 } 4512 AlignedThis = E; 4513 continue; 4514 } 4515 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4516 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4517 } 4518 // The optional parameter of the aligned clause, alignment, must be a constant 4519 // positive integer expression. If no optional parameter is specified, 4520 // implementation-defined default alignments for SIMD instructions on the 4521 // target platforms are assumed. 4522 SmallVector<const Expr *, 4> NewAligns; 4523 for (Expr *E : Alignments) { 4524 ExprResult Align; 4525 if (E) 4526 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4527 NewAligns.push_back(Align.get()); 4528 } 4529 // OpenMP [2.8.2, declare simd construct, Description] 4530 // The linear clause declares one or more list items to be private to a SIMD 4531 // lane and to have a linear relationship with respect to the iteration space 4532 // of a loop. 4533 // The special this pointer can be used as if was one of the arguments to the 4534 // function in any of the linear, aligned, or uniform clauses. 4535 // When a linear-step expression is specified in a linear clause it must be 4536 // either a constant integer expression or an integer-typed parameter that is 4537 // specified in a uniform clause on the directive. 4538 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4539 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4540 auto MI = LinModifiers.begin(); 4541 for (const Expr *E : Linears) { 4542 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4543 ++MI; 4544 E = E->IgnoreParenImpCasts(); 4545 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4546 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4547 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4548 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4549 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4550 ->getCanonicalDecl() == CanonPVD) { 4551 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4552 // A list-item cannot appear in more than one linear clause. 4553 if (LinearArgs.count(CanonPVD) > 0) { 4554 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4555 << getOpenMPClauseName(OMPC_linear) 4556 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4557 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4558 diag::note_omp_explicit_dsa) 4559 << getOpenMPClauseName(OMPC_linear); 4560 continue; 4561 } 4562 // Each argument can appear in at most one uniform or linear clause. 4563 if (UniformedArgs.count(CanonPVD) > 0) { 4564 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4565 << getOpenMPClauseName(OMPC_linear) 4566 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4567 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4568 diag::note_omp_explicit_dsa) 4569 << getOpenMPClauseName(OMPC_uniform); 4570 continue; 4571 } 4572 LinearArgs[CanonPVD] = E; 4573 if (E->isValueDependent() || E->isTypeDependent() || 4574 E->isInstantiationDependent() || 4575 E->containsUnexpandedParameterPack()) 4576 continue; 4577 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4578 PVD->getOriginalType()); 4579 continue; 4580 } 4581 } 4582 if (isa<CXXThisExpr>(E)) { 4583 if (UniformedLinearThis) { 4584 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4585 << getOpenMPClauseName(OMPC_linear) 4586 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4587 << E->getSourceRange(); 4588 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4589 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4590 : OMPC_linear); 4591 continue; 4592 } 4593 UniformedLinearThis = E; 4594 if (E->isValueDependent() || E->isTypeDependent() || 4595 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4596 continue; 4597 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4598 E->getType()); 4599 continue; 4600 } 4601 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4602 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4603 } 4604 Expr *Step = nullptr; 4605 Expr *NewStep = nullptr; 4606 SmallVector<Expr *, 4> NewSteps; 4607 for (Expr *E : Steps) { 4608 // Skip the same step expression, it was checked already. 4609 if (Step == E || !E) { 4610 NewSteps.push_back(E ? NewStep : nullptr); 4611 continue; 4612 } 4613 Step = E; 4614 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4615 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4616 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4617 if (UniformedArgs.count(CanonPVD) == 0) { 4618 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4619 << Step->getSourceRange(); 4620 } else if (E->isValueDependent() || E->isTypeDependent() || 4621 E->isInstantiationDependent() || 4622 E->containsUnexpandedParameterPack() || 4623 CanonPVD->getType()->hasIntegerRepresentation()) { 4624 NewSteps.push_back(Step); 4625 } else { 4626 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4627 << Step->getSourceRange(); 4628 } 4629 continue; 4630 } 4631 NewStep = Step; 4632 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4633 !Step->isInstantiationDependent() && 4634 !Step->containsUnexpandedParameterPack()) { 4635 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4636 .get(); 4637 if (NewStep) 4638 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4639 } 4640 NewSteps.push_back(NewStep); 4641 } 4642 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4643 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4644 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4645 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4646 const_cast<Expr **>(Linears.data()), Linears.size(), 4647 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4648 NewSteps.data(), NewSteps.size(), SR); 4649 ADecl->addAttr(NewAttr); 4650 return ConvertDeclToDeclGroup(ADecl); 4651 } 4652 4653 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4654 Stmt *AStmt, 4655 SourceLocation StartLoc, 4656 SourceLocation EndLoc) { 4657 if (!AStmt) 4658 return StmtError(); 4659 4660 auto *CS = cast<CapturedStmt>(AStmt); 4661 // 1.2.2 OpenMP Language Terminology 4662 // Structured block - An executable statement with a single entry at the 4663 // top and a single exit at the bottom. 4664 // The point of exit cannot be a branch out of the structured block. 4665 // longjmp() and throw() must not violate the entry/exit criteria. 4666 CS->getCapturedDecl()->setNothrow(); 4667 4668 setFunctionHasBranchProtectedScope(); 4669 4670 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4671 DSAStack->isCancelRegion()); 4672 } 4673 4674 namespace { 4675 /// Helper class for checking canonical form of the OpenMP loops and 4676 /// extracting iteration space of each loop in the loop nest, that will be used 4677 /// for IR generation. 4678 class OpenMPIterationSpaceChecker { 4679 /// Reference to Sema. 4680 Sema &SemaRef; 4681 /// Data-sharing stack. 4682 DSAStackTy &Stack; 4683 /// A location for diagnostics (when there is no some better location). 4684 SourceLocation DefaultLoc; 4685 /// A location for diagnostics (when increment is not compatible). 4686 SourceLocation ConditionLoc; 4687 /// A source location for referring to loop init later. 4688 SourceRange InitSrcRange; 4689 /// A source location for referring to condition later. 4690 SourceRange ConditionSrcRange; 4691 /// A source location for referring to increment later. 4692 SourceRange IncrementSrcRange; 4693 /// Loop variable. 4694 ValueDecl *LCDecl = nullptr; 4695 /// Reference to loop variable. 4696 Expr *LCRef = nullptr; 4697 /// Lower bound (initializer for the var). 4698 Expr *LB = nullptr; 4699 /// Upper bound. 4700 Expr *UB = nullptr; 4701 /// Loop step (increment). 4702 Expr *Step = nullptr; 4703 /// This flag is true when condition is one of: 4704 /// Var < UB 4705 /// Var <= UB 4706 /// UB > Var 4707 /// UB >= Var 4708 /// This will have no value when the condition is != 4709 llvm::Optional<bool> TestIsLessOp; 4710 /// This flag is true when condition is strict ( < or > ). 4711 bool TestIsStrictOp = false; 4712 /// This flag is true when step is subtracted on each iteration. 4713 bool SubtractStep = false; 4714 /// The outer loop counter this loop depends on (if any). 4715 const ValueDecl *DepDecl = nullptr; 4716 /// Contains number of loop (starts from 1) on which loop counter init 4717 /// expression of this loop depends on. 4718 Optional<unsigned> InitDependOnLC; 4719 /// Contains number of loop (starts from 1) on which loop counter condition 4720 /// expression of this loop depends on. 4721 Optional<unsigned> CondDependOnLC; 4722 /// Checks if the provide statement depends on the loop counter. 4723 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 4724 4725 public: 4726 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 4727 SourceLocation DefaultLoc) 4728 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 4729 ConditionLoc(DefaultLoc) {} 4730 /// Check init-expr for canonical loop form and save loop counter 4731 /// variable - #Var and its initialization value - #LB. 4732 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4733 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4734 /// for less/greater and for strict/non-strict comparison. 4735 bool checkAndSetCond(Expr *S); 4736 /// Check incr-expr for canonical loop form and return true if it 4737 /// does not conform, otherwise save loop step (#Step). 4738 bool checkAndSetInc(Expr *S); 4739 /// Return the loop counter variable. 4740 ValueDecl *getLoopDecl() const { return LCDecl; } 4741 /// Return the reference expression to loop counter variable. 4742 Expr *getLoopDeclRefExpr() const { return LCRef; } 4743 /// Source range of the loop init. 4744 SourceRange getInitSrcRange() const { return InitSrcRange; } 4745 /// Source range of the loop condition. 4746 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4747 /// Source range of the loop increment. 4748 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4749 /// True if the step should be subtracted. 4750 bool shouldSubtractStep() const { return SubtractStep; } 4751 /// True, if the compare operator is strict (<, > or !=). 4752 bool isStrictTestOp() const { return TestIsStrictOp; } 4753 /// Build the expression to calculate the number of iterations. 4754 Expr *buildNumIterations( 4755 Scope *S, const bool LimitedType, 4756 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4757 /// Build the precondition expression for the loops. 4758 Expr * 4759 buildPreCond(Scope *S, Expr *Cond, 4760 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4761 /// Build reference expression to the counter be used for codegen. 4762 DeclRefExpr * 4763 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4764 DSAStackTy &DSA) const; 4765 /// Build reference expression to the private counter be used for 4766 /// codegen. 4767 Expr *buildPrivateCounterVar() const; 4768 /// Build initialization of the counter be used for codegen. 4769 Expr *buildCounterInit() const; 4770 /// Build step of the counter be used for codegen. 4771 Expr *buildCounterStep() const; 4772 /// Build loop data with counter value for depend clauses in ordered 4773 /// directives. 4774 Expr * 4775 buildOrderedLoopData(Scope *S, Expr *Counter, 4776 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4777 SourceLocation Loc, Expr *Inc = nullptr, 4778 OverloadedOperatorKind OOK = OO_Amp); 4779 /// Return true if any expression is dependent. 4780 bool dependent() const; 4781 4782 private: 4783 /// Check the right-hand side of an assignment in the increment 4784 /// expression. 4785 bool checkAndSetIncRHS(Expr *RHS); 4786 /// Helper to set loop counter variable and its initializer. 4787 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 4788 bool EmitDiags); 4789 /// Helper to set upper bound. 4790 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4791 SourceRange SR, SourceLocation SL); 4792 /// Helper to set loop increment. 4793 bool setStep(Expr *NewStep, bool Subtract); 4794 }; 4795 4796 bool OpenMPIterationSpaceChecker::dependent() const { 4797 if (!LCDecl) { 4798 assert(!LB && !UB && !Step); 4799 return false; 4800 } 4801 return LCDecl->getType()->isDependentType() || 4802 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4803 (Step && Step->isValueDependent()); 4804 } 4805 4806 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4807 Expr *NewLCRefExpr, 4808 Expr *NewLB, bool EmitDiags) { 4809 // State consistency checking to ensure correct usage. 4810 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4811 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4812 if (!NewLCDecl || !NewLB) 4813 return true; 4814 LCDecl = getCanonicalDecl(NewLCDecl); 4815 LCRef = NewLCRefExpr; 4816 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4817 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4818 if ((Ctor->isCopyOrMoveConstructor() || 4819 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4820 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4821 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4822 LB = NewLB; 4823 if (EmitDiags) 4824 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 4825 return false; 4826 } 4827 4828 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4829 llvm::Optional<bool> LessOp, 4830 bool StrictOp, SourceRange SR, 4831 SourceLocation SL) { 4832 // State consistency checking to ensure correct usage. 4833 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4834 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4835 if (!NewUB) 4836 return true; 4837 UB = NewUB; 4838 if (LessOp) 4839 TestIsLessOp = LessOp; 4840 TestIsStrictOp = StrictOp; 4841 ConditionSrcRange = SR; 4842 ConditionLoc = SL; 4843 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 4844 return false; 4845 } 4846 4847 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4848 // State consistency checking to ensure correct usage. 4849 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4850 if (!NewStep) 4851 return true; 4852 if (!NewStep->isValueDependent()) { 4853 // Check that the step is integer expression. 4854 SourceLocation StepLoc = NewStep->getBeginLoc(); 4855 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4856 StepLoc, getExprAsWritten(NewStep)); 4857 if (Val.isInvalid()) 4858 return true; 4859 NewStep = Val.get(); 4860 4861 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4862 // If test-expr is of form var relational-op b and relational-op is < or 4863 // <= then incr-expr must cause var to increase on each iteration of the 4864 // loop. If test-expr is of form var relational-op b and relational-op is 4865 // > or >= then incr-expr must cause var to decrease on each iteration of 4866 // the loop. 4867 // If test-expr is of form b relational-op var and relational-op is < or 4868 // <= then incr-expr must cause var to decrease on each iteration of the 4869 // loop. If test-expr is of form b relational-op var and relational-op is 4870 // > or >= then incr-expr must cause var to increase on each iteration of 4871 // the loop. 4872 llvm::APSInt Result; 4873 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4874 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4875 bool IsConstNeg = 4876 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4877 bool IsConstPos = 4878 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4879 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4880 4881 // != with increment is treated as <; != with decrement is treated as > 4882 if (!TestIsLessOp.hasValue()) 4883 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4884 if (UB && (IsConstZero || 4885 (TestIsLessOp.getValue() ? 4886 (IsConstNeg || (IsUnsigned && Subtract)) : 4887 (IsConstPos || (IsUnsigned && !Subtract))))) { 4888 SemaRef.Diag(NewStep->getExprLoc(), 4889 diag::err_omp_loop_incr_not_compatible) 4890 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4891 SemaRef.Diag(ConditionLoc, 4892 diag::note_omp_loop_cond_requres_compatible_incr) 4893 << TestIsLessOp.getValue() << ConditionSrcRange; 4894 return true; 4895 } 4896 if (TestIsLessOp.getValue() == Subtract) { 4897 NewStep = 4898 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4899 .get(); 4900 Subtract = !Subtract; 4901 } 4902 } 4903 4904 Step = NewStep; 4905 SubtractStep = Subtract; 4906 return false; 4907 } 4908 4909 namespace { 4910 /// Checker for the non-rectangular loops. Checks if the initializer or 4911 /// condition expression references loop counter variable. 4912 class LoopCounterRefChecker final 4913 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 4914 Sema &SemaRef; 4915 DSAStackTy &Stack; 4916 const ValueDecl *CurLCDecl = nullptr; 4917 const ValueDecl *DepDecl = nullptr; 4918 const ValueDecl *PrevDepDecl = nullptr; 4919 bool IsInitializer = true; 4920 unsigned BaseLoopId = 0; 4921 bool checkDecl(const Expr *E, const ValueDecl *VD) { 4922 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 4923 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 4924 << (IsInitializer ? 0 : 1); 4925 return false; 4926 } 4927 const auto &&Data = Stack.isLoopControlVariable(VD); 4928 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 4929 // The type of the loop iterator on which we depend may not have a random 4930 // access iterator type. 4931 if (Data.first && VD->getType()->isRecordType()) { 4932 SmallString<128> Name; 4933 llvm::raw_svector_ostream OS(Name); 4934 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4935 /*Qualified=*/true); 4936 SemaRef.Diag(E->getExprLoc(), 4937 diag::err_omp_wrong_dependency_iterator_type) 4938 << OS.str(); 4939 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 4940 return false; 4941 } 4942 if (Data.first && 4943 (DepDecl || (PrevDepDecl && 4944 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 4945 if (!DepDecl && PrevDepDecl) 4946 DepDecl = PrevDepDecl; 4947 SmallString<128> Name; 4948 llvm::raw_svector_ostream OS(Name); 4949 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4950 /*Qualified=*/true); 4951 SemaRef.Diag(E->getExprLoc(), 4952 diag::err_omp_invariant_or_linear_dependency) 4953 << OS.str(); 4954 return false; 4955 } 4956 if (Data.first) { 4957 DepDecl = VD; 4958 BaseLoopId = Data.first; 4959 } 4960 return Data.first; 4961 } 4962 4963 public: 4964 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4965 const ValueDecl *VD = E->getDecl(); 4966 if (isa<VarDecl>(VD)) 4967 return checkDecl(E, VD); 4968 return false; 4969 } 4970 bool VisitMemberExpr(const MemberExpr *E) { 4971 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 4972 const ValueDecl *VD = E->getMemberDecl(); 4973 return checkDecl(E, VD); 4974 } 4975 return false; 4976 } 4977 bool VisitStmt(const Stmt *S) { 4978 bool Res = true; 4979 for (const Stmt *Child : S->children()) 4980 Res = Child && Visit(Child) && Res; 4981 return Res; 4982 } 4983 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 4984 const ValueDecl *CurLCDecl, bool IsInitializer, 4985 const ValueDecl *PrevDepDecl = nullptr) 4986 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 4987 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 4988 unsigned getBaseLoopId() const { 4989 assert(CurLCDecl && "Expected loop dependency."); 4990 return BaseLoopId; 4991 } 4992 const ValueDecl *getDepDecl() const { 4993 assert(CurLCDecl && "Expected loop dependency."); 4994 return DepDecl; 4995 } 4996 }; 4997 } // namespace 4998 4999 Optional<unsigned> 5000 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5001 bool IsInitializer) { 5002 // Check for the non-rectangular loops. 5003 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5004 DepDecl); 5005 if (LoopStmtChecker.Visit(S)) { 5006 DepDecl = LoopStmtChecker.getDepDecl(); 5007 return LoopStmtChecker.getBaseLoopId(); 5008 } 5009 return llvm::None; 5010 } 5011 5012 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5013 // Check init-expr for canonical loop form and save loop counter 5014 // variable - #Var and its initialization value - #LB. 5015 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5016 // var = lb 5017 // integer-type var = lb 5018 // random-access-iterator-type var = lb 5019 // pointer-type var = lb 5020 // 5021 if (!S) { 5022 if (EmitDiags) { 5023 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5024 } 5025 return true; 5026 } 5027 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5028 if (!ExprTemp->cleanupsHaveSideEffects()) 5029 S = ExprTemp->getSubExpr(); 5030 5031 InitSrcRange = S->getSourceRange(); 5032 if (Expr *E = dyn_cast<Expr>(S)) 5033 S = E->IgnoreParens(); 5034 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5035 if (BO->getOpcode() == BO_Assign) { 5036 Expr *LHS = BO->getLHS()->IgnoreParens(); 5037 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5038 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5039 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5040 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5041 EmitDiags); 5042 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5043 } 5044 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5045 if (ME->isArrow() && 5046 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5047 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5048 EmitDiags); 5049 } 5050 } 5051 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5052 if (DS->isSingleDecl()) { 5053 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5054 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5055 // Accept non-canonical init form here but emit ext. warning. 5056 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5057 SemaRef.Diag(S->getBeginLoc(), 5058 diag::ext_omp_loop_not_canonical_init) 5059 << S->getSourceRange(); 5060 return setLCDeclAndLB( 5061 Var, 5062 buildDeclRefExpr(SemaRef, Var, 5063 Var->getType().getNonReferenceType(), 5064 DS->getBeginLoc()), 5065 Var->getInit(), EmitDiags); 5066 } 5067 } 5068 } 5069 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5070 if (CE->getOperator() == OO_Equal) { 5071 Expr *LHS = CE->getArg(0); 5072 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5073 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5074 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5075 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5076 EmitDiags); 5077 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5078 } 5079 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5080 if (ME->isArrow() && 5081 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5082 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5083 EmitDiags); 5084 } 5085 } 5086 } 5087 5088 if (dependent() || SemaRef.CurContext->isDependentContext()) 5089 return false; 5090 if (EmitDiags) { 5091 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5092 << S->getSourceRange(); 5093 } 5094 return true; 5095 } 5096 5097 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5098 /// variable (which may be the loop variable) if possible. 5099 static const ValueDecl *getInitLCDecl(const Expr *E) { 5100 if (!E) 5101 return nullptr; 5102 E = getExprAsWritten(E); 5103 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5104 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5105 if ((Ctor->isCopyOrMoveConstructor() || 5106 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5107 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5108 E = CE->getArg(0)->IgnoreParenImpCasts(); 5109 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5110 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5111 return getCanonicalDecl(VD); 5112 } 5113 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5114 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5115 return getCanonicalDecl(ME->getMemberDecl()); 5116 return nullptr; 5117 } 5118 5119 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5120 // Check test-expr for canonical form, save upper-bound UB, flags for 5121 // less/greater and for strict/non-strict comparison. 5122 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5123 // var relational-op b 5124 // b relational-op var 5125 // 5126 if (!S) { 5127 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 5128 return true; 5129 } 5130 S = getExprAsWritten(S); 5131 SourceLocation CondLoc = S->getBeginLoc(); 5132 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5133 if (BO->isRelationalOp()) { 5134 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5135 return setUB(BO->getRHS(), 5136 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5137 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5138 BO->getSourceRange(), BO->getOperatorLoc()); 5139 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5140 return setUB(BO->getLHS(), 5141 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5142 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5143 BO->getSourceRange(), BO->getOperatorLoc()); 5144 } else if (BO->getOpcode() == BO_NE) 5145 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 5146 BO->getRHS() : BO->getLHS(), 5147 /*LessOp=*/llvm::None, 5148 /*StrictOp=*/true, 5149 BO->getSourceRange(), BO->getOperatorLoc()); 5150 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5151 if (CE->getNumArgs() == 2) { 5152 auto Op = CE->getOperator(); 5153 switch (Op) { 5154 case OO_Greater: 5155 case OO_GreaterEqual: 5156 case OO_Less: 5157 case OO_LessEqual: 5158 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5159 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5160 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5161 CE->getOperatorLoc()); 5162 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5163 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5164 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5165 CE->getOperatorLoc()); 5166 break; 5167 case OO_ExclaimEqual: 5168 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 5169 CE->getArg(1) : CE->getArg(0), 5170 /*LessOp=*/llvm::None, 5171 /*StrictOp=*/true, 5172 CE->getSourceRange(), 5173 CE->getOperatorLoc()); 5174 break; 5175 default: 5176 break; 5177 } 5178 } 5179 } 5180 if (dependent() || SemaRef.CurContext->isDependentContext()) 5181 return false; 5182 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5183 << S->getSourceRange() << LCDecl; 5184 return true; 5185 } 5186 5187 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5188 // RHS of canonical loop form increment can be: 5189 // var + incr 5190 // incr + var 5191 // var - incr 5192 // 5193 RHS = RHS->IgnoreParenImpCasts(); 5194 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5195 if (BO->isAdditiveOp()) { 5196 bool IsAdd = BO->getOpcode() == BO_Add; 5197 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5198 return setStep(BO->getRHS(), !IsAdd); 5199 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5200 return setStep(BO->getLHS(), /*Subtract=*/false); 5201 } 5202 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5203 bool IsAdd = CE->getOperator() == OO_Plus; 5204 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5205 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5206 return setStep(CE->getArg(1), !IsAdd); 5207 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5208 return setStep(CE->getArg(0), /*Subtract=*/false); 5209 } 5210 } 5211 if (dependent() || SemaRef.CurContext->isDependentContext()) 5212 return false; 5213 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5214 << RHS->getSourceRange() << LCDecl; 5215 return true; 5216 } 5217 5218 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5219 // Check incr-expr for canonical loop form and return true if it 5220 // does not conform. 5221 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5222 // ++var 5223 // var++ 5224 // --var 5225 // var-- 5226 // var += incr 5227 // var -= incr 5228 // var = var + incr 5229 // var = incr + var 5230 // var = var - incr 5231 // 5232 if (!S) { 5233 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5234 return true; 5235 } 5236 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5237 if (!ExprTemp->cleanupsHaveSideEffects()) 5238 S = ExprTemp->getSubExpr(); 5239 5240 IncrementSrcRange = S->getSourceRange(); 5241 S = S->IgnoreParens(); 5242 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5243 if (UO->isIncrementDecrementOp() && 5244 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5245 return setStep(SemaRef 5246 .ActOnIntegerConstant(UO->getBeginLoc(), 5247 (UO->isDecrementOp() ? -1 : 1)) 5248 .get(), 5249 /*Subtract=*/false); 5250 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5251 switch (BO->getOpcode()) { 5252 case BO_AddAssign: 5253 case BO_SubAssign: 5254 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5255 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5256 break; 5257 case BO_Assign: 5258 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5259 return checkAndSetIncRHS(BO->getRHS()); 5260 break; 5261 default: 5262 break; 5263 } 5264 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5265 switch (CE->getOperator()) { 5266 case OO_PlusPlus: 5267 case OO_MinusMinus: 5268 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5269 return setStep(SemaRef 5270 .ActOnIntegerConstant( 5271 CE->getBeginLoc(), 5272 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5273 .get(), 5274 /*Subtract=*/false); 5275 break; 5276 case OO_PlusEqual: 5277 case OO_MinusEqual: 5278 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5279 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5280 break; 5281 case OO_Equal: 5282 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5283 return checkAndSetIncRHS(CE->getArg(1)); 5284 break; 5285 default: 5286 break; 5287 } 5288 } 5289 if (dependent() || SemaRef.CurContext->isDependentContext()) 5290 return false; 5291 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5292 << S->getSourceRange() << LCDecl; 5293 return true; 5294 } 5295 5296 static ExprResult 5297 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5298 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5299 if (SemaRef.CurContext->isDependentContext()) 5300 return ExprResult(Capture); 5301 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5302 return SemaRef.PerformImplicitConversion( 5303 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5304 /*AllowExplicit=*/true); 5305 auto I = Captures.find(Capture); 5306 if (I != Captures.end()) 5307 return buildCapture(SemaRef, Capture, I->second); 5308 DeclRefExpr *Ref = nullptr; 5309 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5310 Captures[Capture] = Ref; 5311 return Res; 5312 } 5313 5314 /// Build the expression to calculate the number of iterations. 5315 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5316 Scope *S, const bool LimitedType, 5317 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5318 ExprResult Diff; 5319 QualType VarType = LCDecl->getType().getNonReferenceType(); 5320 if (VarType->isIntegerType() || VarType->isPointerType() || 5321 SemaRef.getLangOpts().CPlusPlus) { 5322 // Upper - Lower 5323 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5324 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5325 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5326 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5327 if (!Upper || !Lower) 5328 return nullptr; 5329 5330 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5331 5332 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5333 // BuildBinOp already emitted error, this one is to point user to upper 5334 // and lower bound, and to tell what is passed to 'operator-'. 5335 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5336 << Upper->getSourceRange() << Lower->getSourceRange(); 5337 return nullptr; 5338 } 5339 } 5340 5341 if (!Diff.isUsable()) 5342 return nullptr; 5343 5344 // Upper - Lower [- 1] 5345 if (TestIsStrictOp) 5346 Diff = SemaRef.BuildBinOp( 5347 S, DefaultLoc, BO_Sub, Diff.get(), 5348 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5349 if (!Diff.isUsable()) 5350 return nullptr; 5351 5352 // Upper - Lower [- 1] + Step 5353 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5354 if (!NewStep.isUsable()) 5355 return nullptr; 5356 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5357 if (!Diff.isUsable()) 5358 return nullptr; 5359 5360 // Parentheses (for dumping/debugging purposes only). 5361 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5362 if (!Diff.isUsable()) 5363 return nullptr; 5364 5365 // (Upper - Lower [- 1] + Step) / Step 5366 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5367 if (!Diff.isUsable()) 5368 return nullptr; 5369 5370 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5371 QualType Type = Diff.get()->getType(); 5372 ASTContext &C = SemaRef.Context; 5373 bool UseVarType = VarType->hasIntegerRepresentation() && 5374 C.getTypeSize(Type) > C.getTypeSize(VarType); 5375 if (!Type->isIntegerType() || UseVarType) { 5376 unsigned NewSize = 5377 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5378 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5379 : Type->hasSignedIntegerRepresentation(); 5380 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5381 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5382 Diff = SemaRef.PerformImplicitConversion( 5383 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5384 if (!Diff.isUsable()) 5385 return nullptr; 5386 } 5387 } 5388 if (LimitedType) { 5389 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5390 if (NewSize != C.getTypeSize(Type)) { 5391 if (NewSize < C.getTypeSize(Type)) { 5392 assert(NewSize == 64 && "incorrect loop var size"); 5393 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5394 << InitSrcRange << ConditionSrcRange; 5395 } 5396 QualType NewType = C.getIntTypeForBitwidth( 5397 NewSize, Type->hasSignedIntegerRepresentation() || 5398 C.getTypeSize(Type) < NewSize); 5399 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5400 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5401 Sema::AA_Converting, true); 5402 if (!Diff.isUsable()) 5403 return nullptr; 5404 } 5405 } 5406 } 5407 5408 return Diff.get(); 5409 } 5410 5411 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5412 Scope *S, Expr *Cond, 5413 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5414 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5415 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5416 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5417 5418 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 5419 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 5420 if (!NewLB.isUsable() || !NewUB.isUsable()) 5421 return nullptr; 5422 5423 ExprResult CondExpr = 5424 SemaRef.BuildBinOp(S, DefaultLoc, 5425 TestIsLessOp.getValue() ? 5426 (TestIsStrictOp ? BO_LT : BO_LE) : 5427 (TestIsStrictOp ? BO_GT : BO_GE), 5428 NewLB.get(), NewUB.get()); 5429 if (CondExpr.isUsable()) { 5430 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 5431 SemaRef.Context.BoolTy)) 5432 CondExpr = SemaRef.PerformImplicitConversion( 5433 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 5434 /*AllowExplicit=*/true); 5435 } 5436 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5437 // Otherwise use original loop condition and evaluate it in runtime. 5438 return CondExpr.isUsable() ? CondExpr.get() : Cond; 5439 } 5440 5441 /// Build reference expression to the counter be used for codegen. 5442 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 5443 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5444 DSAStackTy &DSA) const { 5445 auto *VD = dyn_cast<VarDecl>(LCDecl); 5446 if (!VD) { 5447 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 5448 DeclRefExpr *Ref = buildDeclRefExpr( 5449 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 5450 const DSAStackTy::DSAVarData Data = 5451 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 5452 // If the loop control decl is explicitly marked as private, do not mark it 5453 // as captured again. 5454 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 5455 Captures.insert(std::make_pair(LCRef, Ref)); 5456 return Ref; 5457 } 5458 return cast<DeclRefExpr>(LCRef); 5459 } 5460 5461 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 5462 if (LCDecl && !LCDecl->isInvalidDecl()) { 5463 QualType Type = LCDecl->getType().getNonReferenceType(); 5464 VarDecl *PrivateVar = buildVarDecl( 5465 SemaRef, DefaultLoc, Type, LCDecl->getName(), 5466 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 5467 isa<VarDecl>(LCDecl) 5468 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 5469 : nullptr); 5470 if (PrivateVar->isInvalidDecl()) 5471 return nullptr; 5472 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 5473 } 5474 return nullptr; 5475 } 5476 5477 /// Build initialization of the counter to be used for codegen. 5478 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 5479 5480 /// Build step of the counter be used for codegen. 5481 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 5482 5483 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 5484 Scope *S, Expr *Counter, 5485 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 5486 Expr *Inc, OverloadedOperatorKind OOK) { 5487 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 5488 if (!Cnt) 5489 return nullptr; 5490 if (Inc) { 5491 assert((OOK == OO_Plus || OOK == OO_Minus) && 5492 "Expected only + or - operations for depend clauses."); 5493 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 5494 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 5495 if (!Cnt) 5496 return nullptr; 5497 } 5498 ExprResult Diff; 5499 QualType VarType = LCDecl->getType().getNonReferenceType(); 5500 if (VarType->isIntegerType() || VarType->isPointerType() || 5501 SemaRef.getLangOpts().CPlusPlus) { 5502 // Upper - Lower 5503 Expr *Upper = TestIsLessOp.getValue() 5504 ? Cnt 5505 : tryBuildCapture(SemaRef, UB, Captures).get(); 5506 Expr *Lower = TestIsLessOp.getValue() 5507 ? tryBuildCapture(SemaRef, LB, Captures).get() 5508 : Cnt; 5509 if (!Upper || !Lower) 5510 return nullptr; 5511 5512 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5513 5514 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5515 // BuildBinOp already emitted error, this one is to point user to upper 5516 // and lower bound, and to tell what is passed to 'operator-'. 5517 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5518 << Upper->getSourceRange() << Lower->getSourceRange(); 5519 return nullptr; 5520 } 5521 } 5522 5523 if (!Diff.isUsable()) 5524 return nullptr; 5525 5526 // Parentheses (for dumping/debugging purposes only). 5527 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5528 if (!Diff.isUsable()) 5529 return nullptr; 5530 5531 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5532 if (!NewStep.isUsable()) 5533 return nullptr; 5534 // (Upper - Lower) / Step 5535 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5536 if (!Diff.isUsable()) 5537 return nullptr; 5538 5539 return Diff.get(); 5540 } 5541 5542 /// Iteration space of a single for loop. 5543 struct LoopIterationSpace final { 5544 /// True if the condition operator is the strict compare operator (<, > or 5545 /// !=). 5546 bool IsStrictCompare = false; 5547 /// Condition of the loop. 5548 Expr *PreCond = nullptr; 5549 /// This expression calculates the number of iterations in the loop. 5550 /// It is always possible to calculate it before starting the loop. 5551 Expr *NumIterations = nullptr; 5552 /// The loop counter variable. 5553 Expr *CounterVar = nullptr; 5554 /// Private loop counter variable. 5555 Expr *PrivateCounterVar = nullptr; 5556 /// This is initializer for the initial value of #CounterVar. 5557 Expr *CounterInit = nullptr; 5558 /// This is step for the #CounterVar used to generate its update: 5559 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5560 Expr *CounterStep = nullptr; 5561 /// Should step be subtracted? 5562 bool Subtract = false; 5563 /// Source range of the loop init. 5564 SourceRange InitSrcRange; 5565 /// Source range of the loop condition. 5566 SourceRange CondSrcRange; 5567 /// Source range of the loop increment. 5568 SourceRange IncSrcRange; 5569 }; 5570 5571 } // namespace 5572 5573 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5574 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5575 assert(Init && "Expected loop in canonical form."); 5576 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5577 if (AssociatedLoops > 0 && 5578 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5579 DSAStack->loopStart(); 5580 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 5581 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5582 if (ValueDecl *D = ISC.getLoopDecl()) { 5583 auto *VD = dyn_cast<VarDecl>(D); 5584 if (!VD) { 5585 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5586 VD = Private; 5587 } else { 5588 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5589 /*WithInit=*/false); 5590 VD = cast<VarDecl>(Ref->getDecl()); 5591 } 5592 } 5593 DSAStack->addLoopControlVariable(D, VD); 5594 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5595 if (LD != D->getCanonicalDecl()) { 5596 DSAStack->resetPossibleLoopCounter(); 5597 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5598 MarkDeclarationsReferencedInExpr( 5599 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5600 Var->getType().getNonLValueExprType(Context), 5601 ForLoc, /*RefersToCapture=*/true)); 5602 } 5603 } 5604 } 5605 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 5606 } 5607 } 5608 5609 /// Called on a for stmt to check and extract its iteration space 5610 /// for further processing (such as collapsing). 5611 static bool checkOpenMPIterationSpace( 5612 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 5613 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 5614 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 5615 Expr *OrderedLoopCountExpr, 5616 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5617 LoopIterationSpace &ResultIterSpace, 5618 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5619 // OpenMP [2.6, Canonical Loop Form] 5620 // for (init-expr; test-expr; incr-expr) structured-block 5621 auto *For = dyn_cast_or_null<ForStmt>(S); 5622 if (!For) { 5623 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 5624 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 5625 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 5626 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 5627 if (TotalNestedLoopCount > 1) { 5628 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 5629 SemaRef.Diag(DSA.getConstructLoc(), 5630 diag::note_omp_collapse_ordered_expr) 5631 << 2 << CollapseLoopCountExpr->getSourceRange() 5632 << OrderedLoopCountExpr->getSourceRange(); 5633 else if (CollapseLoopCountExpr) 5634 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5635 diag::note_omp_collapse_ordered_expr) 5636 << 0 << CollapseLoopCountExpr->getSourceRange(); 5637 else 5638 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5639 diag::note_omp_collapse_ordered_expr) 5640 << 1 << OrderedLoopCountExpr->getSourceRange(); 5641 } 5642 return true; 5643 } 5644 assert(For->getBody()); 5645 5646 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 5647 5648 // Check init. 5649 Stmt *Init = For->getInit(); 5650 if (ISC.checkAndSetInit(Init)) 5651 return true; 5652 5653 bool HasErrors = false; 5654 5655 // Check loop variable's type. 5656 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 5657 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5658 5659 // OpenMP [2.6, Canonical Loop Form] 5660 // Var is one of the following: 5661 // A variable of signed or unsigned integer type. 5662 // For C++, a variable of a random access iterator type. 5663 // For C, a variable of a pointer type. 5664 QualType VarType = LCDecl->getType().getNonReferenceType(); 5665 if (!VarType->isDependentType() && !VarType->isIntegerType() && 5666 !VarType->isPointerType() && 5667 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 5668 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 5669 << SemaRef.getLangOpts().CPlusPlus; 5670 HasErrors = true; 5671 } 5672 5673 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 5674 // a Construct 5675 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5676 // parallel for construct is (are) private. 5677 // The loop iteration variable in the associated for-loop of a simd 5678 // construct with just one associated for-loop is linear with a 5679 // constant-linear-step that is the increment of the associated for-loop. 5680 // Exclude loop var from the list of variables with implicitly defined data 5681 // sharing attributes. 5682 VarsWithImplicitDSA.erase(LCDecl); 5683 5684 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5685 // in a Construct, C/C++]. 5686 // The loop iteration variable in the associated for-loop of a simd 5687 // construct with just one associated for-loop may be listed in a linear 5688 // clause with a constant-linear-step that is the increment of the 5689 // associated for-loop. 5690 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5691 // parallel for construct may be listed in a private or lastprivate clause. 5692 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 5693 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 5694 // declared in the loop and it is predetermined as a private. 5695 OpenMPClauseKind PredeterminedCKind = 5696 isOpenMPSimdDirective(DKind) 5697 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5698 : OMPC_private; 5699 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5700 DVar.CKind != PredeterminedCKind) || 5701 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5702 isOpenMPDistributeDirective(DKind)) && 5703 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5704 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5705 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5706 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5707 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5708 << getOpenMPClauseName(PredeterminedCKind); 5709 if (DVar.RefExpr == nullptr) 5710 DVar.CKind = PredeterminedCKind; 5711 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5712 HasErrors = true; 5713 } else if (LoopDeclRefExpr != nullptr) { 5714 // Make the loop iteration variable private (for worksharing constructs), 5715 // linear (for simd directives with the only one associated loop) or 5716 // lastprivate (for simd directives with several collapsed or ordered 5717 // loops). 5718 if (DVar.CKind == OMPC_unknown) 5719 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5720 } 5721 5722 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5723 5724 // Check test-expr. 5725 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5726 5727 // Check incr-expr. 5728 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5729 } 5730 5731 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5732 return HasErrors; 5733 5734 // Build the loop's iteration space representation. 5735 ResultIterSpace.PreCond = 5736 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5737 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5738 DSA.getCurScope(), 5739 (isOpenMPWorksharingDirective(DKind) || 5740 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5741 Captures); 5742 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5743 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5744 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5745 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5746 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5747 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5748 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5749 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5750 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5751 5752 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5753 ResultIterSpace.NumIterations == nullptr || 5754 ResultIterSpace.CounterVar == nullptr || 5755 ResultIterSpace.PrivateCounterVar == nullptr || 5756 ResultIterSpace.CounterInit == nullptr || 5757 ResultIterSpace.CounterStep == nullptr); 5758 if (!HasErrors && DSA.isOrderedRegion()) { 5759 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5760 if (CurrentNestedLoopCount < 5761 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5762 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5763 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5764 DSA.getOrderedRegionParam().second->setLoopCounter( 5765 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5766 } 5767 } 5768 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5769 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5770 // Erroneous case - clause has some problems. 5771 continue; 5772 } 5773 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5774 Pair.second.size() <= CurrentNestedLoopCount) { 5775 // Erroneous case - clause has some problems. 5776 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5777 continue; 5778 } 5779 Expr *CntValue; 5780 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5781 CntValue = ISC.buildOrderedLoopData( 5782 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5783 Pair.first->getDependencyLoc()); 5784 else 5785 CntValue = ISC.buildOrderedLoopData( 5786 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5787 Pair.first->getDependencyLoc(), 5788 Pair.second[CurrentNestedLoopCount].first, 5789 Pair.second[CurrentNestedLoopCount].second); 5790 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5791 } 5792 } 5793 5794 return HasErrors; 5795 } 5796 5797 /// Build 'VarRef = Start. 5798 static ExprResult 5799 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5800 ExprResult Start, 5801 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5802 // Build 'VarRef = Start. 5803 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5804 if (!NewStart.isUsable()) 5805 return ExprError(); 5806 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5807 VarRef.get()->getType())) { 5808 NewStart = SemaRef.PerformImplicitConversion( 5809 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5810 /*AllowExplicit=*/true); 5811 if (!NewStart.isUsable()) 5812 return ExprError(); 5813 } 5814 5815 ExprResult Init = 5816 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5817 return Init; 5818 } 5819 5820 /// Build 'VarRef = Start + Iter * Step'. 5821 static ExprResult buildCounterUpdate( 5822 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5823 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5824 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5825 // Add parentheses (for debugging purposes only). 5826 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5827 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5828 !Step.isUsable()) 5829 return ExprError(); 5830 5831 ExprResult NewStep = Step; 5832 if (Captures) 5833 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5834 if (NewStep.isInvalid()) 5835 return ExprError(); 5836 ExprResult Update = 5837 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5838 if (!Update.isUsable()) 5839 return ExprError(); 5840 5841 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5842 // 'VarRef = Start (+|-) Iter * Step'. 5843 ExprResult NewStart = Start; 5844 if (Captures) 5845 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5846 if (NewStart.isInvalid()) 5847 return ExprError(); 5848 5849 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5850 ExprResult SavedUpdate = Update; 5851 ExprResult UpdateVal; 5852 if (VarRef.get()->getType()->isOverloadableType() || 5853 NewStart.get()->getType()->isOverloadableType() || 5854 Update.get()->getType()->isOverloadableType()) { 5855 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5856 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5857 Update = 5858 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5859 if (Update.isUsable()) { 5860 UpdateVal = 5861 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5862 VarRef.get(), SavedUpdate.get()); 5863 if (UpdateVal.isUsable()) { 5864 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5865 UpdateVal.get()); 5866 } 5867 } 5868 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5869 } 5870 5871 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5872 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5873 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5874 NewStart.get(), SavedUpdate.get()); 5875 if (!Update.isUsable()) 5876 return ExprError(); 5877 5878 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5879 VarRef.get()->getType())) { 5880 Update = SemaRef.PerformImplicitConversion( 5881 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5882 if (!Update.isUsable()) 5883 return ExprError(); 5884 } 5885 5886 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5887 } 5888 return Update; 5889 } 5890 5891 /// Convert integer expression \a E to make it have at least \a Bits 5892 /// bits. 5893 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5894 if (E == nullptr) 5895 return ExprError(); 5896 ASTContext &C = SemaRef.Context; 5897 QualType OldType = E->getType(); 5898 unsigned HasBits = C.getTypeSize(OldType); 5899 if (HasBits >= Bits) 5900 return ExprResult(E); 5901 // OK to convert to signed, because new type has more bits than old. 5902 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5903 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5904 true); 5905 } 5906 5907 /// Check if the given expression \a E is a constant integer that fits 5908 /// into \a Bits bits. 5909 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5910 if (E == nullptr) 5911 return false; 5912 llvm::APSInt Result; 5913 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5914 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5915 return false; 5916 } 5917 5918 /// Build preinits statement for the given declarations. 5919 static Stmt *buildPreInits(ASTContext &Context, 5920 MutableArrayRef<Decl *> PreInits) { 5921 if (!PreInits.empty()) { 5922 return new (Context) DeclStmt( 5923 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5924 SourceLocation(), SourceLocation()); 5925 } 5926 return nullptr; 5927 } 5928 5929 /// Build preinits statement for the given declarations. 5930 static Stmt * 5931 buildPreInits(ASTContext &Context, 5932 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5933 if (!Captures.empty()) { 5934 SmallVector<Decl *, 16> PreInits; 5935 for (const auto &Pair : Captures) 5936 PreInits.push_back(Pair.second->getDecl()); 5937 return buildPreInits(Context, PreInits); 5938 } 5939 return nullptr; 5940 } 5941 5942 /// Build postupdate expression for the given list of postupdates expressions. 5943 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5944 Expr *PostUpdate = nullptr; 5945 if (!PostUpdates.empty()) { 5946 for (Expr *E : PostUpdates) { 5947 Expr *ConvE = S.BuildCStyleCastExpr( 5948 E->getExprLoc(), 5949 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5950 E->getExprLoc(), E) 5951 .get(); 5952 PostUpdate = PostUpdate 5953 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5954 PostUpdate, ConvE) 5955 .get() 5956 : ConvE; 5957 } 5958 } 5959 return PostUpdate; 5960 } 5961 5962 /// Called on a for stmt to check itself and nested loops (if any). 5963 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5964 /// number of collapsed loops otherwise. 5965 static unsigned 5966 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5967 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5968 DSAStackTy &DSA, 5969 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5970 OMPLoopDirective::HelperExprs &Built) { 5971 unsigned NestedLoopCount = 1; 5972 if (CollapseLoopCountExpr) { 5973 // Found 'collapse' clause - calculate collapse number. 5974 Expr::EvalResult Result; 5975 if (!CollapseLoopCountExpr->isValueDependent() && 5976 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 5977 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5978 } else { 5979 Built.clear(/*size=*/1); 5980 return 1; 5981 } 5982 } 5983 unsigned OrderedLoopCount = 1; 5984 if (OrderedLoopCountExpr) { 5985 // Found 'ordered' clause - calculate collapse number. 5986 Expr::EvalResult EVResult; 5987 if (!OrderedLoopCountExpr->isValueDependent() && 5988 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 5989 SemaRef.getASTContext())) { 5990 llvm::APSInt Result = EVResult.Val.getInt(); 5991 if (Result.getLimitedValue() < NestedLoopCount) { 5992 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5993 diag::err_omp_wrong_ordered_loop_count) 5994 << OrderedLoopCountExpr->getSourceRange(); 5995 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5996 diag::note_collapse_loop_count) 5997 << CollapseLoopCountExpr->getSourceRange(); 5998 } 5999 OrderedLoopCount = Result.getLimitedValue(); 6000 } else { 6001 Built.clear(/*size=*/1); 6002 return 1; 6003 } 6004 } 6005 // This is helper routine for loop directives (e.g., 'for', 'simd', 6006 // 'for simd', etc.). 6007 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6008 SmallVector<LoopIterationSpace, 4> IterSpaces( 6009 std::max(OrderedLoopCount, NestedLoopCount)); 6010 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6011 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6012 if (checkOpenMPIterationSpace( 6013 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6014 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6015 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 6016 Captures)) 6017 return 0; 6018 // Move on to the next nested for loop, or to the loop body. 6019 // OpenMP [2.8.1, simd construct, Restrictions] 6020 // All loops associated with the construct must be perfectly nested; that 6021 // is, there must be no intervening code nor any OpenMP directive between 6022 // any two loops. 6023 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6024 } 6025 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6026 if (checkOpenMPIterationSpace( 6027 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6028 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6029 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 6030 Captures)) 6031 return 0; 6032 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6033 // Handle initialization of captured loop iterator variables. 6034 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6035 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6036 Captures[DRE] = DRE; 6037 } 6038 } 6039 // Move on to the next nested for loop, or to the loop body. 6040 // OpenMP [2.8.1, simd construct, Restrictions] 6041 // All loops associated with the construct must be perfectly nested; that 6042 // is, there must be no intervening code nor any OpenMP directive between 6043 // any two loops. 6044 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6045 } 6046 6047 Built.clear(/* size */ NestedLoopCount); 6048 6049 if (SemaRef.CurContext->isDependentContext()) 6050 return NestedLoopCount; 6051 6052 // An example of what is generated for the following code: 6053 // 6054 // #pragma omp simd collapse(2) ordered(2) 6055 // for (i = 0; i < NI; ++i) 6056 // for (k = 0; k < NK; ++k) 6057 // for (j = J0; j < NJ; j+=2) { 6058 // <loop body> 6059 // } 6060 // 6061 // We generate the code below. 6062 // Note: the loop body may be outlined in CodeGen. 6063 // Note: some counters may be C++ classes, operator- is used to find number of 6064 // iterations and operator+= to calculate counter value. 6065 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6066 // or i64 is currently supported). 6067 // 6068 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6069 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6070 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6071 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6072 // // similar updates for vars in clauses (e.g. 'linear') 6073 // <loop body (using local i and j)> 6074 // } 6075 // i = NI; // assign final values of counters 6076 // j = NJ; 6077 // 6078 6079 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6080 // the iteration counts of the collapsed for loops. 6081 // Precondition tests if there is at least one iteration (all conditions are 6082 // true). 6083 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6084 Expr *N0 = IterSpaces[0].NumIterations; 6085 ExprResult LastIteration32 = 6086 widenIterationCount(/*Bits=*/32, 6087 SemaRef 6088 .PerformImplicitConversion( 6089 N0->IgnoreImpCasts(), N0->getType(), 6090 Sema::AA_Converting, /*AllowExplicit=*/true) 6091 .get(), 6092 SemaRef); 6093 ExprResult LastIteration64 = widenIterationCount( 6094 /*Bits=*/64, 6095 SemaRef 6096 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6097 Sema::AA_Converting, 6098 /*AllowExplicit=*/true) 6099 .get(), 6100 SemaRef); 6101 6102 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6103 return NestedLoopCount; 6104 6105 ASTContext &C = SemaRef.Context; 6106 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6107 6108 Scope *CurScope = DSA.getCurScope(); 6109 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6110 if (PreCond.isUsable()) { 6111 PreCond = 6112 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6113 PreCond.get(), IterSpaces[Cnt].PreCond); 6114 } 6115 Expr *N = IterSpaces[Cnt].NumIterations; 6116 SourceLocation Loc = N->getExprLoc(); 6117 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6118 if (LastIteration32.isUsable()) 6119 LastIteration32 = SemaRef.BuildBinOp( 6120 CurScope, Loc, BO_Mul, LastIteration32.get(), 6121 SemaRef 6122 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6123 Sema::AA_Converting, 6124 /*AllowExplicit=*/true) 6125 .get()); 6126 if (LastIteration64.isUsable()) 6127 LastIteration64 = SemaRef.BuildBinOp( 6128 CurScope, Loc, BO_Mul, LastIteration64.get(), 6129 SemaRef 6130 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6131 Sema::AA_Converting, 6132 /*AllowExplicit=*/true) 6133 .get()); 6134 } 6135 6136 // Choose either the 32-bit or 64-bit version. 6137 ExprResult LastIteration = LastIteration64; 6138 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6139 (LastIteration32.isUsable() && 6140 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6141 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6142 fitsInto( 6143 /*Bits=*/32, 6144 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6145 LastIteration64.get(), SemaRef)))) 6146 LastIteration = LastIteration32; 6147 QualType VType = LastIteration.get()->getType(); 6148 QualType RealVType = VType; 6149 QualType StrideVType = VType; 6150 if (isOpenMPTaskLoopDirective(DKind)) { 6151 VType = 6152 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6153 StrideVType = 6154 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6155 } 6156 6157 if (!LastIteration.isUsable()) 6158 return 0; 6159 6160 // Save the number of iterations. 6161 ExprResult NumIterations = LastIteration; 6162 { 6163 LastIteration = SemaRef.BuildBinOp( 6164 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6165 LastIteration.get(), 6166 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6167 if (!LastIteration.isUsable()) 6168 return 0; 6169 } 6170 6171 // Calculate the last iteration number beforehand instead of doing this on 6172 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6173 llvm::APSInt Result; 6174 bool IsConstant = 6175 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6176 ExprResult CalcLastIteration; 6177 if (!IsConstant) { 6178 ExprResult SaveRef = 6179 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6180 LastIteration = SaveRef; 6181 6182 // Prepare SaveRef + 1. 6183 NumIterations = SemaRef.BuildBinOp( 6184 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6185 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6186 if (!NumIterations.isUsable()) 6187 return 0; 6188 } 6189 6190 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6191 6192 // Build variables passed into runtime, necessary for worksharing directives. 6193 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6194 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6195 isOpenMPDistributeDirective(DKind)) { 6196 // Lower bound variable, initialized with zero. 6197 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6198 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6199 SemaRef.AddInitializerToDecl(LBDecl, 6200 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6201 /*DirectInit*/ false); 6202 6203 // Upper bound variable, initialized with last iteration number. 6204 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6205 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6206 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6207 /*DirectInit*/ false); 6208 6209 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6210 // This will be used to implement clause 'lastprivate'. 6211 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6212 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6213 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6214 SemaRef.AddInitializerToDecl(ILDecl, 6215 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6216 /*DirectInit*/ false); 6217 6218 // Stride variable returned by runtime (we initialize it to 1 by default). 6219 VarDecl *STDecl = 6220 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6221 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6222 SemaRef.AddInitializerToDecl(STDecl, 6223 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6224 /*DirectInit*/ false); 6225 6226 // Build expression: UB = min(UB, LastIteration) 6227 // It is necessary for CodeGen of directives with static scheduling. 6228 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6229 UB.get(), LastIteration.get()); 6230 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6231 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6232 LastIteration.get(), UB.get()); 6233 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6234 CondOp.get()); 6235 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6236 6237 // If we have a combined directive that combines 'distribute', 'for' or 6238 // 'simd' we need to be able to access the bounds of the schedule of the 6239 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6240 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6241 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6242 // Lower bound variable, initialized with zero. 6243 VarDecl *CombLBDecl = 6244 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6245 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6246 SemaRef.AddInitializerToDecl( 6247 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6248 /*DirectInit*/ false); 6249 6250 // Upper bound variable, initialized with last iteration number. 6251 VarDecl *CombUBDecl = 6252 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6253 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6254 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6255 /*DirectInit*/ false); 6256 6257 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6258 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6259 ExprResult CombCondOp = 6260 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6261 LastIteration.get(), CombUB.get()); 6262 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6263 CombCondOp.get()); 6264 CombEUB = 6265 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6266 6267 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6268 // We expect to have at least 2 more parameters than the 'parallel' 6269 // directive does - the lower and upper bounds of the previous schedule. 6270 assert(CD->getNumParams() >= 4 && 6271 "Unexpected number of parameters in loop combined directive"); 6272 6273 // Set the proper type for the bounds given what we learned from the 6274 // enclosed loops. 6275 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6276 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6277 6278 // Previous lower and upper bounds are obtained from the region 6279 // parameters. 6280 PrevLB = 6281 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6282 PrevUB = 6283 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6284 } 6285 } 6286 6287 // Build the iteration variable and its initialization before loop. 6288 ExprResult IV; 6289 ExprResult Init, CombInit; 6290 { 6291 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6292 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6293 Expr *RHS = 6294 (isOpenMPWorksharingDirective(DKind) || 6295 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6296 ? LB.get() 6297 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6298 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6299 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6300 6301 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6302 Expr *CombRHS = 6303 (isOpenMPWorksharingDirective(DKind) || 6304 isOpenMPTaskLoopDirective(DKind) || 6305 isOpenMPDistributeDirective(DKind)) 6306 ? CombLB.get() 6307 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6308 CombInit = 6309 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6310 CombInit = 6311 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6312 } 6313 } 6314 6315 bool UseStrictCompare = 6316 RealVType->hasUnsignedIntegerRepresentation() && 6317 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6318 return LIS.IsStrictCompare; 6319 }); 6320 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6321 // unsigned IV)) for worksharing loops. 6322 SourceLocation CondLoc = AStmt->getBeginLoc(); 6323 Expr *BoundUB = UB.get(); 6324 if (UseStrictCompare) { 6325 BoundUB = 6326 SemaRef 6327 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6328 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6329 .get(); 6330 BoundUB = 6331 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6332 } 6333 ExprResult Cond = 6334 (isOpenMPWorksharingDirective(DKind) || 6335 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6336 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6337 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6338 BoundUB) 6339 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6340 NumIterations.get()); 6341 ExprResult CombDistCond; 6342 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6343 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6344 NumIterations.get()); 6345 } 6346 6347 ExprResult CombCond; 6348 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6349 Expr *BoundCombUB = CombUB.get(); 6350 if (UseStrictCompare) { 6351 BoundCombUB = 6352 SemaRef 6353 .BuildBinOp( 6354 CurScope, CondLoc, BO_Add, BoundCombUB, 6355 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6356 .get(); 6357 BoundCombUB = 6358 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6359 .get(); 6360 } 6361 CombCond = 6362 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6363 IV.get(), BoundCombUB); 6364 } 6365 // Loop increment (IV = IV + 1) 6366 SourceLocation IncLoc = AStmt->getBeginLoc(); 6367 ExprResult Inc = 6368 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6369 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6370 if (!Inc.isUsable()) 6371 return 0; 6372 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6373 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6374 if (!Inc.isUsable()) 6375 return 0; 6376 6377 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6378 // Used for directives with static scheduling. 6379 // In combined construct, add combined version that use CombLB and CombUB 6380 // base variables for the update 6381 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6382 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6383 isOpenMPDistributeDirective(DKind)) { 6384 // LB + ST 6385 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6386 if (!NextLB.isUsable()) 6387 return 0; 6388 // LB = LB + ST 6389 NextLB = 6390 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6391 NextLB = 6392 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6393 if (!NextLB.isUsable()) 6394 return 0; 6395 // UB + ST 6396 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6397 if (!NextUB.isUsable()) 6398 return 0; 6399 // UB = UB + ST 6400 NextUB = 6401 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6402 NextUB = 6403 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6404 if (!NextUB.isUsable()) 6405 return 0; 6406 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6407 CombNextLB = 6408 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6409 if (!NextLB.isUsable()) 6410 return 0; 6411 // LB = LB + ST 6412 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6413 CombNextLB.get()); 6414 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6415 /*DiscardedValue*/ false); 6416 if (!CombNextLB.isUsable()) 6417 return 0; 6418 // UB + ST 6419 CombNextUB = 6420 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 6421 if (!CombNextUB.isUsable()) 6422 return 0; 6423 // UB = UB + ST 6424 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 6425 CombNextUB.get()); 6426 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 6427 /*DiscardedValue*/ false); 6428 if (!CombNextUB.isUsable()) 6429 return 0; 6430 } 6431 } 6432 6433 // Create increment expression for distribute loop when combined in a same 6434 // directive with for as IV = IV + ST; ensure upper bound expression based 6435 // on PrevUB instead of NumIterations - used to implement 'for' when found 6436 // in combination with 'distribute', like in 'distribute parallel for' 6437 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 6438 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 6439 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6440 DistCond = SemaRef.BuildBinOp( 6441 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 6442 assert(DistCond.isUsable() && "distribute cond expr was not built"); 6443 6444 DistInc = 6445 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 6446 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6447 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 6448 DistInc.get()); 6449 DistInc = 6450 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 6451 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6452 6453 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 6454 // construct 6455 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 6456 ExprResult IsUBGreater = 6457 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 6458 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6459 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 6460 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 6461 CondOp.get()); 6462 PrevEUB = 6463 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 6464 6465 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 6466 // parallel for is in combination with a distribute directive with 6467 // schedule(static, 1) 6468 Expr *BoundPrevUB = PrevUB.get(); 6469 if (UseStrictCompare) { 6470 BoundPrevUB = 6471 SemaRef 6472 .BuildBinOp( 6473 CurScope, CondLoc, BO_Add, BoundPrevUB, 6474 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6475 .get(); 6476 BoundPrevUB = 6477 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 6478 .get(); 6479 } 6480 ParForInDistCond = 6481 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6482 IV.get(), BoundPrevUB); 6483 } 6484 6485 // Build updates and final values of the loop counters. 6486 bool HasErrors = false; 6487 Built.Counters.resize(NestedLoopCount); 6488 Built.Inits.resize(NestedLoopCount); 6489 Built.Updates.resize(NestedLoopCount); 6490 Built.Finals.resize(NestedLoopCount); 6491 { 6492 // We implement the following algorithm for obtaining the 6493 // original loop iteration variable values based on the 6494 // value of the collapsed loop iteration variable IV. 6495 // 6496 // Let n+1 be the number of collapsed loops in the nest. 6497 // Iteration variables (I0, I1, .... In) 6498 // Iteration counts (N0, N1, ... Nn) 6499 // 6500 // Acc = IV; 6501 // 6502 // To compute Ik for loop k, 0 <= k <= n, generate: 6503 // Prod = N(k+1) * N(k+2) * ... * Nn; 6504 // Ik = Acc / Prod; 6505 // Acc -= Ik * Prod; 6506 // 6507 ExprResult Acc = IV; 6508 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6509 LoopIterationSpace &IS = IterSpaces[Cnt]; 6510 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 6511 ExprResult Iter; 6512 6513 // Compute prod 6514 ExprResult Prod = 6515 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6516 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 6517 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 6518 IterSpaces[K].NumIterations); 6519 6520 // Iter = Acc / Prod 6521 // If there is at least one more inner loop to avoid 6522 // multiplication by 1. 6523 if (Cnt + 1 < NestedLoopCount) 6524 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 6525 Acc.get(), Prod.get()); 6526 else 6527 Iter = Acc; 6528 if (!Iter.isUsable()) { 6529 HasErrors = true; 6530 break; 6531 } 6532 6533 // Update Acc: 6534 // Acc -= Iter * Prod 6535 // Check if there is at least one more inner loop to avoid 6536 // multiplication by 1. 6537 if (Cnt + 1 < NestedLoopCount) 6538 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 6539 Iter.get(), Prod.get()); 6540 else 6541 Prod = Iter; 6542 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 6543 Acc.get(), Prod.get()); 6544 6545 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 6546 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 6547 DeclRefExpr *CounterVar = buildDeclRefExpr( 6548 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 6549 /*RefersToCapture=*/true); 6550 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 6551 IS.CounterInit, Captures); 6552 if (!Init.isUsable()) { 6553 HasErrors = true; 6554 break; 6555 } 6556 ExprResult Update = buildCounterUpdate( 6557 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 6558 IS.CounterStep, IS.Subtract, &Captures); 6559 if (!Update.isUsable()) { 6560 HasErrors = true; 6561 break; 6562 } 6563 6564 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6565 ExprResult Final = buildCounterUpdate( 6566 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 6567 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 6568 if (!Final.isUsable()) { 6569 HasErrors = true; 6570 break; 6571 } 6572 6573 if (!Update.isUsable() || !Final.isUsable()) { 6574 HasErrors = true; 6575 break; 6576 } 6577 // Save results 6578 Built.Counters[Cnt] = IS.CounterVar; 6579 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6580 Built.Inits[Cnt] = Init.get(); 6581 Built.Updates[Cnt] = Update.get(); 6582 Built.Finals[Cnt] = Final.get(); 6583 } 6584 } 6585 6586 if (HasErrors) 6587 return 0; 6588 6589 // Save results 6590 Built.IterationVarRef = IV.get(); 6591 Built.LastIteration = LastIteration.get(); 6592 Built.NumIterations = NumIterations.get(); 6593 Built.CalcLastIteration = SemaRef 6594 .ActOnFinishFullExpr(CalcLastIteration.get(), 6595 /*DiscardedValue*/ false) 6596 .get(); 6597 Built.PreCond = PreCond.get(); 6598 Built.PreInits = buildPreInits(C, Captures); 6599 Built.Cond = Cond.get(); 6600 Built.Init = Init.get(); 6601 Built.Inc = Inc.get(); 6602 Built.LB = LB.get(); 6603 Built.UB = UB.get(); 6604 Built.IL = IL.get(); 6605 Built.ST = ST.get(); 6606 Built.EUB = EUB.get(); 6607 Built.NLB = NextLB.get(); 6608 Built.NUB = NextUB.get(); 6609 Built.PrevLB = PrevLB.get(); 6610 Built.PrevUB = PrevUB.get(); 6611 Built.DistInc = DistInc.get(); 6612 Built.PrevEUB = PrevEUB.get(); 6613 Built.DistCombinedFields.LB = CombLB.get(); 6614 Built.DistCombinedFields.UB = CombUB.get(); 6615 Built.DistCombinedFields.EUB = CombEUB.get(); 6616 Built.DistCombinedFields.Init = CombInit.get(); 6617 Built.DistCombinedFields.Cond = CombCond.get(); 6618 Built.DistCombinedFields.NLB = CombNextLB.get(); 6619 Built.DistCombinedFields.NUB = CombNextUB.get(); 6620 Built.DistCombinedFields.DistCond = CombDistCond.get(); 6621 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 6622 6623 return NestedLoopCount; 6624 } 6625 6626 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 6627 auto CollapseClauses = 6628 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 6629 if (CollapseClauses.begin() != CollapseClauses.end()) 6630 return (*CollapseClauses.begin())->getNumForLoops(); 6631 return nullptr; 6632 } 6633 6634 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 6635 auto OrderedClauses = 6636 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 6637 if (OrderedClauses.begin() != OrderedClauses.end()) 6638 return (*OrderedClauses.begin())->getNumForLoops(); 6639 return nullptr; 6640 } 6641 6642 static bool checkSimdlenSafelenSpecified(Sema &S, 6643 const ArrayRef<OMPClause *> Clauses) { 6644 const OMPSafelenClause *Safelen = nullptr; 6645 const OMPSimdlenClause *Simdlen = nullptr; 6646 6647 for (const OMPClause *Clause : Clauses) { 6648 if (Clause->getClauseKind() == OMPC_safelen) 6649 Safelen = cast<OMPSafelenClause>(Clause); 6650 else if (Clause->getClauseKind() == OMPC_simdlen) 6651 Simdlen = cast<OMPSimdlenClause>(Clause); 6652 if (Safelen && Simdlen) 6653 break; 6654 } 6655 6656 if (Simdlen && Safelen) { 6657 const Expr *SimdlenLength = Simdlen->getSimdlen(); 6658 const Expr *SafelenLength = Safelen->getSafelen(); 6659 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 6660 SimdlenLength->isInstantiationDependent() || 6661 SimdlenLength->containsUnexpandedParameterPack()) 6662 return false; 6663 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 6664 SafelenLength->isInstantiationDependent() || 6665 SafelenLength->containsUnexpandedParameterPack()) 6666 return false; 6667 Expr::EvalResult SimdlenResult, SafelenResult; 6668 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 6669 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 6670 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 6671 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 6672 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 6673 // If both simdlen and safelen clauses are specified, the value of the 6674 // simdlen parameter must be less than or equal to the value of the safelen 6675 // parameter. 6676 if (SimdlenRes > SafelenRes) { 6677 S.Diag(SimdlenLength->getExprLoc(), 6678 diag::err_omp_wrong_simdlen_safelen_values) 6679 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 6680 return true; 6681 } 6682 } 6683 return false; 6684 } 6685 6686 StmtResult 6687 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6688 SourceLocation StartLoc, SourceLocation EndLoc, 6689 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6690 if (!AStmt) 6691 return StmtError(); 6692 6693 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6694 OMPLoopDirective::HelperExprs B; 6695 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6696 // define the nested loops number. 6697 unsigned NestedLoopCount = checkOpenMPLoop( 6698 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6699 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6700 if (NestedLoopCount == 0) 6701 return StmtError(); 6702 6703 assert((CurContext->isDependentContext() || B.builtAll()) && 6704 "omp simd loop exprs were not built"); 6705 6706 if (!CurContext->isDependentContext()) { 6707 // Finalize the clauses that need pre-built expressions for CodeGen. 6708 for (OMPClause *C : Clauses) { 6709 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6710 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6711 B.NumIterations, *this, CurScope, 6712 DSAStack)) 6713 return StmtError(); 6714 } 6715 } 6716 6717 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6718 return StmtError(); 6719 6720 setFunctionHasBranchProtectedScope(); 6721 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6722 Clauses, AStmt, B); 6723 } 6724 6725 StmtResult 6726 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6727 SourceLocation StartLoc, SourceLocation EndLoc, 6728 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6729 if (!AStmt) 6730 return StmtError(); 6731 6732 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6733 OMPLoopDirective::HelperExprs B; 6734 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6735 // define the nested loops number. 6736 unsigned NestedLoopCount = checkOpenMPLoop( 6737 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6738 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6739 if (NestedLoopCount == 0) 6740 return StmtError(); 6741 6742 assert((CurContext->isDependentContext() || B.builtAll()) && 6743 "omp for loop exprs were not built"); 6744 6745 if (!CurContext->isDependentContext()) { 6746 // Finalize the clauses that need pre-built expressions for CodeGen. 6747 for (OMPClause *C : Clauses) { 6748 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6749 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6750 B.NumIterations, *this, CurScope, 6751 DSAStack)) 6752 return StmtError(); 6753 } 6754 } 6755 6756 setFunctionHasBranchProtectedScope(); 6757 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6758 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6759 } 6760 6761 StmtResult Sema::ActOnOpenMPForSimdDirective( 6762 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6763 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6764 if (!AStmt) 6765 return StmtError(); 6766 6767 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6768 OMPLoopDirective::HelperExprs B; 6769 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6770 // define the nested loops number. 6771 unsigned NestedLoopCount = 6772 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6773 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6774 VarsWithImplicitDSA, B); 6775 if (NestedLoopCount == 0) 6776 return StmtError(); 6777 6778 assert((CurContext->isDependentContext() || B.builtAll()) && 6779 "omp for simd loop exprs were not built"); 6780 6781 if (!CurContext->isDependentContext()) { 6782 // Finalize the clauses that need pre-built expressions for CodeGen. 6783 for (OMPClause *C : Clauses) { 6784 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6785 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6786 B.NumIterations, *this, CurScope, 6787 DSAStack)) 6788 return StmtError(); 6789 } 6790 } 6791 6792 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6793 return StmtError(); 6794 6795 setFunctionHasBranchProtectedScope(); 6796 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6797 Clauses, AStmt, B); 6798 } 6799 6800 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6801 Stmt *AStmt, 6802 SourceLocation StartLoc, 6803 SourceLocation EndLoc) { 6804 if (!AStmt) 6805 return StmtError(); 6806 6807 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6808 auto BaseStmt = AStmt; 6809 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6810 BaseStmt = CS->getCapturedStmt(); 6811 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6812 auto S = C->children(); 6813 if (S.begin() == S.end()) 6814 return StmtError(); 6815 // All associated statements must be '#pragma omp section' except for 6816 // the first one. 6817 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6818 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6819 if (SectionStmt) 6820 Diag(SectionStmt->getBeginLoc(), 6821 diag::err_omp_sections_substmt_not_section); 6822 return StmtError(); 6823 } 6824 cast<OMPSectionDirective>(SectionStmt) 6825 ->setHasCancel(DSAStack->isCancelRegion()); 6826 } 6827 } else { 6828 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6829 return StmtError(); 6830 } 6831 6832 setFunctionHasBranchProtectedScope(); 6833 6834 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6835 DSAStack->isCancelRegion()); 6836 } 6837 6838 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6839 SourceLocation StartLoc, 6840 SourceLocation EndLoc) { 6841 if (!AStmt) 6842 return StmtError(); 6843 6844 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6845 6846 setFunctionHasBranchProtectedScope(); 6847 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6848 6849 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6850 DSAStack->isCancelRegion()); 6851 } 6852 6853 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6854 Stmt *AStmt, 6855 SourceLocation StartLoc, 6856 SourceLocation EndLoc) { 6857 if (!AStmt) 6858 return StmtError(); 6859 6860 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6861 6862 setFunctionHasBranchProtectedScope(); 6863 6864 // OpenMP [2.7.3, single Construct, Restrictions] 6865 // The copyprivate clause must not be used with the nowait clause. 6866 const OMPClause *Nowait = nullptr; 6867 const OMPClause *Copyprivate = nullptr; 6868 for (const OMPClause *Clause : Clauses) { 6869 if (Clause->getClauseKind() == OMPC_nowait) 6870 Nowait = Clause; 6871 else if (Clause->getClauseKind() == OMPC_copyprivate) 6872 Copyprivate = Clause; 6873 if (Copyprivate && Nowait) { 6874 Diag(Copyprivate->getBeginLoc(), 6875 diag::err_omp_single_copyprivate_with_nowait); 6876 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6877 return StmtError(); 6878 } 6879 } 6880 6881 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6882 } 6883 6884 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6885 SourceLocation StartLoc, 6886 SourceLocation EndLoc) { 6887 if (!AStmt) 6888 return StmtError(); 6889 6890 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6891 6892 setFunctionHasBranchProtectedScope(); 6893 6894 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6895 } 6896 6897 StmtResult Sema::ActOnOpenMPCriticalDirective( 6898 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6899 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6900 if (!AStmt) 6901 return StmtError(); 6902 6903 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6904 6905 bool ErrorFound = false; 6906 llvm::APSInt Hint; 6907 SourceLocation HintLoc; 6908 bool DependentHint = false; 6909 for (const OMPClause *C : Clauses) { 6910 if (C->getClauseKind() == OMPC_hint) { 6911 if (!DirName.getName()) { 6912 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6913 ErrorFound = true; 6914 } 6915 Expr *E = cast<OMPHintClause>(C)->getHint(); 6916 if (E->isTypeDependent() || E->isValueDependent() || 6917 E->isInstantiationDependent()) { 6918 DependentHint = true; 6919 } else { 6920 Hint = E->EvaluateKnownConstInt(Context); 6921 HintLoc = C->getBeginLoc(); 6922 } 6923 } 6924 } 6925 if (ErrorFound) 6926 return StmtError(); 6927 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6928 if (Pair.first && DirName.getName() && !DependentHint) { 6929 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6930 Diag(StartLoc, diag::err_omp_critical_with_hint); 6931 if (HintLoc.isValid()) 6932 Diag(HintLoc, diag::note_omp_critical_hint_here) 6933 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6934 else 6935 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6936 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6937 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6938 << 1 6939 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6940 /*Radix=*/10, /*Signed=*/false); 6941 } else { 6942 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6943 } 6944 } 6945 } 6946 6947 setFunctionHasBranchProtectedScope(); 6948 6949 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6950 Clauses, AStmt); 6951 if (!Pair.first && DirName.getName() && !DependentHint) 6952 DSAStack->addCriticalWithHint(Dir, Hint); 6953 return Dir; 6954 } 6955 6956 StmtResult Sema::ActOnOpenMPParallelForDirective( 6957 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6958 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6959 if (!AStmt) 6960 return StmtError(); 6961 6962 auto *CS = cast<CapturedStmt>(AStmt); 6963 // 1.2.2 OpenMP Language Terminology 6964 // Structured block - An executable statement with a single entry at the 6965 // top and a single exit at the bottom. 6966 // The point of exit cannot be a branch out of the structured block. 6967 // longjmp() and throw() must not violate the entry/exit criteria. 6968 CS->getCapturedDecl()->setNothrow(); 6969 6970 OMPLoopDirective::HelperExprs B; 6971 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6972 // define the nested loops number. 6973 unsigned NestedLoopCount = 6974 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6975 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6976 VarsWithImplicitDSA, B); 6977 if (NestedLoopCount == 0) 6978 return StmtError(); 6979 6980 assert((CurContext->isDependentContext() || B.builtAll()) && 6981 "omp parallel for loop exprs were not built"); 6982 6983 if (!CurContext->isDependentContext()) { 6984 // Finalize the clauses that need pre-built expressions for CodeGen. 6985 for (OMPClause *C : Clauses) { 6986 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6987 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6988 B.NumIterations, *this, CurScope, 6989 DSAStack)) 6990 return StmtError(); 6991 } 6992 } 6993 6994 setFunctionHasBranchProtectedScope(); 6995 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6996 NestedLoopCount, Clauses, AStmt, B, 6997 DSAStack->isCancelRegion()); 6998 } 6999 7000 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7001 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7002 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7003 if (!AStmt) 7004 return StmtError(); 7005 7006 auto *CS = cast<CapturedStmt>(AStmt); 7007 // 1.2.2 OpenMP Language Terminology 7008 // Structured block - An executable statement with a single entry at the 7009 // top and a single exit at the bottom. 7010 // The point of exit cannot be a branch out of the structured block. 7011 // longjmp() and throw() must not violate the entry/exit criteria. 7012 CS->getCapturedDecl()->setNothrow(); 7013 7014 OMPLoopDirective::HelperExprs B; 7015 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7016 // define the nested loops number. 7017 unsigned NestedLoopCount = 7018 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7019 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7020 VarsWithImplicitDSA, B); 7021 if (NestedLoopCount == 0) 7022 return StmtError(); 7023 7024 if (!CurContext->isDependentContext()) { 7025 // Finalize the clauses that need pre-built expressions for CodeGen. 7026 for (OMPClause *C : Clauses) { 7027 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7028 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7029 B.NumIterations, *this, CurScope, 7030 DSAStack)) 7031 return StmtError(); 7032 } 7033 } 7034 7035 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7036 return StmtError(); 7037 7038 setFunctionHasBranchProtectedScope(); 7039 return OMPParallelForSimdDirective::Create( 7040 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7041 } 7042 7043 StmtResult 7044 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7045 Stmt *AStmt, SourceLocation StartLoc, 7046 SourceLocation EndLoc) { 7047 if (!AStmt) 7048 return StmtError(); 7049 7050 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7051 auto BaseStmt = AStmt; 7052 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7053 BaseStmt = CS->getCapturedStmt(); 7054 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7055 auto S = C->children(); 7056 if (S.begin() == S.end()) 7057 return StmtError(); 7058 // All associated statements must be '#pragma omp section' except for 7059 // the first one. 7060 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7061 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7062 if (SectionStmt) 7063 Diag(SectionStmt->getBeginLoc(), 7064 diag::err_omp_parallel_sections_substmt_not_section); 7065 return StmtError(); 7066 } 7067 cast<OMPSectionDirective>(SectionStmt) 7068 ->setHasCancel(DSAStack->isCancelRegion()); 7069 } 7070 } else { 7071 Diag(AStmt->getBeginLoc(), 7072 diag::err_omp_parallel_sections_not_compound_stmt); 7073 return StmtError(); 7074 } 7075 7076 setFunctionHasBranchProtectedScope(); 7077 7078 return OMPParallelSectionsDirective::Create( 7079 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7080 } 7081 7082 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7083 Stmt *AStmt, SourceLocation StartLoc, 7084 SourceLocation EndLoc) { 7085 if (!AStmt) 7086 return StmtError(); 7087 7088 auto *CS = cast<CapturedStmt>(AStmt); 7089 // 1.2.2 OpenMP Language Terminology 7090 // Structured block - An executable statement with a single entry at the 7091 // top and a single exit at the bottom. 7092 // The point of exit cannot be a branch out of the structured block. 7093 // longjmp() and throw() must not violate the entry/exit criteria. 7094 CS->getCapturedDecl()->setNothrow(); 7095 7096 setFunctionHasBranchProtectedScope(); 7097 7098 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7099 DSAStack->isCancelRegion()); 7100 } 7101 7102 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7103 SourceLocation EndLoc) { 7104 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7105 } 7106 7107 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7108 SourceLocation EndLoc) { 7109 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7110 } 7111 7112 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7113 SourceLocation EndLoc) { 7114 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7115 } 7116 7117 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7118 Stmt *AStmt, 7119 SourceLocation StartLoc, 7120 SourceLocation EndLoc) { 7121 if (!AStmt) 7122 return StmtError(); 7123 7124 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7125 7126 setFunctionHasBranchProtectedScope(); 7127 7128 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7129 AStmt, 7130 DSAStack->getTaskgroupReductionRef()); 7131 } 7132 7133 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7134 SourceLocation StartLoc, 7135 SourceLocation EndLoc) { 7136 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7137 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7138 } 7139 7140 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7141 Stmt *AStmt, 7142 SourceLocation StartLoc, 7143 SourceLocation EndLoc) { 7144 const OMPClause *DependFound = nullptr; 7145 const OMPClause *DependSourceClause = nullptr; 7146 const OMPClause *DependSinkClause = nullptr; 7147 bool ErrorFound = false; 7148 const OMPThreadsClause *TC = nullptr; 7149 const OMPSIMDClause *SC = nullptr; 7150 for (const OMPClause *C : Clauses) { 7151 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7152 DependFound = C; 7153 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7154 if (DependSourceClause) { 7155 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7156 << getOpenMPDirectiveName(OMPD_ordered) 7157 << getOpenMPClauseName(OMPC_depend) << 2; 7158 ErrorFound = true; 7159 } else { 7160 DependSourceClause = C; 7161 } 7162 if (DependSinkClause) { 7163 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7164 << 0; 7165 ErrorFound = true; 7166 } 7167 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7168 if (DependSourceClause) { 7169 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7170 << 1; 7171 ErrorFound = true; 7172 } 7173 DependSinkClause = C; 7174 } 7175 } else if (C->getClauseKind() == OMPC_threads) { 7176 TC = cast<OMPThreadsClause>(C); 7177 } else if (C->getClauseKind() == OMPC_simd) { 7178 SC = cast<OMPSIMDClause>(C); 7179 } 7180 } 7181 if (!ErrorFound && !SC && 7182 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7183 // OpenMP [2.8.1,simd Construct, Restrictions] 7184 // An ordered construct with the simd clause is the only OpenMP construct 7185 // that can appear in the simd region. 7186 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7187 ErrorFound = true; 7188 } else if (DependFound && (TC || SC)) { 7189 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7190 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7191 ErrorFound = true; 7192 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7193 Diag(DependFound->getBeginLoc(), 7194 diag::err_omp_ordered_directive_without_param); 7195 ErrorFound = true; 7196 } else if (TC || Clauses.empty()) { 7197 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7198 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7199 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7200 << (TC != nullptr); 7201 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7202 ErrorFound = true; 7203 } 7204 } 7205 if ((!AStmt && !DependFound) || ErrorFound) 7206 return StmtError(); 7207 7208 if (AStmt) { 7209 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7210 7211 setFunctionHasBranchProtectedScope(); 7212 } 7213 7214 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7215 } 7216 7217 namespace { 7218 /// Helper class for checking expression in 'omp atomic [update]' 7219 /// construct. 7220 class OpenMPAtomicUpdateChecker { 7221 /// Error results for atomic update expressions. 7222 enum ExprAnalysisErrorCode { 7223 /// A statement is not an expression statement. 7224 NotAnExpression, 7225 /// Expression is not builtin binary or unary operation. 7226 NotABinaryOrUnaryExpression, 7227 /// Unary operation is not post-/pre- increment/decrement operation. 7228 NotAnUnaryIncDecExpression, 7229 /// An expression is not of scalar type. 7230 NotAScalarType, 7231 /// A binary operation is not an assignment operation. 7232 NotAnAssignmentOp, 7233 /// RHS part of the binary operation is not a binary expression. 7234 NotABinaryExpression, 7235 /// RHS part is not additive/multiplicative/shift/biwise binary 7236 /// expression. 7237 NotABinaryOperator, 7238 /// RHS binary operation does not have reference to the updated LHS 7239 /// part. 7240 NotAnUpdateExpression, 7241 /// No errors is found. 7242 NoError 7243 }; 7244 /// Reference to Sema. 7245 Sema &SemaRef; 7246 /// A location for note diagnostics (when error is found). 7247 SourceLocation NoteLoc; 7248 /// 'x' lvalue part of the source atomic expression. 7249 Expr *X; 7250 /// 'expr' rvalue part of the source atomic expression. 7251 Expr *E; 7252 /// Helper expression of the form 7253 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7254 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7255 Expr *UpdateExpr; 7256 /// Is 'x' a LHS in a RHS part of full update expression. It is 7257 /// important for non-associative operations. 7258 bool IsXLHSInRHSPart; 7259 BinaryOperatorKind Op; 7260 SourceLocation OpLoc; 7261 /// true if the source expression is a postfix unary operation, false 7262 /// if it is a prefix unary operation. 7263 bool IsPostfixUpdate; 7264 7265 public: 7266 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7267 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7268 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7269 /// Check specified statement that it is suitable for 'atomic update' 7270 /// constructs and extract 'x', 'expr' and Operation from the original 7271 /// expression. If DiagId and NoteId == 0, then only check is performed 7272 /// without error notification. 7273 /// \param DiagId Diagnostic which should be emitted if error is found. 7274 /// \param NoteId Diagnostic note for the main error message. 7275 /// \return true if statement is not an update expression, false otherwise. 7276 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7277 /// Return the 'x' lvalue part of the source atomic expression. 7278 Expr *getX() const { return X; } 7279 /// Return the 'expr' rvalue part of the source atomic expression. 7280 Expr *getExpr() const { return E; } 7281 /// Return the update expression used in calculation of the updated 7282 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7283 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7284 Expr *getUpdateExpr() const { return UpdateExpr; } 7285 /// Return true if 'x' is LHS in RHS part of full update expression, 7286 /// false otherwise. 7287 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7288 7289 /// true if the source expression is a postfix unary operation, false 7290 /// if it is a prefix unary operation. 7291 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7292 7293 private: 7294 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7295 unsigned NoteId = 0); 7296 }; 7297 } // namespace 7298 7299 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7300 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7301 ExprAnalysisErrorCode ErrorFound = NoError; 7302 SourceLocation ErrorLoc, NoteLoc; 7303 SourceRange ErrorRange, NoteRange; 7304 // Allowed constructs are: 7305 // x = x binop expr; 7306 // x = expr binop x; 7307 if (AtomicBinOp->getOpcode() == BO_Assign) { 7308 X = AtomicBinOp->getLHS(); 7309 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7310 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7311 if (AtomicInnerBinOp->isMultiplicativeOp() || 7312 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7313 AtomicInnerBinOp->isBitwiseOp()) { 7314 Op = AtomicInnerBinOp->getOpcode(); 7315 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7316 Expr *LHS = AtomicInnerBinOp->getLHS(); 7317 Expr *RHS = AtomicInnerBinOp->getRHS(); 7318 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7319 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7320 /*Canonical=*/true); 7321 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7322 /*Canonical=*/true); 7323 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7324 /*Canonical=*/true); 7325 if (XId == LHSId) { 7326 E = RHS; 7327 IsXLHSInRHSPart = true; 7328 } else if (XId == RHSId) { 7329 E = LHS; 7330 IsXLHSInRHSPart = false; 7331 } else { 7332 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7333 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7334 NoteLoc = X->getExprLoc(); 7335 NoteRange = X->getSourceRange(); 7336 ErrorFound = NotAnUpdateExpression; 7337 } 7338 } else { 7339 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7340 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7341 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7342 NoteRange = SourceRange(NoteLoc, NoteLoc); 7343 ErrorFound = NotABinaryOperator; 7344 } 7345 } else { 7346 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7347 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7348 ErrorFound = NotABinaryExpression; 7349 } 7350 } else { 7351 ErrorLoc = AtomicBinOp->getExprLoc(); 7352 ErrorRange = AtomicBinOp->getSourceRange(); 7353 NoteLoc = AtomicBinOp->getOperatorLoc(); 7354 NoteRange = SourceRange(NoteLoc, NoteLoc); 7355 ErrorFound = NotAnAssignmentOp; 7356 } 7357 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7358 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7359 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7360 return true; 7361 } 7362 if (SemaRef.CurContext->isDependentContext()) 7363 E = X = UpdateExpr = nullptr; 7364 return ErrorFound != NoError; 7365 } 7366 7367 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7368 unsigned NoteId) { 7369 ExprAnalysisErrorCode ErrorFound = NoError; 7370 SourceLocation ErrorLoc, NoteLoc; 7371 SourceRange ErrorRange, NoteRange; 7372 // Allowed constructs are: 7373 // x++; 7374 // x--; 7375 // ++x; 7376 // --x; 7377 // x binop= expr; 7378 // x = x binop expr; 7379 // x = expr binop x; 7380 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7381 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7382 if (AtomicBody->getType()->isScalarType() || 7383 AtomicBody->isInstantiationDependent()) { 7384 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7385 AtomicBody->IgnoreParenImpCasts())) { 7386 // Check for Compound Assignment Operation 7387 Op = BinaryOperator::getOpForCompoundAssignment( 7388 AtomicCompAssignOp->getOpcode()); 7389 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7390 E = AtomicCompAssignOp->getRHS(); 7391 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7392 IsXLHSInRHSPart = true; 7393 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7394 AtomicBody->IgnoreParenImpCasts())) { 7395 // Check for Binary Operation 7396 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7397 return true; 7398 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7399 AtomicBody->IgnoreParenImpCasts())) { 7400 // Check for Unary Operation 7401 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7402 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7403 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7404 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7405 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 7406 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 7407 IsXLHSInRHSPart = true; 7408 } else { 7409 ErrorFound = NotAnUnaryIncDecExpression; 7410 ErrorLoc = AtomicUnaryOp->getExprLoc(); 7411 ErrorRange = AtomicUnaryOp->getSourceRange(); 7412 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 7413 NoteRange = SourceRange(NoteLoc, NoteLoc); 7414 } 7415 } else if (!AtomicBody->isInstantiationDependent()) { 7416 ErrorFound = NotABinaryOrUnaryExpression; 7417 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 7418 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 7419 } 7420 } else { 7421 ErrorFound = NotAScalarType; 7422 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 7423 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7424 } 7425 } else { 7426 ErrorFound = NotAnExpression; 7427 NoteLoc = ErrorLoc = S->getBeginLoc(); 7428 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7429 } 7430 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7431 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7432 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7433 return true; 7434 } 7435 if (SemaRef.CurContext->isDependentContext()) 7436 E = X = UpdateExpr = nullptr; 7437 if (ErrorFound == NoError && E && X) { 7438 // Build an update expression of form 'OpaqueValueExpr(x) binop 7439 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 7440 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 7441 auto *OVEX = new (SemaRef.getASTContext()) 7442 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 7443 auto *OVEExpr = new (SemaRef.getASTContext()) 7444 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 7445 ExprResult Update = 7446 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 7447 IsXLHSInRHSPart ? OVEExpr : OVEX); 7448 if (Update.isInvalid()) 7449 return true; 7450 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 7451 Sema::AA_Casting); 7452 if (Update.isInvalid()) 7453 return true; 7454 UpdateExpr = Update.get(); 7455 } 7456 return ErrorFound != NoError; 7457 } 7458 7459 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 7460 Stmt *AStmt, 7461 SourceLocation StartLoc, 7462 SourceLocation EndLoc) { 7463 if (!AStmt) 7464 return StmtError(); 7465 7466 auto *CS = cast<CapturedStmt>(AStmt); 7467 // 1.2.2 OpenMP Language Terminology 7468 // Structured block - An executable statement with a single entry at the 7469 // top and a single exit at the bottom. 7470 // The point of exit cannot be a branch out of the structured block. 7471 // longjmp() and throw() must not violate the entry/exit criteria. 7472 OpenMPClauseKind AtomicKind = OMPC_unknown; 7473 SourceLocation AtomicKindLoc; 7474 for (const OMPClause *C : Clauses) { 7475 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 7476 C->getClauseKind() == OMPC_update || 7477 C->getClauseKind() == OMPC_capture) { 7478 if (AtomicKind != OMPC_unknown) { 7479 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 7480 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 7481 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 7482 << getOpenMPClauseName(AtomicKind); 7483 } else { 7484 AtomicKind = C->getClauseKind(); 7485 AtomicKindLoc = C->getBeginLoc(); 7486 } 7487 } 7488 } 7489 7490 Stmt *Body = CS->getCapturedStmt(); 7491 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 7492 Body = EWC->getSubExpr(); 7493 7494 Expr *X = nullptr; 7495 Expr *V = nullptr; 7496 Expr *E = nullptr; 7497 Expr *UE = nullptr; 7498 bool IsXLHSInRHSPart = false; 7499 bool IsPostfixUpdate = false; 7500 // OpenMP [2.12.6, atomic Construct] 7501 // In the next expressions: 7502 // * x and v (as applicable) are both l-value expressions with scalar type. 7503 // * During the execution of an atomic region, multiple syntactic 7504 // occurrences of x must designate the same storage location. 7505 // * Neither of v and expr (as applicable) may access the storage location 7506 // designated by x. 7507 // * Neither of x and expr (as applicable) may access the storage location 7508 // designated by v. 7509 // * expr is an expression with scalar type. 7510 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 7511 // * binop, binop=, ++, and -- are not overloaded operators. 7512 // * The expression x binop expr must be numerically equivalent to x binop 7513 // (expr). This requirement is satisfied if the operators in expr have 7514 // precedence greater than binop, or by using parentheses around expr or 7515 // subexpressions of expr. 7516 // * The expression expr binop x must be numerically equivalent to (expr) 7517 // binop x. This requirement is satisfied if the operators in expr have 7518 // precedence equal to or greater than binop, or by using parentheses around 7519 // expr or subexpressions of expr. 7520 // * For forms that allow multiple occurrences of x, the number of times 7521 // that x is evaluated is unspecified. 7522 if (AtomicKind == OMPC_read) { 7523 enum { 7524 NotAnExpression, 7525 NotAnAssignmentOp, 7526 NotAScalarType, 7527 NotAnLValue, 7528 NoError 7529 } ErrorFound = NoError; 7530 SourceLocation ErrorLoc, NoteLoc; 7531 SourceRange ErrorRange, NoteRange; 7532 // If clause is read: 7533 // v = x; 7534 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7535 const auto *AtomicBinOp = 7536 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7537 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7538 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7539 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 7540 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7541 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 7542 if (!X->isLValue() || !V->isLValue()) { 7543 const Expr *NotLValueExpr = X->isLValue() ? V : X; 7544 ErrorFound = NotAnLValue; 7545 ErrorLoc = AtomicBinOp->getExprLoc(); 7546 ErrorRange = AtomicBinOp->getSourceRange(); 7547 NoteLoc = NotLValueExpr->getExprLoc(); 7548 NoteRange = NotLValueExpr->getSourceRange(); 7549 } 7550 } else if (!X->isInstantiationDependent() || 7551 !V->isInstantiationDependent()) { 7552 const Expr *NotScalarExpr = 7553 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7554 ? V 7555 : X; 7556 ErrorFound = NotAScalarType; 7557 ErrorLoc = AtomicBinOp->getExprLoc(); 7558 ErrorRange = AtomicBinOp->getSourceRange(); 7559 NoteLoc = NotScalarExpr->getExprLoc(); 7560 NoteRange = NotScalarExpr->getSourceRange(); 7561 } 7562 } else if (!AtomicBody->isInstantiationDependent()) { 7563 ErrorFound = NotAnAssignmentOp; 7564 ErrorLoc = AtomicBody->getExprLoc(); 7565 ErrorRange = AtomicBody->getSourceRange(); 7566 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7567 : AtomicBody->getExprLoc(); 7568 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7569 : AtomicBody->getSourceRange(); 7570 } 7571 } else { 7572 ErrorFound = NotAnExpression; 7573 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7574 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7575 } 7576 if (ErrorFound != NoError) { 7577 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7578 << ErrorRange; 7579 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7580 << NoteRange; 7581 return StmtError(); 7582 } 7583 if (CurContext->isDependentContext()) 7584 V = X = nullptr; 7585 } else if (AtomicKind == OMPC_write) { 7586 enum { 7587 NotAnExpression, 7588 NotAnAssignmentOp, 7589 NotAScalarType, 7590 NotAnLValue, 7591 NoError 7592 } ErrorFound = NoError; 7593 SourceLocation ErrorLoc, NoteLoc; 7594 SourceRange ErrorRange, NoteRange; 7595 // If clause is write: 7596 // x = expr; 7597 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7598 const auto *AtomicBinOp = 7599 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7600 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7601 X = AtomicBinOp->getLHS(); 7602 E = AtomicBinOp->getRHS(); 7603 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7604 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 7605 if (!X->isLValue()) { 7606 ErrorFound = NotAnLValue; 7607 ErrorLoc = AtomicBinOp->getExprLoc(); 7608 ErrorRange = AtomicBinOp->getSourceRange(); 7609 NoteLoc = X->getExprLoc(); 7610 NoteRange = X->getSourceRange(); 7611 } 7612 } else if (!X->isInstantiationDependent() || 7613 !E->isInstantiationDependent()) { 7614 const Expr *NotScalarExpr = 7615 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7616 ? E 7617 : X; 7618 ErrorFound = NotAScalarType; 7619 ErrorLoc = AtomicBinOp->getExprLoc(); 7620 ErrorRange = AtomicBinOp->getSourceRange(); 7621 NoteLoc = NotScalarExpr->getExprLoc(); 7622 NoteRange = NotScalarExpr->getSourceRange(); 7623 } 7624 } else if (!AtomicBody->isInstantiationDependent()) { 7625 ErrorFound = NotAnAssignmentOp; 7626 ErrorLoc = AtomicBody->getExprLoc(); 7627 ErrorRange = AtomicBody->getSourceRange(); 7628 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7629 : AtomicBody->getExprLoc(); 7630 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7631 : AtomicBody->getSourceRange(); 7632 } 7633 } else { 7634 ErrorFound = NotAnExpression; 7635 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7636 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7637 } 7638 if (ErrorFound != NoError) { 7639 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 7640 << ErrorRange; 7641 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7642 << NoteRange; 7643 return StmtError(); 7644 } 7645 if (CurContext->isDependentContext()) 7646 E = X = nullptr; 7647 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 7648 // If clause is update: 7649 // x++; 7650 // x--; 7651 // ++x; 7652 // --x; 7653 // x binop= expr; 7654 // x = x binop expr; 7655 // x = expr binop x; 7656 OpenMPAtomicUpdateChecker Checker(*this); 7657 if (Checker.checkStatement( 7658 Body, (AtomicKind == OMPC_update) 7659 ? diag::err_omp_atomic_update_not_expression_statement 7660 : diag::err_omp_atomic_not_expression_statement, 7661 diag::note_omp_atomic_update)) 7662 return StmtError(); 7663 if (!CurContext->isDependentContext()) { 7664 E = Checker.getExpr(); 7665 X = Checker.getX(); 7666 UE = Checker.getUpdateExpr(); 7667 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7668 } 7669 } else if (AtomicKind == OMPC_capture) { 7670 enum { 7671 NotAnAssignmentOp, 7672 NotACompoundStatement, 7673 NotTwoSubstatements, 7674 NotASpecificExpression, 7675 NoError 7676 } ErrorFound = NoError; 7677 SourceLocation ErrorLoc, NoteLoc; 7678 SourceRange ErrorRange, NoteRange; 7679 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7680 // If clause is a capture: 7681 // v = x++; 7682 // v = x--; 7683 // v = ++x; 7684 // v = --x; 7685 // v = x binop= expr; 7686 // v = x = x binop expr; 7687 // v = x = expr binop x; 7688 const auto *AtomicBinOp = 7689 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7690 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7691 V = AtomicBinOp->getLHS(); 7692 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7693 OpenMPAtomicUpdateChecker Checker(*this); 7694 if (Checker.checkStatement( 7695 Body, diag::err_omp_atomic_capture_not_expression_statement, 7696 diag::note_omp_atomic_update)) 7697 return StmtError(); 7698 E = Checker.getExpr(); 7699 X = Checker.getX(); 7700 UE = Checker.getUpdateExpr(); 7701 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7702 IsPostfixUpdate = Checker.isPostfixUpdate(); 7703 } else if (!AtomicBody->isInstantiationDependent()) { 7704 ErrorLoc = AtomicBody->getExprLoc(); 7705 ErrorRange = AtomicBody->getSourceRange(); 7706 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7707 : AtomicBody->getExprLoc(); 7708 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7709 : AtomicBody->getSourceRange(); 7710 ErrorFound = NotAnAssignmentOp; 7711 } 7712 if (ErrorFound != NoError) { 7713 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7714 << ErrorRange; 7715 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7716 return StmtError(); 7717 } 7718 if (CurContext->isDependentContext()) 7719 UE = V = E = X = nullptr; 7720 } else { 7721 // If clause is a capture: 7722 // { v = x; x = expr; } 7723 // { v = x; x++; } 7724 // { v = x; x--; } 7725 // { v = x; ++x; } 7726 // { v = x; --x; } 7727 // { v = x; x binop= expr; } 7728 // { v = x; x = x binop expr; } 7729 // { v = x; x = expr binop x; } 7730 // { x++; v = x; } 7731 // { x--; v = x; } 7732 // { ++x; v = x; } 7733 // { --x; v = x; } 7734 // { x binop= expr; v = x; } 7735 // { x = x binop expr; v = x; } 7736 // { x = expr binop x; v = x; } 7737 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7738 // Check that this is { expr1; expr2; } 7739 if (CS->size() == 2) { 7740 Stmt *First = CS->body_front(); 7741 Stmt *Second = CS->body_back(); 7742 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7743 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7744 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7745 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7746 // Need to find what subexpression is 'v' and what is 'x'. 7747 OpenMPAtomicUpdateChecker Checker(*this); 7748 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7749 BinaryOperator *BinOp = nullptr; 7750 if (IsUpdateExprFound) { 7751 BinOp = dyn_cast<BinaryOperator>(First); 7752 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7753 } 7754 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7755 // { v = x; x++; } 7756 // { v = x; x--; } 7757 // { v = x; ++x; } 7758 // { v = x; --x; } 7759 // { v = x; x binop= expr; } 7760 // { v = x; x = x binop expr; } 7761 // { v = x; x = expr binop x; } 7762 // Check that the first expression has form v = x. 7763 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7764 llvm::FoldingSetNodeID XId, PossibleXId; 7765 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7766 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7767 IsUpdateExprFound = XId == PossibleXId; 7768 if (IsUpdateExprFound) { 7769 V = BinOp->getLHS(); 7770 X = Checker.getX(); 7771 E = Checker.getExpr(); 7772 UE = Checker.getUpdateExpr(); 7773 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7774 IsPostfixUpdate = true; 7775 } 7776 } 7777 if (!IsUpdateExprFound) { 7778 IsUpdateExprFound = !Checker.checkStatement(First); 7779 BinOp = nullptr; 7780 if (IsUpdateExprFound) { 7781 BinOp = dyn_cast<BinaryOperator>(Second); 7782 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7783 } 7784 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7785 // { x++; v = x; } 7786 // { x--; v = x; } 7787 // { ++x; v = x; } 7788 // { --x; v = x; } 7789 // { x binop= expr; v = x; } 7790 // { x = x binop expr; v = x; } 7791 // { x = expr binop x; v = x; } 7792 // Check that the second expression has form v = x. 7793 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7794 llvm::FoldingSetNodeID XId, PossibleXId; 7795 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7796 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7797 IsUpdateExprFound = XId == PossibleXId; 7798 if (IsUpdateExprFound) { 7799 V = BinOp->getLHS(); 7800 X = Checker.getX(); 7801 E = Checker.getExpr(); 7802 UE = Checker.getUpdateExpr(); 7803 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7804 IsPostfixUpdate = false; 7805 } 7806 } 7807 } 7808 if (!IsUpdateExprFound) { 7809 // { v = x; x = expr; } 7810 auto *FirstExpr = dyn_cast<Expr>(First); 7811 auto *SecondExpr = dyn_cast<Expr>(Second); 7812 if (!FirstExpr || !SecondExpr || 7813 !(FirstExpr->isInstantiationDependent() || 7814 SecondExpr->isInstantiationDependent())) { 7815 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7816 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7817 ErrorFound = NotAnAssignmentOp; 7818 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7819 : First->getBeginLoc(); 7820 NoteRange = ErrorRange = FirstBinOp 7821 ? FirstBinOp->getSourceRange() 7822 : SourceRange(ErrorLoc, ErrorLoc); 7823 } else { 7824 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7825 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7826 ErrorFound = NotAnAssignmentOp; 7827 NoteLoc = ErrorLoc = SecondBinOp 7828 ? SecondBinOp->getOperatorLoc() 7829 : Second->getBeginLoc(); 7830 NoteRange = ErrorRange = 7831 SecondBinOp ? SecondBinOp->getSourceRange() 7832 : SourceRange(ErrorLoc, ErrorLoc); 7833 } else { 7834 Expr *PossibleXRHSInFirst = 7835 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7836 Expr *PossibleXLHSInSecond = 7837 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7838 llvm::FoldingSetNodeID X1Id, X2Id; 7839 PossibleXRHSInFirst->Profile(X1Id, Context, 7840 /*Canonical=*/true); 7841 PossibleXLHSInSecond->Profile(X2Id, Context, 7842 /*Canonical=*/true); 7843 IsUpdateExprFound = X1Id == X2Id; 7844 if (IsUpdateExprFound) { 7845 V = FirstBinOp->getLHS(); 7846 X = SecondBinOp->getLHS(); 7847 E = SecondBinOp->getRHS(); 7848 UE = nullptr; 7849 IsXLHSInRHSPart = false; 7850 IsPostfixUpdate = true; 7851 } else { 7852 ErrorFound = NotASpecificExpression; 7853 ErrorLoc = FirstBinOp->getExprLoc(); 7854 ErrorRange = FirstBinOp->getSourceRange(); 7855 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7856 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7857 } 7858 } 7859 } 7860 } 7861 } 7862 } else { 7863 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7864 NoteRange = ErrorRange = 7865 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7866 ErrorFound = NotTwoSubstatements; 7867 } 7868 } else { 7869 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7870 NoteRange = ErrorRange = 7871 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7872 ErrorFound = NotACompoundStatement; 7873 } 7874 if (ErrorFound != NoError) { 7875 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7876 << ErrorRange; 7877 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7878 return StmtError(); 7879 } 7880 if (CurContext->isDependentContext()) 7881 UE = V = E = X = nullptr; 7882 } 7883 } 7884 7885 setFunctionHasBranchProtectedScope(); 7886 7887 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7888 X, V, E, UE, IsXLHSInRHSPart, 7889 IsPostfixUpdate); 7890 } 7891 7892 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7893 Stmt *AStmt, 7894 SourceLocation StartLoc, 7895 SourceLocation EndLoc) { 7896 if (!AStmt) 7897 return StmtError(); 7898 7899 auto *CS = cast<CapturedStmt>(AStmt); 7900 // 1.2.2 OpenMP Language Terminology 7901 // Structured block - An executable statement with a single entry at the 7902 // top and a single exit at the bottom. 7903 // The point of exit cannot be a branch out of the structured block. 7904 // longjmp() and throw() must not violate the entry/exit criteria. 7905 CS->getCapturedDecl()->setNothrow(); 7906 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7907 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7908 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7909 // 1.2.2 OpenMP Language Terminology 7910 // Structured block - An executable statement with a single entry at the 7911 // top and a single exit at the bottom. 7912 // The point of exit cannot be a branch out of the structured block. 7913 // longjmp() and throw() must not violate the entry/exit criteria. 7914 CS->getCapturedDecl()->setNothrow(); 7915 } 7916 7917 // OpenMP [2.16, Nesting of Regions] 7918 // If specified, a teams construct must be contained within a target 7919 // construct. That target construct must contain no statements or directives 7920 // outside of the teams construct. 7921 if (DSAStack->hasInnerTeamsRegion()) { 7922 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7923 bool OMPTeamsFound = true; 7924 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7925 auto I = CS->body_begin(); 7926 while (I != CS->body_end()) { 7927 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7928 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7929 OMPTeamsFound) { 7930 7931 OMPTeamsFound = false; 7932 break; 7933 } 7934 ++I; 7935 } 7936 assert(I != CS->body_end() && "Not found statement"); 7937 S = *I; 7938 } else { 7939 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7940 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7941 } 7942 if (!OMPTeamsFound) { 7943 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7944 Diag(DSAStack->getInnerTeamsRegionLoc(), 7945 diag::note_omp_nested_teams_construct_here); 7946 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7947 << isa<OMPExecutableDirective>(S); 7948 return StmtError(); 7949 } 7950 } 7951 7952 setFunctionHasBranchProtectedScope(); 7953 7954 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7955 } 7956 7957 StmtResult 7958 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7959 Stmt *AStmt, SourceLocation StartLoc, 7960 SourceLocation EndLoc) { 7961 if (!AStmt) 7962 return StmtError(); 7963 7964 auto *CS = cast<CapturedStmt>(AStmt); 7965 // 1.2.2 OpenMP Language Terminology 7966 // Structured block - An executable statement with a single entry at the 7967 // top and a single exit at the bottom. 7968 // The point of exit cannot be a branch out of the structured block. 7969 // longjmp() and throw() must not violate the entry/exit criteria. 7970 CS->getCapturedDecl()->setNothrow(); 7971 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7972 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7973 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7974 // 1.2.2 OpenMP Language Terminology 7975 // Structured block - An executable statement with a single entry at the 7976 // top and a single exit at the bottom. 7977 // The point of exit cannot be a branch out of the structured block. 7978 // longjmp() and throw() must not violate the entry/exit criteria. 7979 CS->getCapturedDecl()->setNothrow(); 7980 } 7981 7982 setFunctionHasBranchProtectedScope(); 7983 7984 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7985 AStmt); 7986 } 7987 7988 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7989 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7990 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7991 if (!AStmt) 7992 return StmtError(); 7993 7994 auto *CS = cast<CapturedStmt>(AStmt); 7995 // 1.2.2 OpenMP Language Terminology 7996 // Structured block - An executable statement with a single entry at the 7997 // top and a single exit at the bottom. 7998 // The point of exit cannot be a branch out of the structured block. 7999 // longjmp() and throw() must not violate the entry/exit criteria. 8000 CS->getCapturedDecl()->setNothrow(); 8001 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8002 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8003 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8004 // 1.2.2 OpenMP Language Terminology 8005 // Structured block - An executable statement with a single entry at the 8006 // top and a single exit at the bottom. 8007 // The point of exit cannot be a branch out of the structured block. 8008 // longjmp() and throw() must not violate the entry/exit criteria. 8009 CS->getCapturedDecl()->setNothrow(); 8010 } 8011 8012 OMPLoopDirective::HelperExprs B; 8013 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8014 // define the nested loops number. 8015 unsigned NestedLoopCount = 8016 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8017 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8018 VarsWithImplicitDSA, B); 8019 if (NestedLoopCount == 0) 8020 return StmtError(); 8021 8022 assert((CurContext->isDependentContext() || B.builtAll()) && 8023 "omp target parallel for loop exprs were not built"); 8024 8025 if (!CurContext->isDependentContext()) { 8026 // Finalize the clauses that need pre-built expressions for CodeGen. 8027 for (OMPClause *C : Clauses) { 8028 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8029 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8030 B.NumIterations, *this, CurScope, 8031 DSAStack)) 8032 return StmtError(); 8033 } 8034 } 8035 8036 setFunctionHasBranchProtectedScope(); 8037 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8038 NestedLoopCount, Clauses, AStmt, 8039 B, DSAStack->isCancelRegion()); 8040 } 8041 8042 /// Check for existence of a map clause in the list of clauses. 8043 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8044 const OpenMPClauseKind K) { 8045 return llvm::any_of( 8046 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8047 } 8048 8049 template <typename... Params> 8050 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8051 const Params... ClauseTypes) { 8052 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8053 } 8054 8055 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8056 Stmt *AStmt, 8057 SourceLocation StartLoc, 8058 SourceLocation EndLoc) { 8059 if (!AStmt) 8060 return StmtError(); 8061 8062 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8063 8064 // OpenMP [2.10.1, Restrictions, p. 97] 8065 // At least one map clause must appear on the directive. 8066 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8067 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8068 << "'map' or 'use_device_ptr'" 8069 << getOpenMPDirectiveName(OMPD_target_data); 8070 return StmtError(); 8071 } 8072 8073 setFunctionHasBranchProtectedScope(); 8074 8075 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8076 AStmt); 8077 } 8078 8079 StmtResult 8080 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8081 SourceLocation StartLoc, 8082 SourceLocation EndLoc, Stmt *AStmt) { 8083 if (!AStmt) 8084 return StmtError(); 8085 8086 auto *CS = cast<CapturedStmt>(AStmt); 8087 // 1.2.2 OpenMP Language Terminology 8088 // Structured block - An executable statement with a single entry at the 8089 // top and a single exit at the bottom. 8090 // The point of exit cannot be a branch out of the structured block. 8091 // longjmp() and throw() must not violate the entry/exit criteria. 8092 CS->getCapturedDecl()->setNothrow(); 8093 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8094 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8095 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8096 // 1.2.2 OpenMP Language Terminology 8097 // Structured block - An executable statement with a single entry at the 8098 // top and a single exit at the bottom. 8099 // The point of exit cannot be a branch out of the structured block. 8100 // longjmp() and throw() must not violate the entry/exit criteria. 8101 CS->getCapturedDecl()->setNothrow(); 8102 } 8103 8104 // OpenMP [2.10.2, Restrictions, p. 99] 8105 // At least one map clause must appear on the directive. 8106 if (!hasClauses(Clauses, OMPC_map)) { 8107 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8108 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8109 return StmtError(); 8110 } 8111 8112 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8113 AStmt); 8114 } 8115 8116 StmtResult 8117 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8118 SourceLocation StartLoc, 8119 SourceLocation EndLoc, Stmt *AStmt) { 8120 if (!AStmt) 8121 return StmtError(); 8122 8123 auto *CS = cast<CapturedStmt>(AStmt); 8124 // 1.2.2 OpenMP Language Terminology 8125 // Structured block - An executable statement with a single entry at the 8126 // top and a single exit at the bottom. 8127 // The point of exit cannot be a branch out of the structured block. 8128 // longjmp() and throw() must not violate the entry/exit criteria. 8129 CS->getCapturedDecl()->setNothrow(); 8130 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8131 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8132 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8133 // 1.2.2 OpenMP Language Terminology 8134 // Structured block - An executable statement with a single entry at the 8135 // top and a single exit at the bottom. 8136 // The point of exit cannot be a branch out of the structured block. 8137 // longjmp() and throw() must not violate the entry/exit criteria. 8138 CS->getCapturedDecl()->setNothrow(); 8139 } 8140 8141 // OpenMP [2.10.3, Restrictions, p. 102] 8142 // At least one map clause must appear on the directive. 8143 if (!hasClauses(Clauses, OMPC_map)) { 8144 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8145 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8146 return StmtError(); 8147 } 8148 8149 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8150 AStmt); 8151 } 8152 8153 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8154 SourceLocation StartLoc, 8155 SourceLocation EndLoc, 8156 Stmt *AStmt) { 8157 if (!AStmt) 8158 return StmtError(); 8159 8160 auto *CS = cast<CapturedStmt>(AStmt); 8161 // 1.2.2 OpenMP Language Terminology 8162 // Structured block - An executable statement with a single entry at the 8163 // top and a single exit at the bottom. 8164 // The point of exit cannot be a branch out of the structured block. 8165 // longjmp() and throw() must not violate the entry/exit criteria. 8166 CS->getCapturedDecl()->setNothrow(); 8167 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8168 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8169 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8170 // 1.2.2 OpenMP Language Terminology 8171 // Structured block - An executable statement with a single entry at the 8172 // top and a single exit at the bottom. 8173 // The point of exit cannot be a branch out of the structured block. 8174 // longjmp() and throw() must not violate the entry/exit criteria. 8175 CS->getCapturedDecl()->setNothrow(); 8176 } 8177 8178 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8179 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8180 return StmtError(); 8181 } 8182 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8183 AStmt); 8184 } 8185 8186 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8187 Stmt *AStmt, SourceLocation StartLoc, 8188 SourceLocation EndLoc) { 8189 if (!AStmt) 8190 return StmtError(); 8191 8192 auto *CS = cast<CapturedStmt>(AStmt); 8193 // 1.2.2 OpenMP Language Terminology 8194 // Structured block - An executable statement with a single entry at the 8195 // top and a single exit at the bottom. 8196 // The point of exit cannot be a branch out of the structured block. 8197 // longjmp() and throw() must not violate the entry/exit criteria. 8198 CS->getCapturedDecl()->setNothrow(); 8199 8200 setFunctionHasBranchProtectedScope(); 8201 8202 DSAStack->setParentTeamsRegionLoc(StartLoc); 8203 8204 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8205 } 8206 8207 StmtResult 8208 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8209 SourceLocation EndLoc, 8210 OpenMPDirectiveKind CancelRegion) { 8211 if (DSAStack->isParentNowaitRegion()) { 8212 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8213 return StmtError(); 8214 } 8215 if (DSAStack->isParentOrderedRegion()) { 8216 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8217 return StmtError(); 8218 } 8219 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8220 CancelRegion); 8221 } 8222 8223 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8224 SourceLocation StartLoc, 8225 SourceLocation EndLoc, 8226 OpenMPDirectiveKind CancelRegion) { 8227 if (DSAStack->isParentNowaitRegion()) { 8228 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8229 return StmtError(); 8230 } 8231 if (DSAStack->isParentOrderedRegion()) { 8232 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8233 return StmtError(); 8234 } 8235 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8236 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8237 CancelRegion); 8238 } 8239 8240 static bool checkGrainsizeNumTasksClauses(Sema &S, 8241 ArrayRef<OMPClause *> Clauses) { 8242 const OMPClause *PrevClause = nullptr; 8243 bool ErrorFound = false; 8244 for (const OMPClause *C : Clauses) { 8245 if (C->getClauseKind() == OMPC_grainsize || 8246 C->getClauseKind() == OMPC_num_tasks) { 8247 if (!PrevClause) 8248 PrevClause = C; 8249 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8250 S.Diag(C->getBeginLoc(), 8251 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8252 << getOpenMPClauseName(C->getClauseKind()) 8253 << getOpenMPClauseName(PrevClause->getClauseKind()); 8254 S.Diag(PrevClause->getBeginLoc(), 8255 diag::note_omp_previous_grainsize_num_tasks) 8256 << getOpenMPClauseName(PrevClause->getClauseKind()); 8257 ErrorFound = true; 8258 } 8259 } 8260 } 8261 return ErrorFound; 8262 } 8263 8264 static bool checkReductionClauseWithNogroup(Sema &S, 8265 ArrayRef<OMPClause *> Clauses) { 8266 const OMPClause *ReductionClause = nullptr; 8267 const OMPClause *NogroupClause = nullptr; 8268 for (const OMPClause *C : Clauses) { 8269 if (C->getClauseKind() == OMPC_reduction) { 8270 ReductionClause = C; 8271 if (NogroupClause) 8272 break; 8273 continue; 8274 } 8275 if (C->getClauseKind() == OMPC_nogroup) { 8276 NogroupClause = C; 8277 if (ReductionClause) 8278 break; 8279 continue; 8280 } 8281 } 8282 if (ReductionClause && NogroupClause) { 8283 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8284 << SourceRange(NogroupClause->getBeginLoc(), 8285 NogroupClause->getEndLoc()); 8286 return true; 8287 } 8288 return false; 8289 } 8290 8291 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8292 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8293 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8294 if (!AStmt) 8295 return StmtError(); 8296 8297 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8298 OMPLoopDirective::HelperExprs B; 8299 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8300 // define the nested loops number. 8301 unsigned NestedLoopCount = 8302 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8303 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8304 VarsWithImplicitDSA, B); 8305 if (NestedLoopCount == 0) 8306 return StmtError(); 8307 8308 assert((CurContext->isDependentContext() || B.builtAll()) && 8309 "omp for loop exprs were not built"); 8310 8311 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8312 // The grainsize clause and num_tasks clause are mutually exclusive and may 8313 // not appear on the same taskloop directive. 8314 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8315 return StmtError(); 8316 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8317 // If a reduction clause is present on the taskloop directive, the nogroup 8318 // clause must not be specified. 8319 if (checkReductionClauseWithNogroup(*this, Clauses)) 8320 return StmtError(); 8321 8322 setFunctionHasBranchProtectedScope(); 8323 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8324 NestedLoopCount, Clauses, AStmt, B); 8325 } 8326 8327 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8328 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8329 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8330 if (!AStmt) 8331 return StmtError(); 8332 8333 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8334 OMPLoopDirective::HelperExprs B; 8335 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8336 // define the nested loops number. 8337 unsigned NestedLoopCount = 8338 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8339 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8340 VarsWithImplicitDSA, B); 8341 if (NestedLoopCount == 0) 8342 return StmtError(); 8343 8344 assert((CurContext->isDependentContext() || B.builtAll()) && 8345 "omp for loop exprs were not built"); 8346 8347 if (!CurContext->isDependentContext()) { 8348 // Finalize the clauses that need pre-built expressions for CodeGen. 8349 for (OMPClause *C : Clauses) { 8350 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8351 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8352 B.NumIterations, *this, CurScope, 8353 DSAStack)) 8354 return StmtError(); 8355 } 8356 } 8357 8358 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8359 // The grainsize clause and num_tasks clause are mutually exclusive and may 8360 // not appear on the same taskloop directive. 8361 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8362 return StmtError(); 8363 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8364 // If a reduction clause is present on the taskloop directive, the nogroup 8365 // clause must not be specified. 8366 if (checkReductionClauseWithNogroup(*this, Clauses)) 8367 return StmtError(); 8368 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8369 return StmtError(); 8370 8371 setFunctionHasBranchProtectedScope(); 8372 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8373 NestedLoopCount, Clauses, AStmt, B); 8374 } 8375 8376 StmtResult Sema::ActOnOpenMPDistributeDirective( 8377 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8378 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8379 if (!AStmt) 8380 return StmtError(); 8381 8382 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8383 OMPLoopDirective::HelperExprs B; 8384 // In presence of clause 'collapse' with number of loops, it will 8385 // define the nested loops number. 8386 unsigned NestedLoopCount = 8387 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8388 nullptr /*ordered not a clause on distribute*/, AStmt, 8389 *this, *DSAStack, VarsWithImplicitDSA, B); 8390 if (NestedLoopCount == 0) 8391 return StmtError(); 8392 8393 assert((CurContext->isDependentContext() || B.builtAll()) && 8394 "omp for loop exprs were not built"); 8395 8396 setFunctionHasBranchProtectedScope(); 8397 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8398 NestedLoopCount, Clauses, AStmt, B); 8399 } 8400 8401 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8402 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8403 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8404 if (!AStmt) 8405 return StmtError(); 8406 8407 auto *CS = cast<CapturedStmt>(AStmt); 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 for (int ThisCaptureLevel = 8415 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 8416 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8417 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8418 // 1.2.2 OpenMP Language Terminology 8419 // Structured block - An executable statement with a single entry at the 8420 // top and a single exit at the bottom. 8421 // The point of exit cannot be a branch out of the structured block. 8422 // longjmp() and throw() must not violate the entry/exit criteria. 8423 CS->getCapturedDecl()->setNothrow(); 8424 } 8425 8426 OMPLoopDirective::HelperExprs B; 8427 // In presence of clause 'collapse' with number of loops, it will 8428 // define the nested loops number. 8429 unsigned NestedLoopCount = checkOpenMPLoop( 8430 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8431 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8432 VarsWithImplicitDSA, B); 8433 if (NestedLoopCount == 0) 8434 return StmtError(); 8435 8436 assert((CurContext->isDependentContext() || B.builtAll()) && 8437 "omp for loop exprs were not built"); 8438 8439 setFunctionHasBranchProtectedScope(); 8440 return OMPDistributeParallelForDirective::Create( 8441 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8442 DSAStack->isCancelRegion()); 8443 } 8444 8445 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 8446 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8447 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8448 if (!AStmt) 8449 return StmtError(); 8450 8451 auto *CS = cast<CapturedStmt>(AStmt); 8452 // 1.2.2 OpenMP Language Terminology 8453 // Structured block - An executable statement with a single entry at the 8454 // top and a single exit at the bottom. 8455 // The point of exit cannot be a branch out of the structured block. 8456 // longjmp() and throw() must not violate the entry/exit criteria. 8457 CS->getCapturedDecl()->setNothrow(); 8458 for (int ThisCaptureLevel = 8459 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 8460 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8461 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8462 // 1.2.2 OpenMP Language Terminology 8463 // Structured block - An executable statement with a single entry at the 8464 // top and a single exit at the bottom. 8465 // The point of exit cannot be a branch out of the structured block. 8466 // longjmp() and throw() must not violate the entry/exit criteria. 8467 CS->getCapturedDecl()->setNothrow(); 8468 } 8469 8470 OMPLoopDirective::HelperExprs B; 8471 // In presence of clause 'collapse' with number of loops, it will 8472 // define the nested loops number. 8473 unsigned NestedLoopCount = checkOpenMPLoop( 8474 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8475 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8476 VarsWithImplicitDSA, B); 8477 if (NestedLoopCount == 0) 8478 return StmtError(); 8479 8480 assert((CurContext->isDependentContext() || B.builtAll()) && 8481 "omp for loop exprs were not built"); 8482 8483 if (!CurContext->isDependentContext()) { 8484 // Finalize the clauses that need pre-built expressions for CodeGen. 8485 for (OMPClause *C : Clauses) { 8486 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8487 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8488 B.NumIterations, *this, CurScope, 8489 DSAStack)) 8490 return StmtError(); 8491 } 8492 } 8493 8494 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8495 return StmtError(); 8496 8497 setFunctionHasBranchProtectedScope(); 8498 return OMPDistributeParallelForSimdDirective::Create( 8499 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8500 } 8501 8502 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 8503 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8504 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8505 if (!AStmt) 8506 return StmtError(); 8507 8508 auto *CS = cast<CapturedStmt>(AStmt); 8509 // 1.2.2 OpenMP Language Terminology 8510 // Structured block - An executable statement with a single entry at the 8511 // top and a single exit at the bottom. 8512 // The point of exit cannot be a branch out of the structured block. 8513 // longjmp() and throw() must not violate the entry/exit criteria. 8514 CS->getCapturedDecl()->setNothrow(); 8515 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 8516 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8517 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8518 // 1.2.2 OpenMP Language Terminology 8519 // Structured block - An executable statement with a single entry at the 8520 // top and a single exit at the bottom. 8521 // The point of exit cannot be a branch out of the structured block. 8522 // longjmp() and throw() must not violate the entry/exit criteria. 8523 CS->getCapturedDecl()->setNothrow(); 8524 } 8525 8526 OMPLoopDirective::HelperExprs B; 8527 // In presence of clause 'collapse' with number of loops, it will 8528 // define the nested loops number. 8529 unsigned NestedLoopCount = 8530 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 8531 nullptr /*ordered not a clause on distribute*/, CS, *this, 8532 *DSAStack, VarsWithImplicitDSA, B); 8533 if (NestedLoopCount == 0) 8534 return StmtError(); 8535 8536 assert((CurContext->isDependentContext() || B.builtAll()) && 8537 "omp for loop exprs were not built"); 8538 8539 if (!CurContext->isDependentContext()) { 8540 // Finalize the clauses that need pre-built expressions for CodeGen. 8541 for (OMPClause *C : Clauses) { 8542 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8543 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8544 B.NumIterations, *this, CurScope, 8545 DSAStack)) 8546 return StmtError(); 8547 } 8548 } 8549 8550 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8551 return StmtError(); 8552 8553 setFunctionHasBranchProtectedScope(); 8554 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 8555 NestedLoopCount, Clauses, AStmt, B); 8556 } 8557 8558 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 8559 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8560 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 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_parallel_for); 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 OMPLoopDirective::HelperExprs B; 8583 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8584 // define the nested loops number. 8585 unsigned NestedLoopCount = checkOpenMPLoop( 8586 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8587 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8588 VarsWithImplicitDSA, B); 8589 if (NestedLoopCount == 0) 8590 return StmtError(); 8591 8592 assert((CurContext->isDependentContext() || B.builtAll()) && 8593 "omp target parallel for simd loop exprs were not built"); 8594 8595 if (!CurContext->isDependentContext()) { 8596 // Finalize the clauses that need pre-built expressions for CodeGen. 8597 for (OMPClause *C : Clauses) { 8598 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8599 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8600 B.NumIterations, *this, CurScope, 8601 DSAStack)) 8602 return StmtError(); 8603 } 8604 } 8605 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8606 return StmtError(); 8607 8608 setFunctionHasBranchProtectedScope(); 8609 return OMPTargetParallelForSimdDirective::Create( 8610 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8611 } 8612 8613 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 8614 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8615 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8616 if (!AStmt) 8617 return StmtError(); 8618 8619 auto *CS = cast<CapturedStmt>(AStmt); 8620 // 1.2.2 OpenMP Language Terminology 8621 // Structured block - An executable statement with a single entry at the 8622 // top and a single exit at the bottom. 8623 // The point of exit cannot be a branch out of the structured block. 8624 // longjmp() and throw() must not violate the entry/exit criteria. 8625 CS->getCapturedDecl()->setNothrow(); 8626 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 8627 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8628 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8629 // 1.2.2 OpenMP Language Terminology 8630 // Structured block - An executable statement with a single entry at the 8631 // top and a single exit at the bottom. 8632 // The point of exit cannot be a branch out of the structured block. 8633 // longjmp() and throw() must not violate the entry/exit criteria. 8634 CS->getCapturedDecl()->setNothrow(); 8635 } 8636 8637 OMPLoopDirective::HelperExprs B; 8638 // In presence of clause 'collapse' with number of loops, it will define the 8639 // nested loops number. 8640 unsigned NestedLoopCount = 8641 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 8642 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8643 VarsWithImplicitDSA, B); 8644 if (NestedLoopCount == 0) 8645 return StmtError(); 8646 8647 assert((CurContext->isDependentContext() || B.builtAll()) && 8648 "omp target simd loop exprs were not built"); 8649 8650 if (!CurContext->isDependentContext()) { 8651 // Finalize the clauses that need pre-built expressions for CodeGen. 8652 for (OMPClause *C : Clauses) { 8653 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8654 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8655 B.NumIterations, *this, CurScope, 8656 DSAStack)) 8657 return StmtError(); 8658 } 8659 } 8660 8661 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8662 return StmtError(); 8663 8664 setFunctionHasBranchProtectedScope(); 8665 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 8666 NestedLoopCount, Clauses, AStmt, B); 8667 } 8668 8669 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 8670 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8671 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8672 if (!AStmt) 8673 return StmtError(); 8674 8675 auto *CS = cast<CapturedStmt>(AStmt); 8676 // 1.2.2 OpenMP Language Terminology 8677 // Structured block - An executable statement with a single entry at the 8678 // top and a single exit at the bottom. 8679 // The point of exit cannot be a branch out of the structured block. 8680 // longjmp() and throw() must not violate the entry/exit criteria. 8681 CS->getCapturedDecl()->setNothrow(); 8682 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 8683 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8684 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8685 // 1.2.2 OpenMP Language Terminology 8686 // Structured block - An executable statement with a single entry at the 8687 // top and a single exit at the bottom. 8688 // The point of exit cannot be a branch out of the structured block. 8689 // longjmp() and throw() must not violate the entry/exit criteria. 8690 CS->getCapturedDecl()->setNothrow(); 8691 } 8692 8693 OMPLoopDirective::HelperExprs B; 8694 // In presence of clause 'collapse' with number of loops, it will 8695 // define the nested loops number. 8696 unsigned NestedLoopCount = 8697 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 8698 nullptr /*ordered not a clause on distribute*/, CS, *this, 8699 *DSAStack, VarsWithImplicitDSA, B); 8700 if (NestedLoopCount == 0) 8701 return StmtError(); 8702 8703 assert((CurContext->isDependentContext() || B.builtAll()) && 8704 "omp teams distribute loop exprs were not built"); 8705 8706 setFunctionHasBranchProtectedScope(); 8707 8708 DSAStack->setParentTeamsRegionLoc(StartLoc); 8709 8710 return OMPTeamsDistributeDirective::Create( 8711 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8712 } 8713 8714 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 8715 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8716 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8717 if (!AStmt) 8718 return StmtError(); 8719 8720 auto *CS = cast<CapturedStmt>(AStmt); 8721 // 1.2.2 OpenMP Language Terminology 8722 // Structured block - An executable statement with a single entry at the 8723 // top and a single exit at the bottom. 8724 // The point of exit cannot be a branch out of the structured block. 8725 // longjmp() and throw() must not violate the entry/exit criteria. 8726 CS->getCapturedDecl()->setNothrow(); 8727 for (int ThisCaptureLevel = 8728 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8729 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8730 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8731 // 1.2.2 OpenMP Language Terminology 8732 // Structured block - An executable statement with a single entry at the 8733 // top and a single exit at the bottom. 8734 // The point of exit cannot be a branch out of the structured block. 8735 // longjmp() and throw() must not violate the entry/exit criteria. 8736 CS->getCapturedDecl()->setNothrow(); 8737 } 8738 8739 8740 OMPLoopDirective::HelperExprs B; 8741 // In presence of clause 'collapse' with number of loops, it will 8742 // define the nested loops number. 8743 unsigned NestedLoopCount = checkOpenMPLoop( 8744 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8745 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8746 VarsWithImplicitDSA, B); 8747 8748 if (NestedLoopCount == 0) 8749 return StmtError(); 8750 8751 assert((CurContext->isDependentContext() || B.builtAll()) && 8752 "omp teams distribute simd loop exprs were not built"); 8753 8754 if (!CurContext->isDependentContext()) { 8755 // Finalize the clauses that need pre-built expressions for CodeGen. 8756 for (OMPClause *C : Clauses) { 8757 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8758 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8759 B.NumIterations, *this, CurScope, 8760 DSAStack)) 8761 return StmtError(); 8762 } 8763 } 8764 8765 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8766 return StmtError(); 8767 8768 setFunctionHasBranchProtectedScope(); 8769 8770 DSAStack->setParentTeamsRegionLoc(StartLoc); 8771 8772 return OMPTeamsDistributeSimdDirective::Create( 8773 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8774 } 8775 8776 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8777 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8778 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8779 if (!AStmt) 8780 return StmtError(); 8781 8782 auto *CS = cast<CapturedStmt>(AStmt); 8783 // 1.2.2 OpenMP Language Terminology 8784 // Structured block - An executable statement with a single entry at the 8785 // top and a single exit at the bottom. 8786 // The point of exit cannot be a branch out of the structured block. 8787 // longjmp() and throw() must not violate the entry/exit criteria. 8788 CS->getCapturedDecl()->setNothrow(); 8789 8790 for (int ThisCaptureLevel = 8791 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8792 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8793 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8794 // 1.2.2 OpenMP Language Terminology 8795 // Structured block - An executable statement with a single entry at the 8796 // top and a single exit at the bottom. 8797 // The point of exit cannot be a branch out of the structured block. 8798 // longjmp() and throw() must not violate the entry/exit criteria. 8799 CS->getCapturedDecl()->setNothrow(); 8800 } 8801 8802 OMPLoopDirective::HelperExprs B; 8803 // In presence of clause 'collapse' with number of loops, it will 8804 // define the nested loops number. 8805 unsigned NestedLoopCount = checkOpenMPLoop( 8806 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8807 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8808 VarsWithImplicitDSA, B); 8809 8810 if (NestedLoopCount == 0) 8811 return StmtError(); 8812 8813 assert((CurContext->isDependentContext() || B.builtAll()) && 8814 "omp for loop exprs were not built"); 8815 8816 if (!CurContext->isDependentContext()) { 8817 // Finalize the clauses that need pre-built expressions for CodeGen. 8818 for (OMPClause *C : Clauses) { 8819 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8820 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8821 B.NumIterations, *this, CurScope, 8822 DSAStack)) 8823 return StmtError(); 8824 } 8825 } 8826 8827 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8828 return StmtError(); 8829 8830 setFunctionHasBranchProtectedScope(); 8831 8832 DSAStack->setParentTeamsRegionLoc(StartLoc); 8833 8834 return OMPTeamsDistributeParallelForSimdDirective::Create( 8835 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8836 } 8837 8838 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 8839 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8840 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8841 if (!AStmt) 8842 return StmtError(); 8843 8844 auto *CS = cast<CapturedStmt>(AStmt); 8845 // 1.2.2 OpenMP Language Terminology 8846 // Structured block - An executable statement with a single entry at the 8847 // top and a single exit at the bottom. 8848 // The point of exit cannot be a branch out of the structured block. 8849 // longjmp() and throw() must not violate the entry/exit criteria. 8850 CS->getCapturedDecl()->setNothrow(); 8851 8852 for (int ThisCaptureLevel = 8853 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8854 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8855 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 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 } 8863 8864 OMPLoopDirective::HelperExprs B; 8865 // In presence of clause 'collapse' with number of loops, it will 8866 // define the nested loops number. 8867 unsigned NestedLoopCount = checkOpenMPLoop( 8868 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8869 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8870 VarsWithImplicitDSA, B); 8871 8872 if (NestedLoopCount == 0) 8873 return StmtError(); 8874 8875 assert((CurContext->isDependentContext() || B.builtAll()) && 8876 "omp for loop exprs were not built"); 8877 8878 setFunctionHasBranchProtectedScope(); 8879 8880 DSAStack->setParentTeamsRegionLoc(StartLoc); 8881 8882 return OMPTeamsDistributeParallelForDirective::Create( 8883 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8884 DSAStack->isCancelRegion()); 8885 } 8886 8887 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8888 Stmt *AStmt, 8889 SourceLocation StartLoc, 8890 SourceLocation EndLoc) { 8891 if (!AStmt) 8892 return StmtError(); 8893 8894 auto *CS = cast<CapturedStmt>(AStmt); 8895 // 1.2.2 OpenMP Language Terminology 8896 // Structured block - An executable statement with a single entry at the 8897 // top and a single exit at the bottom. 8898 // The point of exit cannot be a branch out of the structured block. 8899 // longjmp() and throw() must not violate the entry/exit criteria. 8900 CS->getCapturedDecl()->setNothrow(); 8901 8902 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8903 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8904 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8905 // 1.2.2 OpenMP Language Terminology 8906 // Structured block - An executable statement with a single entry at the 8907 // top and a single exit at the bottom. 8908 // The point of exit cannot be a branch out of the structured block. 8909 // longjmp() and throw() must not violate the entry/exit criteria. 8910 CS->getCapturedDecl()->setNothrow(); 8911 } 8912 setFunctionHasBranchProtectedScope(); 8913 8914 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8915 AStmt); 8916 } 8917 8918 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8919 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8920 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8921 if (!AStmt) 8922 return StmtError(); 8923 8924 auto *CS = cast<CapturedStmt>(AStmt); 8925 // 1.2.2 OpenMP Language Terminology 8926 // Structured block - An executable statement with a single entry at the 8927 // top and a single exit at the bottom. 8928 // The point of exit cannot be a branch out of the structured block. 8929 // longjmp() and throw() must not violate the entry/exit criteria. 8930 CS->getCapturedDecl()->setNothrow(); 8931 for (int ThisCaptureLevel = 8932 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8933 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8934 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8935 // 1.2.2 OpenMP Language Terminology 8936 // Structured block - An executable statement with a single entry at the 8937 // top and a single exit at the bottom. 8938 // The point of exit cannot be a branch out of the structured block. 8939 // longjmp() and throw() must not violate the entry/exit criteria. 8940 CS->getCapturedDecl()->setNothrow(); 8941 } 8942 8943 OMPLoopDirective::HelperExprs B; 8944 // In presence of clause 'collapse' with number of loops, it will 8945 // define the nested loops number. 8946 unsigned NestedLoopCount = checkOpenMPLoop( 8947 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8948 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8949 VarsWithImplicitDSA, B); 8950 if (NestedLoopCount == 0) 8951 return StmtError(); 8952 8953 assert((CurContext->isDependentContext() || B.builtAll()) && 8954 "omp target teams distribute loop exprs were not built"); 8955 8956 setFunctionHasBranchProtectedScope(); 8957 return OMPTargetTeamsDistributeDirective::Create( 8958 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8959 } 8960 8961 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8962 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8963 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8964 if (!AStmt) 8965 return StmtError(); 8966 8967 auto *CS = cast<CapturedStmt>(AStmt); 8968 // 1.2.2 OpenMP Language Terminology 8969 // Structured block - An executable statement with a single entry at the 8970 // top and a single exit at the bottom. 8971 // The point of exit cannot be a branch out of the structured block. 8972 // longjmp() and throw() must not violate the entry/exit criteria. 8973 CS->getCapturedDecl()->setNothrow(); 8974 for (int ThisCaptureLevel = 8975 getOpenMPCaptureLevels(OMPD_target_teams_distribute_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' with number of loops, it will 8988 // define the nested loops number. 8989 unsigned NestedLoopCount = checkOpenMPLoop( 8990 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8991 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8992 VarsWithImplicitDSA, B); 8993 if (NestedLoopCount == 0) 8994 return StmtError(); 8995 8996 assert((CurContext->isDependentContext() || B.builtAll()) && 8997 "omp target teams distribute parallel for 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 9010 setFunctionHasBranchProtectedScope(); 9011 return OMPTargetTeamsDistributeParallelForDirective::Create( 9012 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9013 DSAStack->isCancelRegion()); 9014 } 9015 9016 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9017 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9018 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9019 if (!AStmt) 9020 return StmtError(); 9021 9022 auto *CS = cast<CapturedStmt>(AStmt); 9023 // 1.2.2 OpenMP Language Terminology 9024 // Structured block - An executable statement with a single entry at the 9025 // top and a single exit at the bottom. 9026 // The point of exit cannot be a branch out of the structured block. 9027 // longjmp() and throw() must not violate the entry/exit criteria. 9028 CS->getCapturedDecl()->setNothrow(); 9029 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9030 OMPD_target_teams_distribute_parallel_for_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 9043 // define the nested loops number. 9044 unsigned NestedLoopCount = 9045 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9046 getCollapseNumberExpr(Clauses), 9047 nullptr /*ordered not a clause on distribute*/, CS, *this, 9048 *DSAStack, VarsWithImplicitDSA, B); 9049 if (NestedLoopCount == 0) 9050 return StmtError(); 9051 9052 assert((CurContext->isDependentContext() || B.builtAll()) && 9053 "omp target teams distribute parallel for simd loop exprs were not " 9054 "built"); 9055 9056 if (!CurContext->isDependentContext()) { 9057 // Finalize the clauses that need pre-built expressions for CodeGen. 9058 for (OMPClause *C : Clauses) { 9059 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9060 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9061 B.NumIterations, *this, CurScope, 9062 DSAStack)) 9063 return StmtError(); 9064 } 9065 } 9066 9067 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9068 return StmtError(); 9069 9070 setFunctionHasBranchProtectedScope(); 9071 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9072 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9073 } 9074 9075 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9076 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9077 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9078 if (!AStmt) 9079 return StmtError(); 9080 9081 auto *CS = cast<CapturedStmt>(AStmt); 9082 // 1.2.2 OpenMP Language Terminology 9083 // Structured block - An executable statement with a single entry at the 9084 // top and a single exit at the bottom. 9085 // The point of exit cannot be a branch out of the structured block. 9086 // longjmp() and throw() must not violate the entry/exit criteria. 9087 CS->getCapturedDecl()->setNothrow(); 9088 for (int ThisCaptureLevel = 9089 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9090 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9091 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9092 // 1.2.2 OpenMP Language Terminology 9093 // Structured block - An executable statement with a single entry at the 9094 // top and a single exit at the bottom. 9095 // The point of exit cannot be a branch out of the structured block. 9096 // longjmp() and throw() must not violate the entry/exit criteria. 9097 CS->getCapturedDecl()->setNothrow(); 9098 } 9099 9100 OMPLoopDirective::HelperExprs B; 9101 // In presence of clause 'collapse' with number of loops, it will 9102 // define the nested loops number. 9103 unsigned NestedLoopCount = checkOpenMPLoop( 9104 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9105 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9106 VarsWithImplicitDSA, B); 9107 if (NestedLoopCount == 0) 9108 return StmtError(); 9109 9110 assert((CurContext->isDependentContext() || B.builtAll()) && 9111 "omp target teams distribute simd loop exprs were not built"); 9112 9113 if (!CurContext->isDependentContext()) { 9114 // Finalize the clauses that need pre-built expressions for CodeGen. 9115 for (OMPClause *C : Clauses) { 9116 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9117 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9118 B.NumIterations, *this, CurScope, 9119 DSAStack)) 9120 return StmtError(); 9121 } 9122 } 9123 9124 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9125 return StmtError(); 9126 9127 setFunctionHasBranchProtectedScope(); 9128 return OMPTargetTeamsDistributeSimdDirective::Create( 9129 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9130 } 9131 9132 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9133 SourceLocation StartLoc, 9134 SourceLocation LParenLoc, 9135 SourceLocation EndLoc) { 9136 OMPClause *Res = nullptr; 9137 switch (Kind) { 9138 case OMPC_final: 9139 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9140 break; 9141 case OMPC_num_threads: 9142 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9143 break; 9144 case OMPC_safelen: 9145 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9146 break; 9147 case OMPC_simdlen: 9148 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9149 break; 9150 case OMPC_allocator: 9151 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9152 break; 9153 case OMPC_collapse: 9154 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9155 break; 9156 case OMPC_ordered: 9157 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9158 break; 9159 case OMPC_device: 9160 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9161 break; 9162 case OMPC_num_teams: 9163 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9164 break; 9165 case OMPC_thread_limit: 9166 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9167 break; 9168 case OMPC_priority: 9169 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9170 break; 9171 case OMPC_grainsize: 9172 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9173 break; 9174 case OMPC_num_tasks: 9175 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9176 break; 9177 case OMPC_hint: 9178 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9179 break; 9180 case OMPC_if: 9181 case OMPC_default: 9182 case OMPC_proc_bind: 9183 case OMPC_schedule: 9184 case OMPC_private: 9185 case OMPC_firstprivate: 9186 case OMPC_lastprivate: 9187 case OMPC_shared: 9188 case OMPC_reduction: 9189 case OMPC_task_reduction: 9190 case OMPC_in_reduction: 9191 case OMPC_linear: 9192 case OMPC_aligned: 9193 case OMPC_copyin: 9194 case OMPC_copyprivate: 9195 case OMPC_nowait: 9196 case OMPC_untied: 9197 case OMPC_mergeable: 9198 case OMPC_threadprivate: 9199 case OMPC_allocate: 9200 case OMPC_flush: 9201 case OMPC_read: 9202 case OMPC_write: 9203 case OMPC_update: 9204 case OMPC_capture: 9205 case OMPC_seq_cst: 9206 case OMPC_depend: 9207 case OMPC_threads: 9208 case OMPC_simd: 9209 case OMPC_map: 9210 case OMPC_nogroup: 9211 case OMPC_dist_schedule: 9212 case OMPC_defaultmap: 9213 case OMPC_unknown: 9214 case OMPC_uniform: 9215 case OMPC_to: 9216 case OMPC_from: 9217 case OMPC_use_device_ptr: 9218 case OMPC_is_device_ptr: 9219 case OMPC_unified_address: 9220 case OMPC_unified_shared_memory: 9221 case OMPC_reverse_offload: 9222 case OMPC_dynamic_allocators: 9223 case OMPC_atomic_default_mem_order: 9224 llvm_unreachable("Clause is not allowed."); 9225 } 9226 return Res; 9227 } 9228 9229 // An OpenMP directive such as 'target parallel' has two captured regions: 9230 // for the 'target' and 'parallel' respectively. This function returns 9231 // the region in which to capture expressions associated with a clause. 9232 // A return value of OMPD_unknown signifies that the expression should not 9233 // be captured. 9234 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9235 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9236 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9237 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9238 switch (CKind) { 9239 case OMPC_if: 9240 switch (DKind) { 9241 case OMPD_target_parallel: 9242 case OMPD_target_parallel_for: 9243 case OMPD_target_parallel_for_simd: 9244 // If this clause applies to the nested 'parallel' region, capture within 9245 // the 'target' region, otherwise do not capture. 9246 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9247 CaptureRegion = OMPD_target; 9248 break; 9249 case OMPD_target_teams_distribute_parallel_for: 9250 case OMPD_target_teams_distribute_parallel_for_simd: 9251 // If this clause applies to the nested 'parallel' region, capture within 9252 // the 'teams' region, otherwise do not capture. 9253 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9254 CaptureRegion = OMPD_teams; 9255 break; 9256 case OMPD_teams_distribute_parallel_for: 9257 case OMPD_teams_distribute_parallel_for_simd: 9258 CaptureRegion = OMPD_teams; 9259 break; 9260 case OMPD_target_update: 9261 case OMPD_target_enter_data: 9262 case OMPD_target_exit_data: 9263 CaptureRegion = OMPD_task; 9264 break; 9265 case OMPD_cancel: 9266 case OMPD_parallel: 9267 case OMPD_parallel_sections: 9268 case OMPD_parallel_for: 9269 case OMPD_parallel_for_simd: 9270 case OMPD_target: 9271 case OMPD_target_simd: 9272 case OMPD_target_teams: 9273 case OMPD_target_teams_distribute: 9274 case OMPD_target_teams_distribute_simd: 9275 case OMPD_distribute_parallel_for: 9276 case OMPD_distribute_parallel_for_simd: 9277 case OMPD_task: 9278 case OMPD_taskloop: 9279 case OMPD_taskloop_simd: 9280 case OMPD_target_data: 9281 // Do not capture if-clause expressions. 9282 break; 9283 case OMPD_threadprivate: 9284 case OMPD_allocate: 9285 case OMPD_taskyield: 9286 case OMPD_barrier: 9287 case OMPD_taskwait: 9288 case OMPD_cancellation_point: 9289 case OMPD_flush: 9290 case OMPD_declare_reduction: 9291 case OMPD_declare_mapper: 9292 case OMPD_declare_simd: 9293 case OMPD_declare_target: 9294 case OMPD_end_declare_target: 9295 case OMPD_teams: 9296 case OMPD_simd: 9297 case OMPD_for: 9298 case OMPD_for_simd: 9299 case OMPD_sections: 9300 case OMPD_section: 9301 case OMPD_single: 9302 case OMPD_master: 9303 case OMPD_critical: 9304 case OMPD_taskgroup: 9305 case OMPD_distribute: 9306 case OMPD_ordered: 9307 case OMPD_atomic: 9308 case OMPD_distribute_simd: 9309 case OMPD_teams_distribute: 9310 case OMPD_teams_distribute_simd: 9311 case OMPD_requires: 9312 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9313 case OMPD_unknown: 9314 llvm_unreachable("Unknown OpenMP directive"); 9315 } 9316 break; 9317 case OMPC_num_threads: 9318 switch (DKind) { 9319 case OMPD_target_parallel: 9320 case OMPD_target_parallel_for: 9321 case OMPD_target_parallel_for_simd: 9322 CaptureRegion = OMPD_target; 9323 break; 9324 case OMPD_teams_distribute_parallel_for: 9325 case OMPD_teams_distribute_parallel_for_simd: 9326 case OMPD_target_teams_distribute_parallel_for: 9327 case OMPD_target_teams_distribute_parallel_for_simd: 9328 CaptureRegion = OMPD_teams; 9329 break; 9330 case OMPD_parallel: 9331 case OMPD_parallel_sections: 9332 case OMPD_parallel_for: 9333 case OMPD_parallel_for_simd: 9334 case OMPD_distribute_parallel_for: 9335 case OMPD_distribute_parallel_for_simd: 9336 // Do not capture num_threads-clause expressions. 9337 break; 9338 case OMPD_target_data: 9339 case OMPD_target_enter_data: 9340 case OMPD_target_exit_data: 9341 case OMPD_target_update: 9342 case OMPD_target: 9343 case OMPD_target_simd: 9344 case OMPD_target_teams: 9345 case OMPD_target_teams_distribute: 9346 case OMPD_target_teams_distribute_simd: 9347 case OMPD_cancel: 9348 case OMPD_task: 9349 case OMPD_taskloop: 9350 case OMPD_taskloop_simd: 9351 case OMPD_threadprivate: 9352 case OMPD_allocate: 9353 case OMPD_taskyield: 9354 case OMPD_barrier: 9355 case OMPD_taskwait: 9356 case OMPD_cancellation_point: 9357 case OMPD_flush: 9358 case OMPD_declare_reduction: 9359 case OMPD_declare_mapper: 9360 case OMPD_declare_simd: 9361 case OMPD_declare_target: 9362 case OMPD_end_declare_target: 9363 case OMPD_teams: 9364 case OMPD_simd: 9365 case OMPD_for: 9366 case OMPD_for_simd: 9367 case OMPD_sections: 9368 case OMPD_section: 9369 case OMPD_single: 9370 case OMPD_master: 9371 case OMPD_critical: 9372 case OMPD_taskgroup: 9373 case OMPD_distribute: 9374 case OMPD_ordered: 9375 case OMPD_atomic: 9376 case OMPD_distribute_simd: 9377 case OMPD_teams_distribute: 9378 case OMPD_teams_distribute_simd: 9379 case OMPD_requires: 9380 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9381 case OMPD_unknown: 9382 llvm_unreachable("Unknown OpenMP directive"); 9383 } 9384 break; 9385 case OMPC_num_teams: 9386 switch (DKind) { 9387 case OMPD_target_teams: 9388 case OMPD_target_teams_distribute: 9389 case OMPD_target_teams_distribute_simd: 9390 case OMPD_target_teams_distribute_parallel_for: 9391 case OMPD_target_teams_distribute_parallel_for_simd: 9392 CaptureRegion = OMPD_target; 9393 break; 9394 case OMPD_teams_distribute_parallel_for: 9395 case OMPD_teams_distribute_parallel_for_simd: 9396 case OMPD_teams: 9397 case OMPD_teams_distribute: 9398 case OMPD_teams_distribute_simd: 9399 // Do not capture num_teams-clause expressions. 9400 break; 9401 case OMPD_distribute_parallel_for: 9402 case OMPD_distribute_parallel_for_simd: 9403 case OMPD_task: 9404 case OMPD_taskloop: 9405 case OMPD_taskloop_simd: 9406 case OMPD_target_data: 9407 case OMPD_target_enter_data: 9408 case OMPD_target_exit_data: 9409 case OMPD_target_update: 9410 case OMPD_cancel: 9411 case OMPD_parallel: 9412 case OMPD_parallel_sections: 9413 case OMPD_parallel_for: 9414 case OMPD_parallel_for_simd: 9415 case OMPD_target: 9416 case OMPD_target_simd: 9417 case OMPD_target_parallel: 9418 case OMPD_target_parallel_for: 9419 case OMPD_target_parallel_for_simd: 9420 case OMPD_threadprivate: 9421 case OMPD_allocate: 9422 case OMPD_taskyield: 9423 case OMPD_barrier: 9424 case OMPD_taskwait: 9425 case OMPD_cancellation_point: 9426 case OMPD_flush: 9427 case OMPD_declare_reduction: 9428 case OMPD_declare_mapper: 9429 case OMPD_declare_simd: 9430 case OMPD_declare_target: 9431 case OMPD_end_declare_target: 9432 case OMPD_simd: 9433 case OMPD_for: 9434 case OMPD_for_simd: 9435 case OMPD_sections: 9436 case OMPD_section: 9437 case OMPD_single: 9438 case OMPD_master: 9439 case OMPD_critical: 9440 case OMPD_taskgroup: 9441 case OMPD_distribute: 9442 case OMPD_ordered: 9443 case OMPD_atomic: 9444 case OMPD_distribute_simd: 9445 case OMPD_requires: 9446 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9447 case OMPD_unknown: 9448 llvm_unreachable("Unknown OpenMP directive"); 9449 } 9450 break; 9451 case OMPC_thread_limit: 9452 switch (DKind) { 9453 case OMPD_target_teams: 9454 case OMPD_target_teams_distribute: 9455 case OMPD_target_teams_distribute_simd: 9456 case OMPD_target_teams_distribute_parallel_for: 9457 case OMPD_target_teams_distribute_parallel_for_simd: 9458 CaptureRegion = OMPD_target; 9459 break; 9460 case OMPD_teams_distribute_parallel_for: 9461 case OMPD_teams_distribute_parallel_for_simd: 9462 case OMPD_teams: 9463 case OMPD_teams_distribute: 9464 case OMPD_teams_distribute_simd: 9465 // Do not capture thread_limit-clause expressions. 9466 break; 9467 case OMPD_distribute_parallel_for: 9468 case OMPD_distribute_parallel_for_simd: 9469 case OMPD_task: 9470 case OMPD_taskloop: 9471 case OMPD_taskloop_simd: 9472 case OMPD_target_data: 9473 case OMPD_target_enter_data: 9474 case OMPD_target_exit_data: 9475 case OMPD_target_update: 9476 case OMPD_cancel: 9477 case OMPD_parallel: 9478 case OMPD_parallel_sections: 9479 case OMPD_parallel_for: 9480 case OMPD_parallel_for_simd: 9481 case OMPD_target: 9482 case OMPD_target_simd: 9483 case OMPD_target_parallel: 9484 case OMPD_target_parallel_for: 9485 case OMPD_target_parallel_for_simd: 9486 case OMPD_threadprivate: 9487 case OMPD_allocate: 9488 case OMPD_taskyield: 9489 case OMPD_barrier: 9490 case OMPD_taskwait: 9491 case OMPD_cancellation_point: 9492 case OMPD_flush: 9493 case OMPD_declare_reduction: 9494 case OMPD_declare_mapper: 9495 case OMPD_declare_simd: 9496 case OMPD_declare_target: 9497 case OMPD_end_declare_target: 9498 case OMPD_simd: 9499 case OMPD_for: 9500 case OMPD_for_simd: 9501 case OMPD_sections: 9502 case OMPD_section: 9503 case OMPD_single: 9504 case OMPD_master: 9505 case OMPD_critical: 9506 case OMPD_taskgroup: 9507 case OMPD_distribute: 9508 case OMPD_ordered: 9509 case OMPD_atomic: 9510 case OMPD_distribute_simd: 9511 case OMPD_requires: 9512 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 9513 case OMPD_unknown: 9514 llvm_unreachable("Unknown OpenMP directive"); 9515 } 9516 break; 9517 case OMPC_schedule: 9518 switch (DKind) { 9519 case OMPD_parallel_for: 9520 case OMPD_parallel_for_simd: 9521 case OMPD_distribute_parallel_for: 9522 case OMPD_distribute_parallel_for_simd: 9523 case OMPD_teams_distribute_parallel_for: 9524 case OMPD_teams_distribute_parallel_for_simd: 9525 case OMPD_target_parallel_for: 9526 case OMPD_target_parallel_for_simd: 9527 case OMPD_target_teams_distribute_parallel_for: 9528 case OMPD_target_teams_distribute_parallel_for_simd: 9529 CaptureRegion = OMPD_parallel; 9530 break; 9531 case OMPD_for: 9532 case OMPD_for_simd: 9533 // Do not capture schedule-clause expressions. 9534 break; 9535 case OMPD_task: 9536 case OMPD_taskloop: 9537 case OMPD_taskloop_simd: 9538 case OMPD_target_data: 9539 case OMPD_target_enter_data: 9540 case OMPD_target_exit_data: 9541 case OMPD_target_update: 9542 case OMPD_teams: 9543 case OMPD_teams_distribute: 9544 case OMPD_teams_distribute_simd: 9545 case OMPD_target_teams_distribute: 9546 case OMPD_target_teams_distribute_simd: 9547 case OMPD_target: 9548 case OMPD_target_simd: 9549 case OMPD_target_parallel: 9550 case OMPD_cancel: 9551 case OMPD_parallel: 9552 case OMPD_parallel_sections: 9553 case OMPD_threadprivate: 9554 case OMPD_allocate: 9555 case OMPD_taskyield: 9556 case OMPD_barrier: 9557 case OMPD_taskwait: 9558 case OMPD_cancellation_point: 9559 case OMPD_flush: 9560 case OMPD_declare_reduction: 9561 case OMPD_declare_mapper: 9562 case OMPD_declare_simd: 9563 case OMPD_declare_target: 9564 case OMPD_end_declare_target: 9565 case OMPD_simd: 9566 case OMPD_sections: 9567 case OMPD_section: 9568 case OMPD_single: 9569 case OMPD_master: 9570 case OMPD_critical: 9571 case OMPD_taskgroup: 9572 case OMPD_distribute: 9573 case OMPD_ordered: 9574 case OMPD_atomic: 9575 case OMPD_distribute_simd: 9576 case OMPD_target_teams: 9577 case OMPD_requires: 9578 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9579 case OMPD_unknown: 9580 llvm_unreachable("Unknown OpenMP directive"); 9581 } 9582 break; 9583 case OMPC_dist_schedule: 9584 switch (DKind) { 9585 case OMPD_teams_distribute_parallel_for: 9586 case OMPD_teams_distribute_parallel_for_simd: 9587 case OMPD_teams_distribute: 9588 case OMPD_teams_distribute_simd: 9589 case OMPD_target_teams_distribute_parallel_for: 9590 case OMPD_target_teams_distribute_parallel_for_simd: 9591 case OMPD_target_teams_distribute: 9592 case OMPD_target_teams_distribute_simd: 9593 CaptureRegion = OMPD_teams; 9594 break; 9595 case OMPD_distribute_parallel_for: 9596 case OMPD_distribute_parallel_for_simd: 9597 case OMPD_distribute: 9598 case OMPD_distribute_simd: 9599 // Do not capture thread_limit-clause expressions. 9600 break; 9601 case OMPD_parallel_for: 9602 case OMPD_parallel_for_simd: 9603 case OMPD_target_parallel_for_simd: 9604 case OMPD_target_parallel_for: 9605 case OMPD_task: 9606 case OMPD_taskloop: 9607 case OMPD_taskloop_simd: 9608 case OMPD_target_data: 9609 case OMPD_target_enter_data: 9610 case OMPD_target_exit_data: 9611 case OMPD_target_update: 9612 case OMPD_teams: 9613 case OMPD_target: 9614 case OMPD_target_simd: 9615 case OMPD_target_parallel: 9616 case OMPD_cancel: 9617 case OMPD_parallel: 9618 case OMPD_parallel_sections: 9619 case OMPD_threadprivate: 9620 case OMPD_allocate: 9621 case OMPD_taskyield: 9622 case OMPD_barrier: 9623 case OMPD_taskwait: 9624 case OMPD_cancellation_point: 9625 case OMPD_flush: 9626 case OMPD_declare_reduction: 9627 case OMPD_declare_mapper: 9628 case OMPD_declare_simd: 9629 case OMPD_declare_target: 9630 case OMPD_end_declare_target: 9631 case OMPD_simd: 9632 case OMPD_for: 9633 case OMPD_for_simd: 9634 case OMPD_sections: 9635 case OMPD_section: 9636 case OMPD_single: 9637 case OMPD_master: 9638 case OMPD_critical: 9639 case OMPD_taskgroup: 9640 case OMPD_ordered: 9641 case OMPD_atomic: 9642 case OMPD_target_teams: 9643 case OMPD_requires: 9644 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9645 case OMPD_unknown: 9646 llvm_unreachable("Unknown OpenMP directive"); 9647 } 9648 break; 9649 case OMPC_device: 9650 switch (DKind) { 9651 case OMPD_target_update: 9652 case OMPD_target_enter_data: 9653 case OMPD_target_exit_data: 9654 case OMPD_target: 9655 case OMPD_target_simd: 9656 case OMPD_target_teams: 9657 case OMPD_target_parallel: 9658 case OMPD_target_teams_distribute: 9659 case OMPD_target_teams_distribute_simd: 9660 case OMPD_target_parallel_for: 9661 case OMPD_target_parallel_for_simd: 9662 case OMPD_target_teams_distribute_parallel_for: 9663 case OMPD_target_teams_distribute_parallel_for_simd: 9664 CaptureRegion = OMPD_task; 9665 break; 9666 case OMPD_target_data: 9667 // Do not capture device-clause expressions. 9668 break; 9669 case OMPD_teams_distribute_parallel_for: 9670 case OMPD_teams_distribute_parallel_for_simd: 9671 case OMPD_teams: 9672 case OMPD_teams_distribute: 9673 case OMPD_teams_distribute_simd: 9674 case OMPD_distribute_parallel_for: 9675 case OMPD_distribute_parallel_for_simd: 9676 case OMPD_task: 9677 case OMPD_taskloop: 9678 case OMPD_taskloop_simd: 9679 case OMPD_cancel: 9680 case OMPD_parallel: 9681 case OMPD_parallel_sections: 9682 case OMPD_parallel_for: 9683 case OMPD_parallel_for_simd: 9684 case OMPD_threadprivate: 9685 case OMPD_allocate: 9686 case OMPD_taskyield: 9687 case OMPD_barrier: 9688 case OMPD_taskwait: 9689 case OMPD_cancellation_point: 9690 case OMPD_flush: 9691 case OMPD_declare_reduction: 9692 case OMPD_declare_mapper: 9693 case OMPD_declare_simd: 9694 case OMPD_declare_target: 9695 case OMPD_end_declare_target: 9696 case OMPD_simd: 9697 case OMPD_for: 9698 case OMPD_for_simd: 9699 case OMPD_sections: 9700 case OMPD_section: 9701 case OMPD_single: 9702 case OMPD_master: 9703 case OMPD_critical: 9704 case OMPD_taskgroup: 9705 case OMPD_distribute: 9706 case OMPD_ordered: 9707 case OMPD_atomic: 9708 case OMPD_distribute_simd: 9709 case OMPD_requires: 9710 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9711 case OMPD_unknown: 9712 llvm_unreachable("Unknown OpenMP directive"); 9713 } 9714 break; 9715 case OMPC_firstprivate: 9716 case OMPC_lastprivate: 9717 case OMPC_reduction: 9718 case OMPC_task_reduction: 9719 case OMPC_in_reduction: 9720 case OMPC_linear: 9721 case OMPC_default: 9722 case OMPC_proc_bind: 9723 case OMPC_final: 9724 case OMPC_safelen: 9725 case OMPC_simdlen: 9726 case OMPC_allocator: 9727 case OMPC_collapse: 9728 case OMPC_private: 9729 case OMPC_shared: 9730 case OMPC_aligned: 9731 case OMPC_copyin: 9732 case OMPC_copyprivate: 9733 case OMPC_ordered: 9734 case OMPC_nowait: 9735 case OMPC_untied: 9736 case OMPC_mergeable: 9737 case OMPC_threadprivate: 9738 case OMPC_allocate: 9739 case OMPC_flush: 9740 case OMPC_read: 9741 case OMPC_write: 9742 case OMPC_update: 9743 case OMPC_capture: 9744 case OMPC_seq_cst: 9745 case OMPC_depend: 9746 case OMPC_threads: 9747 case OMPC_simd: 9748 case OMPC_map: 9749 case OMPC_priority: 9750 case OMPC_grainsize: 9751 case OMPC_nogroup: 9752 case OMPC_num_tasks: 9753 case OMPC_hint: 9754 case OMPC_defaultmap: 9755 case OMPC_unknown: 9756 case OMPC_uniform: 9757 case OMPC_to: 9758 case OMPC_from: 9759 case OMPC_use_device_ptr: 9760 case OMPC_is_device_ptr: 9761 case OMPC_unified_address: 9762 case OMPC_unified_shared_memory: 9763 case OMPC_reverse_offload: 9764 case OMPC_dynamic_allocators: 9765 case OMPC_atomic_default_mem_order: 9766 llvm_unreachable("Unexpected OpenMP clause."); 9767 } 9768 return CaptureRegion; 9769 } 9770 9771 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9772 Expr *Condition, SourceLocation StartLoc, 9773 SourceLocation LParenLoc, 9774 SourceLocation NameModifierLoc, 9775 SourceLocation ColonLoc, 9776 SourceLocation EndLoc) { 9777 Expr *ValExpr = Condition; 9778 Stmt *HelperValStmt = nullptr; 9779 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9780 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9781 !Condition->isInstantiationDependent() && 9782 !Condition->containsUnexpandedParameterPack()) { 9783 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9784 if (Val.isInvalid()) 9785 return nullptr; 9786 9787 ValExpr = Val.get(); 9788 9789 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9790 CaptureRegion = 9791 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9792 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9793 ValExpr = MakeFullExpr(ValExpr).get(); 9794 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9795 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9796 HelperValStmt = buildPreInits(Context, Captures); 9797 } 9798 } 9799 9800 return new (Context) 9801 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9802 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9803 } 9804 9805 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9806 SourceLocation StartLoc, 9807 SourceLocation LParenLoc, 9808 SourceLocation EndLoc) { 9809 Expr *ValExpr = Condition; 9810 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9811 !Condition->isInstantiationDependent() && 9812 !Condition->containsUnexpandedParameterPack()) { 9813 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9814 if (Val.isInvalid()) 9815 return nullptr; 9816 9817 ValExpr = MakeFullExpr(Val.get()).get(); 9818 } 9819 9820 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9821 } 9822 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9823 Expr *Op) { 9824 if (!Op) 9825 return ExprError(); 9826 9827 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9828 public: 9829 IntConvertDiagnoser() 9830 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9831 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9832 QualType T) override { 9833 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9834 } 9835 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9836 QualType T) override { 9837 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9838 } 9839 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9840 QualType T, 9841 QualType ConvTy) override { 9842 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9843 } 9844 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9845 QualType ConvTy) override { 9846 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9847 << ConvTy->isEnumeralType() << ConvTy; 9848 } 9849 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9850 QualType T) override { 9851 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9852 } 9853 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9854 QualType ConvTy) override { 9855 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9856 << ConvTy->isEnumeralType() << ConvTy; 9857 } 9858 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9859 QualType) override { 9860 llvm_unreachable("conversion functions are permitted"); 9861 } 9862 } ConvertDiagnoser; 9863 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9864 } 9865 9866 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9867 OpenMPClauseKind CKind, 9868 bool StrictlyPositive) { 9869 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9870 !ValExpr->isInstantiationDependent()) { 9871 SourceLocation Loc = ValExpr->getExprLoc(); 9872 ExprResult Value = 9873 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9874 if (Value.isInvalid()) 9875 return false; 9876 9877 ValExpr = Value.get(); 9878 // The expression must evaluate to a non-negative integer value. 9879 llvm::APSInt Result; 9880 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9881 Result.isSigned() && 9882 !((!StrictlyPositive && Result.isNonNegative()) || 9883 (StrictlyPositive && Result.isStrictlyPositive()))) { 9884 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9885 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9886 << ValExpr->getSourceRange(); 9887 return false; 9888 } 9889 } 9890 return true; 9891 } 9892 9893 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9894 SourceLocation StartLoc, 9895 SourceLocation LParenLoc, 9896 SourceLocation EndLoc) { 9897 Expr *ValExpr = NumThreads; 9898 Stmt *HelperValStmt = nullptr; 9899 9900 // OpenMP [2.5, Restrictions] 9901 // The num_threads expression must evaluate to a positive integer value. 9902 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9903 /*StrictlyPositive=*/true)) 9904 return nullptr; 9905 9906 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9907 OpenMPDirectiveKind CaptureRegion = 9908 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9909 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9910 ValExpr = MakeFullExpr(ValExpr).get(); 9911 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9912 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9913 HelperValStmt = buildPreInits(Context, Captures); 9914 } 9915 9916 return new (Context) OMPNumThreadsClause( 9917 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9918 } 9919 9920 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9921 OpenMPClauseKind CKind, 9922 bool StrictlyPositive) { 9923 if (!E) 9924 return ExprError(); 9925 if (E->isValueDependent() || E->isTypeDependent() || 9926 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9927 return E; 9928 llvm::APSInt Result; 9929 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9930 if (ICE.isInvalid()) 9931 return ExprError(); 9932 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9933 (!StrictlyPositive && !Result.isNonNegative())) { 9934 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9935 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9936 << E->getSourceRange(); 9937 return ExprError(); 9938 } 9939 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9940 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9941 << E->getSourceRange(); 9942 return ExprError(); 9943 } 9944 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9945 DSAStack->setAssociatedLoops(Result.getExtValue()); 9946 else if (CKind == OMPC_ordered) 9947 DSAStack->setAssociatedLoops(Result.getExtValue()); 9948 return ICE; 9949 } 9950 9951 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9952 SourceLocation LParenLoc, 9953 SourceLocation EndLoc) { 9954 // OpenMP [2.8.1, simd construct, Description] 9955 // The parameter of the safelen clause must be a constant 9956 // positive integer expression. 9957 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9958 if (Safelen.isInvalid()) 9959 return nullptr; 9960 return new (Context) 9961 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9962 } 9963 9964 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9965 SourceLocation LParenLoc, 9966 SourceLocation EndLoc) { 9967 // OpenMP [2.8.1, simd construct, Description] 9968 // The parameter of the simdlen clause must be a constant 9969 // positive integer expression. 9970 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9971 if (Simdlen.isInvalid()) 9972 return nullptr; 9973 return new (Context) 9974 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9975 } 9976 9977 /// Tries to find omp_allocator_handle_t type. 9978 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 9979 DSAStackTy *Stack) { 9980 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 9981 if (!OMPAllocatorHandleT.isNull()) 9982 return true; 9983 // Build the predefined allocator expressions. 9984 bool ErrorFound = false; 9985 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 9986 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 9987 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 9988 StringRef Allocator = 9989 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 9990 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 9991 auto *VD = dyn_cast_or_null<ValueDecl>( 9992 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 9993 if (!VD) { 9994 ErrorFound = true; 9995 break; 9996 } 9997 QualType AllocatorType = 9998 VD->getType().getNonLValueExprType(S.getASTContext()); 9999 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10000 if (!Res.isUsable()) { 10001 ErrorFound = true; 10002 break; 10003 } 10004 if (OMPAllocatorHandleT.isNull()) 10005 OMPAllocatorHandleT = AllocatorType; 10006 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10007 ErrorFound = true; 10008 break; 10009 } 10010 Stack->setAllocator(AllocatorKind, Res.get()); 10011 } 10012 if (ErrorFound) { 10013 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10014 return false; 10015 } 10016 OMPAllocatorHandleT.addConst(); 10017 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10018 return true; 10019 } 10020 10021 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10022 SourceLocation LParenLoc, 10023 SourceLocation EndLoc) { 10024 // OpenMP [2.11.3, allocate Directive, Description] 10025 // allocator is an expression of omp_allocator_handle_t type. 10026 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10027 return nullptr; 10028 10029 ExprResult Allocator = DefaultLvalueConversion(A); 10030 if (Allocator.isInvalid()) 10031 return nullptr; 10032 Allocator = PerformImplicitConversion(Allocator.get(), 10033 DSAStack->getOMPAllocatorHandleT(), 10034 Sema::AA_Initializing, 10035 /*AllowExplicit=*/true); 10036 if (Allocator.isInvalid()) 10037 return nullptr; 10038 return new (Context) 10039 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10040 } 10041 10042 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10043 SourceLocation StartLoc, 10044 SourceLocation LParenLoc, 10045 SourceLocation EndLoc) { 10046 // OpenMP [2.7.1, loop construct, Description] 10047 // OpenMP [2.8.1, simd construct, Description] 10048 // OpenMP [2.9.6, distribute construct, Description] 10049 // The parameter of the collapse clause must be a constant 10050 // positive integer expression. 10051 ExprResult NumForLoopsResult = 10052 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10053 if (NumForLoopsResult.isInvalid()) 10054 return nullptr; 10055 return new (Context) 10056 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10057 } 10058 10059 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10060 SourceLocation EndLoc, 10061 SourceLocation LParenLoc, 10062 Expr *NumForLoops) { 10063 // OpenMP [2.7.1, loop construct, Description] 10064 // OpenMP [2.8.1, simd construct, Description] 10065 // OpenMP [2.9.6, distribute construct, Description] 10066 // The parameter of the ordered clause must be a constant 10067 // positive integer expression if any. 10068 if (NumForLoops && LParenLoc.isValid()) { 10069 ExprResult NumForLoopsResult = 10070 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10071 if (NumForLoopsResult.isInvalid()) 10072 return nullptr; 10073 NumForLoops = NumForLoopsResult.get(); 10074 } else { 10075 NumForLoops = nullptr; 10076 } 10077 auto *Clause = OMPOrderedClause::Create( 10078 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10079 StartLoc, LParenLoc, EndLoc); 10080 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10081 return Clause; 10082 } 10083 10084 OMPClause *Sema::ActOnOpenMPSimpleClause( 10085 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10086 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10087 OMPClause *Res = nullptr; 10088 switch (Kind) { 10089 case OMPC_default: 10090 Res = 10091 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10092 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10093 break; 10094 case OMPC_proc_bind: 10095 Res = ActOnOpenMPProcBindClause( 10096 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10097 LParenLoc, EndLoc); 10098 break; 10099 case OMPC_atomic_default_mem_order: 10100 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10101 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10102 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10103 break; 10104 case OMPC_if: 10105 case OMPC_final: 10106 case OMPC_num_threads: 10107 case OMPC_safelen: 10108 case OMPC_simdlen: 10109 case OMPC_allocator: 10110 case OMPC_collapse: 10111 case OMPC_schedule: 10112 case OMPC_private: 10113 case OMPC_firstprivate: 10114 case OMPC_lastprivate: 10115 case OMPC_shared: 10116 case OMPC_reduction: 10117 case OMPC_task_reduction: 10118 case OMPC_in_reduction: 10119 case OMPC_linear: 10120 case OMPC_aligned: 10121 case OMPC_copyin: 10122 case OMPC_copyprivate: 10123 case OMPC_ordered: 10124 case OMPC_nowait: 10125 case OMPC_untied: 10126 case OMPC_mergeable: 10127 case OMPC_threadprivate: 10128 case OMPC_allocate: 10129 case OMPC_flush: 10130 case OMPC_read: 10131 case OMPC_write: 10132 case OMPC_update: 10133 case OMPC_capture: 10134 case OMPC_seq_cst: 10135 case OMPC_depend: 10136 case OMPC_device: 10137 case OMPC_threads: 10138 case OMPC_simd: 10139 case OMPC_map: 10140 case OMPC_num_teams: 10141 case OMPC_thread_limit: 10142 case OMPC_priority: 10143 case OMPC_grainsize: 10144 case OMPC_nogroup: 10145 case OMPC_num_tasks: 10146 case OMPC_hint: 10147 case OMPC_dist_schedule: 10148 case OMPC_defaultmap: 10149 case OMPC_unknown: 10150 case OMPC_uniform: 10151 case OMPC_to: 10152 case OMPC_from: 10153 case OMPC_use_device_ptr: 10154 case OMPC_is_device_ptr: 10155 case OMPC_unified_address: 10156 case OMPC_unified_shared_memory: 10157 case OMPC_reverse_offload: 10158 case OMPC_dynamic_allocators: 10159 llvm_unreachable("Clause is not allowed."); 10160 } 10161 return Res; 10162 } 10163 10164 static std::string 10165 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10166 ArrayRef<unsigned> Exclude = llvm::None) { 10167 SmallString<256> Buffer; 10168 llvm::raw_svector_ostream Out(Buffer); 10169 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10170 unsigned Skipped = Exclude.size(); 10171 auto S = Exclude.begin(), E = Exclude.end(); 10172 for (unsigned I = First; I < Last; ++I) { 10173 if (std::find(S, E, I) != E) { 10174 --Skipped; 10175 continue; 10176 } 10177 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10178 if (I == Bound - Skipped) 10179 Out << " or "; 10180 else if (I != Bound + 1 - Skipped) 10181 Out << ", "; 10182 } 10183 return Out.str(); 10184 } 10185 10186 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10187 SourceLocation KindKwLoc, 10188 SourceLocation StartLoc, 10189 SourceLocation LParenLoc, 10190 SourceLocation EndLoc) { 10191 if (Kind == OMPC_DEFAULT_unknown) { 10192 static_assert(OMPC_DEFAULT_unknown > 0, 10193 "OMPC_DEFAULT_unknown not greater than 0"); 10194 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10195 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10196 /*Last=*/OMPC_DEFAULT_unknown) 10197 << getOpenMPClauseName(OMPC_default); 10198 return nullptr; 10199 } 10200 switch (Kind) { 10201 case OMPC_DEFAULT_none: 10202 DSAStack->setDefaultDSANone(KindKwLoc); 10203 break; 10204 case OMPC_DEFAULT_shared: 10205 DSAStack->setDefaultDSAShared(KindKwLoc); 10206 break; 10207 case OMPC_DEFAULT_unknown: 10208 llvm_unreachable("Clause kind is not allowed."); 10209 break; 10210 } 10211 return new (Context) 10212 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10213 } 10214 10215 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10216 SourceLocation KindKwLoc, 10217 SourceLocation StartLoc, 10218 SourceLocation LParenLoc, 10219 SourceLocation EndLoc) { 10220 if (Kind == OMPC_PROC_BIND_unknown) { 10221 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10222 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10223 /*Last=*/OMPC_PROC_BIND_unknown) 10224 << getOpenMPClauseName(OMPC_proc_bind); 10225 return nullptr; 10226 } 10227 return new (Context) 10228 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10229 } 10230 10231 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10232 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10233 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10234 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10235 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10236 << getListOfPossibleValues( 10237 OMPC_atomic_default_mem_order, /*First=*/0, 10238 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10239 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10240 return nullptr; 10241 } 10242 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10243 LParenLoc, EndLoc); 10244 } 10245 10246 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10247 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10248 SourceLocation StartLoc, SourceLocation LParenLoc, 10249 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10250 SourceLocation EndLoc) { 10251 OMPClause *Res = nullptr; 10252 switch (Kind) { 10253 case OMPC_schedule: 10254 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10255 assert(Argument.size() == NumberOfElements && 10256 ArgumentLoc.size() == NumberOfElements); 10257 Res = ActOnOpenMPScheduleClause( 10258 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10259 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10260 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10261 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10262 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10263 break; 10264 case OMPC_if: 10265 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10266 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10267 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10268 DelimLoc, EndLoc); 10269 break; 10270 case OMPC_dist_schedule: 10271 Res = ActOnOpenMPDistScheduleClause( 10272 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10273 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10274 break; 10275 case OMPC_defaultmap: 10276 enum { Modifier, DefaultmapKind }; 10277 Res = ActOnOpenMPDefaultmapClause( 10278 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10279 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10280 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10281 EndLoc); 10282 break; 10283 case OMPC_final: 10284 case OMPC_num_threads: 10285 case OMPC_safelen: 10286 case OMPC_simdlen: 10287 case OMPC_allocator: 10288 case OMPC_collapse: 10289 case OMPC_default: 10290 case OMPC_proc_bind: 10291 case OMPC_private: 10292 case OMPC_firstprivate: 10293 case OMPC_lastprivate: 10294 case OMPC_shared: 10295 case OMPC_reduction: 10296 case OMPC_task_reduction: 10297 case OMPC_in_reduction: 10298 case OMPC_linear: 10299 case OMPC_aligned: 10300 case OMPC_copyin: 10301 case OMPC_copyprivate: 10302 case OMPC_ordered: 10303 case OMPC_nowait: 10304 case OMPC_untied: 10305 case OMPC_mergeable: 10306 case OMPC_threadprivate: 10307 case OMPC_allocate: 10308 case OMPC_flush: 10309 case OMPC_read: 10310 case OMPC_write: 10311 case OMPC_update: 10312 case OMPC_capture: 10313 case OMPC_seq_cst: 10314 case OMPC_depend: 10315 case OMPC_device: 10316 case OMPC_threads: 10317 case OMPC_simd: 10318 case OMPC_map: 10319 case OMPC_num_teams: 10320 case OMPC_thread_limit: 10321 case OMPC_priority: 10322 case OMPC_grainsize: 10323 case OMPC_nogroup: 10324 case OMPC_num_tasks: 10325 case OMPC_hint: 10326 case OMPC_unknown: 10327 case OMPC_uniform: 10328 case OMPC_to: 10329 case OMPC_from: 10330 case OMPC_use_device_ptr: 10331 case OMPC_is_device_ptr: 10332 case OMPC_unified_address: 10333 case OMPC_unified_shared_memory: 10334 case OMPC_reverse_offload: 10335 case OMPC_dynamic_allocators: 10336 case OMPC_atomic_default_mem_order: 10337 llvm_unreachable("Clause is not allowed."); 10338 } 10339 return Res; 10340 } 10341 10342 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10343 OpenMPScheduleClauseModifier M2, 10344 SourceLocation M1Loc, SourceLocation M2Loc) { 10345 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10346 SmallVector<unsigned, 2> Excluded; 10347 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10348 Excluded.push_back(M2); 10349 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10350 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10351 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10352 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10353 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10354 << getListOfPossibleValues(OMPC_schedule, 10355 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10356 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10357 Excluded) 10358 << getOpenMPClauseName(OMPC_schedule); 10359 return true; 10360 } 10361 return false; 10362 } 10363 10364 OMPClause *Sema::ActOnOpenMPScheduleClause( 10365 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10366 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10367 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10368 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10369 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10370 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10371 return nullptr; 10372 // OpenMP, 2.7.1, Loop Construct, Restrictions 10373 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10374 // but not both. 10375 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10376 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10377 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10378 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10379 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10380 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10381 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10382 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10383 return nullptr; 10384 } 10385 if (Kind == OMPC_SCHEDULE_unknown) { 10386 std::string Values; 10387 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10388 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10389 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10390 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10391 Exclude); 10392 } else { 10393 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10394 /*Last=*/OMPC_SCHEDULE_unknown); 10395 } 10396 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10397 << Values << getOpenMPClauseName(OMPC_schedule); 10398 return nullptr; 10399 } 10400 // OpenMP, 2.7.1, Loop Construct, Restrictions 10401 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 10402 // schedule(guided). 10403 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 10404 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 10405 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 10406 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 10407 diag::err_omp_schedule_nonmonotonic_static); 10408 return nullptr; 10409 } 10410 Expr *ValExpr = ChunkSize; 10411 Stmt *HelperValStmt = nullptr; 10412 if (ChunkSize) { 10413 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10414 !ChunkSize->isInstantiationDependent() && 10415 !ChunkSize->containsUnexpandedParameterPack()) { 10416 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 10417 ExprResult Val = 10418 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10419 if (Val.isInvalid()) 10420 return nullptr; 10421 10422 ValExpr = Val.get(); 10423 10424 // OpenMP [2.7.1, Restrictions] 10425 // chunk_size must be a loop invariant integer expression with a positive 10426 // value. 10427 llvm::APSInt Result; 10428 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10429 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10430 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10431 << "schedule" << 1 << ChunkSize->getSourceRange(); 10432 return nullptr; 10433 } 10434 } else if (getOpenMPCaptureRegionForClause( 10435 DSAStack->getCurrentDirective(), OMPC_schedule) != 10436 OMPD_unknown && 10437 !CurContext->isDependentContext()) { 10438 ValExpr = MakeFullExpr(ValExpr).get(); 10439 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10440 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10441 HelperValStmt = buildPreInits(Context, Captures); 10442 } 10443 } 10444 } 10445 10446 return new (Context) 10447 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 10448 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 10449 } 10450 10451 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 10452 SourceLocation StartLoc, 10453 SourceLocation EndLoc) { 10454 OMPClause *Res = nullptr; 10455 switch (Kind) { 10456 case OMPC_ordered: 10457 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 10458 break; 10459 case OMPC_nowait: 10460 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 10461 break; 10462 case OMPC_untied: 10463 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 10464 break; 10465 case OMPC_mergeable: 10466 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 10467 break; 10468 case OMPC_read: 10469 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 10470 break; 10471 case OMPC_write: 10472 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 10473 break; 10474 case OMPC_update: 10475 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 10476 break; 10477 case OMPC_capture: 10478 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 10479 break; 10480 case OMPC_seq_cst: 10481 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 10482 break; 10483 case OMPC_threads: 10484 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 10485 break; 10486 case OMPC_simd: 10487 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 10488 break; 10489 case OMPC_nogroup: 10490 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 10491 break; 10492 case OMPC_unified_address: 10493 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 10494 break; 10495 case OMPC_unified_shared_memory: 10496 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10497 break; 10498 case OMPC_reverse_offload: 10499 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 10500 break; 10501 case OMPC_dynamic_allocators: 10502 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 10503 break; 10504 case OMPC_if: 10505 case OMPC_final: 10506 case OMPC_num_threads: 10507 case OMPC_safelen: 10508 case OMPC_simdlen: 10509 case OMPC_allocator: 10510 case OMPC_collapse: 10511 case OMPC_schedule: 10512 case OMPC_private: 10513 case OMPC_firstprivate: 10514 case OMPC_lastprivate: 10515 case OMPC_shared: 10516 case OMPC_reduction: 10517 case OMPC_task_reduction: 10518 case OMPC_in_reduction: 10519 case OMPC_linear: 10520 case OMPC_aligned: 10521 case OMPC_copyin: 10522 case OMPC_copyprivate: 10523 case OMPC_default: 10524 case OMPC_proc_bind: 10525 case OMPC_threadprivate: 10526 case OMPC_allocate: 10527 case OMPC_flush: 10528 case OMPC_depend: 10529 case OMPC_device: 10530 case OMPC_map: 10531 case OMPC_num_teams: 10532 case OMPC_thread_limit: 10533 case OMPC_priority: 10534 case OMPC_grainsize: 10535 case OMPC_num_tasks: 10536 case OMPC_hint: 10537 case OMPC_dist_schedule: 10538 case OMPC_defaultmap: 10539 case OMPC_unknown: 10540 case OMPC_uniform: 10541 case OMPC_to: 10542 case OMPC_from: 10543 case OMPC_use_device_ptr: 10544 case OMPC_is_device_ptr: 10545 case OMPC_atomic_default_mem_order: 10546 llvm_unreachable("Clause is not allowed."); 10547 } 10548 return Res; 10549 } 10550 10551 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 10552 SourceLocation EndLoc) { 10553 DSAStack->setNowaitRegion(); 10554 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 10555 } 10556 10557 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 10558 SourceLocation EndLoc) { 10559 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 10560 } 10561 10562 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 10563 SourceLocation EndLoc) { 10564 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10565 } 10566 10567 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10568 SourceLocation EndLoc) { 10569 return new (Context) OMPReadClause(StartLoc, EndLoc); 10570 } 10571 10572 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10573 SourceLocation EndLoc) { 10574 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10575 } 10576 10577 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10578 SourceLocation EndLoc) { 10579 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10580 } 10581 10582 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10583 SourceLocation EndLoc) { 10584 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10585 } 10586 10587 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10588 SourceLocation EndLoc) { 10589 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10590 } 10591 10592 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10593 SourceLocation EndLoc) { 10594 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10595 } 10596 10597 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 10598 SourceLocation EndLoc) { 10599 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 10600 } 10601 10602 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 10603 SourceLocation EndLoc) { 10604 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 10605 } 10606 10607 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 10608 SourceLocation EndLoc) { 10609 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 10610 } 10611 10612 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 10613 SourceLocation EndLoc) { 10614 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10615 } 10616 10617 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 10618 SourceLocation EndLoc) { 10619 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 10620 } 10621 10622 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 10623 SourceLocation EndLoc) { 10624 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 10625 } 10626 10627 OMPClause *Sema::ActOnOpenMPVarListClause( 10628 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 10629 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 10630 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 10631 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 10632 OpenMPLinearClauseKind LinKind, 10633 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 10634 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 10635 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 10636 SourceLocation StartLoc = Locs.StartLoc; 10637 SourceLocation LParenLoc = Locs.LParenLoc; 10638 SourceLocation EndLoc = Locs.EndLoc; 10639 OMPClause *Res = nullptr; 10640 switch (Kind) { 10641 case OMPC_private: 10642 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10643 break; 10644 case OMPC_firstprivate: 10645 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10646 break; 10647 case OMPC_lastprivate: 10648 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10649 break; 10650 case OMPC_shared: 10651 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 10652 break; 10653 case OMPC_reduction: 10654 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10655 EndLoc, ReductionOrMapperIdScopeSpec, 10656 ReductionOrMapperId); 10657 break; 10658 case OMPC_task_reduction: 10659 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10660 EndLoc, ReductionOrMapperIdScopeSpec, 10661 ReductionOrMapperId); 10662 break; 10663 case OMPC_in_reduction: 10664 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10665 EndLoc, ReductionOrMapperIdScopeSpec, 10666 ReductionOrMapperId); 10667 break; 10668 case OMPC_linear: 10669 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 10670 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 10671 break; 10672 case OMPC_aligned: 10673 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 10674 ColonLoc, EndLoc); 10675 break; 10676 case OMPC_copyin: 10677 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 10678 break; 10679 case OMPC_copyprivate: 10680 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10681 break; 10682 case OMPC_flush: 10683 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 10684 break; 10685 case OMPC_depend: 10686 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 10687 StartLoc, LParenLoc, EndLoc); 10688 break; 10689 case OMPC_map: 10690 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 10691 ReductionOrMapperIdScopeSpec, 10692 ReductionOrMapperId, MapType, IsMapTypeImplicit, 10693 DepLinMapLoc, ColonLoc, VarList, Locs); 10694 break; 10695 case OMPC_to: 10696 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 10697 ReductionOrMapperId, Locs); 10698 break; 10699 case OMPC_from: 10700 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 10701 ReductionOrMapperId, Locs); 10702 break; 10703 case OMPC_use_device_ptr: 10704 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 10705 break; 10706 case OMPC_is_device_ptr: 10707 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 10708 break; 10709 case OMPC_allocate: 10710 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 10711 ColonLoc, EndLoc); 10712 break; 10713 case OMPC_if: 10714 case OMPC_final: 10715 case OMPC_num_threads: 10716 case OMPC_safelen: 10717 case OMPC_simdlen: 10718 case OMPC_allocator: 10719 case OMPC_collapse: 10720 case OMPC_default: 10721 case OMPC_proc_bind: 10722 case OMPC_schedule: 10723 case OMPC_ordered: 10724 case OMPC_nowait: 10725 case OMPC_untied: 10726 case OMPC_mergeable: 10727 case OMPC_threadprivate: 10728 case OMPC_read: 10729 case OMPC_write: 10730 case OMPC_update: 10731 case OMPC_capture: 10732 case OMPC_seq_cst: 10733 case OMPC_device: 10734 case OMPC_threads: 10735 case OMPC_simd: 10736 case OMPC_num_teams: 10737 case OMPC_thread_limit: 10738 case OMPC_priority: 10739 case OMPC_grainsize: 10740 case OMPC_nogroup: 10741 case OMPC_num_tasks: 10742 case OMPC_hint: 10743 case OMPC_dist_schedule: 10744 case OMPC_defaultmap: 10745 case OMPC_unknown: 10746 case OMPC_uniform: 10747 case OMPC_unified_address: 10748 case OMPC_unified_shared_memory: 10749 case OMPC_reverse_offload: 10750 case OMPC_dynamic_allocators: 10751 case OMPC_atomic_default_mem_order: 10752 llvm_unreachable("Clause is not allowed."); 10753 } 10754 return Res; 10755 } 10756 10757 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10758 ExprObjectKind OK, SourceLocation Loc) { 10759 ExprResult Res = BuildDeclRefExpr( 10760 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10761 if (!Res.isUsable()) 10762 return ExprError(); 10763 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10764 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10765 if (!Res.isUsable()) 10766 return ExprError(); 10767 } 10768 if (VK != VK_LValue && Res.get()->isGLValue()) { 10769 Res = DefaultLvalueConversion(Res.get()); 10770 if (!Res.isUsable()) 10771 return ExprError(); 10772 } 10773 return Res; 10774 } 10775 10776 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10777 SourceLocation StartLoc, 10778 SourceLocation LParenLoc, 10779 SourceLocation EndLoc) { 10780 SmallVector<Expr *, 8> Vars; 10781 SmallVector<Expr *, 8> PrivateCopies; 10782 for (Expr *RefExpr : VarList) { 10783 assert(RefExpr && "NULL expr in OpenMP private clause."); 10784 SourceLocation ELoc; 10785 SourceRange ERange; 10786 Expr *SimpleRefExpr = RefExpr; 10787 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10788 if (Res.second) { 10789 // It will be analyzed later. 10790 Vars.push_back(RefExpr); 10791 PrivateCopies.push_back(nullptr); 10792 } 10793 ValueDecl *D = Res.first; 10794 if (!D) 10795 continue; 10796 10797 QualType Type = D->getType(); 10798 auto *VD = dyn_cast<VarDecl>(D); 10799 10800 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10801 // A variable that appears in a private clause must not have an incomplete 10802 // type or a reference type. 10803 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10804 continue; 10805 Type = Type.getNonReferenceType(); 10806 10807 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10808 // A variable that is privatized must not have a const-qualified type 10809 // unless it is of class type with a mutable member. This restriction does 10810 // not apply to the firstprivate clause. 10811 // 10812 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10813 // A variable that appears in a private clause must not have a 10814 // const-qualified type unless it is of class type with a mutable member. 10815 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10816 continue; 10817 10818 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10819 // in a Construct] 10820 // Variables with the predetermined data-sharing attributes may not be 10821 // listed in data-sharing attributes clauses, except for the cases 10822 // listed below. For these exceptions only, listing a predetermined 10823 // variable in a data-sharing attribute clause is allowed and overrides 10824 // the variable's predetermined data-sharing attributes. 10825 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10826 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10827 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10828 << getOpenMPClauseName(OMPC_private); 10829 reportOriginalDsa(*this, DSAStack, D, DVar); 10830 continue; 10831 } 10832 10833 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10834 // Variably modified types are not supported for tasks. 10835 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10836 isOpenMPTaskingDirective(CurrDir)) { 10837 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10838 << getOpenMPClauseName(OMPC_private) << Type 10839 << getOpenMPDirectiveName(CurrDir); 10840 bool IsDecl = 10841 !VD || 10842 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10843 Diag(D->getLocation(), 10844 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10845 << D; 10846 continue; 10847 } 10848 10849 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10850 // A list item cannot appear in both a map clause and a data-sharing 10851 // attribute clause on the same construct 10852 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10853 OpenMPClauseKind ConflictKind; 10854 if (DSAStack->checkMappableExprComponentListsForDecl( 10855 VD, /*CurrentRegionOnly=*/true, 10856 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10857 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10858 ConflictKind = WhereFoundClauseKind; 10859 return true; 10860 })) { 10861 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10862 << getOpenMPClauseName(OMPC_private) 10863 << getOpenMPClauseName(ConflictKind) 10864 << getOpenMPDirectiveName(CurrDir); 10865 reportOriginalDsa(*this, DSAStack, D, DVar); 10866 continue; 10867 } 10868 } 10869 10870 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10871 // A variable of class type (or array thereof) that appears in a private 10872 // clause requires an accessible, unambiguous default constructor for the 10873 // class type. 10874 // Generate helper private variable and initialize it with the default 10875 // value. The address of the original variable is replaced by the address of 10876 // the new private variable in CodeGen. This new variable is not added to 10877 // IdResolver, so the code in the OpenMP region uses original variable for 10878 // proper diagnostics. 10879 Type = Type.getUnqualifiedType(); 10880 VarDecl *VDPrivate = 10881 buildVarDecl(*this, ELoc, Type, D->getName(), 10882 D->hasAttrs() ? &D->getAttrs() : nullptr, 10883 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10884 ActOnUninitializedDecl(VDPrivate); 10885 if (VDPrivate->isInvalidDecl()) 10886 continue; 10887 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10888 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10889 10890 DeclRefExpr *Ref = nullptr; 10891 if (!VD && !CurContext->isDependentContext()) 10892 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10893 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10894 Vars.push_back((VD || CurContext->isDependentContext()) 10895 ? RefExpr->IgnoreParens() 10896 : Ref); 10897 PrivateCopies.push_back(VDPrivateRefExpr); 10898 } 10899 10900 if (Vars.empty()) 10901 return nullptr; 10902 10903 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10904 PrivateCopies); 10905 } 10906 10907 namespace { 10908 class DiagsUninitializedSeveretyRAII { 10909 private: 10910 DiagnosticsEngine &Diags; 10911 SourceLocation SavedLoc; 10912 bool IsIgnored = false; 10913 10914 public: 10915 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10916 bool IsIgnored) 10917 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10918 if (!IsIgnored) { 10919 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10920 /*Map*/ diag::Severity::Ignored, Loc); 10921 } 10922 } 10923 ~DiagsUninitializedSeveretyRAII() { 10924 if (!IsIgnored) 10925 Diags.popMappings(SavedLoc); 10926 } 10927 }; 10928 } 10929 10930 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10931 SourceLocation StartLoc, 10932 SourceLocation LParenLoc, 10933 SourceLocation EndLoc) { 10934 SmallVector<Expr *, 8> Vars; 10935 SmallVector<Expr *, 8> PrivateCopies; 10936 SmallVector<Expr *, 8> Inits; 10937 SmallVector<Decl *, 4> ExprCaptures; 10938 bool IsImplicitClause = 10939 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10940 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10941 10942 for (Expr *RefExpr : VarList) { 10943 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10944 SourceLocation ELoc; 10945 SourceRange ERange; 10946 Expr *SimpleRefExpr = RefExpr; 10947 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10948 if (Res.second) { 10949 // It will be analyzed later. 10950 Vars.push_back(RefExpr); 10951 PrivateCopies.push_back(nullptr); 10952 Inits.push_back(nullptr); 10953 } 10954 ValueDecl *D = Res.first; 10955 if (!D) 10956 continue; 10957 10958 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 10959 QualType Type = D->getType(); 10960 auto *VD = dyn_cast<VarDecl>(D); 10961 10962 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10963 // A variable that appears in a private clause must not have an incomplete 10964 // type or a reference type. 10965 if (RequireCompleteType(ELoc, Type, 10966 diag::err_omp_firstprivate_incomplete_type)) 10967 continue; 10968 Type = Type.getNonReferenceType(); 10969 10970 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10971 // A variable of class type (or array thereof) that appears in a private 10972 // clause requires an accessible, unambiguous copy constructor for the 10973 // class type. 10974 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10975 10976 // If an implicit firstprivate variable found it was checked already. 10977 DSAStackTy::DSAVarData TopDVar; 10978 if (!IsImplicitClause) { 10979 DSAStackTy::DSAVarData DVar = 10980 DSAStack->getTopDSA(D, /*FromParent=*/false); 10981 TopDVar = DVar; 10982 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10983 bool IsConstant = ElemType.isConstant(Context); 10984 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10985 // A list item that specifies a given variable may not appear in more 10986 // than one clause on the same directive, except that a variable may be 10987 // specified in both firstprivate and lastprivate clauses. 10988 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10989 // A list item may appear in a firstprivate or lastprivate clause but not 10990 // both. 10991 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10992 (isOpenMPDistributeDirective(CurrDir) || 10993 DVar.CKind != OMPC_lastprivate) && 10994 DVar.RefExpr) { 10995 Diag(ELoc, diag::err_omp_wrong_dsa) 10996 << getOpenMPClauseName(DVar.CKind) 10997 << getOpenMPClauseName(OMPC_firstprivate); 10998 reportOriginalDsa(*this, DSAStack, D, DVar); 10999 continue; 11000 } 11001 11002 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11003 // in a Construct] 11004 // Variables with the predetermined data-sharing attributes may not be 11005 // listed in data-sharing attributes clauses, except for the cases 11006 // listed below. For these exceptions only, listing a predetermined 11007 // variable in a data-sharing attribute clause is allowed and overrides 11008 // the variable's predetermined data-sharing attributes. 11009 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11010 // in a Construct, C/C++, p.2] 11011 // Variables with const-qualified type having no mutable member may be 11012 // listed in a firstprivate clause, even if they are static data members. 11013 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11014 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11015 Diag(ELoc, diag::err_omp_wrong_dsa) 11016 << getOpenMPClauseName(DVar.CKind) 11017 << getOpenMPClauseName(OMPC_firstprivate); 11018 reportOriginalDsa(*this, DSAStack, D, DVar); 11019 continue; 11020 } 11021 11022 // OpenMP [2.9.3.4, Restrictions, p.2] 11023 // A list item that is private within a parallel region must not appear 11024 // in a firstprivate clause on a worksharing construct if any of the 11025 // worksharing regions arising from the worksharing construct ever bind 11026 // to any of the parallel regions arising from the parallel construct. 11027 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11028 // A list item that is private within a teams region must not appear in a 11029 // firstprivate clause on a distribute construct if any of the distribute 11030 // regions arising from the distribute construct ever bind to any of the 11031 // teams regions arising from the teams construct. 11032 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11033 // A list item that appears in a reduction clause of a teams construct 11034 // must not appear in a firstprivate clause on a distribute construct if 11035 // any of the distribute regions arising from the distribute construct 11036 // ever bind to any of the teams regions arising from the teams construct. 11037 if ((isOpenMPWorksharingDirective(CurrDir) || 11038 isOpenMPDistributeDirective(CurrDir)) && 11039 !isOpenMPParallelDirective(CurrDir) && 11040 !isOpenMPTeamsDirective(CurrDir)) { 11041 DVar = DSAStack->getImplicitDSA(D, true); 11042 if (DVar.CKind != OMPC_shared && 11043 (isOpenMPParallelDirective(DVar.DKind) || 11044 isOpenMPTeamsDirective(DVar.DKind) || 11045 DVar.DKind == OMPD_unknown)) { 11046 Diag(ELoc, diag::err_omp_required_access) 11047 << getOpenMPClauseName(OMPC_firstprivate) 11048 << getOpenMPClauseName(OMPC_shared); 11049 reportOriginalDsa(*this, DSAStack, D, DVar); 11050 continue; 11051 } 11052 } 11053 // OpenMP [2.9.3.4, Restrictions, p.3] 11054 // A list item that appears in a reduction clause of a parallel construct 11055 // must not appear in a firstprivate clause on a worksharing or task 11056 // construct if any of the worksharing or task regions arising from the 11057 // worksharing or task construct ever bind to any of the parallel regions 11058 // arising from the parallel construct. 11059 // OpenMP [2.9.3.4, Restrictions, p.4] 11060 // A list item that appears in a reduction clause in worksharing 11061 // construct must not appear in a firstprivate clause in a task construct 11062 // encountered during execution of any of the worksharing regions arising 11063 // from the worksharing construct. 11064 if (isOpenMPTaskingDirective(CurrDir)) { 11065 DVar = DSAStack->hasInnermostDSA( 11066 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11067 [](OpenMPDirectiveKind K) { 11068 return isOpenMPParallelDirective(K) || 11069 isOpenMPWorksharingDirective(K) || 11070 isOpenMPTeamsDirective(K); 11071 }, 11072 /*FromParent=*/true); 11073 if (DVar.CKind == OMPC_reduction && 11074 (isOpenMPParallelDirective(DVar.DKind) || 11075 isOpenMPWorksharingDirective(DVar.DKind) || 11076 isOpenMPTeamsDirective(DVar.DKind))) { 11077 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11078 << getOpenMPDirectiveName(DVar.DKind); 11079 reportOriginalDsa(*this, DSAStack, D, DVar); 11080 continue; 11081 } 11082 } 11083 11084 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11085 // A list item cannot appear in both a map clause and a data-sharing 11086 // attribute clause on the same construct 11087 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11088 OpenMPClauseKind ConflictKind; 11089 if (DSAStack->checkMappableExprComponentListsForDecl( 11090 VD, /*CurrentRegionOnly=*/true, 11091 [&ConflictKind]( 11092 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11093 OpenMPClauseKind WhereFoundClauseKind) { 11094 ConflictKind = WhereFoundClauseKind; 11095 return true; 11096 })) { 11097 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11098 << getOpenMPClauseName(OMPC_firstprivate) 11099 << getOpenMPClauseName(ConflictKind) 11100 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11101 reportOriginalDsa(*this, DSAStack, D, DVar); 11102 continue; 11103 } 11104 } 11105 } 11106 11107 // Variably modified types are not supported for tasks. 11108 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11109 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11110 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11111 << getOpenMPClauseName(OMPC_firstprivate) << Type 11112 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11113 bool IsDecl = 11114 !VD || 11115 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11116 Diag(D->getLocation(), 11117 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11118 << D; 11119 continue; 11120 } 11121 11122 Type = Type.getUnqualifiedType(); 11123 VarDecl *VDPrivate = 11124 buildVarDecl(*this, ELoc, Type, D->getName(), 11125 D->hasAttrs() ? &D->getAttrs() : nullptr, 11126 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11127 // Generate helper private variable and initialize it with the value of the 11128 // original variable. The address of the original variable is replaced by 11129 // the address of the new private variable in the CodeGen. This new variable 11130 // is not added to IdResolver, so the code in the OpenMP region uses 11131 // original variable for proper diagnostics and variable capturing. 11132 Expr *VDInitRefExpr = nullptr; 11133 // For arrays generate initializer for single element and replace it by the 11134 // original array element in CodeGen. 11135 if (Type->isArrayType()) { 11136 VarDecl *VDInit = 11137 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11138 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11139 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11140 ElemType = ElemType.getUnqualifiedType(); 11141 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11142 ".firstprivate.temp"); 11143 InitializedEntity Entity = 11144 InitializedEntity::InitializeVariable(VDInitTemp); 11145 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11146 11147 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11148 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11149 if (Result.isInvalid()) 11150 VDPrivate->setInvalidDecl(); 11151 else 11152 VDPrivate->setInit(Result.getAs<Expr>()); 11153 // Remove temp variable declaration. 11154 Context.Deallocate(VDInitTemp); 11155 } else { 11156 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11157 ".firstprivate.temp"); 11158 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11159 RefExpr->getExprLoc()); 11160 AddInitializerToDecl(VDPrivate, 11161 DefaultLvalueConversion(VDInitRefExpr).get(), 11162 /*DirectInit=*/false); 11163 } 11164 if (VDPrivate->isInvalidDecl()) { 11165 if (IsImplicitClause) { 11166 Diag(RefExpr->getExprLoc(), 11167 diag::note_omp_task_predetermined_firstprivate_here); 11168 } 11169 continue; 11170 } 11171 CurContext->addDecl(VDPrivate); 11172 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11173 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11174 RefExpr->getExprLoc()); 11175 DeclRefExpr *Ref = nullptr; 11176 if (!VD && !CurContext->isDependentContext()) { 11177 if (TopDVar.CKind == OMPC_lastprivate) { 11178 Ref = TopDVar.PrivateCopy; 11179 } else { 11180 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11181 if (!isOpenMPCapturedDecl(D)) 11182 ExprCaptures.push_back(Ref->getDecl()); 11183 } 11184 } 11185 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11186 Vars.push_back((VD || CurContext->isDependentContext()) 11187 ? RefExpr->IgnoreParens() 11188 : Ref); 11189 PrivateCopies.push_back(VDPrivateRefExpr); 11190 Inits.push_back(VDInitRefExpr); 11191 } 11192 11193 if (Vars.empty()) 11194 return nullptr; 11195 11196 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11197 Vars, PrivateCopies, Inits, 11198 buildPreInits(Context, ExprCaptures)); 11199 } 11200 11201 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11202 SourceLocation StartLoc, 11203 SourceLocation LParenLoc, 11204 SourceLocation EndLoc) { 11205 SmallVector<Expr *, 8> Vars; 11206 SmallVector<Expr *, 8> SrcExprs; 11207 SmallVector<Expr *, 8> DstExprs; 11208 SmallVector<Expr *, 8> AssignmentOps; 11209 SmallVector<Decl *, 4> ExprCaptures; 11210 SmallVector<Expr *, 4> ExprPostUpdates; 11211 for (Expr *RefExpr : VarList) { 11212 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11213 SourceLocation ELoc; 11214 SourceRange ERange; 11215 Expr *SimpleRefExpr = RefExpr; 11216 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11217 if (Res.second) { 11218 // It will be analyzed later. 11219 Vars.push_back(RefExpr); 11220 SrcExprs.push_back(nullptr); 11221 DstExprs.push_back(nullptr); 11222 AssignmentOps.push_back(nullptr); 11223 } 11224 ValueDecl *D = Res.first; 11225 if (!D) 11226 continue; 11227 11228 QualType Type = D->getType(); 11229 auto *VD = dyn_cast<VarDecl>(D); 11230 11231 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11232 // A variable that appears in a lastprivate clause must not have an 11233 // incomplete type or a reference type. 11234 if (RequireCompleteType(ELoc, Type, 11235 diag::err_omp_lastprivate_incomplete_type)) 11236 continue; 11237 Type = Type.getNonReferenceType(); 11238 11239 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11240 // A variable that is privatized must not have a const-qualified type 11241 // unless it is of class type with a mutable member. This restriction does 11242 // not apply to the firstprivate clause. 11243 // 11244 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11245 // A variable that appears in a lastprivate clause must not have a 11246 // const-qualified type unless it is of class type with a mutable member. 11247 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11248 continue; 11249 11250 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11251 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11252 // in a Construct] 11253 // Variables with the predetermined data-sharing attributes may not be 11254 // listed in data-sharing attributes clauses, except for the cases 11255 // listed below. 11256 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11257 // A list item may appear in a firstprivate or lastprivate clause but not 11258 // both. 11259 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11260 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11261 (isOpenMPDistributeDirective(CurrDir) || 11262 DVar.CKind != OMPC_firstprivate) && 11263 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11264 Diag(ELoc, diag::err_omp_wrong_dsa) 11265 << getOpenMPClauseName(DVar.CKind) 11266 << getOpenMPClauseName(OMPC_lastprivate); 11267 reportOriginalDsa(*this, DSAStack, D, DVar); 11268 continue; 11269 } 11270 11271 // OpenMP [2.14.3.5, Restrictions, p.2] 11272 // A list item that is private within a parallel region, or that appears in 11273 // the reduction clause of a parallel construct, must not appear in a 11274 // lastprivate clause on a worksharing construct if any of the corresponding 11275 // worksharing regions ever binds to any of the corresponding parallel 11276 // regions. 11277 DSAStackTy::DSAVarData TopDVar = DVar; 11278 if (isOpenMPWorksharingDirective(CurrDir) && 11279 !isOpenMPParallelDirective(CurrDir) && 11280 !isOpenMPTeamsDirective(CurrDir)) { 11281 DVar = DSAStack->getImplicitDSA(D, true); 11282 if (DVar.CKind != OMPC_shared) { 11283 Diag(ELoc, diag::err_omp_required_access) 11284 << getOpenMPClauseName(OMPC_lastprivate) 11285 << getOpenMPClauseName(OMPC_shared); 11286 reportOriginalDsa(*this, DSAStack, D, DVar); 11287 continue; 11288 } 11289 } 11290 11291 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11292 // A variable of class type (or array thereof) that appears in a 11293 // lastprivate clause requires an accessible, unambiguous default 11294 // constructor for the class type, unless the list item is also specified 11295 // in a firstprivate clause. 11296 // A variable of class type (or array thereof) that appears in a 11297 // lastprivate clause requires an accessible, unambiguous copy assignment 11298 // operator for the class type. 11299 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11300 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11301 Type.getUnqualifiedType(), ".lastprivate.src", 11302 D->hasAttrs() ? &D->getAttrs() : nullptr); 11303 DeclRefExpr *PseudoSrcExpr = 11304 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11305 VarDecl *DstVD = 11306 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11307 D->hasAttrs() ? &D->getAttrs() : nullptr); 11308 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11309 // For arrays generate assignment operation for single element and replace 11310 // it by the original array element in CodeGen. 11311 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11312 PseudoDstExpr, PseudoSrcExpr); 11313 if (AssignmentOp.isInvalid()) 11314 continue; 11315 AssignmentOp = 11316 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11317 if (AssignmentOp.isInvalid()) 11318 continue; 11319 11320 DeclRefExpr *Ref = nullptr; 11321 if (!VD && !CurContext->isDependentContext()) { 11322 if (TopDVar.CKind == OMPC_firstprivate) { 11323 Ref = TopDVar.PrivateCopy; 11324 } else { 11325 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11326 if (!isOpenMPCapturedDecl(D)) 11327 ExprCaptures.push_back(Ref->getDecl()); 11328 } 11329 if (TopDVar.CKind == OMPC_firstprivate || 11330 (!isOpenMPCapturedDecl(D) && 11331 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11332 ExprResult RefRes = DefaultLvalueConversion(Ref); 11333 if (!RefRes.isUsable()) 11334 continue; 11335 ExprResult PostUpdateRes = 11336 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11337 RefRes.get()); 11338 if (!PostUpdateRes.isUsable()) 11339 continue; 11340 ExprPostUpdates.push_back( 11341 IgnoredValueConversions(PostUpdateRes.get()).get()); 11342 } 11343 } 11344 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11345 Vars.push_back((VD || CurContext->isDependentContext()) 11346 ? RefExpr->IgnoreParens() 11347 : Ref); 11348 SrcExprs.push_back(PseudoSrcExpr); 11349 DstExprs.push_back(PseudoDstExpr); 11350 AssignmentOps.push_back(AssignmentOp.get()); 11351 } 11352 11353 if (Vars.empty()) 11354 return nullptr; 11355 11356 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11357 Vars, SrcExprs, DstExprs, AssignmentOps, 11358 buildPreInits(Context, ExprCaptures), 11359 buildPostUpdate(*this, ExprPostUpdates)); 11360 } 11361 11362 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11363 SourceLocation StartLoc, 11364 SourceLocation LParenLoc, 11365 SourceLocation EndLoc) { 11366 SmallVector<Expr *, 8> Vars; 11367 for (Expr *RefExpr : VarList) { 11368 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11369 SourceLocation ELoc; 11370 SourceRange ERange; 11371 Expr *SimpleRefExpr = RefExpr; 11372 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11373 if (Res.second) { 11374 // It will be analyzed later. 11375 Vars.push_back(RefExpr); 11376 } 11377 ValueDecl *D = Res.first; 11378 if (!D) 11379 continue; 11380 11381 auto *VD = dyn_cast<VarDecl>(D); 11382 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11383 // in a Construct] 11384 // Variables with the predetermined data-sharing attributes may not be 11385 // listed in data-sharing attributes clauses, except for the cases 11386 // listed below. For these exceptions only, listing a predetermined 11387 // variable in a data-sharing attribute clause is allowed and overrides 11388 // the variable's predetermined data-sharing attributes. 11389 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11390 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 11391 DVar.RefExpr) { 11392 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11393 << getOpenMPClauseName(OMPC_shared); 11394 reportOriginalDsa(*this, DSAStack, D, DVar); 11395 continue; 11396 } 11397 11398 DeclRefExpr *Ref = nullptr; 11399 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 11400 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11401 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 11402 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 11403 ? RefExpr->IgnoreParens() 11404 : Ref); 11405 } 11406 11407 if (Vars.empty()) 11408 return nullptr; 11409 11410 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 11411 } 11412 11413 namespace { 11414 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 11415 DSAStackTy *Stack; 11416 11417 public: 11418 bool VisitDeclRefExpr(DeclRefExpr *E) { 11419 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 11420 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 11421 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 11422 return false; 11423 if (DVar.CKind != OMPC_unknown) 11424 return true; 11425 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 11426 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 11427 /*FromParent=*/true); 11428 return DVarPrivate.CKind != OMPC_unknown; 11429 } 11430 return false; 11431 } 11432 bool VisitStmt(Stmt *S) { 11433 for (Stmt *Child : S->children()) { 11434 if (Child && Visit(Child)) 11435 return true; 11436 } 11437 return false; 11438 } 11439 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 11440 }; 11441 } // namespace 11442 11443 namespace { 11444 // Transform MemberExpression for specified FieldDecl of current class to 11445 // DeclRefExpr to specified OMPCapturedExprDecl. 11446 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 11447 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 11448 ValueDecl *Field = nullptr; 11449 DeclRefExpr *CapturedExpr = nullptr; 11450 11451 public: 11452 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 11453 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 11454 11455 ExprResult TransformMemberExpr(MemberExpr *E) { 11456 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 11457 E->getMemberDecl() == Field) { 11458 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 11459 return CapturedExpr; 11460 } 11461 return BaseTransform::TransformMemberExpr(E); 11462 } 11463 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 11464 }; 11465 } // namespace 11466 11467 template <typename T, typename U> 11468 static T filterLookupForUDReductionAndMapper( 11469 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 11470 for (U &Set : Lookups) { 11471 for (auto *D : Set) { 11472 if (T Res = Gen(cast<ValueDecl>(D))) 11473 return Res; 11474 } 11475 } 11476 return T(); 11477 } 11478 11479 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 11480 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 11481 11482 for (auto RD : D->redecls()) { 11483 // Don't bother with extra checks if we already know this one isn't visible. 11484 if (RD == D) 11485 continue; 11486 11487 auto ND = cast<NamedDecl>(RD); 11488 if (LookupResult::isVisible(SemaRef, ND)) 11489 return ND; 11490 } 11491 11492 return nullptr; 11493 } 11494 11495 static void 11496 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 11497 SourceLocation Loc, QualType Ty, 11498 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 11499 // Find all of the associated namespaces and classes based on the 11500 // arguments we have. 11501 Sema::AssociatedNamespaceSet AssociatedNamespaces; 11502 Sema::AssociatedClassSet AssociatedClasses; 11503 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 11504 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 11505 AssociatedClasses); 11506 11507 // C++ [basic.lookup.argdep]p3: 11508 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11509 // and let Y be the lookup set produced by argument dependent 11510 // lookup (defined as follows). If X contains [...] then Y is 11511 // empty. Otherwise Y is the set of declarations found in the 11512 // namespaces associated with the argument types as described 11513 // below. The set of declarations found by the lookup of the name 11514 // is the union of X and Y. 11515 // 11516 // Here, we compute Y and add its members to the overloaded 11517 // candidate set. 11518 for (auto *NS : AssociatedNamespaces) { 11519 // When considering an associated namespace, the lookup is the 11520 // same as the lookup performed when the associated namespace is 11521 // used as a qualifier (3.4.3.2) except that: 11522 // 11523 // -- Any using-directives in the associated namespace are 11524 // ignored. 11525 // 11526 // -- Any namespace-scope friend functions declared in 11527 // associated classes are visible within their respective 11528 // namespaces even if they are not visible during an ordinary 11529 // lookup (11.4). 11530 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11531 for (auto *D : R) { 11532 auto *Underlying = D; 11533 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11534 Underlying = USD->getTargetDecl(); 11535 11536 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11537 !isa<OMPDeclareMapperDecl>(Underlying)) 11538 continue; 11539 11540 if (!SemaRef.isVisible(D)) { 11541 D = findAcceptableDecl(SemaRef, D); 11542 if (!D) 11543 continue; 11544 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11545 Underlying = USD->getTargetDecl(); 11546 } 11547 Lookups.emplace_back(); 11548 Lookups.back().addDecl(Underlying); 11549 } 11550 } 11551 } 11552 11553 static ExprResult 11554 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11555 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11556 const DeclarationNameInfo &ReductionId, QualType Ty, 11557 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11558 if (ReductionIdScopeSpec.isInvalid()) 11559 return ExprError(); 11560 SmallVector<UnresolvedSet<8>, 4> Lookups; 11561 if (S) { 11562 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11563 Lookup.suppressDiagnostics(); 11564 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11565 NamedDecl *D = Lookup.getRepresentativeDecl(); 11566 do { 11567 S = S->getParent(); 11568 } while (S && !S->isDeclScope(D)); 11569 if (S) 11570 S = S->getParent(); 11571 Lookups.emplace_back(); 11572 Lookups.back().append(Lookup.begin(), Lookup.end()); 11573 Lookup.clear(); 11574 } 11575 } else if (auto *ULE = 11576 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11577 Lookups.push_back(UnresolvedSet<8>()); 11578 Decl *PrevD = nullptr; 11579 for (NamedDecl *D : ULE->decls()) { 11580 if (D == PrevD) 11581 Lookups.push_back(UnresolvedSet<8>()); 11582 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11583 Lookups.back().addDecl(DRD); 11584 PrevD = D; 11585 } 11586 } 11587 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11588 Ty->isInstantiationDependentType() || 11589 Ty->containsUnexpandedParameterPack() || 11590 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11591 return !D->isInvalidDecl() && 11592 (D->getType()->isDependentType() || 11593 D->getType()->isInstantiationDependentType() || 11594 D->getType()->containsUnexpandedParameterPack()); 11595 })) { 11596 UnresolvedSet<8> ResSet; 11597 for (const UnresolvedSet<8> &Set : Lookups) { 11598 if (Set.empty()) 11599 continue; 11600 ResSet.append(Set.begin(), Set.end()); 11601 // The last item marks the end of all declarations at the specified scope. 11602 ResSet.addDecl(Set[Set.size() - 1]); 11603 } 11604 return UnresolvedLookupExpr::Create( 11605 SemaRef.Context, /*NamingClass=*/nullptr, 11606 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 11607 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 11608 } 11609 // Lookup inside the classes. 11610 // C++ [over.match.oper]p3: 11611 // For a unary operator @ with an operand of a type whose 11612 // cv-unqualified version is T1, and for a binary operator @ with 11613 // a left operand of a type whose cv-unqualified version is T1 and 11614 // a right operand of a type whose cv-unqualified version is T2, 11615 // three sets of candidate functions, designated member 11616 // candidates, non-member candidates and built-in candidates, are 11617 // constructed as follows: 11618 // -- If T1 is a complete class type or a class currently being 11619 // defined, the set of member candidates is the result of the 11620 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 11621 // the set of member candidates is empty. 11622 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11623 Lookup.suppressDiagnostics(); 11624 if (const auto *TyRec = Ty->getAs<RecordType>()) { 11625 // Complete the type if it can be completed. 11626 // If the type is neither complete nor being defined, bail out now. 11627 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 11628 TyRec->getDecl()->getDefinition()) { 11629 Lookup.clear(); 11630 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 11631 if (Lookup.empty()) { 11632 Lookups.emplace_back(); 11633 Lookups.back().append(Lookup.begin(), Lookup.end()); 11634 } 11635 } 11636 } 11637 // Perform ADL. 11638 if (SemaRef.getLangOpts().CPlusPlus) 11639 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 11640 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11641 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 11642 if (!D->isInvalidDecl() && 11643 SemaRef.Context.hasSameType(D->getType(), Ty)) 11644 return D; 11645 return nullptr; 11646 })) 11647 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 11648 VK_LValue, Loc); 11649 if (SemaRef.getLangOpts().CPlusPlus) { 11650 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11651 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 11652 if (!D->isInvalidDecl() && 11653 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 11654 !Ty.isMoreQualifiedThan(D->getType())) 11655 return D; 11656 return nullptr; 11657 })) { 11658 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 11659 /*DetectVirtual=*/false); 11660 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 11661 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 11662 VD->getType().getUnqualifiedType()))) { 11663 if (SemaRef.CheckBaseClassAccess( 11664 Loc, VD->getType(), Ty, Paths.front(), 11665 /*DiagID=*/0) != Sema::AR_inaccessible) { 11666 SemaRef.BuildBasePathArray(Paths, BasePath); 11667 return SemaRef.BuildDeclRefExpr( 11668 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 11669 } 11670 } 11671 } 11672 } 11673 } 11674 if (ReductionIdScopeSpec.isSet()) { 11675 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 11676 return ExprError(); 11677 } 11678 return ExprEmpty(); 11679 } 11680 11681 namespace { 11682 /// Data for the reduction-based clauses. 11683 struct ReductionData { 11684 /// List of original reduction items. 11685 SmallVector<Expr *, 8> Vars; 11686 /// List of private copies of the reduction items. 11687 SmallVector<Expr *, 8> Privates; 11688 /// LHS expressions for the reduction_op expressions. 11689 SmallVector<Expr *, 8> LHSs; 11690 /// RHS expressions for the reduction_op expressions. 11691 SmallVector<Expr *, 8> RHSs; 11692 /// Reduction operation expression. 11693 SmallVector<Expr *, 8> ReductionOps; 11694 /// Taskgroup descriptors for the corresponding reduction items in 11695 /// in_reduction clauses. 11696 SmallVector<Expr *, 8> TaskgroupDescriptors; 11697 /// List of captures for clause. 11698 SmallVector<Decl *, 4> ExprCaptures; 11699 /// List of postupdate expressions. 11700 SmallVector<Expr *, 4> ExprPostUpdates; 11701 ReductionData() = delete; 11702 /// Reserves required memory for the reduction data. 11703 ReductionData(unsigned Size) { 11704 Vars.reserve(Size); 11705 Privates.reserve(Size); 11706 LHSs.reserve(Size); 11707 RHSs.reserve(Size); 11708 ReductionOps.reserve(Size); 11709 TaskgroupDescriptors.reserve(Size); 11710 ExprCaptures.reserve(Size); 11711 ExprPostUpdates.reserve(Size); 11712 } 11713 /// Stores reduction item and reduction operation only (required for dependent 11714 /// reduction item). 11715 void push(Expr *Item, Expr *ReductionOp) { 11716 Vars.emplace_back(Item); 11717 Privates.emplace_back(nullptr); 11718 LHSs.emplace_back(nullptr); 11719 RHSs.emplace_back(nullptr); 11720 ReductionOps.emplace_back(ReductionOp); 11721 TaskgroupDescriptors.emplace_back(nullptr); 11722 } 11723 /// Stores reduction data. 11724 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11725 Expr *TaskgroupDescriptor) { 11726 Vars.emplace_back(Item); 11727 Privates.emplace_back(Private); 11728 LHSs.emplace_back(LHS); 11729 RHSs.emplace_back(RHS); 11730 ReductionOps.emplace_back(ReductionOp); 11731 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11732 } 11733 }; 11734 } // namespace 11735 11736 static bool checkOMPArraySectionConstantForReduction( 11737 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11738 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11739 const Expr *Length = OASE->getLength(); 11740 if (Length == nullptr) { 11741 // For array sections of the form [1:] or [:], we would need to analyze 11742 // the lower bound... 11743 if (OASE->getColonLoc().isValid()) 11744 return false; 11745 11746 // This is an array subscript which has implicit length 1! 11747 SingleElement = true; 11748 ArraySizes.push_back(llvm::APSInt::get(1)); 11749 } else { 11750 Expr::EvalResult Result; 11751 if (!Length->EvaluateAsInt(Result, Context)) 11752 return false; 11753 11754 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11755 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11756 ArraySizes.push_back(ConstantLengthValue); 11757 } 11758 11759 // Get the base of this array section and walk up from there. 11760 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11761 11762 // We require length = 1 for all array sections except the right-most to 11763 // guarantee that the memory region is contiguous and has no holes in it. 11764 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11765 Length = TempOASE->getLength(); 11766 if (Length == nullptr) { 11767 // For array sections of the form [1:] or [:], we would need to analyze 11768 // the lower bound... 11769 if (OASE->getColonLoc().isValid()) 11770 return false; 11771 11772 // This is an array subscript which has implicit length 1! 11773 ArraySizes.push_back(llvm::APSInt::get(1)); 11774 } else { 11775 Expr::EvalResult Result; 11776 if (!Length->EvaluateAsInt(Result, Context)) 11777 return false; 11778 11779 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11780 if (ConstantLengthValue.getSExtValue() != 1) 11781 return false; 11782 11783 ArraySizes.push_back(ConstantLengthValue); 11784 } 11785 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11786 } 11787 11788 // If we have a single element, we don't need to add the implicit lengths. 11789 if (!SingleElement) { 11790 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11791 // Has implicit length 1! 11792 ArraySizes.push_back(llvm::APSInt::get(1)); 11793 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11794 } 11795 } 11796 11797 // This array section can be privatized as a single value or as a constant 11798 // sized array. 11799 return true; 11800 } 11801 11802 static bool actOnOMPReductionKindClause( 11803 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11804 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11805 SourceLocation ColonLoc, SourceLocation EndLoc, 11806 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11807 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11808 DeclarationName DN = ReductionId.getName(); 11809 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11810 BinaryOperatorKind BOK = BO_Comma; 11811 11812 ASTContext &Context = S.Context; 11813 // OpenMP [2.14.3.6, reduction clause] 11814 // C 11815 // reduction-identifier is either an identifier or one of the following 11816 // operators: +, -, *, &, |, ^, && and || 11817 // C++ 11818 // reduction-identifier is either an id-expression or one of the following 11819 // operators: +, -, *, &, |, ^, && and || 11820 switch (OOK) { 11821 case OO_Plus: 11822 case OO_Minus: 11823 BOK = BO_Add; 11824 break; 11825 case OO_Star: 11826 BOK = BO_Mul; 11827 break; 11828 case OO_Amp: 11829 BOK = BO_And; 11830 break; 11831 case OO_Pipe: 11832 BOK = BO_Or; 11833 break; 11834 case OO_Caret: 11835 BOK = BO_Xor; 11836 break; 11837 case OO_AmpAmp: 11838 BOK = BO_LAnd; 11839 break; 11840 case OO_PipePipe: 11841 BOK = BO_LOr; 11842 break; 11843 case OO_New: 11844 case OO_Delete: 11845 case OO_Array_New: 11846 case OO_Array_Delete: 11847 case OO_Slash: 11848 case OO_Percent: 11849 case OO_Tilde: 11850 case OO_Exclaim: 11851 case OO_Equal: 11852 case OO_Less: 11853 case OO_Greater: 11854 case OO_LessEqual: 11855 case OO_GreaterEqual: 11856 case OO_PlusEqual: 11857 case OO_MinusEqual: 11858 case OO_StarEqual: 11859 case OO_SlashEqual: 11860 case OO_PercentEqual: 11861 case OO_CaretEqual: 11862 case OO_AmpEqual: 11863 case OO_PipeEqual: 11864 case OO_LessLess: 11865 case OO_GreaterGreater: 11866 case OO_LessLessEqual: 11867 case OO_GreaterGreaterEqual: 11868 case OO_EqualEqual: 11869 case OO_ExclaimEqual: 11870 case OO_Spaceship: 11871 case OO_PlusPlus: 11872 case OO_MinusMinus: 11873 case OO_Comma: 11874 case OO_ArrowStar: 11875 case OO_Arrow: 11876 case OO_Call: 11877 case OO_Subscript: 11878 case OO_Conditional: 11879 case OO_Coawait: 11880 case NUM_OVERLOADED_OPERATORS: 11881 llvm_unreachable("Unexpected reduction identifier"); 11882 case OO_None: 11883 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11884 if (II->isStr("max")) 11885 BOK = BO_GT; 11886 else if (II->isStr("min")) 11887 BOK = BO_LT; 11888 } 11889 break; 11890 } 11891 SourceRange ReductionIdRange; 11892 if (ReductionIdScopeSpec.isValid()) 11893 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11894 else 11895 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11896 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11897 11898 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11899 bool FirstIter = true; 11900 for (Expr *RefExpr : VarList) { 11901 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11902 // OpenMP [2.1, C/C++] 11903 // A list item is a variable or array section, subject to the restrictions 11904 // specified in Section 2.4 on page 42 and in each of the sections 11905 // describing clauses and directives for which a list appears. 11906 // OpenMP [2.14.3.3, Restrictions, p.1] 11907 // A variable that is part of another variable (as an array or 11908 // structure element) cannot appear in a private clause. 11909 if (!FirstIter && IR != ER) 11910 ++IR; 11911 FirstIter = false; 11912 SourceLocation ELoc; 11913 SourceRange ERange; 11914 Expr *SimpleRefExpr = RefExpr; 11915 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11916 /*AllowArraySection=*/true); 11917 if (Res.second) { 11918 // Try to find 'declare reduction' corresponding construct before using 11919 // builtin/overloaded operators. 11920 QualType Type = Context.DependentTy; 11921 CXXCastPath BasePath; 11922 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11923 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11924 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11925 Expr *ReductionOp = nullptr; 11926 if (S.CurContext->isDependentContext() && 11927 (DeclareReductionRef.isUnset() || 11928 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11929 ReductionOp = DeclareReductionRef.get(); 11930 // It will be analyzed later. 11931 RD.push(RefExpr, ReductionOp); 11932 } 11933 ValueDecl *D = Res.first; 11934 if (!D) 11935 continue; 11936 11937 Expr *TaskgroupDescriptor = nullptr; 11938 QualType Type; 11939 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11940 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11941 if (ASE) { 11942 Type = ASE->getType().getNonReferenceType(); 11943 } else if (OASE) { 11944 QualType BaseType = 11945 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11946 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11947 Type = ATy->getElementType(); 11948 else 11949 Type = BaseType->getPointeeType(); 11950 Type = Type.getNonReferenceType(); 11951 } else { 11952 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11953 } 11954 auto *VD = dyn_cast<VarDecl>(D); 11955 11956 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11957 // A variable that appears in a private clause must not have an incomplete 11958 // type or a reference type. 11959 if (S.RequireCompleteType(ELoc, D->getType(), 11960 diag::err_omp_reduction_incomplete_type)) 11961 continue; 11962 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11963 // A list item that appears in a reduction clause must not be 11964 // const-qualified. 11965 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 11966 /*AcceptIfMutable*/ false, ASE || OASE)) 11967 continue; 11968 11969 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 11970 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 11971 // If a list-item is a reference type then it must bind to the same object 11972 // for all threads of the team. 11973 if (!ASE && !OASE) { 11974 if (VD) { 11975 VarDecl *VDDef = VD->getDefinition(); 11976 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11977 DSARefChecker Check(Stack); 11978 if (Check.Visit(VDDef->getInit())) { 11979 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11980 << getOpenMPClauseName(ClauseKind) << ERange; 11981 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11982 continue; 11983 } 11984 } 11985 } 11986 11987 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11988 // in a Construct] 11989 // Variables with the predetermined data-sharing attributes may not be 11990 // listed in data-sharing attributes clauses, except for the cases 11991 // listed below. For these exceptions only, listing a predetermined 11992 // variable in a data-sharing attribute clause is allowed and overrides 11993 // the variable's predetermined data-sharing attributes. 11994 // OpenMP [2.14.3.6, Restrictions, p.3] 11995 // Any number of reduction clauses can be specified on the directive, 11996 // but a list item can appear only once in the reduction clauses for that 11997 // directive. 11998 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11999 if (DVar.CKind == OMPC_reduction) { 12000 S.Diag(ELoc, diag::err_omp_once_referenced) 12001 << getOpenMPClauseName(ClauseKind); 12002 if (DVar.RefExpr) 12003 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12004 continue; 12005 } 12006 if (DVar.CKind != OMPC_unknown) { 12007 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12008 << getOpenMPClauseName(DVar.CKind) 12009 << getOpenMPClauseName(OMPC_reduction); 12010 reportOriginalDsa(S, Stack, D, DVar); 12011 continue; 12012 } 12013 12014 // OpenMP [2.14.3.6, Restrictions, p.1] 12015 // A list item that appears in a reduction clause of a worksharing 12016 // construct must be shared in the parallel regions to which any of the 12017 // worksharing regions arising from the worksharing construct bind. 12018 if (isOpenMPWorksharingDirective(CurrDir) && 12019 !isOpenMPParallelDirective(CurrDir) && 12020 !isOpenMPTeamsDirective(CurrDir)) { 12021 DVar = Stack->getImplicitDSA(D, true); 12022 if (DVar.CKind != OMPC_shared) { 12023 S.Diag(ELoc, diag::err_omp_required_access) 12024 << getOpenMPClauseName(OMPC_reduction) 12025 << getOpenMPClauseName(OMPC_shared); 12026 reportOriginalDsa(S, Stack, D, DVar); 12027 continue; 12028 } 12029 } 12030 } 12031 12032 // Try to find 'declare reduction' corresponding construct before using 12033 // builtin/overloaded operators. 12034 CXXCastPath BasePath; 12035 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12036 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12037 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12038 if (DeclareReductionRef.isInvalid()) 12039 continue; 12040 if (S.CurContext->isDependentContext() && 12041 (DeclareReductionRef.isUnset() || 12042 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12043 RD.push(RefExpr, DeclareReductionRef.get()); 12044 continue; 12045 } 12046 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12047 // Not allowed reduction identifier is found. 12048 S.Diag(ReductionId.getBeginLoc(), 12049 diag::err_omp_unknown_reduction_identifier) 12050 << Type << ReductionIdRange; 12051 continue; 12052 } 12053 12054 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12055 // The type of a list item that appears in a reduction clause must be valid 12056 // for the reduction-identifier. For a max or min reduction in C, the type 12057 // of the list item must be an allowed arithmetic data type: char, int, 12058 // float, double, or _Bool, possibly modified with long, short, signed, or 12059 // unsigned. For a max or min reduction in C++, the type of the list item 12060 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12061 // double, or bool, possibly modified with long, short, signed, or unsigned. 12062 if (DeclareReductionRef.isUnset()) { 12063 if ((BOK == BO_GT || BOK == BO_LT) && 12064 !(Type->isScalarType() || 12065 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12066 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12067 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12068 if (!ASE && !OASE) { 12069 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12070 VarDecl::DeclarationOnly; 12071 S.Diag(D->getLocation(), 12072 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12073 << D; 12074 } 12075 continue; 12076 } 12077 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12078 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12079 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12080 << getOpenMPClauseName(ClauseKind); 12081 if (!ASE && !OASE) { 12082 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12083 VarDecl::DeclarationOnly; 12084 S.Diag(D->getLocation(), 12085 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12086 << D; 12087 } 12088 continue; 12089 } 12090 } 12091 12092 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12093 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12094 D->hasAttrs() ? &D->getAttrs() : nullptr); 12095 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12096 D->hasAttrs() ? &D->getAttrs() : nullptr); 12097 QualType PrivateTy = Type; 12098 12099 // Try if we can determine constant lengths for all array sections and avoid 12100 // the VLA. 12101 bool ConstantLengthOASE = false; 12102 if (OASE) { 12103 bool SingleElement; 12104 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12105 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12106 Context, OASE, SingleElement, ArraySizes); 12107 12108 // If we don't have a single element, we must emit a constant array type. 12109 if (ConstantLengthOASE && !SingleElement) { 12110 for (llvm::APSInt &Size : ArraySizes) 12111 PrivateTy = Context.getConstantArrayType( 12112 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12113 } 12114 } 12115 12116 if ((OASE && !ConstantLengthOASE) || 12117 (!OASE && !ASE && 12118 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12119 if (!Context.getTargetInfo().isVLASupported() && 12120 S.shouldDiagnoseTargetSupportFromOpenMP()) { 12121 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12122 S.Diag(ELoc, diag::note_vla_unsupported); 12123 continue; 12124 } 12125 // For arrays/array sections only: 12126 // Create pseudo array type for private copy. The size for this array will 12127 // be generated during codegen. 12128 // For array subscripts or single variables Private Ty is the same as Type 12129 // (type of the variable or single array element). 12130 PrivateTy = Context.getVariableArrayType( 12131 Type, 12132 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12133 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12134 } else if (!ASE && !OASE && 12135 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12136 PrivateTy = D->getType().getNonReferenceType(); 12137 } 12138 // Private copy. 12139 VarDecl *PrivateVD = 12140 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12141 D->hasAttrs() ? &D->getAttrs() : nullptr, 12142 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12143 // Add initializer for private variable. 12144 Expr *Init = nullptr; 12145 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12146 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12147 if (DeclareReductionRef.isUsable()) { 12148 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12149 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12150 if (DRD->getInitializer()) { 12151 Init = DRDRef; 12152 RHSVD->setInit(DRDRef); 12153 RHSVD->setInitStyle(VarDecl::CallInit); 12154 } 12155 } else { 12156 switch (BOK) { 12157 case BO_Add: 12158 case BO_Xor: 12159 case BO_Or: 12160 case BO_LOr: 12161 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12162 if (Type->isScalarType() || Type->isAnyComplexType()) 12163 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12164 break; 12165 case BO_Mul: 12166 case BO_LAnd: 12167 if (Type->isScalarType() || Type->isAnyComplexType()) { 12168 // '*' and '&&' reduction ops - initializer is '1'. 12169 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12170 } 12171 break; 12172 case BO_And: { 12173 // '&' reduction op - initializer is '~0'. 12174 QualType OrigType = Type; 12175 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12176 Type = ComplexTy->getElementType(); 12177 if (Type->isRealFloatingType()) { 12178 llvm::APFloat InitValue = 12179 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12180 /*isIEEE=*/true); 12181 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12182 Type, ELoc); 12183 } else if (Type->isScalarType()) { 12184 uint64_t Size = Context.getTypeSize(Type); 12185 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12186 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12187 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12188 } 12189 if (Init && OrigType->isAnyComplexType()) { 12190 // Init = 0xFFFF + 0xFFFFi; 12191 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12192 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12193 } 12194 Type = OrigType; 12195 break; 12196 } 12197 case BO_LT: 12198 case BO_GT: { 12199 // 'min' reduction op - initializer is 'Largest representable number in 12200 // the reduction list item type'. 12201 // 'max' reduction op - initializer is 'Least representable number in 12202 // the reduction list item type'. 12203 if (Type->isIntegerType() || Type->isPointerType()) { 12204 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12205 uint64_t Size = Context.getTypeSize(Type); 12206 QualType IntTy = 12207 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12208 llvm::APInt InitValue = 12209 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12210 : llvm::APInt::getMinValue(Size) 12211 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12212 : llvm::APInt::getMaxValue(Size); 12213 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12214 if (Type->isPointerType()) { 12215 // Cast to pointer type. 12216 ExprResult CastExpr = S.BuildCStyleCastExpr( 12217 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12218 if (CastExpr.isInvalid()) 12219 continue; 12220 Init = CastExpr.get(); 12221 } 12222 } else if (Type->isRealFloatingType()) { 12223 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12224 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12225 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12226 Type, ELoc); 12227 } 12228 break; 12229 } 12230 case BO_PtrMemD: 12231 case BO_PtrMemI: 12232 case BO_MulAssign: 12233 case BO_Div: 12234 case BO_Rem: 12235 case BO_Sub: 12236 case BO_Shl: 12237 case BO_Shr: 12238 case BO_LE: 12239 case BO_GE: 12240 case BO_EQ: 12241 case BO_NE: 12242 case BO_Cmp: 12243 case BO_AndAssign: 12244 case BO_XorAssign: 12245 case BO_OrAssign: 12246 case BO_Assign: 12247 case BO_AddAssign: 12248 case BO_SubAssign: 12249 case BO_DivAssign: 12250 case BO_RemAssign: 12251 case BO_ShlAssign: 12252 case BO_ShrAssign: 12253 case BO_Comma: 12254 llvm_unreachable("Unexpected reduction operation"); 12255 } 12256 } 12257 if (Init && DeclareReductionRef.isUnset()) 12258 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12259 else if (!Init) 12260 S.ActOnUninitializedDecl(RHSVD); 12261 if (RHSVD->isInvalidDecl()) 12262 continue; 12263 if (!RHSVD->hasInit() && 12264 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12265 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12266 << Type << ReductionIdRange; 12267 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12268 VarDecl::DeclarationOnly; 12269 S.Diag(D->getLocation(), 12270 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12271 << D; 12272 continue; 12273 } 12274 // Store initializer for single element in private copy. Will be used during 12275 // codegen. 12276 PrivateVD->setInit(RHSVD->getInit()); 12277 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12278 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12279 ExprResult ReductionOp; 12280 if (DeclareReductionRef.isUsable()) { 12281 QualType RedTy = DeclareReductionRef.get()->getType(); 12282 QualType PtrRedTy = Context.getPointerType(RedTy); 12283 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12284 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12285 if (!BasePath.empty()) { 12286 LHS = S.DefaultLvalueConversion(LHS.get()); 12287 RHS = S.DefaultLvalueConversion(RHS.get()); 12288 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12289 CK_UncheckedDerivedToBase, LHS.get(), 12290 &BasePath, LHS.get()->getValueKind()); 12291 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12292 CK_UncheckedDerivedToBase, RHS.get(), 12293 &BasePath, RHS.get()->getValueKind()); 12294 } 12295 FunctionProtoType::ExtProtoInfo EPI; 12296 QualType Params[] = {PtrRedTy, PtrRedTy}; 12297 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12298 auto *OVE = new (Context) OpaqueValueExpr( 12299 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12300 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12301 Expr *Args[] = {LHS.get(), RHS.get()}; 12302 ReductionOp = 12303 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12304 } else { 12305 ReductionOp = S.BuildBinOp( 12306 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12307 if (ReductionOp.isUsable()) { 12308 if (BOK != BO_LT && BOK != BO_GT) { 12309 ReductionOp = 12310 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12311 BO_Assign, LHSDRE, ReductionOp.get()); 12312 } else { 12313 auto *ConditionalOp = new (Context) 12314 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12315 Type, VK_LValue, OK_Ordinary); 12316 ReductionOp = 12317 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12318 BO_Assign, LHSDRE, ConditionalOp); 12319 } 12320 if (ReductionOp.isUsable()) 12321 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12322 /*DiscardedValue*/ false); 12323 } 12324 if (!ReductionOp.isUsable()) 12325 continue; 12326 } 12327 12328 // OpenMP [2.15.4.6, Restrictions, p.2] 12329 // A list item that appears in an in_reduction clause of a task construct 12330 // must appear in a task_reduction clause of a construct associated with a 12331 // taskgroup region that includes the participating task in its taskgroup 12332 // set. The construct associated with the innermost region that meets this 12333 // condition must specify the same reduction-identifier as the in_reduction 12334 // clause. 12335 if (ClauseKind == OMPC_in_reduction) { 12336 SourceRange ParentSR; 12337 BinaryOperatorKind ParentBOK; 12338 const Expr *ParentReductionOp; 12339 Expr *ParentBOKTD, *ParentReductionOpTD; 12340 DSAStackTy::DSAVarData ParentBOKDSA = 12341 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12342 ParentBOKTD); 12343 DSAStackTy::DSAVarData ParentReductionOpDSA = 12344 Stack->getTopMostTaskgroupReductionData( 12345 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12346 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12347 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12348 if (!IsParentBOK && !IsParentReductionOp) { 12349 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12350 continue; 12351 } 12352 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12353 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12354 IsParentReductionOp) { 12355 bool EmitError = true; 12356 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12357 llvm::FoldingSetNodeID RedId, ParentRedId; 12358 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12359 DeclareReductionRef.get()->Profile(RedId, Context, 12360 /*Canonical=*/true); 12361 EmitError = RedId != ParentRedId; 12362 } 12363 if (EmitError) { 12364 S.Diag(ReductionId.getBeginLoc(), 12365 diag::err_omp_reduction_identifier_mismatch) 12366 << ReductionIdRange << RefExpr->getSourceRange(); 12367 S.Diag(ParentSR.getBegin(), 12368 diag::note_omp_previous_reduction_identifier) 12369 << ParentSR 12370 << (IsParentBOK ? ParentBOKDSA.RefExpr 12371 : ParentReductionOpDSA.RefExpr) 12372 ->getSourceRange(); 12373 continue; 12374 } 12375 } 12376 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12377 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12378 } 12379 12380 DeclRefExpr *Ref = nullptr; 12381 Expr *VarsExpr = RefExpr->IgnoreParens(); 12382 if (!VD && !S.CurContext->isDependentContext()) { 12383 if (ASE || OASE) { 12384 TransformExprToCaptures RebuildToCapture(S, D); 12385 VarsExpr = 12386 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 12387 Ref = RebuildToCapture.getCapturedExpr(); 12388 } else { 12389 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 12390 } 12391 if (!S.isOpenMPCapturedDecl(D)) { 12392 RD.ExprCaptures.emplace_back(Ref->getDecl()); 12393 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12394 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 12395 if (!RefRes.isUsable()) 12396 continue; 12397 ExprResult PostUpdateRes = 12398 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12399 RefRes.get()); 12400 if (!PostUpdateRes.isUsable()) 12401 continue; 12402 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 12403 Stack->getCurrentDirective() == OMPD_taskgroup) { 12404 S.Diag(RefExpr->getExprLoc(), 12405 diag::err_omp_reduction_non_addressable_expression) 12406 << RefExpr->getSourceRange(); 12407 continue; 12408 } 12409 RD.ExprPostUpdates.emplace_back( 12410 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 12411 } 12412 } 12413 } 12414 // All reduction items are still marked as reduction (to do not increase 12415 // code base size). 12416 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 12417 if (CurrDir == OMPD_taskgroup) { 12418 if (DeclareReductionRef.isUsable()) 12419 Stack->addTaskgroupReductionData(D, ReductionIdRange, 12420 DeclareReductionRef.get()); 12421 else 12422 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 12423 } 12424 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 12425 TaskgroupDescriptor); 12426 } 12427 return RD.Vars.empty(); 12428 } 12429 12430 OMPClause *Sema::ActOnOpenMPReductionClause( 12431 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12432 SourceLocation ColonLoc, SourceLocation EndLoc, 12433 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12434 ArrayRef<Expr *> UnresolvedReductions) { 12435 ReductionData RD(VarList.size()); 12436 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 12437 StartLoc, LParenLoc, ColonLoc, EndLoc, 12438 ReductionIdScopeSpec, ReductionId, 12439 UnresolvedReductions, RD)) 12440 return nullptr; 12441 12442 return OMPReductionClause::Create( 12443 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12444 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12445 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12446 buildPreInits(Context, RD.ExprCaptures), 12447 buildPostUpdate(*this, RD.ExprPostUpdates)); 12448 } 12449 12450 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 12451 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12452 SourceLocation ColonLoc, SourceLocation EndLoc, 12453 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12454 ArrayRef<Expr *> UnresolvedReductions) { 12455 ReductionData RD(VarList.size()); 12456 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 12457 StartLoc, LParenLoc, ColonLoc, EndLoc, 12458 ReductionIdScopeSpec, ReductionId, 12459 UnresolvedReductions, RD)) 12460 return nullptr; 12461 12462 return OMPTaskReductionClause::Create( 12463 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12464 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12465 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12466 buildPreInits(Context, RD.ExprCaptures), 12467 buildPostUpdate(*this, RD.ExprPostUpdates)); 12468 } 12469 12470 OMPClause *Sema::ActOnOpenMPInReductionClause( 12471 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12472 SourceLocation ColonLoc, SourceLocation EndLoc, 12473 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12474 ArrayRef<Expr *> UnresolvedReductions) { 12475 ReductionData RD(VarList.size()); 12476 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 12477 StartLoc, LParenLoc, ColonLoc, EndLoc, 12478 ReductionIdScopeSpec, ReductionId, 12479 UnresolvedReductions, RD)) 12480 return nullptr; 12481 12482 return OMPInReductionClause::Create( 12483 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12484 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12485 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 12486 buildPreInits(Context, RD.ExprCaptures), 12487 buildPostUpdate(*this, RD.ExprPostUpdates)); 12488 } 12489 12490 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 12491 SourceLocation LinLoc) { 12492 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 12493 LinKind == OMPC_LINEAR_unknown) { 12494 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 12495 return true; 12496 } 12497 return false; 12498 } 12499 12500 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 12501 OpenMPLinearClauseKind LinKind, 12502 QualType Type) { 12503 const auto *VD = dyn_cast_or_null<VarDecl>(D); 12504 // A variable must not have an incomplete type or a reference type. 12505 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 12506 return true; 12507 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 12508 !Type->isReferenceType()) { 12509 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12510 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12511 return true; 12512 } 12513 Type = Type.getNonReferenceType(); 12514 12515 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12516 // A variable that is privatized must not have a const-qualified type 12517 // unless it is of class type with a mutable member. This restriction does 12518 // not apply to the firstprivate clause. 12519 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12520 return true; 12521 12522 // A list item must be of integral or pointer type. 12523 Type = Type.getUnqualifiedType().getCanonicalType(); 12524 const auto *Ty = Type.getTypePtrOrNull(); 12525 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12526 !Ty->isPointerType())) { 12527 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12528 if (D) { 12529 bool IsDecl = 12530 !VD || 12531 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12532 Diag(D->getLocation(), 12533 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12534 << D; 12535 } 12536 return true; 12537 } 12538 return false; 12539 } 12540 12541 OMPClause *Sema::ActOnOpenMPLinearClause( 12542 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12543 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12544 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12545 SmallVector<Expr *, 8> Vars; 12546 SmallVector<Expr *, 8> Privates; 12547 SmallVector<Expr *, 8> Inits; 12548 SmallVector<Decl *, 4> ExprCaptures; 12549 SmallVector<Expr *, 4> ExprPostUpdates; 12550 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12551 LinKind = OMPC_LINEAR_val; 12552 for (Expr *RefExpr : VarList) { 12553 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12554 SourceLocation ELoc; 12555 SourceRange ERange; 12556 Expr *SimpleRefExpr = RefExpr; 12557 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12558 if (Res.second) { 12559 // It will be analyzed later. 12560 Vars.push_back(RefExpr); 12561 Privates.push_back(nullptr); 12562 Inits.push_back(nullptr); 12563 } 12564 ValueDecl *D = Res.first; 12565 if (!D) 12566 continue; 12567 12568 QualType Type = D->getType(); 12569 auto *VD = dyn_cast<VarDecl>(D); 12570 12571 // OpenMP [2.14.3.7, linear clause] 12572 // A list-item cannot appear in more than one linear clause. 12573 // A list-item that appears in a linear clause cannot appear in any 12574 // other data-sharing attribute clause. 12575 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12576 if (DVar.RefExpr) { 12577 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12578 << getOpenMPClauseName(OMPC_linear); 12579 reportOriginalDsa(*this, DSAStack, D, DVar); 12580 continue; 12581 } 12582 12583 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12584 continue; 12585 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12586 12587 // Build private copy of original var. 12588 VarDecl *Private = 12589 buildVarDecl(*this, ELoc, Type, D->getName(), 12590 D->hasAttrs() ? &D->getAttrs() : nullptr, 12591 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12592 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 12593 // Build var to save initial value. 12594 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 12595 Expr *InitExpr; 12596 DeclRefExpr *Ref = nullptr; 12597 if (!VD && !CurContext->isDependentContext()) { 12598 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12599 if (!isOpenMPCapturedDecl(D)) { 12600 ExprCaptures.push_back(Ref->getDecl()); 12601 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12602 ExprResult RefRes = DefaultLvalueConversion(Ref); 12603 if (!RefRes.isUsable()) 12604 continue; 12605 ExprResult PostUpdateRes = 12606 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 12607 SimpleRefExpr, RefRes.get()); 12608 if (!PostUpdateRes.isUsable()) 12609 continue; 12610 ExprPostUpdates.push_back( 12611 IgnoredValueConversions(PostUpdateRes.get()).get()); 12612 } 12613 } 12614 } 12615 if (LinKind == OMPC_LINEAR_uval) 12616 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 12617 else 12618 InitExpr = VD ? SimpleRefExpr : Ref; 12619 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 12620 /*DirectInit=*/false); 12621 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 12622 12623 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 12624 Vars.push_back((VD || CurContext->isDependentContext()) 12625 ? RefExpr->IgnoreParens() 12626 : Ref); 12627 Privates.push_back(PrivateRef); 12628 Inits.push_back(InitRef); 12629 } 12630 12631 if (Vars.empty()) 12632 return nullptr; 12633 12634 Expr *StepExpr = Step; 12635 Expr *CalcStepExpr = nullptr; 12636 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 12637 !Step->isInstantiationDependent() && 12638 !Step->containsUnexpandedParameterPack()) { 12639 SourceLocation StepLoc = Step->getBeginLoc(); 12640 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 12641 if (Val.isInvalid()) 12642 return nullptr; 12643 StepExpr = Val.get(); 12644 12645 // Build var to save the step value. 12646 VarDecl *SaveVar = 12647 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 12648 ExprResult SaveRef = 12649 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 12650 ExprResult CalcStep = 12651 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 12652 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 12653 12654 // Warn about zero linear step (it would be probably better specified as 12655 // making corresponding variables 'const'). 12656 llvm::APSInt Result; 12657 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 12658 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 12659 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 12660 << (Vars.size() > 1); 12661 if (!IsConstant && CalcStep.isUsable()) { 12662 // Calculate the step beforehand instead of doing this on each iteration. 12663 // (This is not used if the number of iterations may be kfold-ed). 12664 CalcStepExpr = CalcStep.get(); 12665 } 12666 } 12667 12668 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 12669 ColonLoc, EndLoc, Vars, Privates, Inits, 12670 StepExpr, CalcStepExpr, 12671 buildPreInits(Context, ExprCaptures), 12672 buildPostUpdate(*this, ExprPostUpdates)); 12673 } 12674 12675 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 12676 Expr *NumIterations, Sema &SemaRef, 12677 Scope *S, DSAStackTy *Stack) { 12678 // Walk the vars and build update/final expressions for the CodeGen. 12679 SmallVector<Expr *, 8> Updates; 12680 SmallVector<Expr *, 8> Finals; 12681 Expr *Step = Clause.getStep(); 12682 Expr *CalcStep = Clause.getCalcStep(); 12683 // OpenMP [2.14.3.7, linear clause] 12684 // If linear-step is not specified it is assumed to be 1. 12685 if (!Step) 12686 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12687 else if (CalcStep) 12688 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12689 bool HasErrors = false; 12690 auto CurInit = Clause.inits().begin(); 12691 auto CurPrivate = Clause.privates().begin(); 12692 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12693 for (Expr *RefExpr : Clause.varlists()) { 12694 SourceLocation ELoc; 12695 SourceRange ERange; 12696 Expr *SimpleRefExpr = RefExpr; 12697 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12698 ValueDecl *D = Res.first; 12699 if (Res.second || !D) { 12700 Updates.push_back(nullptr); 12701 Finals.push_back(nullptr); 12702 HasErrors = true; 12703 continue; 12704 } 12705 auto &&Info = Stack->isLoopControlVariable(D); 12706 // OpenMP [2.15.11, distribute simd Construct] 12707 // A list item may not appear in a linear clause, unless it is the loop 12708 // iteration variable. 12709 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12710 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12711 SemaRef.Diag(ELoc, 12712 diag::err_omp_linear_distribute_var_non_loop_iteration); 12713 Updates.push_back(nullptr); 12714 Finals.push_back(nullptr); 12715 HasErrors = true; 12716 continue; 12717 } 12718 Expr *InitExpr = *CurInit; 12719 12720 // Build privatized reference to the current linear var. 12721 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12722 Expr *CapturedRef; 12723 if (LinKind == OMPC_LINEAR_uval) 12724 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12725 else 12726 CapturedRef = 12727 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12728 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12729 /*RefersToCapture=*/true); 12730 12731 // Build update: Var = InitExpr + IV * Step 12732 ExprResult Update; 12733 if (!Info.first) 12734 Update = 12735 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12736 InitExpr, IV, Step, /* Subtract */ false); 12737 else 12738 Update = *CurPrivate; 12739 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12740 /*DiscardedValue*/ false); 12741 12742 // Build final: Var = InitExpr + NumIterations * Step 12743 ExprResult Final; 12744 if (!Info.first) 12745 Final = 12746 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12747 InitExpr, NumIterations, Step, /*Subtract=*/false); 12748 else 12749 Final = *CurPrivate; 12750 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12751 /*DiscardedValue*/ false); 12752 12753 if (!Update.isUsable() || !Final.isUsable()) { 12754 Updates.push_back(nullptr); 12755 Finals.push_back(nullptr); 12756 HasErrors = true; 12757 } else { 12758 Updates.push_back(Update.get()); 12759 Finals.push_back(Final.get()); 12760 } 12761 ++CurInit; 12762 ++CurPrivate; 12763 } 12764 Clause.setUpdates(Updates); 12765 Clause.setFinals(Finals); 12766 return HasErrors; 12767 } 12768 12769 OMPClause *Sema::ActOnOpenMPAlignedClause( 12770 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12771 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12772 SmallVector<Expr *, 8> Vars; 12773 for (Expr *RefExpr : VarList) { 12774 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12775 SourceLocation ELoc; 12776 SourceRange ERange; 12777 Expr *SimpleRefExpr = RefExpr; 12778 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12779 if (Res.second) { 12780 // It will be analyzed later. 12781 Vars.push_back(RefExpr); 12782 } 12783 ValueDecl *D = Res.first; 12784 if (!D) 12785 continue; 12786 12787 QualType QType = D->getType(); 12788 auto *VD = dyn_cast<VarDecl>(D); 12789 12790 // OpenMP [2.8.1, simd construct, Restrictions] 12791 // The type of list items appearing in the aligned clause must be 12792 // array, pointer, reference to array, or reference to pointer. 12793 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12794 const Type *Ty = QType.getTypePtrOrNull(); 12795 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12796 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12797 << QType << getLangOpts().CPlusPlus << ERange; 12798 bool IsDecl = 12799 !VD || 12800 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12801 Diag(D->getLocation(), 12802 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12803 << D; 12804 continue; 12805 } 12806 12807 // OpenMP [2.8.1, simd construct, Restrictions] 12808 // A list-item cannot appear in more than one aligned clause. 12809 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12810 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12811 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12812 << getOpenMPClauseName(OMPC_aligned); 12813 continue; 12814 } 12815 12816 DeclRefExpr *Ref = nullptr; 12817 if (!VD && isOpenMPCapturedDecl(D)) 12818 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12819 Vars.push_back(DefaultFunctionArrayConversion( 12820 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12821 .get()); 12822 } 12823 12824 // OpenMP [2.8.1, simd construct, Description] 12825 // The parameter of the aligned clause, alignment, must be a constant 12826 // positive integer expression. 12827 // If no optional parameter is specified, implementation-defined default 12828 // alignments for SIMD instructions on the target platforms are assumed. 12829 if (Alignment != nullptr) { 12830 ExprResult AlignResult = 12831 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12832 if (AlignResult.isInvalid()) 12833 return nullptr; 12834 Alignment = AlignResult.get(); 12835 } 12836 if (Vars.empty()) 12837 return nullptr; 12838 12839 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12840 EndLoc, Vars, Alignment); 12841 } 12842 12843 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12844 SourceLocation StartLoc, 12845 SourceLocation LParenLoc, 12846 SourceLocation EndLoc) { 12847 SmallVector<Expr *, 8> Vars; 12848 SmallVector<Expr *, 8> SrcExprs; 12849 SmallVector<Expr *, 8> DstExprs; 12850 SmallVector<Expr *, 8> AssignmentOps; 12851 for (Expr *RefExpr : VarList) { 12852 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12853 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12854 // It will be analyzed later. 12855 Vars.push_back(RefExpr); 12856 SrcExprs.push_back(nullptr); 12857 DstExprs.push_back(nullptr); 12858 AssignmentOps.push_back(nullptr); 12859 continue; 12860 } 12861 12862 SourceLocation ELoc = RefExpr->getExprLoc(); 12863 // OpenMP [2.1, C/C++] 12864 // A list item is a variable name. 12865 // OpenMP [2.14.4.1, Restrictions, p.1] 12866 // A list item that appears in a copyin clause must be threadprivate. 12867 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12868 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12869 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12870 << 0 << RefExpr->getSourceRange(); 12871 continue; 12872 } 12873 12874 Decl *D = DE->getDecl(); 12875 auto *VD = cast<VarDecl>(D); 12876 12877 QualType Type = VD->getType(); 12878 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12879 // It will be analyzed later. 12880 Vars.push_back(DE); 12881 SrcExprs.push_back(nullptr); 12882 DstExprs.push_back(nullptr); 12883 AssignmentOps.push_back(nullptr); 12884 continue; 12885 } 12886 12887 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12888 // A list item that appears in a copyin clause must be threadprivate. 12889 if (!DSAStack->isThreadPrivate(VD)) { 12890 Diag(ELoc, diag::err_omp_required_access) 12891 << getOpenMPClauseName(OMPC_copyin) 12892 << getOpenMPDirectiveName(OMPD_threadprivate); 12893 continue; 12894 } 12895 12896 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12897 // A variable of class type (or array thereof) that appears in a 12898 // copyin clause requires an accessible, unambiguous copy assignment 12899 // operator for the class type. 12900 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12901 VarDecl *SrcVD = 12902 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12903 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12904 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12905 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12906 VarDecl *DstVD = 12907 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12908 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12909 DeclRefExpr *PseudoDstExpr = 12910 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12911 // For arrays generate assignment operation for single element and replace 12912 // it by the original array element in CodeGen. 12913 ExprResult AssignmentOp = 12914 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12915 PseudoSrcExpr); 12916 if (AssignmentOp.isInvalid()) 12917 continue; 12918 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12919 /*DiscardedValue*/ false); 12920 if (AssignmentOp.isInvalid()) 12921 continue; 12922 12923 DSAStack->addDSA(VD, DE, OMPC_copyin); 12924 Vars.push_back(DE); 12925 SrcExprs.push_back(PseudoSrcExpr); 12926 DstExprs.push_back(PseudoDstExpr); 12927 AssignmentOps.push_back(AssignmentOp.get()); 12928 } 12929 12930 if (Vars.empty()) 12931 return nullptr; 12932 12933 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12934 SrcExprs, DstExprs, AssignmentOps); 12935 } 12936 12937 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12938 SourceLocation StartLoc, 12939 SourceLocation LParenLoc, 12940 SourceLocation EndLoc) { 12941 SmallVector<Expr *, 8> Vars; 12942 SmallVector<Expr *, 8> SrcExprs; 12943 SmallVector<Expr *, 8> DstExprs; 12944 SmallVector<Expr *, 8> AssignmentOps; 12945 for (Expr *RefExpr : VarList) { 12946 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12947 SourceLocation ELoc; 12948 SourceRange ERange; 12949 Expr *SimpleRefExpr = RefExpr; 12950 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12951 if (Res.second) { 12952 // It will be analyzed later. 12953 Vars.push_back(RefExpr); 12954 SrcExprs.push_back(nullptr); 12955 DstExprs.push_back(nullptr); 12956 AssignmentOps.push_back(nullptr); 12957 } 12958 ValueDecl *D = Res.first; 12959 if (!D) 12960 continue; 12961 12962 QualType Type = D->getType(); 12963 auto *VD = dyn_cast<VarDecl>(D); 12964 12965 // OpenMP [2.14.4.2, Restrictions, p.2] 12966 // A list item that appears in a copyprivate clause may not appear in a 12967 // private or firstprivate clause on the single construct. 12968 if (!VD || !DSAStack->isThreadPrivate(VD)) { 12969 DSAStackTy::DSAVarData DVar = 12970 DSAStack->getTopDSA(D, /*FromParent=*/false); 12971 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 12972 DVar.RefExpr) { 12973 Diag(ELoc, diag::err_omp_wrong_dsa) 12974 << getOpenMPClauseName(DVar.CKind) 12975 << getOpenMPClauseName(OMPC_copyprivate); 12976 reportOriginalDsa(*this, DSAStack, D, DVar); 12977 continue; 12978 } 12979 12980 // OpenMP [2.11.4.2, Restrictions, p.1] 12981 // All list items that appear in a copyprivate clause must be either 12982 // threadprivate or private in the enclosing context. 12983 if (DVar.CKind == OMPC_unknown) { 12984 DVar = DSAStack->getImplicitDSA(D, false); 12985 if (DVar.CKind == OMPC_shared) { 12986 Diag(ELoc, diag::err_omp_required_access) 12987 << getOpenMPClauseName(OMPC_copyprivate) 12988 << "threadprivate or private in the enclosing context"; 12989 reportOriginalDsa(*this, DSAStack, D, DVar); 12990 continue; 12991 } 12992 } 12993 } 12994 12995 // Variably modified types are not supported. 12996 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12997 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12998 << getOpenMPClauseName(OMPC_copyprivate) << Type 12999 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13000 bool IsDecl = 13001 !VD || 13002 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13003 Diag(D->getLocation(), 13004 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13005 << D; 13006 continue; 13007 } 13008 13009 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13010 // A variable of class type (or array thereof) that appears in a 13011 // copyin clause requires an accessible, unambiguous copy assignment 13012 // operator for the class type. 13013 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13014 .getUnqualifiedType(); 13015 VarDecl *SrcVD = 13016 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13017 D->hasAttrs() ? &D->getAttrs() : nullptr); 13018 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13019 VarDecl *DstVD = 13020 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13021 D->hasAttrs() ? &D->getAttrs() : nullptr); 13022 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13023 ExprResult AssignmentOp = BuildBinOp( 13024 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13025 if (AssignmentOp.isInvalid()) 13026 continue; 13027 AssignmentOp = 13028 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13029 if (AssignmentOp.isInvalid()) 13030 continue; 13031 13032 // No need to mark vars as copyprivate, they are already threadprivate or 13033 // implicitly private. 13034 assert(VD || isOpenMPCapturedDecl(D)); 13035 Vars.push_back( 13036 VD ? RefExpr->IgnoreParens() 13037 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13038 SrcExprs.push_back(PseudoSrcExpr); 13039 DstExprs.push_back(PseudoDstExpr); 13040 AssignmentOps.push_back(AssignmentOp.get()); 13041 } 13042 13043 if (Vars.empty()) 13044 return nullptr; 13045 13046 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13047 Vars, SrcExprs, DstExprs, AssignmentOps); 13048 } 13049 13050 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13051 SourceLocation StartLoc, 13052 SourceLocation LParenLoc, 13053 SourceLocation EndLoc) { 13054 if (VarList.empty()) 13055 return nullptr; 13056 13057 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13058 } 13059 13060 OMPClause * 13061 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13062 SourceLocation DepLoc, SourceLocation ColonLoc, 13063 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13064 SourceLocation LParenLoc, SourceLocation EndLoc) { 13065 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13066 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13067 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13068 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13069 return nullptr; 13070 } 13071 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13072 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13073 DepKind == OMPC_DEPEND_sink)) { 13074 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13075 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13076 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13077 /*Last=*/OMPC_DEPEND_unknown, Except) 13078 << getOpenMPClauseName(OMPC_depend); 13079 return nullptr; 13080 } 13081 SmallVector<Expr *, 8> Vars; 13082 DSAStackTy::OperatorOffsetTy OpsOffs; 13083 llvm::APSInt DepCounter(/*BitWidth=*/32); 13084 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13085 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13086 if (const Expr *OrderedCountExpr = 13087 DSAStack->getParentOrderedRegionParam().first) { 13088 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13089 TotalDepCount.setIsUnsigned(/*Val=*/true); 13090 } 13091 } 13092 for (Expr *RefExpr : VarList) { 13093 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13094 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13095 // It will be analyzed later. 13096 Vars.push_back(RefExpr); 13097 continue; 13098 } 13099 13100 SourceLocation ELoc = RefExpr->getExprLoc(); 13101 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13102 if (DepKind == OMPC_DEPEND_sink) { 13103 if (DSAStack->getParentOrderedRegionParam().first && 13104 DepCounter >= TotalDepCount) { 13105 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13106 continue; 13107 } 13108 ++DepCounter; 13109 // OpenMP [2.13.9, Summary] 13110 // depend(dependence-type : vec), where dependence-type is: 13111 // 'sink' and where vec is the iteration vector, which has the form: 13112 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13113 // where n is the value specified by the ordered clause in the loop 13114 // directive, xi denotes the loop iteration variable of the i-th nested 13115 // loop associated with the loop directive, and di is a constant 13116 // non-negative integer. 13117 if (CurContext->isDependentContext()) { 13118 // It will be analyzed later. 13119 Vars.push_back(RefExpr); 13120 continue; 13121 } 13122 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13123 OverloadedOperatorKind OOK = OO_None; 13124 SourceLocation OOLoc; 13125 Expr *LHS = SimpleExpr; 13126 Expr *RHS = nullptr; 13127 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13128 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13129 OOLoc = BO->getOperatorLoc(); 13130 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13131 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13132 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13133 OOK = OCE->getOperator(); 13134 OOLoc = OCE->getOperatorLoc(); 13135 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13136 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13137 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13138 OOK = MCE->getMethodDecl() 13139 ->getNameInfo() 13140 .getName() 13141 .getCXXOverloadedOperator(); 13142 OOLoc = MCE->getCallee()->getExprLoc(); 13143 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13144 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13145 } 13146 SourceLocation ELoc; 13147 SourceRange ERange; 13148 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13149 if (Res.second) { 13150 // It will be analyzed later. 13151 Vars.push_back(RefExpr); 13152 } 13153 ValueDecl *D = Res.first; 13154 if (!D) 13155 continue; 13156 13157 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13158 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13159 continue; 13160 } 13161 if (RHS) { 13162 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13163 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13164 if (RHSRes.isInvalid()) 13165 continue; 13166 } 13167 if (!CurContext->isDependentContext() && 13168 DSAStack->getParentOrderedRegionParam().first && 13169 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13170 const ValueDecl *VD = 13171 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13172 if (VD) 13173 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13174 << 1 << VD; 13175 else 13176 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13177 continue; 13178 } 13179 OpsOffs.emplace_back(RHS, OOK); 13180 } else { 13181 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13182 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13183 (ASE && 13184 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13185 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13186 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13187 << RefExpr->getSourceRange(); 13188 continue; 13189 } 13190 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 13191 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 13192 ExprResult Res = 13193 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 13194 getDiagnostics().setSuppressAllDiagnostics(Suppress); 13195 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13196 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13197 << RefExpr->getSourceRange(); 13198 continue; 13199 } 13200 } 13201 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13202 } 13203 13204 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13205 TotalDepCount > VarList.size() && 13206 DSAStack->getParentOrderedRegionParam().first && 13207 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13208 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13209 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13210 } 13211 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13212 Vars.empty()) 13213 return nullptr; 13214 13215 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13216 DepKind, DepLoc, ColonLoc, Vars, 13217 TotalDepCount.getZExtValue()); 13218 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13219 DSAStack->isParentOrderedRegion()) 13220 DSAStack->addDoacrossDependClause(C, OpsOffs); 13221 return C; 13222 } 13223 13224 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13225 SourceLocation LParenLoc, 13226 SourceLocation EndLoc) { 13227 Expr *ValExpr = Device; 13228 Stmt *HelperValStmt = nullptr; 13229 13230 // OpenMP [2.9.1, Restrictions] 13231 // The device expression must evaluate to a non-negative integer value. 13232 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13233 /*StrictlyPositive=*/false)) 13234 return nullptr; 13235 13236 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13237 OpenMPDirectiveKind CaptureRegion = 13238 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13239 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13240 ValExpr = MakeFullExpr(ValExpr).get(); 13241 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13242 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13243 HelperValStmt = buildPreInits(Context, Captures); 13244 } 13245 13246 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13247 StartLoc, LParenLoc, EndLoc); 13248 } 13249 13250 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13251 DSAStackTy *Stack, QualType QTy, 13252 bool FullCheck = true) { 13253 NamedDecl *ND; 13254 if (QTy->isIncompleteType(&ND)) { 13255 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13256 return false; 13257 } 13258 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13259 !QTy.isTrivialType(SemaRef.Context)) 13260 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13261 return true; 13262 } 13263 13264 /// Return true if it can be proven that the provided array expression 13265 /// (array section or array subscript) does NOT specify the whole size of the 13266 /// array whose base type is \a BaseQTy. 13267 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13268 const Expr *E, 13269 QualType BaseQTy) { 13270 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13271 13272 // If this is an array subscript, it refers to the whole size if the size of 13273 // the dimension is constant and equals 1. Also, an array section assumes the 13274 // format of an array subscript if no colon is used. 13275 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13276 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13277 return ATy->getSize().getSExtValue() != 1; 13278 // Size can't be evaluated statically. 13279 return false; 13280 } 13281 13282 assert(OASE && "Expecting array section if not an array subscript."); 13283 const Expr *LowerBound = OASE->getLowerBound(); 13284 const Expr *Length = OASE->getLength(); 13285 13286 // If there is a lower bound that does not evaluates to zero, we are not 13287 // covering the whole dimension. 13288 if (LowerBound) { 13289 Expr::EvalResult Result; 13290 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13291 return false; // Can't get the integer value as a constant. 13292 13293 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13294 if (ConstLowerBound.getSExtValue()) 13295 return true; 13296 } 13297 13298 // If we don't have a length we covering the whole dimension. 13299 if (!Length) 13300 return false; 13301 13302 // If the base is a pointer, we don't have a way to get the size of the 13303 // pointee. 13304 if (BaseQTy->isPointerType()) 13305 return false; 13306 13307 // We can only check if the length is the same as the size of the dimension 13308 // if we have a constant array. 13309 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13310 if (!CATy) 13311 return false; 13312 13313 Expr::EvalResult Result; 13314 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13315 return false; // Can't get the integer value as a constant. 13316 13317 llvm::APSInt ConstLength = Result.Val.getInt(); 13318 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13319 } 13320 13321 // Return true if it can be proven that the provided array expression (array 13322 // section or array subscript) does NOT specify a single element of the array 13323 // whose base type is \a BaseQTy. 13324 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13325 const Expr *E, 13326 QualType BaseQTy) { 13327 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13328 13329 // An array subscript always refer to a single element. Also, an array section 13330 // assumes the format of an array subscript if no colon is used. 13331 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13332 return false; 13333 13334 assert(OASE && "Expecting array section if not an array subscript."); 13335 const Expr *Length = OASE->getLength(); 13336 13337 // If we don't have a length we have to check if the array has unitary size 13338 // for this dimension. Also, we should always expect a length if the base type 13339 // is pointer. 13340 if (!Length) { 13341 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13342 return ATy->getSize().getSExtValue() != 1; 13343 // We cannot assume anything. 13344 return false; 13345 } 13346 13347 // Check if the length evaluates to 1. 13348 Expr::EvalResult Result; 13349 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13350 return false; // Can't get the integer value as a constant. 13351 13352 llvm::APSInt ConstLength = Result.Val.getInt(); 13353 return ConstLength.getSExtValue() != 1; 13354 } 13355 13356 // Return the expression of the base of the mappable expression or null if it 13357 // cannot be determined and do all the necessary checks to see if the expression 13358 // is valid as a standalone mappable expression. In the process, record all the 13359 // components of the expression. 13360 static const Expr *checkMapClauseExpressionBase( 13361 Sema &SemaRef, Expr *E, 13362 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13363 OpenMPClauseKind CKind, bool NoDiagnose) { 13364 SourceLocation ELoc = E->getExprLoc(); 13365 SourceRange ERange = E->getSourceRange(); 13366 13367 // The base of elements of list in a map clause have to be either: 13368 // - a reference to variable or field. 13369 // - a member expression. 13370 // - an array expression. 13371 // 13372 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 13373 // reference to 'r'. 13374 // 13375 // If we have: 13376 // 13377 // struct SS { 13378 // Bla S; 13379 // foo() { 13380 // #pragma omp target map (S.Arr[:12]); 13381 // } 13382 // } 13383 // 13384 // We want to retrieve the member expression 'this->S'; 13385 13386 const Expr *RelevantExpr = nullptr; 13387 13388 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 13389 // If a list item is an array section, it must specify contiguous storage. 13390 // 13391 // For this restriction it is sufficient that we make sure only references 13392 // to variables or fields and array expressions, and that no array sections 13393 // exist except in the rightmost expression (unless they cover the whole 13394 // dimension of the array). E.g. these would be invalid: 13395 // 13396 // r.ArrS[3:5].Arr[6:7] 13397 // 13398 // r.ArrS[3:5].x 13399 // 13400 // but these would be valid: 13401 // r.ArrS[3].Arr[6:7] 13402 // 13403 // r.ArrS[3].x 13404 13405 bool AllowUnitySizeArraySection = true; 13406 bool AllowWholeSizeArraySection = true; 13407 13408 while (!RelevantExpr) { 13409 E = E->IgnoreParenImpCasts(); 13410 13411 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 13412 if (!isa<VarDecl>(CurE->getDecl())) 13413 return nullptr; 13414 13415 RelevantExpr = CurE; 13416 13417 // If we got a reference to a declaration, we should not expect any array 13418 // section before that. 13419 AllowUnitySizeArraySection = false; 13420 AllowWholeSizeArraySection = false; 13421 13422 // Record the component. 13423 CurComponents.emplace_back(CurE, CurE->getDecl()); 13424 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 13425 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 13426 13427 if (isa<CXXThisExpr>(BaseE)) 13428 // We found a base expression: this->Val. 13429 RelevantExpr = CurE; 13430 else 13431 E = BaseE; 13432 13433 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 13434 if (!NoDiagnose) { 13435 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 13436 << CurE->getSourceRange(); 13437 return nullptr; 13438 } 13439 if (RelevantExpr) 13440 return nullptr; 13441 continue; 13442 } 13443 13444 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 13445 13446 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 13447 // A bit-field cannot appear in a map clause. 13448 // 13449 if (FD->isBitField()) { 13450 if (!NoDiagnose) { 13451 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 13452 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 13453 return nullptr; 13454 } 13455 if (RelevantExpr) 13456 return nullptr; 13457 continue; 13458 } 13459 13460 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13461 // If the type of a list item is a reference to a type T then the type 13462 // will be considered to be T for all purposes of this clause. 13463 QualType CurType = BaseE->getType().getNonReferenceType(); 13464 13465 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 13466 // A list item cannot be a variable that is a member of a structure with 13467 // a union type. 13468 // 13469 if (CurType->isUnionType()) { 13470 if (!NoDiagnose) { 13471 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 13472 << CurE->getSourceRange(); 13473 return nullptr; 13474 } 13475 continue; 13476 } 13477 13478 // If we got a member expression, we should not expect any array section 13479 // before that: 13480 // 13481 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 13482 // If a list item is an element of a structure, only the rightmost symbol 13483 // of the variable reference can be an array section. 13484 // 13485 AllowUnitySizeArraySection = false; 13486 AllowWholeSizeArraySection = false; 13487 13488 // Record the component. 13489 CurComponents.emplace_back(CurE, FD); 13490 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 13491 E = CurE->getBase()->IgnoreParenImpCasts(); 13492 13493 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 13494 if (!NoDiagnose) { 13495 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13496 << 0 << CurE->getSourceRange(); 13497 return nullptr; 13498 } 13499 continue; 13500 } 13501 13502 // If we got an array subscript that express the whole dimension we 13503 // can have any array expressions before. If it only expressing part of 13504 // the dimension, we can only have unitary-size array expressions. 13505 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 13506 E->getType())) 13507 AllowWholeSizeArraySection = false; 13508 13509 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13510 Expr::EvalResult Result; 13511 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13512 if (!Result.Val.getInt().isNullValue()) { 13513 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13514 diag::err_omp_invalid_map_this_expr); 13515 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13516 diag::note_omp_invalid_subscript_on_this_ptr_map); 13517 } 13518 } 13519 RelevantExpr = TE; 13520 } 13521 13522 // Record the component - we don't have any declaration associated. 13523 CurComponents.emplace_back(CurE, nullptr); 13524 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13525 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13526 E = CurE->getBase()->IgnoreParenImpCasts(); 13527 13528 QualType CurType = 13529 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13530 13531 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13532 // If the type of a list item is a reference to a type T then the type 13533 // will be considered to be T for all purposes of this clause. 13534 if (CurType->isReferenceType()) 13535 CurType = CurType->getPointeeType(); 13536 13537 bool IsPointer = CurType->isAnyPointerType(); 13538 13539 if (!IsPointer && !CurType->isArrayType()) { 13540 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13541 << 0 << CurE->getSourceRange(); 13542 return nullptr; 13543 } 13544 13545 bool NotWhole = 13546 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13547 bool NotUnity = 13548 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13549 13550 if (AllowWholeSizeArraySection) { 13551 // Any array section is currently allowed. Allowing a whole size array 13552 // section implies allowing a unity array section as well. 13553 // 13554 // If this array section refers to the whole dimension we can still 13555 // accept other array sections before this one, except if the base is a 13556 // pointer. Otherwise, only unitary sections are accepted. 13557 if (NotWhole || IsPointer) 13558 AllowWholeSizeArraySection = false; 13559 } else if (AllowUnitySizeArraySection && NotUnity) { 13560 // A unity or whole array section is not allowed and that is not 13561 // compatible with the properties of the current array section. 13562 SemaRef.Diag( 13563 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13564 << CurE->getSourceRange(); 13565 return nullptr; 13566 } 13567 13568 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13569 Expr::EvalResult ResultR; 13570 Expr::EvalResult ResultL; 13571 if (CurE->getLength()->EvaluateAsInt(ResultR, 13572 SemaRef.getASTContext())) { 13573 if (!ResultR.Val.getInt().isOneValue()) { 13574 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13575 diag::err_omp_invalid_map_this_expr); 13576 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13577 diag::note_omp_invalid_length_on_this_ptr_mapping); 13578 } 13579 } 13580 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 13581 ResultL, SemaRef.getASTContext())) { 13582 if (!ResultL.Val.getInt().isNullValue()) { 13583 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13584 diag::err_omp_invalid_map_this_expr); 13585 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13586 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 13587 } 13588 } 13589 RelevantExpr = TE; 13590 } 13591 13592 // Record the component - we don't have any declaration associated. 13593 CurComponents.emplace_back(CurE, nullptr); 13594 } else { 13595 if (!NoDiagnose) { 13596 // If nothing else worked, this is not a valid map clause expression. 13597 SemaRef.Diag( 13598 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 13599 << ERange; 13600 } 13601 return nullptr; 13602 } 13603 } 13604 13605 return RelevantExpr; 13606 } 13607 13608 // Return true if expression E associated with value VD has conflicts with other 13609 // map information. 13610 static bool checkMapConflicts( 13611 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 13612 bool CurrentRegionOnly, 13613 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 13614 OpenMPClauseKind CKind) { 13615 assert(VD && E); 13616 SourceLocation ELoc = E->getExprLoc(); 13617 SourceRange ERange = E->getSourceRange(); 13618 13619 // In order to easily check the conflicts we need to match each component of 13620 // the expression under test with the components of the expressions that are 13621 // already in the stack. 13622 13623 assert(!CurComponents.empty() && "Map clause expression with no components!"); 13624 assert(CurComponents.back().getAssociatedDeclaration() == VD && 13625 "Map clause expression with unexpected base!"); 13626 13627 // Variables to help detecting enclosing problems in data environment nests. 13628 bool IsEnclosedByDataEnvironmentExpr = false; 13629 const Expr *EnclosingExpr = nullptr; 13630 13631 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 13632 VD, CurrentRegionOnly, 13633 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 13634 ERange, CKind, &EnclosingExpr, 13635 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 13636 StackComponents, 13637 OpenMPClauseKind) { 13638 assert(!StackComponents.empty() && 13639 "Map clause expression with no components!"); 13640 assert(StackComponents.back().getAssociatedDeclaration() == VD && 13641 "Map clause expression with unexpected base!"); 13642 (void)VD; 13643 13644 // The whole expression in the stack. 13645 const Expr *RE = StackComponents.front().getAssociatedExpression(); 13646 13647 // Expressions must start from the same base. Here we detect at which 13648 // point both expressions diverge from each other and see if we can 13649 // detect if the memory referred to both expressions is contiguous and 13650 // do not overlap. 13651 auto CI = CurComponents.rbegin(); 13652 auto CE = CurComponents.rend(); 13653 auto SI = StackComponents.rbegin(); 13654 auto SE = StackComponents.rend(); 13655 for (; CI != CE && SI != SE; ++CI, ++SI) { 13656 13657 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 13658 // At most one list item can be an array item derived from a given 13659 // variable in map clauses of the same construct. 13660 if (CurrentRegionOnly && 13661 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 13662 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 13663 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 13664 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 13665 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 13666 diag::err_omp_multiple_array_items_in_map_clause) 13667 << CI->getAssociatedExpression()->getSourceRange(); 13668 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 13669 diag::note_used_here) 13670 << SI->getAssociatedExpression()->getSourceRange(); 13671 return true; 13672 } 13673 13674 // Do both expressions have the same kind? 13675 if (CI->getAssociatedExpression()->getStmtClass() != 13676 SI->getAssociatedExpression()->getStmtClass()) 13677 break; 13678 13679 // Are we dealing with different variables/fields? 13680 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13681 break; 13682 } 13683 // Check if the extra components of the expressions in the enclosing 13684 // data environment are redundant for the current base declaration. 13685 // If they are, the maps completely overlap, which is legal. 13686 for (; SI != SE; ++SI) { 13687 QualType Type; 13688 if (const auto *ASE = 13689 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13690 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13691 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13692 SI->getAssociatedExpression())) { 13693 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13694 Type = 13695 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13696 } 13697 if (Type.isNull() || Type->isAnyPointerType() || 13698 checkArrayExpressionDoesNotReferToWholeSize( 13699 SemaRef, SI->getAssociatedExpression(), Type)) 13700 break; 13701 } 13702 13703 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13704 // List items of map clauses in the same construct must not share 13705 // original storage. 13706 // 13707 // If the expressions are exactly the same or one is a subset of the 13708 // other, it means they are sharing storage. 13709 if (CI == CE && SI == SE) { 13710 if (CurrentRegionOnly) { 13711 if (CKind == OMPC_map) { 13712 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13713 } else { 13714 assert(CKind == OMPC_to || CKind == OMPC_from); 13715 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13716 << ERange; 13717 } 13718 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13719 << RE->getSourceRange(); 13720 return true; 13721 } 13722 // If we find the same expression in the enclosing data environment, 13723 // that is legal. 13724 IsEnclosedByDataEnvironmentExpr = true; 13725 return false; 13726 } 13727 13728 QualType DerivedType = 13729 std::prev(CI)->getAssociatedDeclaration()->getType(); 13730 SourceLocation DerivedLoc = 13731 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13732 13733 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13734 // If the type of a list item is a reference to a type T then the type 13735 // will be considered to be T for all purposes of this clause. 13736 DerivedType = DerivedType.getNonReferenceType(); 13737 13738 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13739 // A variable for which the type is pointer and an array section 13740 // derived from that variable must not appear as list items of map 13741 // clauses of the same construct. 13742 // 13743 // Also, cover one of the cases in: 13744 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13745 // If any part of the original storage of a list item has corresponding 13746 // storage in the device data environment, all of the original storage 13747 // must have corresponding storage in the device data environment. 13748 // 13749 if (DerivedType->isAnyPointerType()) { 13750 if (CI == CE || SI == SE) { 13751 SemaRef.Diag( 13752 DerivedLoc, 13753 diag::err_omp_pointer_mapped_along_with_derived_section) 13754 << DerivedLoc; 13755 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13756 << RE->getSourceRange(); 13757 return true; 13758 } 13759 if (CI->getAssociatedExpression()->getStmtClass() != 13760 SI->getAssociatedExpression()->getStmtClass() || 13761 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13762 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13763 assert(CI != CE && SI != SE); 13764 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13765 << DerivedLoc; 13766 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13767 << RE->getSourceRange(); 13768 return true; 13769 } 13770 } 13771 13772 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13773 // List items of map clauses in the same construct must not share 13774 // original storage. 13775 // 13776 // An expression is a subset of the other. 13777 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13778 if (CKind == OMPC_map) { 13779 if (CI != CE || SI != SE) { 13780 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13781 // a pointer. 13782 auto Begin = 13783 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13784 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13785 auto It = Begin; 13786 while (It != End && !It->getAssociatedDeclaration()) 13787 std::advance(It, 1); 13788 assert(It != End && 13789 "Expected at least one component with the declaration."); 13790 if (It != Begin && It->getAssociatedDeclaration() 13791 ->getType() 13792 .getCanonicalType() 13793 ->isAnyPointerType()) { 13794 IsEnclosedByDataEnvironmentExpr = false; 13795 EnclosingExpr = nullptr; 13796 return false; 13797 } 13798 } 13799 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13800 } else { 13801 assert(CKind == OMPC_to || CKind == OMPC_from); 13802 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13803 << ERange; 13804 } 13805 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13806 << RE->getSourceRange(); 13807 return true; 13808 } 13809 13810 // The current expression uses the same base as other expression in the 13811 // data environment but does not contain it completely. 13812 if (!CurrentRegionOnly && SI != SE) 13813 EnclosingExpr = RE; 13814 13815 // The current expression is a subset of the expression in the data 13816 // environment. 13817 IsEnclosedByDataEnvironmentExpr |= 13818 (!CurrentRegionOnly && CI != CE && SI == SE); 13819 13820 return false; 13821 }); 13822 13823 if (CurrentRegionOnly) 13824 return FoundError; 13825 13826 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13827 // If any part of the original storage of a list item has corresponding 13828 // storage in the device data environment, all of the original storage must 13829 // have corresponding storage in the device data environment. 13830 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13831 // If a list item is an element of a structure, and a different element of 13832 // the structure has a corresponding list item in the device data environment 13833 // prior to a task encountering the construct associated with the map clause, 13834 // then the list item must also have a corresponding list item in the device 13835 // data environment prior to the task encountering the construct. 13836 // 13837 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13838 SemaRef.Diag(ELoc, 13839 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13840 << ERange; 13841 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13842 << EnclosingExpr->getSourceRange(); 13843 return true; 13844 } 13845 13846 return FoundError; 13847 } 13848 13849 // Look up the user-defined mapper given the mapper name and mapped type, and 13850 // build a reference to it. 13851 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13852 CXXScopeSpec &MapperIdScopeSpec, 13853 const DeclarationNameInfo &MapperId, 13854 QualType Type, 13855 Expr *UnresolvedMapper) { 13856 if (MapperIdScopeSpec.isInvalid()) 13857 return ExprError(); 13858 // Find all user-defined mappers with the given MapperId. 13859 SmallVector<UnresolvedSet<8>, 4> Lookups; 13860 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13861 Lookup.suppressDiagnostics(); 13862 if (S) { 13863 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13864 NamedDecl *D = Lookup.getRepresentativeDecl(); 13865 while (S && !S->isDeclScope(D)) 13866 S = S->getParent(); 13867 if (S) 13868 S = S->getParent(); 13869 Lookups.emplace_back(); 13870 Lookups.back().append(Lookup.begin(), Lookup.end()); 13871 Lookup.clear(); 13872 } 13873 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13874 // Extract the user-defined mappers with the given MapperId. 13875 Lookups.push_back(UnresolvedSet<8>()); 13876 for (NamedDecl *D : ULE->decls()) { 13877 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13878 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13879 Lookups.back().addDecl(DMD); 13880 } 13881 } 13882 // Defer the lookup for dependent types. The results will be passed through 13883 // UnresolvedMapper on instantiation. 13884 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13885 Type->isInstantiationDependentType() || 13886 Type->containsUnexpandedParameterPack() || 13887 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13888 return !D->isInvalidDecl() && 13889 (D->getType()->isDependentType() || 13890 D->getType()->isInstantiationDependentType() || 13891 D->getType()->containsUnexpandedParameterPack()); 13892 })) { 13893 UnresolvedSet<8> URS; 13894 for (const UnresolvedSet<8> &Set : Lookups) { 13895 if (Set.empty()) 13896 continue; 13897 URS.append(Set.begin(), Set.end()); 13898 } 13899 return UnresolvedLookupExpr::Create( 13900 SemaRef.Context, /*NamingClass=*/nullptr, 13901 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13902 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13903 } 13904 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13905 // The type must be of struct, union or class type in C and C++ 13906 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13907 return ExprEmpty(); 13908 SourceLocation Loc = MapperId.getLoc(); 13909 // Perform argument dependent lookup. 13910 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13911 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13912 // Return the first user-defined mapper with the desired type. 13913 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13914 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13915 if (!D->isInvalidDecl() && 13916 SemaRef.Context.hasSameType(D->getType(), Type)) 13917 return D; 13918 return nullptr; 13919 })) 13920 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13921 // Find the first user-defined mapper with a type derived from the desired 13922 // type. 13923 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13924 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13925 if (!D->isInvalidDecl() && 13926 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13927 !Type.isMoreQualifiedThan(D->getType())) 13928 return D; 13929 return nullptr; 13930 })) { 13931 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13932 /*DetectVirtual=*/false); 13933 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13934 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13935 VD->getType().getUnqualifiedType()))) { 13936 if (SemaRef.CheckBaseClassAccess( 13937 Loc, VD->getType(), Type, Paths.front(), 13938 /*DiagID=*/0) != Sema::AR_inaccessible) { 13939 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13940 } 13941 } 13942 } 13943 } 13944 // Report error if a mapper is specified, but cannot be found. 13945 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13946 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13947 << Type << MapperId.getName(); 13948 return ExprError(); 13949 } 13950 return ExprEmpty(); 13951 } 13952 13953 namespace { 13954 // Utility struct that gathers all the related lists associated with a mappable 13955 // expression. 13956 struct MappableVarListInfo { 13957 // The list of expressions. 13958 ArrayRef<Expr *> VarList; 13959 // The list of processed expressions. 13960 SmallVector<Expr *, 16> ProcessedVarList; 13961 // The mappble components for each expression. 13962 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 13963 // The base declaration of the variable. 13964 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 13965 // The reference to the user-defined mapper associated with every expression. 13966 SmallVector<Expr *, 16> UDMapperList; 13967 13968 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 13969 // We have a list of components and base declarations for each entry in the 13970 // variable list. 13971 VarComponents.reserve(VarList.size()); 13972 VarBaseDeclarations.reserve(VarList.size()); 13973 } 13974 }; 13975 } 13976 13977 // Check the validity of the provided variable list for the provided clause kind 13978 // \a CKind. In the check process the valid expressions, mappable expression 13979 // components, variables, and user-defined mappers are extracted and used to 13980 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 13981 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 13982 // and \a MapperId are expected to be valid if the clause kind is 'map'. 13983 static void checkMappableExpressionList( 13984 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 13985 MappableVarListInfo &MVLI, SourceLocation StartLoc, 13986 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 13987 ArrayRef<Expr *> UnresolvedMappers, 13988 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 13989 bool IsMapTypeImplicit = false) { 13990 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 13991 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 13992 "Unexpected clause kind with mappable expressions!"); 13993 13994 // If the identifier of user-defined mapper is not specified, it is "default". 13995 // We do not change the actual name in this clause to distinguish whether a 13996 // mapper is specified explicitly, i.e., it is not explicitly specified when 13997 // MapperId.getName() is empty. 13998 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 13999 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14000 MapperId.setName(DeclNames.getIdentifier( 14001 &SemaRef.getASTContext().Idents.get("default"))); 14002 } 14003 14004 // Iterators to find the current unresolved mapper expression. 14005 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14006 bool UpdateUMIt = false; 14007 Expr *UnresolvedMapper = nullptr; 14008 14009 // Keep track of the mappable components and base declarations in this clause. 14010 // Each entry in the list is going to have a list of components associated. We 14011 // record each set of the components so that we can build the clause later on. 14012 // In the end we should have the same amount of declarations and component 14013 // lists. 14014 14015 for (Expr *RE : MVLI.VarList) { 14016 assert(RE && "Null expr in omp to/from/map clause"); 14017 SourceLocation ELoc = RE->getExprLoc(); 14018 14019 // Find the current unresolved mapper expression. 14020 if (UpdateUMIt && UMIt != UMEnd) { 14021 UMIt++; 14022 assert( 14023 UMIt != UMEnd && 14024 "Expect the size of UnresolvedMappers to match with that of VarList"); 14025 } 14026 UpdateUMIt = true; 14027 if (UMIt != UMEnd) 14028 UnresolvedMapper = *UMIt; 14029 14030 const Expr *VE = RE->IgnoreParenLValueCasts(); 14031 14032 if (VE->isValueDependent() || VE->isTypeDependent() || 14033 VE->isInstantiationDependent() || 14034 VE->containsUnexpandedParameterPack()) { 14035 // Try to find the associated user-defined mapper. 14036 ExprResult ER = buildUserDefinedMapperRef( 14037 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14038 VE->getType().getCanonicalType(), UnresolvedMapper); 14039 if (ER.isInvalid()) 14040 continue; 14041 MVLI.UDMapperList.push_back(ER.get()); 14042 // We can only analyze this information once the missing information is 14043 // resolved. 14044 MVLI.ProcessedVarList.push_back(RE); 14045 continue; 14046 } 14047 14048 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14049 14050 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14051 SemaRef.Diag(ELoc, 14052 diag::err_omp_expected_named_var_member_or_array_expression) 14053 << RE->getSourceRange(); 14054 continue; 14055 } 14056 14057 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14058 ValueDecl *CurDeclaration = nullptr; 14059 14060 // Obtain the array or member expression bases if required. Also, fill the 14061 // components array with all the components identified in the process. 14062 const Expr *BE = checkMapClauseExpressionBase( 14063 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14064 if (!BE) 14065 continue; 14066 14067 assert(!CurComponents.empty() && 14068 "Invalid mappable expression information."); 14069 14070 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14071 // Add store "this" pointer to class in DSAStackTy for future checking 14072 DSAS->addMappedClassesQualTypes(TE->getType()); 14073 // Try to find the associated user-defined mapper. 14074 ExprResult ER = buildUserDefinedMapperRef( 14075 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14076 VE->getType().getCanonicalType(), UnresolvedMapper); 14077 if (ER.isInvalid()) 14078 continue; 14079 MVLI.UDMapperList.push_back(ER.get()); 14080 // Skip restriction checking for variable or field declarations 14081 MVLI.ProcessedVarList.push_back(RE); 14082 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14083 MVLI.VarComponents.back().append(CurComponents.begin(), 14084 CurComponents.end()); 14085 MVLI.VarBaseDeclarations.push_back(nullptr); 14086 continue; 14087 } 14088 14089 // For the following checks, we rely on the base declaration which is 14090 // expected to be associated with the last component. The declaration is 14091 // expected to be a variable or a field (if 'this' is being mapped). 14092 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14093 assert(CurDeclaration && "Null decl on map clause."); 14094 assert( 14095 CurDeclaration->isCanonicalDecl() && 14096 "Expecting components to have associated only canonical declarations."); 14097 14098 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14099 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14100 14101 assert((VD || FD) && "Only variables or fields are expected here!"); 14102 (void)FD; 14103 14104 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14105 // threadprivate variables cannot appear in a map clause. 14106 // OpenMP 4.5 [2.10.5, target update Construct] 14107 // threadprivate variables cannot appear in a from clause. 14108 if (VD && DSAS->isThreadPrivate(VD)) { 14109 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14110 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14111 << getOpenMPClauseName(CKind); 14112 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14113 continue; 14114 } 14115 14116 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14117 // A list item cannot appear in both a map clause and a data-sharing 14118 // attribute clause on the same construct. 14119 14120 // Check conflicts with other map clause expressions. We check the conflicts 14121 // with the current construct separately from the enclosing data 14122 // environment, because the restrictions are different. We only have to 14123 // check conflicts across regions for the map clauses. 14124 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14125 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14126 break; 14127 if (CKind == OMPC_map && 14128 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14129 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14130 break; 14131 14132 // OpenMP 4.5 [2.10.5, target update Construct] 14133 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14134 // If the type of a list item is a reference to a type T then the type will 14135 // be considered to be T for all purposes of this clause. 14136 auto I = llvm::find_if( 14137 CurComponents, 14138 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14139 return MC.getAssociatedDeclaration(); 14140 }); 14141 assert(I != CurComponents.end() && "Null decl on map clause."); 14142 QualType Type = 14143 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14144 14145 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14146 // A list item in a to or from clause must have a mappable type. 14147 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14148 // A list item must have a mappable type. 14149 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14150 DSAS, Type)) 14151 continue; 14152 14153 if (CKind == OMPC_map) { 14154 // target enter data 14155 // OpenMP [2.10.2, Restrictions, p. 99] 14156 // A map-type must be specified in all map clauses and must be either 14157 // to or alloc. 14158 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14159 if (DKind == OMPD_target_enter_data && 14160 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14161 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14162 << (IsMapTypeImplicit ? 1 : 0) 14163 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14164 << getOpenMPDirectiveName(DKind); 14165 continue; 14166 } 14167 14168 // target exit_data 14169 // OpenMP [2.10.3, Restrictions, p. 102] 14170 // A map-type must be specified in all map clauses and must be either 14171 // from, release, or delete. 14172 if (DKind == OMPD_target_exit_data && 14173 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14174 MapType == OMPC_MAP_delete)) { 14175 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14176 << (IsMapTypeImplicit ? 1 : 0) 14177 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14178 << getOpenMPDirectiveName(DKind); 14179 continue; 14180 } 14181 14182 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14183 // A list item cannot appear in both a map clause and a data-sharing 14184 // attribute clause on the same construct 14185 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 14186 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14187 if (isOpenMPPrivate(DVar.CKind)) { 14188 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14189 << getOpenMPClauseName(DVar.CKind) 14190 << getOpenMPClauseName(OMPC_map) 14191 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14192 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14193 continue; 14194 } 14195 } 14196 } 14197 14198 // Try to find the associated user-defined mapper. 14199 ExprResult ER = buildUserDefinedMapperRef( 14200 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14201 Type.getCanonicalType(), UnresolvedMapper); 14202 if (ER.isInvalid()) 14203 continue; 14204 MVLI.UDMapperList.push_back(ER.get()); 14205 14206 // Save the current expression. 14207 MVLI.ProcessedVarList.push_back(RE); 14208 14209 // Store the components in the stack so that they can be used to check 14210 // against other clauses later on. 14211 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14212 /*WhereFoundClauseKind=*/OMPC_map); 14213 14214 // Save the components and declaration to create the clause. For purposes of 14215 // the clause creation, any component list that has has base 'this' uses 14216 // null as base declaration. 14217 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14218 MVLI.VarComponents.back().append(CurComponents.begin(), 14219 CurComponents.end()); 14220 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14221 : CurDeclaration); 14222 } 14223 } 14224 14225 OMPClause *Sema::ActOnOpenMPMapClause( 14226 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14227 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14228 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14229 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14230 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14231 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14232 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14233 OMPC_MAP_MODIFIER_unknown, 14234 OMPC_MAP_MODIFIER_unknown}; 14235 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14236 14237 // Process map-type-modifiers, flag errors for duplicate modifiers. 14238 unsigned Count = 0; 14239 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14240 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14241 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14242 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14243 continue; 14244 } 14245 assert(Count < OMPMapClause::NumberOfModifiers && 14246 "Modifiers exceed the allowed number of map type modifiers"); 14247 Modifiers[Count] = MapTypeModifiers[I]; 14248 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14249 ++Count; 14250 } 14251 14252 MappableVarListInfo MVLI(VarList); 14253 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14254 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14255 MapType, IsMapTypeImplicit); 14256 14257 // We need to produce a map clause even if we don't have variables so that 14258 // other diagnostics related with non-existing map clauses are accurate. 14259 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14260 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14261 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14262 MapperIdScopeSpec.getWithLocInContext(Context), 14263 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14264 } 14265 14266 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14267 TypeResult ParsedType) { 14268 assert(ParsedType.isUsable()); 14269 14270 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14271 if (ReductionType.isNull()) 14272 return QualType(); 14273 14274 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14275 // A type name in a declare reduction directive cannot be a function type, an 14276 // array type, a reference type, or a type qualified with const, volatile or 14277 // restrict. 14278 if (ReductionType.hasQualifiers()) { 14279 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14280 return QualType(); 14281 } 14282 14283 if (ReductionType->isFunctionType()) { 14284 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14285 return QualType(); 14286 } 14287 if (ReductionType->isReferenceType()) { 14288 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14289 return QualType(); 14290 } 14291 if (ReductionType->isArrayType()) { 14292 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14293 return QualType(); 14294 } 14295 return ReductionType; 14296 } 14297 14298 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14299 Scope *S, DeclContext *DC, DeclarationName Name, 14300 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14301 AccessSpecifier AS, Decl *PrevDeclInScope) { 14302 SmallVector<Decl *, 8> Decls; 14303 Decls.reserve(ReductionTypes.size()); 14304 14305 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14306 forRedeclarationInCurContext()); 14307 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14308 // A reduction-identifier may not be re-declared in the current scope for the 14309 // same type or for a type that is compatible according to the base language 14310 // rules. 14311 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14312 OMPDeclareReductionDecl *PrevDRD = nullptr; 14313 bool InCompoundScope = true; 14314 if (S != nullptr) { 14315 // Find previous declaration with the same name not referenced in other 14316 // declarations. 14317 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14318 InCompoundScope = 14319 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14320 LookupName(Lookup, S); 14321 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14322 /*AllowInlineNamespace=*/false); 14323 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14324 LookupResult::Filter Filter = Lookup.makeFilter(); 14325 while (Filter.hasNext()) { 14326 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14327 if (InCompoundScope) { 14328 auto I = UsedAsPrevious.find(PrevDecl); 14329 if (I == UsedAsPrevious.end()) 14330 UsedAsPrevious[PrevDecl] = false; 14331 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14332 UsedAsPrevious[D] = true; 14333 } 14334 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14335 PrevDecl->getLocation(); 14336 } 14337 Filter.done(); 14338 if (InCompoundScope) { 14339 for (const auto &PrevData : UsedAsPrevious) { 14340 if (!PrevData.second) { 14341 PrevDRD = PrevData.first; 14342 break; 14343 } 14344 } 14345 } 14346 } else if (PrevDeclInScope != nullptr) { 14347 auto *PrevDRDInScope = PrevDRD = 14348 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14349 do { 14350 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14351 PrevDRDInScope->getLocation(); 14352 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14353 } while (PrevDRDInScope != nullptr); 14354 } 14355 for (const auto &TyData : ReductionTypes) { 14356 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14357 bool Invalid = false; 14358 if (I != PreviousRedeclTypes.end()) { 14359 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14360 << TyData.first; 14361 Diag(I->second, diag::note_previous_definition); 14362 Invalid = true; 14363 } 14364 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 14365 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 14366 Name, TyData.first, PrevDRD); 14367 DC->addDecl(DRD); 14368 DRD->setAccess(AS); 14369 Decls.push_back(DRD); 14370 if (Invalid) 14371 DRD->setInvalidDecl(); 14372 else 14373 PrevDRD = DRD; 14374 } 14375 14376 return DeclGroupPtrTy::make( 14377 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 14378 } 14379 14380 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 14381 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14382 14383 // Enter new function scope. 14384 PushFunctionScope(); 14385 setFunctionHasBranchProtectedScope(); 14386 getCurFunction()->setHasOMPDeclareReductionCombiner(); 14387 14388 if (S != nullptr) 14389 PushDeclContext(S, DRD); 14390 else 14391 CurContext = DRD; 14392 14393 PushExpressionEvaluationContext( 14394 ExpressionEvaluationContext::PotentiallyEvaluated); 14395 14396 QualType ReductionType = DRD->getType(); 14397 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 14398 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 14399 // uses semantics of argument handles by value, but it should be passed by 14400 // reference. C lang does not support references, so pass all parameters as 14401 // pointers. 14402 // Create 'T omp_in;' variable. 14403 VarDecl *OmpInParm = 14404 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 14405 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 14406 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 14407 // uses semantics of argument handles by value, but it should be passed by 14408 // reference. C lang does not support references, so pass all parameters as 14409 // pointers. 14410 // Create 'T omp_out;' variable. 14411 VarDecl *OmpOutParm = 14412 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 14413 if (S != nullptr) { 14414 PushOnScopeChains(OmpInParm, S); 14415 PushOnScopeChains(OmpOutParm, S); 14416 } else { 14417 DRD->addDecl(OmpInParm); 14418 DRD->addDecl(OmpOutParm); 14419 } 14420 Expr *InE = 14421 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 14422 Expr *OutE = 14423 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 14424 DRD->setCombinerData(InE, OutE); 14425 } 14426 14427 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 14428 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14429 DiscardCleanupsInEvaluationContext(); 14430 PopExpressionEvaluationContext(); 14431 14432 PopDeclContext(); 14433 PopFunctionScopeInfo(); 14434 14435 if (Combiner != nullptr) 14436 DRD->setCombiner(Combiner); 14437 else 14438 DRD->setInvalidDecl(); 14439 } 14440 14441 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 14442 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14443 14444 // Enter new function scope. 14445 PushFunctionScope(); 14446 setFunctionHasBranchProtectedScope(); 14447 14448 if (S != nullptr) 14449 PushDeclContext(S, DRD); 14450 else 14451 CurContext = DRD; 14452 14453 PushExpressionEvaluationContext( 14454 ExpressionEvaluationContext::PotentiallyEvaluated); 14455 14456 QualType ReductionType = DRD->getType(); 14457 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 14458 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 14459 // uses semantics of argument handles by value, but it should be passed by 14460 // reference. C lang does not support references, so pass all parameters as 14461 // pointers. 14462 // Create 'T omp_priv;' variable. 14463 VarDecl *OmpPrivParm = 14464 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 14465 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 14466 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 14467 // uses semantics of argument handles by value, but it should be passed by 14468 // reference. C lang does not support references, so pass all parameters as 14469 // pointers. 14470 // Create 'T omp_orig;' variable. 14471 VarDecl *OmpOrigParm = 14472 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 14473 if (S != nullptr) { 14474 PushOnScopeChains(OmpPrivParm, S); 14475 PushOnScopeChains(OmpOrigParm, S); 14476 } else { 14477 DRD->addDecl(OmpPrivParm); 14478 DRD->addDecl(OmpOrigParm); 14479 } 14480 Expr *OrigE = 14481 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 14482 Expr *PrivE = 14483 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 14484 DRD->setInitializerData(OrigE, PrivE); 14485 return OmpPrivParm; 14486 } 14487 14488 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 14489 VarDecl *OmpPrivParm) { 14490 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14491 DiscardCleanupsInEvaluationContext(); 14492 PopExpressionEvaluationContext(); 14493 14494 PopDeclContext(); 14495 PopFunctionScopeInfo(); 14496 14497 if (Initializer != nullptr) { 14498 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 14499 } else if (OmpPrivParm->hasInit()) { 14500 DRD->setInitializer(OmpPrivParm->getInit(), 14501 OmpPrivParm->isDirectInit() 14502 ? OMPDeclareReductionDecl::DirectInit 14503 : OMPDeclareReductionDecl::CopyInit); 14504 } else { 14505 DRD->setInvalidDecl(); 14506 } 14507 } 14508 14509 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14510 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14511 for (Decl *D : DeclReductions.get()) { 14512 if (IsValid) { 14513 if (S) 14514 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14515 /*AddToContext=*/false); 14516 } else { 14517 D->setInvalidDecl(); 14518 } 14519 } 14520 return DeclReductions; 14521 } 14522 14523 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14524 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14525 QualType T = TInfo->getType(); 14526 if (D.isInvalidType()) 14527 return true; 14528 14529 if (getLangOpts().CPlusPlus) { 14530 // Check that there are no default arguments (C++ only). 14531 CheckExtraCXXDefaultArguments(D); 14532 } 14533 14534 return CreateParsedType(T, TInfo); 14535 } 14536 14537 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14538 TypeResult ParsedType) { 14539 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14540 14541 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14542 assert(!MapperType.isNull() && "Expect valid mapper type"); 14543 14544 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14545 // The type must be of struct, union or class type in C and C++ 14546 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14547 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14548 return QualType(); 14549 } 14550 return MapperType; 14551 } 14552 14553 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14554 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14555 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14556 Decl *PrevDeclInScope) { 14557 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14558 forRedeclarationInCurContext()); 14559 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14560 // A mapper-identifier may not be redeclared in the current scope for the 14561 // same type or for a type that is compatible according to the base language 14562 // rules. 14563 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14564 OMPDeclareMapperDecl *PrevDMD = nullptr; 14565 bool InCompoundScope = true; 14566 if (S != nullptr) { 14567 // Find previous declaration with the same name not referenced in other 14568 // declarations. 14569 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14570 InCompoundScope = 14571 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14572 LookupName(Lookup, S); 14573 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14574 /*AllowInlineNamespace=*/false); 14575 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14576 LookupResult::Filter Filter = Lookup.makeFilter(); 14577 while (Filter.hasNext()) { 14578 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14579 if (InCompoundScope) { 14580 auto I = UsedAsPrevious.find(PrevDecl); 14581 if (I == UsedAsPrevious.end()) 14582 UsedAsPrevious[PrevDecl] = false; 14583 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 14584 UsedAsPrevious[D] = true; 14585 } 14586 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14587 PrevDecl->getLocation(); 14588 } 14589 Filter.done(); 14590 if (InCompoundScope) { 14591 for (const auto &PrevData : UsedAsPrevious) { 14592 if (!PrevData.second) { 14593 PrevDMD = PrevData.first; 14594 break; 14595 } 14596 } 14597 } 14598 } else if (PrevDeclInScope) { 14599 auto *PrevDMDInScope = PrevDMD = 14600 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 14601 do { 14602 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 14603 PrevDMDInScope->getLocation(); 14604 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 14605 } while (PrevDMDInScope != nullptr); 14606 } 14607 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 14608 bool Invalid = false; 14609 if (I != PreviousRedeclTypes.end()) { 14610 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 14611 << MapperType << Name; 14612 Diag(I->second, diag::note_previous_definition); 14613 Invalid = true; 14614 } 14615 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 14616 MapperType, VN, PrevDMD); 14617 DC->addDecl(DMD); 14618 DMD->setAccess(AS); 14619 if (Invalid) 14620 DMD->setInvalidDecl(); 14621 14622 // Enter new function scope. 14623 PushFunctionScope(); 14624 setFunctionHasBranchProtectedScope(); 14625 14626 CurContext = DMD; 14627 14628 return DMD; 14629 } 14630 14631 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 14632 Scope *S, 14633 QualType MapperType, 14634 SourceLocation StartLoc, 14635 DeclarationName VN) { 14636 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 14637 if (S) 14638 PushOnScopeChains(VD, S); 14639 else 14640 DMD->addDecl(VD); 14641 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 14642 DMD->setMapperVarRef(MapperVarRefExpr); 14643 } 14644 14645 Sema::DeclGroupPtrTy 14646 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 14647 ArrayRef<OMPClause *> ClauseList) { 14648 PopDeclContext(); 14649 PopFunctionScopeInfo(); 14650 14651 if (D) { 14652 if (S) 14653 PushOnScopeChains(D, S, /*AddToContext=*/false); 14654 D->CreateClauses(Context, ClauseList); 14655 } 14656 14657 return DeclGroupPtrTy::make(DeclGroupRef(D)); 14658 } 14659 14660 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 14661 SourceLocation StartLoc, 14662 SourceLocation LParenLoc, 14663 SourceLocation EndLoc) { 14664 Expr *ValExpr = NumTeams; 14665 Stmt *HelperValStmt = nullptr; 14666 14667 // OpenMP [teams Constrcut, Restrictions] 14668 // The num_teams expression must evaluate to a positive integer value. 14669 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 14670 /*StrictlyPositive=*/true)) 14671 return nullptr; 14672 14673 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14674 OpenMPDirectiveKind CaptureRegion = 14675 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 14676 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14677 ValExpr = MakeFullExpr(ValExpr).get(); 14678 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14679 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14680 HelperValStmt = buildPreInits(Context, Captures); 14681 } 14682 14683 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14684 StartLoc, LParenLoc, EndLoc); 14685 } 14686 14687 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14688 SourceLocation StartLoc, 14689 SourceLocation LParenLoc, 14690 SourceLocation EndLoc) { 14691 Expr *ValExpr = ThreadLimit; 14692 Stmt *HelperValStmt = nullptr; 14693 14694 // OpenMP [teams Constrcut, Restrictions] 14695 // The thread_limit expression must evaluate to a positive integer value. 14696 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14697 /*StrictlyPositive=*/true)) 14698 return nullptr; 14699 14700 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14701 OpenMPDirectiveKind CaptureRegion = 14702 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14703 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14704 ValExpr = MakeFullExpr(ValExpr).get(); 14705 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14706 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14707 HelperValStmt = buildPreInits(Context, Captures); 14708 } 14709 14710 return new (Context) OMPThreadLimitClause( 14711 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14712 } 14713 14714 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14715 SourceLocation StartLoc, 14716 SourceLocation LParenLoc, 14717 SourceLocation EndLoc) { 14718 Expr *ValExpr = Priority; 14719 14720 // OpenMP [2.9.1, task Constrcut] 14721 // The priority-value is a non-negative numerical scalar expression. 14722 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14723 /*StrictlyPositive=*/false)) 14724 return nullptr; 14725 14726 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14727 } 14728 14729 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14730 SourceLocation StartLoc, 14731 SourceLocation LParenLoc, 14732 SourceLocation EndLoc) { 14733 Expr *ValExpr = Grainsize; 14734 14735 // OpenMP [2.9.2, taskloop Constrcut] 14736 // The parameter of the grainsize clause must be a positive integer 14737 // expression. 14738 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14739 /*StrictlyPositive=*/true)) 14740 return nullptr; 14741 14742 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14743 } 14744 14745 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14746 SourceLocation StartLoc, 14747 SourceLocation LParenLoc, 14748 SourceLocation EndLoc) { 14749 Expr *ValExpr = NumTasks; 14750 14751 // OpenMP [2.9.2, taskloop Constrcut] 14752 // The parameter of the num_tasks clause must be a positive integer 14753 // expression. 14754 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14755 /*StrictlyPositive=*/true)) 14756 return nullptr; 14757 14758 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14759 } 14760 14761 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14762 SourceLocation LParenLoc, 14763 SourceLocation EndLoc) { 14764 // OpenMP [2.13.2, critical construct, Description] 14765 // ... where hint-expression is an integer constant expression that evaluates 14766 // to a valid lock hint. 14767 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14768 if (HintExpr.isInvalid()) 14769 return nullptr; 14770 return new (Context) 14771 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14772 } 14773 14774 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14775 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14776 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14777 SourceLocation EndLoc) { 14778 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14779 std::string Values; 14780 Values += "'"; 14781 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14782 Values += "'"; 14783 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14784 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14785 return nullptr; 14786 } 14787 Expr *ValExpr = ChunkSize; 14788 Stmt *HelperValStmt = nullptr; 14789 if (ChunkSize) { 14790 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14791 !ChunkSize->isInstantiationDependent() && 14792 !ChunkSize->containsUnexpandedParameterPack()) { 14793 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14794 ExprResult Val = 14795 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14796 if (Val.isInvalid()) 14797 return nullptr; 14798 14799 ValExpr = Val.get(); 14800 14801 // OpenMP [2.7.1, Restrictions] 14802 // chunk_size must be a loop invariant integer expression with a positive 14803 // value. 14804 llvm::APSInt Result; 14805 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14806 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14807 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14808 << "dist_schedule" << ChunkSize->getSourceRange(); 14809 return nullptr; 14810 } 14811 } else if (getOpenMPCaptureRegionForClause( 14812 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14813 OMPD_unknown && 14814 !CurContext->isDependentContext()) { 14815 ValExpr = MakeFullExpr(ValExpr).get(); 14816 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14817 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14818 HelperValStmt = buildPreInits(Context, Captures); 14819 } 14820 } 14821 } 14822 14823 return new (Context) 14824 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14825 Kind, ValExpr, HelperValStmt); 14826 } 14827 14828 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14829 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14830 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14831 SourceLocation KindLoc, SourceLocation EndLoc) { 14832 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14833 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14834 std::string Value; 14835 SourceLocation Loc; 14836 Value += "'"; 14837 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14838 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14839 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14840 Loc = MLoc; 14841 } else { 14842 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14843 OMPC_DEFAULTMAP_scalar); 14844 Loc = KindLoc; 14845 } 14846 Value += "'"; 14847 Diag(Loc, diag::err_omp_unexpected_clause_value) 14848 << Value << getOpenMPClauseName(OMPC_defaultmap); 14849 return nullptr; 14850 } 14851 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14852 14853 return new (Context) 14854 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14855 } 14856 14857 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14858 DeclContext *CurLexicalContext = getCurLexicalContext(); 14859 if (!CurLexicalContext->isFileContext() && 14860 !CurLexicalContext->isExternCContext() && 14861 !CurLexicalContext->isExternCXXContext() && 14862 !isa<CXXRecordDecl>(CurLexicalContext) && 14863 !isa<ClassTemplateDecl>(CurLexicalContext) && 14864 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14865 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14866 Diag(Loc, diag::err_omp_region_not_file_context); 14867 return false; 14868 } 14869 ++DeclareTargetNestingLevel; 14870 return true; 14871 } 14872 14873 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14874 assert(DeclareTargetNestingLevel > 0 && 14875 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14876 --DeclareTargetNestingLevel; 14877 } 14878 14879 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14880 CXXScopeSpec &ScopeSpec, 14881 const DeclarationNameInfo &Id, 14882 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14883 NamedDeclSetType &SameDirectiveDecls) { 14884 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14885 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14886 14887 if (Lookup.isAmbiguous()) 14888 return; 14889 Lookup.suppressDiagnostics(); 14890 14891 if (!Lookup.isSingleResult()) { 14892 VarOrFuncDeclFilterCCC CCC(*this); 14893 if (TypoCorrection Corrected = 14894 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 14895 CTK_ErrorRecovery)) { 14896 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14897 << Id.getName()); 14898 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14899 return; 14900 } 14901 14902 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14903 return; 14904 } 14905 14906 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14907 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14908 isa<FunctionTemplateDecl>(ND)) { 14909 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14910 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14911 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14912 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14913 cast<ValueDecl>(ND)); 14914 if (!Res) { 14915 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14916 ND->addAttr(A); 14917 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14918 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14919 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14920 } else if (*Res != MT) { 14921 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14922 << Id.getName(); 14923 } 14924 } else { 14925 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14926 } 14927 } 14928 14929 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14930 Sema &SemaRef, Decl *D) { 14931 if (!D || !isa<VarDecl>(D)) 14932 return; 14933 auto *VD = cast<VarDecl>(D); 14934 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14935 return; 14936 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14937 SemaRef.Diag(SL, diag::note_used_here) << SR; 14938 } 14939 14940 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14941 Sema &SemaRef, DSAStackTy *Stack, 14942 ValueDecl *VD) { 14943 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14944 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14945 /*FullCheck=*/false); 14946 } 14947 14948 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14949 SourceLocation IdLoc) { 14950 if (!D || D->isInvalidDecl()) 14951 return; 14952 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14953 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 14954 if (auto *VD = dyn_cast<VarDecl>(D)) { 14955 // Only global variables can be marked as declare target. 14956 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 14957 !VD->isStaticDataMember()) 14958 return; 14959 // 2.10.6: threadprivate variable cannot appear in a declare target 14960 // directive. 14961 if (DSAStack->isThreadPrivate(VD)) { 14962 Diag(SL, diag::err_omp_threadprivate_in_target); 14963 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 14964 return; 14965 } 14966 } 14967 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 14968 D = FTD->getTemplatedDecl(); 14969 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 14970 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14971 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 14972 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 14973 assert(IdLoc.isValid() && "Source location is expected"); 14974 Diag(IdLoc, diag::err_omp_function_in_link_clause); 14975 Diag(FD->getLocation(), diag::note_defined_here) << FD; 14976 return; 14977 } 14978 } 14979 if (auto *VD = dyn_cast<ValueDecl>(D)) { 14980 // Problem if any with var declared with incomplete type will be reported 14981 // as normal, so no need to check it here. 14982 if ((E || !VD->getType()->isIncompleteType()) && 14983 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 14984 return; 14985 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 14986 // Checking declaration inside declare target region. 14987 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 14988 isa<FunctionTemplateDecl>(D)) { 14989 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 14990 Context, OMPDeclareTargetDeclAttr::MT_To); 14991 D->addAttr(A); 14992 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14993 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 14994 } 14995 return; 14996 } 14997 } 14998 if (!E) 14999 return; 15000 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15001 } 15002 15003 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15004 CXXScopeSpec &MapperIdScopeSpec, 15005 DeclarationNameInfo &MapperId, 15006 const OMPVarListLocTy &Locs, 15007 ArrayRef<Expr *> UnresolvedMappers) { 15008 MappableVarListInfo MVLI(VarList); 15009 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15010 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15011 if (MVLI.ProcessedVarList.empty()) 15012 return nullptr; 15013 15014 return OMPToClause::Create( 15015 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15016 MVLI.VarComponents, MVLI.UDMapperList, 15017 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15018 } 15019 15020 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15021 CXXScopeSpec &MapperIdScopeSpec, 15022 DeclarationNameInfo &MapperId, 15023 const OMPVarListLocTy &Locs, 15024 ArrayRef<Expr *> UnresolvedMappers) { 15025 MappableVarListInfo MVLI(VarList); 15026 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15027 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15028 if (MVLI.ProcessedVarList.empty()) 15029 return nullptr; 15030 15031 return OMPFromClause::Create( 15032 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15033 MVLI.VarComponents, MVLI.UDMapperList, 15034 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15035 } 15036 15037 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15038 const OMPVarListLocTy &Locs) { 15039 MappableVarListInfo MVLI(VarList); 15040 SmallVector<Expr *, 8> PrivateCopies; 15041 SmallVector<Expr *, 8> Inits; 15042 15043 for (Expr *RefExpr : VarList) { 15044 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15045 SourceLocation ELoc; 15046 SourceRange ERange; 15047 Expr *SimpleRefExpr = RefExpr; 15048 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15049 if (Res.second) { 15050 // It will be analyzed later. 15051 MVLI.ProcessedVarList.push_back(RefExpr); 15052 PrivateCopies.push_back(nullptr); 15053 Inits.push_back(nullptr); 15054 } 15055 ValueDecl *D = Res.first; 15056 if (!D) 15057 continue; 15058 15059 QualType Type = D->getType(); 15060 Type = Type.getNonReferenceType().getUnqualifiedType(); 15061 15062 auto *VD = dyn_cast<VarDecl>(D); 15063 15064 // Item should be a pointer or reference to pointer. 15065 if (!Type->isPointerType()) { 15066 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15067 << 0 << RefExpr->getSourceRange(); 15068 continue; 15069 } 15070 15071 // Build the private variable and the expression that refers to it. 15072 auto VDPrivate = 15073 buildVarDecl(*this, ELoc, Type, D->getName(), 15074 D->hasAttrs() ? &D->getAttrs() : nullptr, 15075 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15076 if (VDPrivate->isInvalidDecl()) 15077 continue; 15078 15079 CurContext->addDecl(VDPrivate); 15080 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15081 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15082 15083 // Add temporary variable to initialize the private copy of the pointer. 15084 VarDecl *VDInit = 15085 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15086 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15087 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15088 AddInitializerToDecl(VDPrivate, 15089 DefaultLvalueConversion(VDInitRefExpr).get(), 15090 /*DirectInit=*/false); 15091 15092 // If required, build a capture to implement the privatization initialized 15093 // with the current list item value. 15094 DeclRefExpr *Ref = nullptr; 15095 if (!VD) 15096 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15097 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15098 PrivateCopies.push_back(VDPrivateRefExpr); 15099 Inits.push_back(VDInitRefExpr); 15100 15101 // We need to add a data sharing attribute for this variable to make sure it 15102 // is correctly captured. A variable that shows up in a use_device_ptr has 15103 // similar properties of a first private variable. 15104 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15105 15106 // Create a mappable component for the list item. List items in this clause 15107 // only need a component. 15108 MVLI.VarBaseDeclarations.push_back(D); 15109 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15110 MVLI.VarComponents.back().push_back( 15111 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15112 } 15113 15114 if (MVLI.ProcessedVarList.empty()) 15115 return nullptr; 15116 15117 return OMPUseDevicePtrClause::Create( 15118 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15119 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15120 } 15121 15122 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15123 const OMPVarListLocTy &Locs) { 15124 MappableVarListInfo MVLI(VarList); 15125 for (Expr *RefExpr : VarList) { 15126 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15127 SourceLocation ELoc; 15128 SourceRange ERange; 15129 Expr *SimpleRefExpr = RefExpr; 15130 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15131 if (Res.second) { 15132 // It will be analyzed later. 15133 MVLI.ProcessedVarList.push_back(RefExpr); 15134 } 15135 ValueDecl *D = Res.first; 15136 if (!D) 15137 continue; 15138 15139 QualType Type = D->getType(); 15140 // item should be a pointer or array or reference to pointer or array 15141 if (!Type.getNonReferenceType()->isPointerType() && 15142 !Type.getNonReferenceType()->isArrayType()) { 15143 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15144 << 0 << RefExpr->getSourceRange(); 15145 continue; 15146 } 15147 15148 // Check if the declaration in the clause does not show up in any data 15149 // sharing attribute. 15150 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15151 if (isOpenMPPrivate(DVar.CKind)) { 15152 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15153 << getOpenMPClauseName(DVar.CKind) 15154 << getOpenMPClauseName(OMPC_is_device_ptr) 15155 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15156 reportOriginalDsa(*this, DSAStack, D, DVar); 15157 continue; 15158 } 15159 15160 const Expr *ConflictExpr; 15161 if (DSAStack->checkMappableExprComponentListsForDecl( 15162 D, /*CurrentRegionOnly=*/true, 15163 [&ConflictExpr]( 15164 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15165 OpenMPClauseKind) -> bool { 15166 ConflictExpr = R.front().getAssociatedExpression(); 15167 return true; 15168 })) { 15169 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15170 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15171 << ConflictExpr->getSourceRange(); 15172 continue; 15173 } 15174 15175 // Store the components in the stack so that they can be used to check 15176 // against other clauses later on. 15177 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15178 DSAStack->addMappableExpressionComponents( 15179 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15180 15181 // Record the expression we've just processed. 15182 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15183 15184 // Create a mappable component for the list item. List items in this clause 15185 // only need a component. We use a null declaration to signal fields in 15186 // 'this'. 15187 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15188 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15189 "Unexpected device pointer expression!"); 15190 MVLI.VarBaseDeclarations.push_back( 15191 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15192 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15193 MVLI.VarComponents.back().push_back(MC); 15194 } 15195 15196 if (MVLI.ProcessedVarList.empty()) 15197 return nullptr; 15198 15199 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15200 MVLI.VarBaseDeclarations, 15201 MVLI.VarComponents); 15202 } 15203 15204 OMPClause *Sema::ActOnOpenMPAllocateClause( 15205 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15206 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15207 if (Allocator) { 15208 // OpenMP [2.11.4 allocate Clause, Description] 15209 // allocator is an expression of omp_allocator_handle_t type. 15210 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15211 return nullptr; 15212 15213 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15214 if (AllocatorRes.isInvalid()) 15215 return nullptr; 15216 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15217 DSAStack->getOMPAllocatorHandleT(), 15218 Sema::AA_Initializing, 15219 /*AllowExplicit=*/true); 15220 if (AllocatorRes.isInvalid()) 15221 return nullptr; 15222 Allocator = AllocatorRes.get(); 15223 } else { 15224 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15225 // allocate clauses that appear on a target construct or on constructs in a 15226 // target region must specify an allocator expression unless a requires 15227 // directive with the dynamic_allocators clause is present in the same 15228 // compilation unit. 15229 if (LangOpts.OpenMPIsDevice && 15230 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15231 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15232 } 15233 // Analyze and build list of variables. 15234 SmallVector<Expr *, 8> Vars; 15235 for (Expr *RefExpr : VarList) { 15236 assert(RefExpr && "NULL expr in OpenMP private clause."); 15237 SourceLocation ELoc; 15238 SourceRange ERange; 15239 Expr *SimpleRefExpr = RefExpr; 15240 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15241 if (Res.second) { 15242 // It will be analyzed later. 15243 Vars.push_back(RefExpr); 15244 } 15245 ValueDecl *D = Res.first; 15246 if (!D) 15247 continue; 15248 15249 auto *VD = dyn_cast<VarDecl>(D); 15250 DeclRefExpr *Ref = nullptr; 15251 if (!VD && !CurContext->isDependentContext()) 15252 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15253 Vars.push_back((VD || CurContext->isDependentContext()) 15254 ? RefExpr->IgnoreParens() 15255 : Ref); 15256 } 15257 15258 if (Vars.empty()) 15259 return nullptr; 15260 15261 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15262 ColonLoc, EndLoc, Vars); 15263 } 15264