1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 bool HasMutipleLoops = false; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 bool BodyComplete = false; 148 SourceLocation InnerTeamsRegionLoc; 149 /// Reference to the taskgroup task_reduction reference expression. 150 Expr *TaskgroupReductionRef = nullptr; 151 llvm::DenseSet<QualType> MappedClassesQualTypes; 152 /// List of globals marked as declare target link in this target region 153 /// (isOpenMPTargetExecutionDirective(Directive) == true). 154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 156 Scope *CurScope, SourceLocation Loc) 157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 158 ConstructLoc(Loc) {} 159 SharingMapTy() = default; 160 }; 161 162 using StackTy = SmallVector<SharingMapTy, 4>; 163 164 /// Stack of used declaration and their data-sharing attributes. 165 DeclSAMapTy Threadprivates; 166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 168 /// true, if check for DSA must be from parent directive, false, if 169 /// from current directive. 170 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 171 Sema &SemaRef; 172 bool ForceCapturing = false; 173 /// true if all the vaiables in the target executable directives must be 174 /// captured by reference. 175 bool ForceCaptureByReferenceInTargetExecutable = false; 176 CriticalsWithHintsTy Criticals; 177 unsigned IgnoredStackElements = 0; 178 179 /// Iterators over the stack iterate in order from innermost to outermost 180 /// directive. 181 using const_iterator = StackTy::const_reverse_iterator; 182 const_iterator begin() const { 183 return Stack.empty() ? const_iterator() 184 : Stack.back().first.rbegin() + IgnoredStackElements; 185 } 186 const_iterator end() const { 187 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 188 } 189 using iterator = StackTy::reverse_iterator; 190 iterator begin() { 191 return Stack.empty() ? iterator() 192 : Stack.back().first.rbegin() + IgnoredStackElements; 193 } 194 iterator end() { 195 return Stack.empty() ? iterator() : Stack.back().first.rend(); 196 } 197 198 // Convenience operations to get at the elements of the stack. 199 200 bool isStackEmpty() const { 201 return Stack.empty() || 202 Stack.back().second != CurrentNonCapturingFunctionScope || 203 Stack.back().first.size() <= IgnoredStackElements; 204 } 205 size_t getStackSize() const { 206 return isStackEmpty() ? 0 207 : Stack.back().first.size() - IgnoredStackElements; 208 } 209 210 SharingMapTy *getTopOfStackOrNull() { 211 size_t Size = getStackSize(); 212 if (Size == 0) 213 return nullptr; 214 return &Stack.back().first[Size - 1]; 215 } 216 const SharingMapTy *getTopOfStackOrNull() const { 217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 218 } 219 SharingMapTy &getTopOfStack() { 220 assert(!isStackEmpty() && "no current directive"); 221 return *getTopOfStackOrNull(); 222 } 223 const SharingMapTy &getTopOfStack() const { 224 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 225 } 226 227 SharingMapTy *getSecondOnStackOrNull() { 228 size_t Size = getStackSize(); 229 if (Size <= 1) 230 return nullptr; 231 return &Stack.back().first[Size - 2]; 232 } 233 const SharingMapTy *getSecondOnStackOrNull() const { 234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 235 } 236 237 /// Get the stack element at a certain level (previously returned by 238 /// \c getNestingLevel). 239 /// 240 /// Note that nesting levels count from outermost to innermost, and this is 241 /// the reverse of our iteration order where new inner levels are pushed at 242 /// the front of the stack. 243 SharingMapTy &getStackElemAtLevel(unsigned Level) { 244 assert(Level < getStackSize() && "no such stack element"); 245 return Stack.back().first[Level]; 246 } 247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 249 } 250 251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 252 253 /// Checks if the variable is a local for OpenMP region. 254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 255 256 /// Vector of previously declared requires directives 257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 258 /// omp_allocator_handle_t type. 259 QualType OMPAllocatorHandleT; 260 /// Expression for the predefined allocators. 261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 262 nullptr}; 263 /// Vector of previously encountered target directives 264 SmallVector<SourceLocation, 2> TargetLocations; 265 266 public: 267 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 268 269 /// Sets omp_allocator_handle_t type. 270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 271 /// Gets omp_allocator_handle_t type. 272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 273 /// Sets the given default allocator. 274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 275 Expr *Allocator) { 276 OMPPredefinedAllocators[AllocatorKind] = Allocator; 277 } 278 /// Returns the specified default allocator. 279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 280 return OMPPredefinedAllocators[AllocatorKind]; 281 } 282 283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 284 OpenMPClauseKind getClauseParsingMode() const { 285 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 286 return ClauseKindMode; 287 } 288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 289 290 bool isBodyComplete() const { 291 const SharingMapTy *Top = getTopOfStackOrNull(); 292 return Top && Top->BodyComplete; 293 } 294 void setBodyComplete() { 295 getTopOfStack().BodyComplete = true; 296 } 297 298 bool isForceVarCapturing() const { return ForceCapturing; } 299 void setForceVarCapturing(bool V) { ForceCapturing = V; } 300 301 void setForceCaptureByReferenceInTargetExecutable(bool V) { 302 ForceCaptureByReferenceInTargetExecutable = V; 303 } 304 bool isForceCaptureByReferenceInTargetExecutable() const { 305 return ForceCaptureByReferenceInTargetExecutable; 306 } 307 308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 309 Scope *CurScope, SourceLocation Loc) { 310 assert(!IgnoredStackElements && 311 "cannot change stack while ignoring elements"); 312 if (Stack.empty() || 313 Stack.back().second != CurrentNonCapturingFunctionScope) 314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 316 Stack.back().first.back().DefaultAttrLoc = Loc; 317 } 318 319 void pop() { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 assert(!Stack.back().first.empty() && 323 "Data-sharing attributes stack is empty!"); 324 Stack.back().first.pop_back(); 325 } 326 327 /// RAII object to temporarily leave the scope of a directive when we want to 328 /// logically operate in its parent. 329 class ParentDirectiveScope { 330 DSAStackTy &Self; 331 bool Active; 332 public: 333 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 334 : Self(Self), Active(false) { 335 if (Activate) 336 enable(); 337 } 338 ~ParentDirectiveScope() { disable(); } 339 void disable() { 340 if (Active) { 341 --Self.IgnoredStackElements; 342 Active = false; 343 } 344 } 345 void enable() { 346 if (!Active) { 347 ++Self.IgnoredStackElements; 348 Active = true; 349 } 350 } 351 }; 352 353 /// Marks that we're started loop parsing. 354 void loopInit() { 355 assert(isOpenMPLoopDirective(getCurrentDirective()) && 356 "Expected loop-based directive."); 357 getTopOfStack().LoopStart = true; 358 } 359 /// Start capturing of the variables in the loop context. 360 void loopStart() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = false; 364 } 365 /// true, if variables are captured, false otherwise. 366 bool isLoopStarted() const { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 return !getTopOfStack().LoopStart; 370 } 371 /// Marks (or clears) declaration as possibly loop counter. 372 void resetPossibleLoopCounter(const Decl *D = nullptr) { 373 getTopOfStack().PossiblyLoopCounter = 374 D ? D->getCanonicalDecl() : D; 375 } 376 /// Gets the possible loop counter decl. 377 const Decl *getPossiblyLoopCunter() const { 378 return getTopOfStack().PossiblyLoopCounter; 379 } 380 /// Start new OpenMP region stack in new non-capturing function. 381 void pushFunction() { 382 assert(!IgnoredStackElements && 383 "cannot change stack while ignoring elements"); 384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 385 assert(!isa<CapturingScopeInfo>(CurFnScope)); 386 CurrentNonCapturingFunctionScope = CurFnScope; 387 } 388 /// Pop region stack for non-capturing function. 389 void popFunction(const FunctionScopeInfo *OldFSI) { 390 assert(!IgnoredStackElements && 391 "cannot change stack while ignoring elements"); 392 if (!Stack.empty() && Stack.back().second == OldFSI) { 393 assert(Stack.back().first.empty()); 394 Stack.pop_back(); 395 } 396 CurrentNonCapturingFunctionScope = nullptr; 397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 398 if (!isa<CapturingScopeInfo>(FSI)) { 399 CurrentNonCapturingFunctionScope = FSI; 400 break; 401 } 402 } 403 } 404 405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 407 } 408 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 409 getCriticalWithHint(const DeclarationNameInfo &Name) const { 410 auto I = Criticals.find(Name.getAsString()); 411 if (I != Criticals.end()) 412 return I->second; 413 return std::make_pair(nullptr, llvm::APSInt()); 414 } 415 /// If 'aligned' declaration for given variable \a D was not seen yet, 416 /// add it and return NULL; otherwise return previous occurrence's expression 417 /// for diagnostics. 418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 419 420 /// Register specified variable as loop control variable. 421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 422 /// Check if the specified variable is a loop control variable for 423 /// current region. 424 /// \return The index of the loop control variable in the list of associated 425 /// for-loops (from outer to inner). 426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 427 /// Check if the specified variable is a loop control variable for 428 /// parent region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 432 /// Get the loop control variable for the I-th loop (or nullptr) in 433 /// parent directive. 434 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 435 436 /// Adds explicit data sharing attribute to the specified declaration. 437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 438 DeclRefExpr *PrivateCopy = nullptr); 439 440 /// Adds additional information for the reduction items with the reduction id 441 /// represented as an operator. 442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 443 BinaryOperatorKind BOK); 444 /// Adds additional information for the reduction items with the reduction id 445 /// represented as reduction identifier. 446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 447 const Expr *ReductionRef); 448 /// Returns the location and reduction operation from the innermost parent 449 /// region for the given \p D. 450 const DSAVarData 451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 452 BinaryOperatorKind &BOK, 453 Expr *&TaskgroupDescriptor) const; 454 /// Returns the location and reduction operation from the innermost parent 455 /// region for the given \p D. 456 const DSAVarData 457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 458 const Expr *&ReductionRef, 459 Expr *&TaskgroupDescriptor) const; 460 /// Return reduction reference expression for the current taskgroup. 461 Expr *getTaskgroupReductionRef() const { 462 assert(getTopOfStack().Directive == OMPD_taskgroup && 463 "taskgroup reference expression requested for non taskgroup " 464 "directive."); 465 return getTopOfStack().TaskgroupReductionRef; 466 } 467 /// Checks if the given \p VD declaration is actually a taskgroup reduction 468 /// descriptor variable at the \p Level of OpenMP regions. 469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 470 return getStackElemAtLevel(Level).TaskgroupReductionRef && 471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 472 ->getDecl() == VD; 473 } 474 475 /// Returns data sharing attributes from top of the stack for the 476 /// specified declaration. 477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 478 /// Returns data-sharing attributes for the specified declaration. 479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 480 /// Checks if the specified variables has data-sharing attributes which 481 /// match specified \a CPred predicate in any directive which matches \a DPred 482 /// predicate. 483 const DSAVarData 484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 486 bool FromParent) const; 487 /// Checks if the specified variables has data-sharing attributes which 488 /// match specified \a CPred predicate in any innermost directive which 489 /// matches \a DPred predicate. 490 const DSAVarData 491 hasInnermostDSA(ValueDecl *D, 492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 494 bool FromParent) const; 495 /// Checks if the specified variables has explicit data-sharing 496 /// attributes which match specified \a CPred predicate at the specified 497 /// OpenMP region. 498 bool hasExplicitDSA(const ValueDecl *D, 499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 500 unsigned Level, bool NotLastprivate = false) const; 501 502 /// Returns true if the directive at level \Level matches in the 503 /// specified \a DPred predicate. 504 bool hasExplicitDirective( 505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 506 unsigned Level) const; 507 508 /// Finds a directive which matches specified \a DPred predicate. 509 bool hasDirective( 510 const llvm::function_ref<bool( 511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 512 DPred, 513 bool FromParent) const; 514 515 /// Returns currently analyzed directive. 516 OpenMPDirectiveKind getCurrentDirective() const { 517 const SharingMapTy *Top = getTopOfStackOrNull(); 518 return Top ? Top->Directive : OMPD_unknown; 519 } 520 /// Returns directive kind at specified level. 521 OpenMPDirectiveKind getDirective(unsigned Level) const { 522 assert(!isStackEmpty() && "No directive at specified level."); 523 return getStackElemAtLevel(Level).Directive; 524 } 525 /// Returns parent directive. 526 OpenMPDirectiveKind getParentDirective() const { 527 const SharingMapTy *Parent = getSecondOnStackOrNull(); 528 return Parent ? Parent->Directive : OMPD_unknown; 529 } 530 531 /// Add requires decl to internal vector 532 void addRequiresDecl(OMPRequiresDecl *RD) { 533 RequiresDecls.push_back(RD); 534 } 535 536 /// Checks if the defined 'requires' directive has specified type of clause. 537 template <typename ClauseType> 538 bool hasRequiresDeclWithClause() { 539 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 540 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 541 return isa<ClauseType>(C); 542 }); 543 }); 544 } 545 546 /// Checks for a duplicate clause amongst previously declared requires 547 /// directives 548 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 549 bool IsDuplicate = false; 550 for (OMPClause *CNew : ClauseList) { 551 for (const OMPRequiresDecl *D : RequiresDecls) { 552 for (const OMPClause *CPrev : D->clauselists()) { 553 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 554 SemaRef.Diag(CNew->getBeginLoc(), 555 diag::err_omp_requires_clause_redeclaration) 556 << getOpenMPClauseName(CNew->getClauseKind()); 557 SemaRef.Diag(CPrev->getBeginLoc(), 558 diag::note_omp_requires_previous_clause) 559 << getOpenMPClauseName(CPrev->getClauseKind()); 560 IsDuplicate = true; 561 } 562 } 563 } 564 } 565 return IsDuplicate; 566 } 567 568 /// Add location of previously encountered target to internal vector 569 void addTargetDirLocation(SourceLocation LocStart) { 570 TargetLocations.push_back(LocStart); 571 } 572 573 // Return previously encountered target region locations. 574 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 575 return TargetLocations; 576 } 577 578 /// Set default data sharing attribute to none. 579 void setDefaultDSANone(SourceLocation Loc) { 580 getTopOfStack().DefaultAttr = DSA_none; 581 getTopOfStack().DefaultAttrLoc = Loc; 582 } 583 /// Set default data sharing attribute to shared. 584 void setDefaultDSAShared(SourceLocation Loc) { 585 getTopOfStack().DefaultAttr = DSA_shared; 586 getTopOfStack().DefaultAttrLoc = Loc; 587 } 588 /// Set default data mapping attribute to 'tofrom:scalar'. 589 void setDefaultDMAToFromScalar(SourceLocation Loc) { 590 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 591 getTopOfStack().DefaultMapAttrLoc = Loc; 592 } 593 594 DefaultDataSharingAttributes getDefaultDSA() const { 595 return isStackEmpty() ? DSA_unspecified 596 : getTopOfStack().DefaultAttr; 597 } 598 SourceLocation getDefaultDSALocation() const { 599 return isStackEmpty() ? SourceLocation() 600 : getTopOfStack().DefaultAttrLoc; 601 } 602 DefaultMapAttributes getDefaultDMA() const { 603 return isStackEmpty() ? DMA_unspecified 604 : getTopOfStack().DefaultMapAttr; 605 } 606 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 607 return getStackElemAtLevel(Level).DefaultMapAttr; 608 } 609 SourceLocation getDefaultDMALocation() const { 610 return isStackEmpty() ? SourceLocation() 611 : getTopOfStack().DefaultMapAttrLoc; 612 } 613 614 /// Checks if the specified variable is a threadprivate. 615 bool isThreadPrivate(VarDecl *D) { 616 const DSAVarData DVar = getTopDSA(D, false); 617 return isOpenMPThreadPrivate(DVar.CKind); 618 } 619 620 /// Marks current region as ordered (it has an 'ordered' clause). 621 void setOrderedRegion(bool IsOrdered, const Expr *Param, 622 OMPOrderedClause *Clause) { 623 if (IsOrdered) 624 getTopOfStack().OrderedRegion.emplace(Param, Clause); 625 else 626 getTopOfStack().OrderedRegion.reset(); 627 } 628 /// Returns true, if region is ordered (has associated 'ordered' clause), 629 /// false - otherwise. 630 bool isOrderedRegion() const { 631 if (const SharingMapTy *Top = getTopOfStackOrNull()) 632 return Top->OrderedRegion.hasValue(); 633 return false; 634 } 635 /// Returns optional parameter for the ordered region. 636 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 637 if (const SharingMapTy *Top = getTopOfStackOrNull()) 638 if (Top->OrderedRegion.hasValue()) 639 return Top->OrderedRegion.getValue(); 640 return std::make_pair(nullptr, nullptr); 641 } 642 /// Returns true, if parent region is ordered (has associated 643 /// 'ordered' clause), false - otherwise. 644 bool isParentOrderedRegion() const { 645 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 646 return Parent->OrderedRegion.hasValue(); 647 return false; 648 } 649 /// Returns optional parameter for the ordered region. 650 std::pair<const Expr *, OMPOrderedClause *> 651 getParentOrderedRegionParam() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 if (Parent->OrderedRegion.hasValue()) 654 return Parent->OrderedRegion.getValue(); 655 return std::make_pair(nullptr, nullptr); 656 } 657 /// Marks current region as nowait (it has a 'nowait' clause). 658 void setNowaitRegion(bool IsNowait = true) { 659 getTopOfStack().NowaitRegion = IsNowait; 660 } 661 /// Returns true, if parent region is nowait (has associated 662 /// 'nowait' clause), false - otherwise. 663 bool isParentNowaitRegion() const { 664 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 665 return Parent->NowaitRegion; 666 return false; 667 } 668 /// Marks parent region as cancel region. 669 void setParentCancelRegion(bool Cancel = true) { 670 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 671 Parent->CancelRegion |= Cancel; 672 } 673 /// Return true if current region has inner cancel construct. 674 bool isCancelRegion() const { 675 const SharingMapTy *Top = getTopOfStackOrNull(); 676 return Top ? Top->CancelRegion : false; 677 } 678 679 /// Set collapse value for the region. 680 void setAssociatedLoops(unsigned Val) { 681 getTopOfStack().AssociatedLoops = Val; 682 if (Val > 1) 683 getTopOfStack().HasMutipleLoops = true; 684 } 685 /// Return collapse value for region. 686 unsigned getAssociatedLoops() const { 687 const SharingMapTy *Top = getTopOfStackOrNull(); 688 return Top ? Top->AssociatedLoops : 0; 689 } 690 /// Returns true if the construct is associated with multiple loops. 691 bool hasMutipleLoops() const { 692 const SharingMapTy *Top = getTopOfStackOrNull(); 693 return Top ? Top->HasMutipleLoops : false; 694 } 695 696 /// Marks current target region as one with closely nested teams 697 /// region. 698 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 699 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 700 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 701 } 702 /// Returns true, if current region has closely nested teams region. 703 bool hasInnerTeamsRegion() const { 704 return getInnerTeamsRegionLoc().isValid(); 705 } 706 /// Returns location of the nested teams region (if any). 707 SourceLocation getInnerTeamsRegionLoc() const { 708 const SharingMapTy *Top = getTopOfStackOrNull(); 709 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 710 } 711 712 Scope *getCurScope() const { 713 const SharingMapTy *Top = getTopOfStackOrNull(); 714 return Top ? Top->CurScope : nullptr; 715 } 716 SourceLocation getConstructLoc() const { 717 const SharingMapTy *Top = getTopOfStackOrNull(); 718 return Top ? Top->ConstructLoc : SourceLocation(); 719 } 720 721 /// Do the check specified in \a Check to all component lists and return true 722 /// if any issue is found. 723 bool checkMappableExprComponentListsForDecl( 724 const ValueDecl *VD, bool CurrentRegionOnly, 725 const llvm::function_ref< 726 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 727 OpenMPClauseKind)> 728 Check) const { 729 if (isStackEmpty()) 730 return false; 731 auto SI = begin(); 732 auto SE = end(); 733 734 if (SI == SE) 735 return false; 736 737 if (CurrentRegionOnly) 738 SE = std::next(SI); 739 else 740 std::advance(SI, 1); 741 742 for (; SI != SE; ++SI) { 743 auto MI = SI->MappedExprComponents.find(VD); 744 if (MI != SI->MappedExprComponents.end()) 745 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 746 MI->second.Components) 747 if (Check(L, MI->second.Kind)) 748 return true; 749 } 750 return false; 751 } 752 753 /// Do the check specified in \a Check to all component lists at a given level 754 /// and return true if any issue is found. 755 bool checkMappableExprComponentListsForDeclAtLevel( 756 const ValueDecl *VD, unsigned Level, 757 const llvm::function_ref< 758 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 759 OpenMPClauseKind)> 760 Check) const { 761 if (getStackSize() <= Level) 762 return false; 763 764 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 765 auto MI = StackElem.MappedExprComponents.find(VD); 766 if (MI != StackElem.MappedExprComponents.end()) 767 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 768 MI->second.Components) 769 if (Check(L, MI->second.Kind)) 770 return true; 771 return false; 772 } 773 774 /// Create a new mappable expression component list associated with a given 775 /// declaration and initialize it with the provided list of components. 776 void addMappableExpressionComponents( 777 const ValueDecl *VD, 778 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 779 OpenMPClauseKind WhereFoundClauseKind) { 780 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 781 // Create new entry and append the new components there. 782 MEC.Components.resize(MEC.Components.size() + 1); 783 MEC.Components.back().append(Components.begin(), Components.end()); 784 MEC.Kind = WhereFoundClauseKind; 785 } 786 787 unsigned getNestingLevel() const { 788 assert(!isStackEmpty()); 789 return getStackSize() - 1; 790 } 791 void addDoacrossDependClause(OMPDependClause *C, 792 const OperatorOffsetTy &OpsOffs) { 793 SharingMapTy *Parent = getSecondOnStackOrNull(); 794 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 795 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 796 } 797 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 798 getDoacrossDependClauses() const { 799 const SharingMapTy &StackElem = getTopOfStack(); 800 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 801 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 802 return llvm::make_range(Ref.begin(), Ref.end()); 803 } 804 return llvm::make_range(StackElem.DoacrossDepends.end(), 805 StackElem.DoacrossDepends.end()); 806 } 807 808 // Store types of classes which have been explicitly mapped 809 void addMappedClassesQualTypes(QualType QT) { 810 SharingMapTy &StackElem = getTopOfStack(); 811 StackElem.MappedClassesQualTypes.insert(QT); 812 } 813 814 // Return set of mapped classes types 815 bool isClassPreviouslyMapped(QualType QT) const { 816 const SharingMapTy &StackElem = getTopOfStack(); 817 return StackElem.MappedClassesQualTypes.count(QT) != 0; 818 } 819 820 /// Adds global declare target to the parent target region. 821 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 822 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 823 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 824 "Expected declare target link global."); 825 for (auto &Elem : *this) { 826 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 827 Elem.DeclareTargetLinkVarDecls.push_back(E); 828 return; 829 } 830 } 831 } 832 833 /// Returns the list of globals with declare target link if current directive 834 /// is target. 835 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 836 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 837 "Expected target executable directive."); 838 return getTopOfStack().DeclareTargetLinkVarDecls; 839 } 840 }; 841 842 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 843 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 844 } 845 846 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 847 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 848 DKind == OMPD_unknown; 849 } 850 851 } // namespace 852 853 static const Expr *getExprAsWritten(const Expr *E) { 854 if (const auto *FE = dyn_cast<FullExpr>(E)) 855 E = FE->getSubExpr(); 856 857 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 858 E = MTE->GetTemporaryExpr(); 859 860 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 861 E = Binder->getSubExpr(); 862 863 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 864 E = ICE->getSubExprAsWritten(); 865 return E->IgnoreParens(); 866 } 867 868 static Expr *getExprAsWritten(Expr *E) { 869 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 870 } 871 872 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 873 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 874 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 875 D = ME->getMemberDecl(); 876 const auto *VD = dyn_cast<VarDecl>(D); 877 const auto *FD = dyn_cast<FieldDecl>(D); 878 if (VD != nullptr) { 879 VD = VD->getCanonicalDecl(); 880 D = VD; 881 } else { 882 assert(FD); 883 FD = FD->getCanonicalDecl(); 884 D = FD; 885 } 886 return D; 887 } 888 889 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 890 return const_cast<ValueDecl *>( 891 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 892 } 893 894 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 895 ValueDecl *D) const { 896 D = getCanonicalDecl(D); 897 auto *VD = dyn_cast<VarDecl>(D); 898 const auto *FD = dyn_cast<FieldDecl>(D); 899 DSAVarData DVar; 900 if (Iter == end()) { 901 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 902 // in a region but not in construct] 903 // File-scope or namespace-scope variables referenced in called routines 904 // in the region are shared unless they appear in a threadprivate 905 // directive. 906 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 907 DVar.CKind = OMPC_shared; 908 909 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 910 // in a region but not in construct] 911 // Variables with static storage duration that are declared in called 912 // routines in the region are shared. 913 if (VD && VD->hasGlobalStorage()) 914 DVar.CKind = OMPC_shared; 915 916 // Non-static data members are shared by default. 917 if (FD) 918 DVar.CKind = OMPC_shared; 919 920 return DVar; 921 } 922 923 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 924 // in a Construct, C/C++, predetermined, p.1] 925 // Variables with automatic storage duration that are declared in a scope 926 // inside the construct are private. 927 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 928 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 929 DVar.CKind = OMPC_private; 930 return DVar; 931 } 932 933 DVar.DKind = Iter->Directive; 934 // Explicitly specified attributes and local variables with predetermined 935 // attributes. 936 if (Iter->SharingMap.count(D)) { 937 const DSAInfo &Data = Iter->SharingMap.lookup(D); 938 DVar.RefExpr = Data.RefExpr.getPointer(); 939 DVar.PrivateCopy = Data.PrivateCopy; 940 DVar.CKind = Data.Attributes; 941 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 942 return DVar; 943 } 944 945 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 946 // in a Construct, C/C++, implicitly determined, p.1] 947 // In a parallel or task construct, the data-sharing attributes of these 948 // variables are determined by the default clause, if present. 949 switch (Iter->DefaultAttr) { 950 case DSA_shared: 951 DVar.CKind = OMPC_shared; 952 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 953 return DVar; 954 case DSA_none: 955 return DVar; 956 case DSA_unspecified: 957 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 958 // in a Construct, implicitly determined, p.2] 959 // In a parallel construct, if no default clause is present, these 960 // variables are shared. 961 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 962 if (isOpenMPParallelDirective(DVar.DKind) || 963 isOpenMPTeamsDirective(DVar.DKind)) { 964 DVar.CKind = OMPC_shared; 965 return DVar; 966 } 967 968 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 969 // in a Construct, implicitly determined, p.4] 970 // In a task construct, if no default clause is present, a variable that in 971 // the enclosing context is determined to be shared by all implicit tasks 972 // bound to the current team is shared. 973 if (isOpenMPTaskingDirective(DVar.DKind)) { 974 DSAVarData DVarTemp; 975 const_iterator I = Iter, E = end(); 976 do { 977 ++I; 978 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 979 // Referenced in a Construct, implicitly determined, p.6] 980 // In a task construct, if no default clause is present, a variable 981 // whose data-sharing attribute is not determined by the rules above is 982 // firstprivate. 983 DVarTemp = getDSA(I, D); 984 if (DVarTemp.CKind != OMPC_shared) { 985 DVar.RefExpr = nullptr; 986 DVar.CKind = OMPC_firstprivate; 987 return DVar; 988 } 989 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 990 DVar.CKind = 991 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 992 return DVar; 993 } 994 } 995 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 996 // in a Construct, implicitly determined, p.3] 997 // For constructs other than task, if no default clause is present, these 998 // variables inherit their data-sharing attributes from the enclosing 999 // context. 1000 return getDSA(++Iter, D); 1001 } 1002 1003 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1004 const Expr *NewDE) { 1005 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1006 D = getCanonicalDecl(D); 1007 SharingMapTy &StackElem = getTopOfStack(); 1008 auto It = StackElem.AlignedMap.find(D); 1009 if (It == StackElem.AlignedMap.end()) { 1010 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1011 StackElem.AlignedMap[D] = NewDE; 1012 return nullptr; 1013 } 1014 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1015 return It->second; 1016 } 1017 1018 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1019 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1020 D = getCanonicalDecl(D); 1021 SharingMapTy &StackElem = getTopOfStack(); 1022 StackElem.LCVMap.try_emplace( 1023 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1024 } 1025 1026 const DSAStackTy::LCDeclInfo 1027 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1028 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1029 D = getCanonicalDecl(D); 1030 const SharingMapTy &StackElem = getTopOfStack(); 1031 auto It = StackElem.LCVMap.find(D); 1032 if (It != StackElem.LCVMap.end()) 1033 return It->second; 1034 return {0, nullptr}; 1035 } 1036 1037 const DSAStackTy::LCDeclInfo 1038 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1039 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1040 assert(Parent && "Data-sharing attributes stack is empty"); 1041 D = getCanonicalDecl(D); 1042 auto It = Parent->LCVMap.find(D); 1043 if (It != Parent->LCVMap.end()) 1044 return It->second; 1045 return {0, nullptr}; 1046 } 1047 1048 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1049 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1050 assert(Parent && "Data-sharing attributes stack is empty"); 1051 if (Parent->LCVMap.size() < I) 1052 return nullptr; 1053 for (const auto &Pair : Parent->LCVMap) 1054 if (Pair.second.first == I) 1055 return Pair.first; 1056 return nullptr; 1057 } 1058 1059 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1060 DeclRefExpr *PrivateCopy) { 1061 D = getCanonicalDecl(D); 1062 if (A == OMPC_threadprivate) { 1063 DSAInfo &Data = Threadprivates[D]; 1064 Data.Attributes = A; 1065 Data.RefExpr.setPointer(E); 1066 Data.PrivateCopy = nullptr; 1067 } else { 1068 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1069 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1070 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1071 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1072 (isLoopControlVariable(D).first && A == OMPC_private)); 1073 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1074 Data.RefExpr.setInt(/*IntVal=*/true); 1075 return; 1076 } 1077 const bool IsLastprivate = 1078 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1079 Data.Attributes = A; 1080 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1081 Data.PrivateCopy = PrivateCopy; 1082 if (PrivateCopy) { 1083 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1084 Data.Attributes = A; 1085 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1086 Data.PrivateCopy = nullptr; 1087 } 1088 } 1089 } 1090 1091 /// Build a variable declaration for OpenMP loop iteration variable. 1092 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1093 StringRef Name, const AttrVec *Attrs = nullptr, 1094 DeclRefExpr *OrigRef = nullptr) { 1095 DeclContext *DC = SemaRef.CurContext; 1096 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1097 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1098 auto *Decl = 1099 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1100 if (Attrs) { 1101 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1102 I != E; ++I) 1103 Decl->addAttr(*I); 1104 } 1105 Decl->setImplicit(); 1106 if (OrigRef) { 1107 Decl->addAttr( 1108 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1109 } 1110 return Decl; 1111 } 1112 1113 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1114 SourceLocation Loc, 1115 bool RefersToCapture = false) { 1116 D->setReferenced(); 1117 D->markUsed(S.Context); 1118 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1119 SourceLocation(), D, RefersToCapture, Loc, Ty, 1120 VK_LValue); 1121 } 1122 1123 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1124 BinaryOperatorKind BOK) { 1125 D = getCanonicalDecl(D); 1126 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1127 assert( 1128 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1129 "Additional reduction info may be specified only for reduction items."); 1130 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1131 assert(ReductionData.ReductionRange.isInvalid() && 1132 getTopOfStack().Directive == OMPD_taskgroup && 1133 "Additional reduction info may be specified only once for reduction " 1134 "items."); 1135 ReductionData.set(BOK, SR); 1136 Expr *&TaskgroupReductionRef = 1137 getTopOfStack().TaskgroupReductionRef; 1138 if (!TaskgroupReductionRef) { 1139 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1140 SemaRef.Context.VoidPtrTy, ".task_red."); 1141 TaskgroupReductionRef = 1142 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1143 } 1144 } 1145 1146 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1147 const Expr *ReductionRef) { 1148 D = getCanonicalDecl(D); 1149 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1150 assert( 1151 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1152 "Additional reduction info may be specified only for reduction items."); 1153 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1154 assert(ReductionData.ReductionRange.isInvalid() && 1155 getTopOfStack().Directive == OMPD_taskgroup && 1156 "Additional reduction info may be specified only once for reduction " 1157 "items."); 1158 ReductionData.set(ReductionRef, SR); 1159 Expr *&TaskgroupReductionRef = 1160 getTopOfStack().TaskgroupReductionRef; 1161 if (!TaskgroupReductionRef) { 1162 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1163 SemaRef.Context.VoidPtrTy, ".task_red."); 1164 TaskgroupReductionRef = 1165 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1166 } 1167 } 1168 1169 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1170 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1171 Expr *&TaskgroupDescriptor) const { 1172 D = getCanonicalDecl(D); 1173 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1174 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1175 const DSAInfo &Data = I->SharingMap.lookup(D); 1176 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1177 continue; 1178 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1179 if (!ReductionData.ReductionOp || 1180 ReductionData.ReductionOp.is<const Expr *>()) 1181 return DSAVarData(); 1182 SR = ReductionData.ReductionRange; 1183 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1184 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1185 "expression for the descriptor is not " 1186 "set."); 1187 TaskgroupDescriptor = I->TaskgroupReductionRef; 1188 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1189 Data.PrivateCopy, I->DefaultAttrLoc); 1190 } 1191 return DSAVarData(); 1192 } 1193 1194 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1195 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1196 Expr *&TaskgroupDescriptor) const { 1197 D = getCanonicalDecl(D); 1198 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1199 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1200 const DSAInfo &Data = I->SharingMap.lookup(D); 1201 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1202 continue; 1203 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1204 if (!ReductionData.ReductionOp || 1205 !ReductionData.ReductionOp.is<const Expr *>()) 1206 return DSAVarData(); 1207 SR = ReductionData.ReductionRange; 1208 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1209 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1210 "expression for the descriptor is not " 1211 "set."); 1212 TaskgroupDescriptor = I->TaskgroupReductionRef; 1213 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1214 Data.PrivateCopy, I->DefaultAttrLoc); 1215 } 1216 return DSAVarData(); 1217 } 1218 1219 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1220 D = D->getCanonicalDecl(); 1221 for (const_iterator E = end(); I != E; ++I) { 1222 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1223 isOpenMPTargetExecutionDirective(I->Directive)) { 1224 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1225 Scope *CurScope = getCurScope(); 1226 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1227 CurScope = CurScope->getParent(); 1228 return CurScope != TopScope; 1229 } 1230 } 1231 return false; 1232 } 1233 1234 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1235 bool AcceptIfMutable = true, 1236 bool *IsClassType = nullptr) { 1237 ASTContext &Context = SemaRef.getASTContext(); 1238 Type = Type.getNonReferenceType().getCanonicalType(); 1239 bool IsConstant = Type.isConstant(Context); 1240 Type = Context.getBaseElementType(Type); 1241 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1242 ? Type->getAsCXXRecordDecl() 1243 : nullptr; 1244 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1245 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1246 RD = CTD->getTemplatedDecl(); 1247 if (IsClassType) 1248 *IsClassType = RD; 1249 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1250 RD->hasDefinition() && RD->hasMutableFields()); 1251 } 1252 1253 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1254 QualType Type, OpenMPClauseKind CKind, 1255 SourceLocation ELoc, 1256 bool AcceptIfMutable = true, 1257 bool ListItemNotVar = false) { 1258 ASTContext &Context = SemaRef.getASTContext(); 1259 bool IsClassType; 1260 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1261 unsigned Diag = ListItemNotVar 1262 ? diag::err_omp_const_list_item 1263 : IsClassType ? diag::err_omp_const_not_mutable_variable 1264 : diag::err_omp_const_variable; 1265 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1266 if (!ListItemNotVar && D) { 1267 const VarDecl *VD = dyn_cast<VarDecl>(D); 1268 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1269 VarDecl::DeclarationOnly; 1270 SemaRef.Diag(D->getLocation(), 1271 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1272 << D; 1273 } 1274 return true; 1275 } 1276 return false; 1277 } 1278 1279 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1280 bool FromParent) { 1281 D = getCanonicalDecl(D); 1282 DSAVarData DVar; 1283 1284 auto *VD = dyn_cast<VarDecl>(D); 1285 auto TI = Threadprivates.find(D); 1286 if (TI != Threadprivates.end()) { 1287 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1288 DVar.CKind = OMPC_threadprivate; 1289 return DVar; 1290 } 1291 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1292 DVar.RefExpr = buildDeclRefExpr( 1293 SemaRef, VD, D->getType().getNonReferenceType(), 1294 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1295 DVar.CKind = OMPC_threadprivate; 1296 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1297 return DVar; 1298 } 1299 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1300 // in a Construct, C/C++, predetermined, p.1] 1301 // Variables appearing in threadprivate directives are threadprivate. 1302 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1303 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1304 SemaRef.getLangOpts().OpenMPUseTLS && 1305 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1306 (VD && VD->getStorageClass() == SC_Register && 1307 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1308 DVar.RefExpr = buildDeclRefExpr( 1309 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1310 DVar.CKind = OMPC_threadprivate; 1311 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1312 return DVar; 1313 } 1314 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1315 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1316 !isLoopControlVariable(D).first) { 1317 const_iterator IterTarget = 1318 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1319 return isOpenMPTargetExecutionDirective(Data.Directive); 1320 }); 1321 if (IterTarget != end()) { 1322 const_iterator ParentIterTarget = IterTarget + 1; 1323 for (const_iterator Iter = begin(); 1324 Iter != ParentIterTarget; ++Iter) { 1325 if (isOpenMPLocal(VD, Iter)) { 1326 DVar.RefExpr = 1327 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1328 D->getLocation()); 1329 DVar.CKind = OMPC_threadprivate; 1330 return DVar; 1331 } 1332 } 1333 if (!isClauseParsingMode() || IterTarget != begin()) { 1334 auto DSAIter = IterTarget->SharingMap.find(D); 1335 if (DSAIter != IterTarget->SharingMap.end() && 1336 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1337 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1338 DVar.CKind = OMPC_threadprivate; 1339 return DVar; 1340 } 1341 const_iterator End = end(); 1342 if (!SemaRef.isOpenMPCapturedByRef( 1343 D, std::distance(ParentIterTarget, End))) { 1344 DVar.RefExpr = 1345 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1346 IterTarget->ConstructLoc); 1347 DVar.CKind = OMPC_threadprivate; 1348 return DVar; 1349 } 1350 } 1351 } 1352 } 1353 1354 if (isStackEmpty()) 1355 // Not in OpenMP execution region and top scope was already checked. 1356 return DVar; 1357 1358 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1359 // in a Construct, C/C++, predetermined, p.4] 1360 // Static data members are shared. 1361 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1362 // in a Construct, C/C++, predetermined, p.7] 1363 // Variables with static storage duration that are declared in a scope 1364 // inside the construct are shared. 1365 if (VD && VD->isStaticDataMember()) { 1366 // Check for explicitly specified attributes. 1367 const_iterator I = begin(); 1368 const_iterator EndI = end(); 1369 if (FromParent && I != EndI) 1370 ++I; 1371 auto It = I->SharingMap.find(D); 1372 if (It != I->SharingMap.end()) { 1373 const DSAInfo &Data = It->getSecond(); 1374 DVar.RefExpr = Data.RefExpr.getPointer(); 1375 DVar.PrivateCopy = Data.PrivateCopy; 1376 DVar.CKind = Data.Attributes; 1377 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1378 DVar.DKind = I->Directive; 1379 return DVar; 1380 } 1381 1382 DVar.CKind = OMPC_shared; 1383 return DVar; 1384 } 1385 1386 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1387 // The predetermined shared attribute for const-qualified types having no 1388 // mutable members was removed after OpenMP 3.1. 1389 if (SemaRef.LangOpts.OpenMP <= 31) { 1390 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1391 // in a Construct, C/C++, predetermined, p.6] 1392 // Variables with const qualified type having no mutable member are 1393 // shared. 1394 if (isConstNotMutableType(SemaRef, D->getType())) { 1395 // Variables with const-qualified type having no mutable member may be 1396 // listed in a firstprivate clause, even if they are static data members. 1397 DSAVarData DVarTemp = hasInnermostDSA( 1398 D, 1399 [](OpenMPClauseKind C) { 1400 return C == OMPC_firstprivate || C == OMPC_shared; 1401 }, 1402 MatchesAlways, FromParent); 1403 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1404 return DVarTemp; 1405 1406 DVar.CKind = OMPC_shared; 1407 return DVar; 1408 } 1409 } 1410 1411 // Explicitly specified attributes and local variables with predetermined 1412 // attributes. 1413 const_iterator I = begin(); 1414 const_iterator EndI = end(); 1415 if (FromParent && I != EndI) 1416 ++I; 1417 auto It = I->SharingMap.find(D); 1418 if (It != I->SharingMap.end()) { 1419 const DSAInfo &Data = It->getSecond(); 1420 DVar.RefExpr = Data.RefExpr.getPointer(); 1421 DVar.PrivateCopy = Data.PrivateCopy; 1422 DVar.CKind = Data.Attributes; 1423 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1424 DVar.DKind = I->Directive; 1425 } 1426 1427 return DVar; 1428 } 1429 1430 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1431 bool FromParent) const { 1432 if (isStackEmpty()) { 1433 const_iterator I; 1434 return getDSA(I, D); 1435 } 1436 D = getCanonicalDecl(D); 1437 const_iterator StartI = begin(); 1438 const_iterator EndI = end(); 1439 if (FromParent && StartI != EndI) 1440 ++StartI; 1441 return getDSA(StartI, D); 1442 } 1443 1444 const DSAStackTy::DSAVarData 1445 DSAStackTy::hasDSA(ValueDecl *D, 1446 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1447 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1448 bool FromParent) const { 1449 if (isStackEmpty()) 1450 return {}; 1451 D = getCanonicalDecl(D); 1452 const_iterator I = begin(); 1453 const_iterator EndI = end(); 1454 if (FromParent && I != EndI) 1455 ++I; 1456 for (; I != EndI; ++I) { 1457 if (!DPred(I->Directive) && 1458 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1459 continue; 1460 const_iterator NewI = I; 1461 DSAVarData DVar = getDSA(NewI, D); 1462 if (I == NewI && CPred(DVar.CKind)) 1463 return DVar; 1464 } 1465 return {}; 1466 } 1467 1468 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1469 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1470 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1471 bool FromParent) const { 1472 if (isStackEmpty()) 1473 return {}; 1474 D = getCanonicalDecl(D); 1475 const_iterator StartI = begin(); 1476 const_iterator EndI = end(); 1477 if (FromParent && StartI != EndI) 1478 ++StartI; 1479 if (StartI == EndI || !DPred(StartI->Directive)) 1480 return {}; 1481 const_iterator NewI = StartI; 1482 DSAVarData DVar = getDSA(NewI, D); 1483 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1484 } 1485 1486 bool DSAStackTy::hasExplicitDSA( 1487 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1488 unsigned Level, bool NotLastprivate) const { 1489 if (getStackSize() <= Level) 1490 return false; 1491 D = getCanonicalDecl(D); 1492 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1493 auto I = StackElem.SharingMap.find(D); 1494 if (I != StackElem.SharingMap.end() && 1495 I->getSecond().RefExpr.getPointer() && 1496 CPred(I->getSecond().Attributes) && 1497 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1498 return true; 1499 // Check predetermined rules for the loop control variables. 1500 auto LI = StackElem.LCVMap.find(D); 1501 if (LI != StackElem.LCVMap.end()) 1502 return CPred(OMPC_private); 1503 return false; 1504 } 1505 1506 bool DSAStackTy::hasExplicitDirective( 1507 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1508 unsigned Level) const { 1509 if (getStackSize() <= Level) 1510 return false; 1511 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1512 return DPred(StackElem.Directive); 1513 } 1514 1515 bool DSAStackTy::hasDirective( 1516 const llvm::function_ref<bool(OpenMPDirectiveKind, 1517 const DeclarationNameInfo &, SourceLocation)> 1518 DPred, 1519 bool FromParent) const { 1520 // We look only in the enclosing region. 1521 size_t Skip = FromParent ? 2 : 1; 1522 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1523 I != E; ++I) { 1524 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1525 return true; 1526 } 1527 return false; 1528 } 1529 1530 void Sema::InitDataSharingAttributesStack() { 1531 VarDataSharingAttributesStack = new DSAStackTy(*this); 1532 } 1533 1534 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1535 1536 void Sema::pushOpenMPFunctionRegion() { 1537 DSAStack->pushFunction(); 1538 } 1539 1540 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1541 DSAStack->popFunction(OldFSI); 1542 } 1543 1544 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1545 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1546 "Expected OpenMP device compilation."); 1547 return !S.isInOpenMPTargetExecutionDirective() && 1548 !S.isInOpenMPDeclareTargetContext(); 1549 } 1550 1551 /// Do we know that we will eventually codegen the given function? 1552 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1553 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1554 "Expected OpenMP device compilation."); 1555 // Templates are emitted when they're instantiated. 1556 if (FD->isDependentContext()) 1557 return false; 1558 1559 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1560 FD->getCanonicalDecl())) 1561 return true; 1562 1563 // Otherwise, the function is known-emitted if it's in our set of 1564 // known-emitted functions. 1565 return S.DeviceKnownEmittedFns.count(FD) > 0; 1566 } 1567 1568 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1569 unsigned DiagID) { 1570 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1571 "Expected OpenMP device compilation."); 1572 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1573 !isKnownEmitted(*this, getCurFunctionDecl())) 1574 ? DeviceDiagBuilder::K_Deferred 1575 : DeviceDiagBuilder::K_Immediate, 1576 Loc, DiagID, getCurFunctionDecl(), *this); 1577 } 1578 1579 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1580 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1581 "Expected OpenMP device compilation."); 1582 assert(Callee && "Callee may not be null."); 1583 FunctionDecl *Caller = getCurFunctionDecl(); 1584 1585 // If the caller is known-emitted, mark the callee as known-emitted. 1586 // Otherwise, mark the call in our call graph so we can traverse it later. 1587 if (!isOpenMPDeviceDelayedContext(*this) || 1588 (Caller && isKnownEmitted(*this, Caller))) 1589 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1590 else if (Caller) 1591 DeviceCallGraph[Caller].insert({Callee, Loc}); 1592 } 1593 1594 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1595 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1596 "OpenMP device compilation mode is expected."); 1597 QualType Ty = E->getType(); 1598 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1599 ((Ty->isFloat128Type() || 1600 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1601 !Context.getTargetInfo().hasFloat128Type()) || 1602 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1603 !Context.getTargetInfo().hasInt128Type())) 1604 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1605 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1606 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1607 } 1608 1609 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1610 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1611 1612 ASTContext &Ctx = getASTContext(); 1613 bool IsByRef = true; 1614 1615 // Find the directive that is associated with the provided scope. 1616 D = cast<ValueDecl>(D->getCanonicalDecl()); 1617 QualType Ty = D->getType(); 1618 1619 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1620 // This table summarizes how a given variable should be passed to the device 1621 // given its type and the clauses where it appears. This table is based on 1622 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1623 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1624 // 1625 // ========================================================================= 1626 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1627 // | |(tofrom:scalar)| | pvt | | | | 1628 // ========================================================================= 1629 // | scl | | | | - | | bycopy| 1630 // | scl | | - | x | - | - | bycopy| 1631 // | scl | | x | - | - | - | null | 1632 // | scl | x | | | - | | byref | 1633 // | scl | x | - | x | - | - | bycopy| 1634 // | scl | x | x | - | - | - | null | 1635 // | scl | | - | - | - | x | byref | 1636 // | scl | x | - | - | - | x | byref | 1637 // 1638 // | agg | n.a. | | | - | | byref | 1639 // | agg | n.a. | - | x | - | - | byref | 1640 // | agg | n.a. | x | - | - | - | null | 1641 // | agg | n.a. | - | - | - | x | byref | 1642 // | agg | n.a. | - | - | - | x[] | byref | 1643 // 1644 // | ptr | n.a. | | | - | | bycopy| 1645 // | ptr | n.a. | - | x | - | - | bycopy| 1646 // | ptr | n.a. | x | - | - | - | null | 1647 // | ptr | n.a. | - | - | - | x | byref | 1648 // | ptr | n.a. | - | - | - | x[] | bycopy| 1649 // | ptr | n.a. | - | - | x | | bycopy| 1650 // | ptr | n.a. | - | - | x | x | bycopy| 1651 // | ptr | n.a. | - | - | x | x[] | bycopy| 1652 // ========================================================================= 1653 // Legend: 1654 // scl - scalar 1655 // ptr - pointer 1656 // agg - aggregate 1657 // x - applies 1658 // - - invalid in this combination 1659 // [] - mapped with an array section 1660 // byref - should be mapped by reference 1661 // byval - should be mapped by value 1662 // null - initialize a local variable to null on the device 1663 // 1664 // Observations: 1665 // - All scalar declarations that show up in a map clause have to be passed 1666 // by reference, because they may have been mapped in the enclosing data 1667 // environment. 1668 // - If the scalar value does not fit the size of uintptr, it has to be 1669 // passed by reference, regardless the result in the table above. 1670 // - For pointers mapped by value that have either an implicit map or an 1671 // array section, the runtime library may pass the NULL value to the 1672 // device instead of the value passed to it by the compiler. 1673 1674 if (Ty->isReferenceType()) 1675 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1676 1677 // Locate map clauses and see if the variable being captured is referred to 1678 // in any of those clauses. Here we only care about variables, not fields, 1679 // because fields are part of aggregates. 1680 bool IsVariableUsedInMapClause = false; 1681 bool IsVariableAssociatedWithSection = false; 1682 1683 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1684 D, Level, 1685 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1686 OMPClauseMappableExprCommon::MappableExprComponentListRef 1687 MapExprComponents, 1688 OpenMPClauseKind WhereFoundClauseKind) { 1689 // Only the map clause information influences how a variable is 1690 // captured. E.g. is_device_ptr does not require changing the default 1691 // behavior. 1692 if (WhereFoundClauseKind != OMPC_map) 1693 return false; 1694 1695 auto EI = MapExprComponents.rbegin(); 1696 auto EE = MapExprComponents.rend(); 1697 1698 assert(EI != EE && "Invalid map expression!"); 1699 1700 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1701 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1702 1703 ++EI; 1704 if (EI == EE) 1705 return false; 1706 1707 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1708 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1709 isa<MemberExpr>(EI->getAssociatedExpression())) { 1710 IsVariableAssociatedWithSection = true; 1711 // There is nothing more we need to know about this variable. 1712 return true; 1713 } 1714 1715 // Keep looking for more map info. 1716 return false; 1717 }); 1718 1719 if (IsVariableUsedInMapClause) { 1720 // If variable is identified in a map clause it is always captured by 1721 // reference except if it is a pointer that is dereferenced somehow. 1722 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1723 } else { 1724 // By default, all the data that has a scalar type is mapped by copy 1725 // (except for reduction variables). 1726 IsByRef = 1727 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1728 !Ty->isAnyPointerType()) || 1729 !Ty->isScalarType() || 1730 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1731 DSAStack->hasExplicitDSA( 1732 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1733 } 1734 } 1735 1736 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1737 IsByRef = 1738 !DSAStack->hasExplicitDSA( 1739 D, 1740 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1741 Level, /*NotLastprivate=*/true) && 1742 // If the variable is artificial and must be captured by value - try to 1743 // capture by value. 1744 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1745 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1746 } 1747 1748 // When passing data by copy, we need to make sure it fits the uintptr size 1749 // and alignment, because the runtime library only deals with uintptr types. 1750 // If it does not fit the uintptr size, we need to pass the data by reference 1751 // instead. 1752 if (!IsByRef && 1753 (Ctx.getTypeSizeInChars(Ty) > 1754 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1755 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1756 IsByRef = true; 1757 } 1758 1759 return IsByRef; 1760 } 1761 1762 unsigned Sema::getOpenMPNestingLevel() const { 1763 assert(getLangOpts().OpenMP); 1764 return DSAStack->getNestingLevel(); 1765 } 1766 1767 bool Sema::isInOpenMPTargetExecutionDirective() const { 1768 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1769 !DSAStack->isClauseParsingMode()) || 1770 DSAStack->hasDirective( 1771 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1772 SourceLocation) -> bool { 1773 return isOpenMPTargetExecutionDirective(K); 1774 }, 1775 false); 1776 } 1777 1778 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1779 unsigned StopAt) { 1780 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1781 D = getCanonicalDecl(D); 1782 1783 // If we want to determine whether the variable should be captured from the 1784 // perspective of the current capturing scope, and we've already left all the 1785 // capturing scopes of the top directive on the stack, check from the 1786 // perspective of its parent directive (if any) instead. 1787 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1788 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1789 1790 // If we are attempting to capture a global variable in a directive with 1791 // 'target' we return true so that this global is also mapped to the device. 1792 // 1793 auto *VD = dyn_cast<VarDecl>(D); 1794 if (VD && !VD->hasLocalStorage() && 1795 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1796 if (isInOpenMPDeclareTargetContext()) { 1797 // Try to mark variable as declare target if it is used in capturing 1798 // regions. 1799 if (LangOpts.OpenMP <= 45 && 1800 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1801 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1802 return nullptr; 1803 } else if (isInOpenMPTargetExecutionDirective()) { 1804 // If the declaration is enclosed in a 'declare target' directive, 1805 // then it should not be captured. 1806 // 1807 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1808 return nullptr; 1809 return VD; 1810 } 1811 } 1812 1813 if (CheckScopeInfo) { 1814 bool OpenMPFound = false; 1815 for (unsigned I = StopAt + 1; I > 0; --I) { 1816 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1817 if(!isa<CapturingScopeInfo>(FSI)) 1818 return nullptr; 1819 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1820 if (RSI->CapRegionKind == CR_OpenMP) { 1821 OpenMPFound = true; 1822 break; 1823 } 1824 } 1825 if (!OpenMPFound) 1826 return nullptr; 1827 } 1828 1829 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1830 (!DSAStack->isClauseParsingMode() || 1831 DSAStack->getParentDirective() != OMPD_unknown)) { 1832 auto &&Info = DSAStack->isLoopControlVariable(D); 1833 if (Info.first || 1834 (VD && VD->hasLocalStorage() && 1835 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1836 (VD && DSAStack->isForceVarCapturing())) 1837 return VD ? VD : Info.second; 1838 DSAStackTy::DSAVarData DVarPrivate = 1839 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1840 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1841 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1842 // Threadprivate variables must not be captured. 1843 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1844 return nullptr; 1845 // The variable is not private or it is the variable in the directive with 1846 // default(none) clause and not used in any clause. 1847 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1848 [](OpenMPDirectiveKind) { return true; }, 1849 DSAStack->isClauseParsingMode()); 1850 if (DVarPrivate.CKind != OMPC_unknown || 1851 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1852 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1853 } 1854 return nullptr; 1855 } 1856 1857 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1858 unsigned Level) const { 1859 SmallVector<OpenMPDirectiveKind, 4> Regions; 1860 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1861 FunctionScopesIndex -= Regions.size(); 1862 } 1863 1864 void Sema::startOpenMPLoop() { 1865 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1866 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1867 DSAStack->loopInit(); 1868 } 1869 1870 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1871 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1872 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1873 if (DSAStack->getAssociatedLoops() > 0 && 1874 !DSAStack->isLoopStarted()) { 1875 DSAStack->resetPossibleLoopCounter(D); 1876 DSAStack->loopStart(); 1877 return true; 1878 } 1879 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1880 DSAStack->isLoopControlVariable(D).first) && 1881 !DSAStack->hasExplicitDSA( 1882 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1883 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1884 return true; 1885 } 1886 if (const auto *VD = dyn_cast<VarDecl>(D)) { 1887 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 1888 DSAStack->isForceVarCapturing() && 1889 !DSAStack->hasExplicitDSA( 1890 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 1891 return true; 1892 } 1893 return DSAStack->hasExplicitDSA( 1894 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1895 (DSAStack->isClauseParsingMode() && 1896 DSAStack->getClauseParsingMode() == OMPC_private) || 1897 // Consider taskgroup reduction descriptor variable a private to avoid 1898 // possible capture in the region. 1899 (DSAStack->hasExplicitDirective( 1900 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1901 Level) && 1902 DSAStack->isTaskgroupReductionRef(D, Level)); 1903 } 1904 1905 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1906 unsigned Level) { 1907 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1908 D = getCanonicalDecl(D); 1909 OpenMPClauseKind OMPC = OMPC_unknown; 1910 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1911 const unsigned NewLevel = I - 1; 1912 if (DSAStack->hasExplicitDSA(D, 1913 [&OMPC](const OpenMPClauseKind K) { 1914 if (isOpenMPPrivate(K)) { 1915 OMPC = K; 1916 return true; 1917 } 1918 return false; 1919 }, 1920 NewLevel)) 1921 break; 1922 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1923 D, NewLevel, 1924 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1925 OpenMPClauseKind) { return true; })) { 1926 OMPC = OMPC_map; 1927 break; 1928 } 1929 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1930 NewLevel)) { 1931 OMPC = OMPC_map; 1932 if (D->getType()->isScalarType() && 1933 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1934 DefaultMapAttributes::DMA_tofrom_scalar) 1935 OMPC = OMPC_firstprivate; 1936 break; 1937 } 1938 } 1939 if (OMPC != OMPC_unknown) 1940 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1941 } 1942 1943 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1944 unsigned Level) const { 1945 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1946 // Return true if the current level is no longer enclosed in a target region. 1947 1948 const auto *VD = dyn_cast<VarDecl>(D); 1949 return VD && !VD->hasLocalStorage() && 1950 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1951 Level); 1952 } 1953 1954 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1955 1956 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1957 const DeclarationNameInfo &DirName, 1958 Scope *CurScope, SourceLocation Loc) { 1959 DSAStack->push(DKind, DirName, CurScope, Loc); 1960 PushExpressionEvaluationContext( 1961 ExpressionEvaluationContext::PotentiallyEvaluated); 1962 } 1963 1964 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1965 DSAStack->setClauseParsingMode(K); 1966 } 1967 1968 void Sema::EndOpenMPClause() { 1969 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1970 } 1971 1972 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 1973 ArrayRef<OMPClause *> Clauses); 1974 1975 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1976 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1977 // A variable of class type (or array thereof) that appears in a lastprivate 1978 // clause requires an accessible, unambiguous default constructor for the 1979 // class type, unless the list item is also specified in a firstprivate 1980 // clause. 1981 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1982 for (OMPClause *C : D->clauses()) { 1983 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1984 SmallVector<Expr *, 8> PrivateCopies; 1985 for (Expr *DE : Clause->varlists()) { 1986 if (DE->isValueDependent() || DE->isTypeDependent()) { 1987 PrivateCopies.push_back(nullptr); 1988 continue; 1989 } 1990 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1991 auto *VD = cast<VarDecl>(DRE->getDecl()); 1992 QualType Type = VD->getType().getNonReferenceType(); 1993 const DSAStackTy::DSAVarData DVar = 1994 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1995 if (DVar.CKind == OMPC_lastprivate) { 1996 // Generate helper private variable and initialize it with the 1997 // default value. The address of the original variable is replaced 1998 // by the address of the new private variable in CodeGen. This new 1999 // variable is not added to IdResolver, so the code in the OpenMP 2000 // region uses original variable for proper diagnostics. 2001 VarDecl *VDPrivate = buildVarDecl( 2002 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2003 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2004 ActOnUninitializedDecl(VDPrivate); 2005 if (VDPrivate->isInvalidDecl()) { 2006 PrivateCopies.push_back(nullptr); 2007 continue; 2008 } 2009 PrivateCopies.push_back(buildDeclRefExpr( 2010 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2011 } else { 2012 // The variable is also a firstprivate, so initialization sequence 2013 // for private copy is generated already. 2014 PrivateCopies.push_back(nullptr); 2015 } 2016 } 2017 Clause->setPrivateCopies(PrivateCopies); 2018 } 2019 } 2020 // Check allocate clauses. 2021 if (!CurContext->isDependentContext()) 2022 checkAllocateClauses(*this, DSAStack, D->clauses()); 2023 } 2024 2025 DSAStack->pop(); 2026 DiscardCleanupsInEvaluationContext(); 2027 PopExpressionEvaluationContext(); 2028 } 2029 2030 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2031 Expr *NumIterations, Sema &SemaRef, 2032 Scope *S, DSAStackTy *Stack); 2033 2034 namespace { 2035 2036 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2037 private: 2038 Sema &SemaRef; 2039 2040 public: 2041 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2042 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2043 NamedDecl *ND = Candidate.getCorrectionDecl(); 2044 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2045 return VD->hasGlobalStorage() && 2046 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2047 SemaRef.getCurScope()); 2048 } 2049 return false; 2050 } 2051 2052 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2053 return std::make_unique<VarDeclFilterCCC>(*this); 2054 } 2055 2056 }; 2057 2058 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2059 private: 2060 Sema &SemaRef; 2061 2062 public: 2063 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2064 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2065 NamedDecl *ND = Candidate.getCorrectionDecl(); 2066 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2067 isa<FunctionDecl>(ND))) { 2068 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2069 SemaRef.getCurScope()); 2070 } 2071 return false; 2072 } 2073 2074 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2075 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2076 } 2077 }; 2078 2079 } // namespace 2080 2081 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2082 CXXScopeSpec &ScopeSpec, 2083 const DeclarationNameInfo &Id, 2084 OpenMPDirectiveKind Kind) { 2085 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2086 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2087 2088 if (Lookup.isAmbiguous()) 2089 return ExprError(); 2090 2091 VarDecl *VD; 2092 if (!Lookup.isSingleResult()) { 2093 VarDeclFilterCCC CCC(*this); 2094 if (TypoCorrection Corrected = 2095 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2096 CTK_ErrorRecovery)) { 2097 diagnoseTypo(Corrected, 2098 PDiag(Lookup.empty() 2099 ? diag::err_undeclared_var_use_suggest 2100 : diag::err_omp_expected_var_arg_suggest) 2101 << Id.getName()); 2102 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2103 } else { 2104 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2105 : diag::err_omp_expected_var_arg) 2106 << Id.getName(); 2107 return ExprError(); 2108 } 2109 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2110 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2111 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2112 return ExprError(); 2113 } 2114 Lookup.suppressDiagnostics(); 2115 2116 // OpenMP [2.9.2, Syntax, C/C++] 2117 // Variables must be file-scope, namespace-scope, or static block-scope. 2118 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2119 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2120 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2121 bool IsDecl = 2122 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2123 Diag(VD->getLocation(), 2124 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2125 << VD; 2126 return ExprError(); 2127 } 2128 2129 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2130 NamedDecl *ND = CanonicalVD; 2131 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2132 // A threadprivate directive for file-scope variables must appear outside 2133 // any definition or declaration. 2134 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2135 !getCurLexicalContext()->isTranslationUnit()) { 2136 Diag(Id.getLoc(), diag::err_omp_var_scope) 2137 << getOpenMPDirectiveName(Kind) << VD; 2138 bool IsDecl = 2139 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2140 Diag(VD->getLocation(), 2141 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2142 << VD; 2143 return ExprError(); 2144 } 2145 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2146 // A threadprivate directive for static class member variables must appear 2147 // in the class definition, in the same scope in which the member 2148 // variables are declared. 2149 if (CanonicalVD->isStaticDataMember() && 2150 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2151 Diag(Id.getLoc(), diag::err_omp_var_scope) 2152 << getOpenMPDirectiveName(Kind) << VD; 2153 bool IsDecl = 2154 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2155 Diag(VD->getLocation(), 2156 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2157 << VD; 2158 return ExprError(); 2159 } 2160 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2161 // A threadprivate directive for namespace-scope variables must appear 2162 // outside any definition or declaration other than the namespace 2163 // definition itself. 2164 if (CanonicalVD->getDeclContext()->isNamespace() && 2165 (!getCurLexicalContext()->isFileContext() || 2166 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2167 Diag(Id.getLoc(), diag::err_omp_var_scope) 2168 << getOpenMPDirectiveName(Kind) << VD; 2169 bool IsDecl = 2170 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2171 Diag(VD->getLocation(), 2172 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2173 << VD; 2174 return ExprError(); 2175 } 2176 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2177 // A threadprivate directive for static block-scope variables must appear 2178 // in the scope of the variable and not in a nested scope. 2179 if (CanonicalVD->isLocalVarDecl() && CurScope && 2180 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2181 Diag(Id.getLoc(), diag::err_omp_var_scope) 2182 << getOpenMPDirectiveName(Kind) << VD; 2183 bool IsDecl = 2184 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2185 Diag(VD->getLocation(), 2186 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2187 << VD; 2188 return ExprError(); 2189 } 2190 2191 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2192 // A threadprivate directive must lexically precede all references to any 2193 // of the variables in its list. 2194 if (Kind == OMPD_threadprivate && VD->isUsed() && 2195 !DSAStack->isThreadPrivate(VD)) { 2196 Diag(Id.getLoc(), diag::err_omp_var_used) 2197 << getOpenMPDirectiveName(Kind) << VD; 2198 return ExprError(); 2199 } 2200 2201 QualType ExprType = VD->getType().getNonReferenceType(); 2202 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2203 SourceLocation(), VD, 2204 /*RefersToEnclosingVariableOrCapture=*/false, 2205 Id.getLoc(), ExprType, VK_LValue); 2206 } 2207 2208 Sema::DeclGroupPtrTy 2209 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2210 ArrayRef<Expr *> VarList) { 2211 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2212 CurContext->addDecl(D); 2213 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2214 } 2215 return nullptr; 2216 } 2217 2218 namespace { 2219 class LocalVarRefChecker final 2220 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2221 Sema &SemaRef; 2222 2223 public: 2224 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2225 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2226 if (VD->hasLocalStorage()) { 2227 SemaRef.Diag(E->getBeginLoc(), 2228 diag::err_omp_local_var_in_threadprivate_init) 2229 << E->getSourceRange(); 2230 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2231 << VD << VD->getSourceRange(); 2232 return true; 2233 } 2234 } 2235 return false; 2236 } 2237 bool VisitStmt(const Stmt *S) { 2238 for (const Stmt *Child : S->children()) { 2239 if (Child && Visit(Child)) 2240 return true; 2241 } 2242 return false; 2243 } 2244 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2245 }; 2246 } // namespace 2247 2248 OMPThreadPrivateDecl * 2249 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2250 SmallVector<Expr *, 8> Vars; 2251 for (Expr *RefExpr : VarList) { 2252 auto *DE = cast<DeclRefExpr>(RefExpr); 2253 auto *VD = cast<VarDecl>(DE->getDecl()); 2254 SourceLocation ILoc = DE->getExprLoc(); 2255 2256 // Mark variable as used. 2257 VD->setReferenced(); 2258 VD->markUsed(Context); 2259 2260 QualType QType = VD->getType(); 2261 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2262 // It will be analyzed later. 2263 Vars.push_back(DE); 2264 continue; 2265 } 2266 2267 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2268 // A threadprivate variable must not have an incomplete type. 2269 if (RequireCompleteType(ILoc, VD->getType(), 2270 diag::err_omp_threadprivate_incomplete_type)) { 2271 continue; 2272 } 2273 2274 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2275 // A threadprivate variable must not have a reference type. 2276 if (VD->getType()->isReferenceType()) { 2277 Diag(ILoc, diag::err_omp_ref_type_arg) 2278 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2279 bool IsDecl = 2280 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2281 Diag(VD->getLocation(), 2282 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2283 << VD; 2284 continue; 2285 } 2286 2287 // Check if this is a TLS variable. If TLS is not being supported, produce 2288 // the corresponding diagnostic. 2289 if ((VD->getTLSKind() != VarDecl::TLS_None && 2290 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2291 getLangOpts().OpenMPUseTLS && 2292 getASTContext().getTargetInfo().isTLSSupported())) || 2293 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2294 !VD->isLocalVarDecl())) { 2295 Diag(ILoc, diag::err_omp_var_thread_local) 2296 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2297 bool IsDecl = 2298 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2299 Diag(VD->getLocation(), 2300 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2301 << VD; 2302 continue; 2303 } 2304 2305 // Check if initial value of threadprivate variable reference variable with 2306 // local storage (it is not supported by runtime). 2307 if (const Expr *Init = VD->getAnyInitializer()) { 2308 LocalVarRefChecker Checker(*this); 2309 if (Checker.Visit(Init)) 2310 continue; 2311 } 2312 2313 Vars.push_back(RefExpr); 2314 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2315 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2316 Context, SourceRange(Loc, Loc))); 2317 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2318 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2319 } 2320 OMPThreadPrivateDecl *D = nullptr; 2321 if (!Vars.empty()) { 2322 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2323 Vars); 2324 D->setAccess(AS_public); 2325 } 2326 return D; 2327 } 2328 2329 static OMPAllocateDeclAttr::AllocatorTypeTy 2330 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2331 if (!Allocator) 2332 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2333 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2334 Allocator->isInstantiationDependent() || 2335 Allocator->containsUnexpandedParameterPack()) 2336 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2337 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2338 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2339 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2340 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2341 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2342 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2343 llvm::FoldingSetNodeID AEId, DAEId; 2344 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2345 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2346 if (AEId == DAEId) { 2347 AllocatorKindRes = AllocatorKind; 2348 break; 2349 } 2350 } 2351 return AllocatorKindRes; 2352 } 2353 2354 static bool checkPreviousOMPAllocateAttribute( 2355 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2356 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2357 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2358 return false; 2359 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2360 Expr *PrevAllocator = A->getAllocator(); 2361 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2362 getAllocatorKind(S, Stack, PrevAllocator); 2363 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2364 if (AllocatorsMatch && 2365 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2366 Allocator && PrevAllocator) { 2367 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2368 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2369 llvm::FoldingSetNodeID AEId, PAEId; 2370 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2371 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2372 AllocatorsMatch = AEId == PAEId; 2373 } 2374 if (!AllocatorsMatch) { 2375 SmallString<256> AllocatorBuffer; 2376 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2377 if (Allocator) 2378 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2379 SmallString<256> PrevAllocatorBuffer; 2380 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2381 if (PrevAllocator) 2382 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2383 S.getPrintingPolicy()); 2384 2385 SourceLocation AllocatorLoc = 2386 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2387 SourceRange AllocatorRange = 2388 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2389 SourceLocation PrevAllocatorLoc = 2390 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2391 SourceRange PrevAllocatorRange = 2392 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2393 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2394 << (Allocator ? 1 : 0) << AllocatorStream.str() 2395 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2396 << AllocatorRange; 2397 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2398 << PrevAllocatorRange; 2399 return true; 2400 } 2401 return false; 2402 } 2403 2404 static void 2405 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2406 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2407 Expr *Allocator, SourceRange SR) { 2408 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2409 return; 2410 if (Allocator && 2411 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2412 Allocator->isInstantiationDependent() || 2413 Allocator->containsUnexpandedParameterPack())) 2414 return; 2415 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2416 Allocator, SR); 2417 VD->addAttr(A); 2418 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2419 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2420 } 2421 2422 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2423 SourceLocation Loc, ArrayRef<Expr *> VarList, 2424 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2425 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2426 Expr *Allocator = nullptr; 2427 if (Clauses.empty()) { 2428 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2429 // allocate directives that appear in a target region must specify an 2430 // allocator clause unless a requires directive with the dynamic_allocators 2431 // clause is present in the same compilation unit. 2432 if (LangOpts.OpenMPIsDevice && 2433 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2434 targetDiag(Loc, diag::err_expected_allocator_clause); 2435 } else { 2436 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2437 } 2438 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2439 getAllocatorKind(*this, DSAStack, Allocator); 2440 SmallVector<Expr *, 8> Vars; 2441 for (Expr *RefExpr : VarList) { 2442 auto *DE = cast<DeclRefExpr>(RefExpr); 2443 auto *VD = cast<VarDecl>(DE->getDecl()); 2444 2445 // Check if this is a TLS variable or global register. 2446 if (VD->getTLSKind() != VarDecl::TLS_None || 2447 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2448 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2449 !VD->isLocalVarDecl())) 2450 continue; 2451 2452 // If the used several times in the allocate directive, the same allocator 2453 // must be used. 2454 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2455 AllocatorKind, Allocator)) 2456 continue; 2457 2458 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2459 // If a list item has a static storage type, the allocator expression in the 2460 // allocator clause must be a constant expression that evaluates to one of 2461 // the predefined memory allocator values. 2462 if (Allocator && VD->hasGlobalStorage()) { 2463 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2464 Diag(Allocator->getExprLoc(), 2465 diag::err_omp_expected_predefined_allocator) 2466 << Allocator->getSourceRange(); 2467 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2468 VarDecl::DeclarationOnly; 2469 Diag(VD->getLocation(), 2470 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2471 << VD; 2472 continue; 2473 } 2474 } 2475 2476 Vars.push_back(RefExpr); 2477 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2478 DE->getSourceRange()); 2479 } 2480 if (Vars.empty()) 2481 return nullptr; 2482 if (!Owner) 2483 Owner = getCurLexicalContext(); 2484 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2485 D->setAccess(AS_public); 2486 Owner->addDecl(D); 2487 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2488 } 2489 2490 Sema::DeclGroupPtrTy 2491 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2492 ArrayRef<OMPClause *> ClauseList) { 2493 OMPRequiresDecl *D = nullptr; 2494 if (!CurContext->isFileContext()) { 2495 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2496 } else { 2497 D = CheckOMPRequiresDecl(Loc, ClauseList); 2498 if (D) { 2499 CurContext->addDecl(D); 2500 DSAStack->addRequiresDecl(D); 2501 } 2502 } 2503 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2504 } 2505 2506 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2507 ArrayRef<OMPClause *> ClauseList) { 2508 /// For target specific clauses, the requires directive cannot be 2509 /// specified after the handling of any of the target regions in the 2510 /// current compilation unit. 2511 ArrayRef<SourceLocation> TargetLocations = 2512 DSAStack->getEncounteredTargetLocs(); 2513 if (!TargetLocations.empty()) { 2514 for (const OMPClause *CNew : ClauseList) { 2515 // Check if any of the requires clauses affect target regions. 2516 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2517 isa<OMPUnifiedAddressClause>(CNew) || 2518 isa<OMPReverseOffloadClause>(CNew) || 2519 isa<OMPDynamicAllocatorsClause>(CNew)) { 2520 Diag(Loc, diag::err_omp_target_before_requires) 2521 << getOpenMPClauseName(CNew->getClauseKind()); 2522 for (SourceLocation TargetLoc : TargetLocations) { 2523 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2524 } 2525 } 2526 } 2527 } 2528 2529 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2530 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2531 ClauseList); 2532 return nullptr; 2533 } 2534 2535 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2536 const ValueDecl *D, 2537 const DSAStackTy::DSAVarData &DVar, 2538 bool IsLoopIterVar = false) { 2539 if (DVar.RefExpr) { 2540 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2541 << getOpenMPClauseName(DVar.CKind); 2542 return; 2543 } 2544 enum { 2545 PDSA_StaticMemberShared, 2546 PDSA_StaticLocalVarShared, 2547 PDSA_LoopIterVarPrivate, 2548 PDSA_LoopIterVarLinear, 2549 PDSA_LoopIterVarLastprivate, 2550 PDSA_ConstVarShared, 2551 PDSA_GlobalVarShared, 2552 PDSA_TaskVarFirstprivate, 2553 PDSA_LocalVarPrivate, 2554 PDSA_Implicit 2555 } Reason = PDSA_Implicit; 2556 bool ReportHint = false; 2557 auto ReportLoc = D->getLocation(); 2558 auto *VD = dyn_cast<VarDecl>(D); 2559 if (IsLoopIterVar) { 2560 if (DVar.CKind == OMPC_private) 2561 Reason = PDSA_LoopIterVarPrivate; 2562 else if (DVar.CKind == OMPC_lastprivate) 2563 Reason = PDSA_LoopIterVarLastprivate; 2564 else 2565 Reason = PDSA_LoopIterVarLinear; 2566 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2567 DVar.CKind == OMPC_firstprivate) { 2568 Reason = PDSA_TaskVarFirstprivate; 2569 ReportLoc = DVar.ImplicitDSALoc; 2570 } else if (VD && VD->isStaticLocal()) 2571 Reason = PDSA_StaticLocalVarShared; 2572 else if (VD && VD->isStaticDataMember()) 2573 Reason = PDSA_StaticMemberShared; 2574 else if (VD && VD->isFileVarDecl()) 2575 Reason = PDSA_GlobalVarShared; 2576 else if (D->getType().isConstant(SemaRef.getASTContext())) 2577 Reason = PDSA_ConstVarShared; 2578 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2579 ReportHint = true; 2580 Reason = PDSA_LocalVarPrivate; 2581 } 2582 if (Reason != PDSA_Implicit) { 2583 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2584 << Reason << ReportHint 2585 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2586 } else if (DVar.ImplicitDSALoc.isValid()) { 2587 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2588 << getOpenMPClauseName(DVar.CKind); 2589 } 2590 } 2591 2592 namespace { 2593 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2594 DSAStackTy *Stack; 2595 Sema &SemaRef; 2596 bool ErrorFound = false; 2597 CapturedStmt *CS = nullptr; 2598 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2599 llvm::SmallVector<Expr *, 4> ImplicitMap; 2600 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2601 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2602 2603 void VisitSubCaptures(OMPExecutableDirective *S) { 2604 // Check implicitly captured variables. 2605 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2606 return; 2607 visitSubCaptures(S->getInnermostCapturedStmt()); 2608 } 2609 2610 public: 2611 void VisitDeclRefExpr(DeclRefExpr *E) { 2612 if (E->isTypeDependent() || E->isValueDependent() || 2613 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2614 return; 2615 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2616 // Check the datasharing rules for the expressions in the clauses. 2617 if (!CS) { 2618 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2619 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2620 Visit(CED->getInit()); 2621 return; 2622 } 2623 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2624 // Do not analyze internal variables and do not enclose them into 2625 // implicit clauses. 2626 return; 2627 VD = VD->getCanonicalDecl(); 2628 // Skip internally declared variables. 2629 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2630 return; 2631 2632 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2633 // Check if the variable has explicit DSA set and stop analysis if it so. 2634 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2635 return; 2636 2637 // Skip internally declared static variables. 2638 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2639 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2640 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2641 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2642 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2643 return; 2644 2645 SourceLocation ELoc = E->getExprLoc(); 2646 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2647 // The default(none) clause requires that each variable that is referenced 2648 // in the construct, and does not have a predetermined data-sharing 2649 // attribute, must have its data-sharing attribute explicitly determined 2650 // by being listed in a data-sharing attribute clause. 2651 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2652 isImplicitOrExplicitTaskingRegion(DKind) && 2653 VarsWithInheritedDSA.count(VD) == 0) { 2654 VarsWithInheritedDSA[VD] = E; 2655 return; 2656 } 2657 2658 if (isOpenMPTargetExecutionDirective(DKind) && 2659 !Stack->isLoopControlVariable(VD).first) { 2660 if (!Stack->checkMappableExprComponentListsForDecl( 2661 VD, /*CurrentRegionOnly=*/true, 2662 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2663 StackComponents, 2664 OpenMPClauseKind) { 2665 // Variable is used if it has been marked as an array, array 2666 // section or the variable iself. 2667 return StackComponents.size() == 1 || 2668 std::all_of( 2669 std::next(StackComponents.rbegin()), 2670 StackComponents.rend(), 2671 [](const OMPClauseMappableExprCommon:: 2672 MappableComponent &MC) { 2673 return MC.getAssociatedDeclaration() == 2674 nullptr && 2675 (isa<OMPArraySectionExpr>( 2676 MC.getAssociatedExpression()) || 2677 isa<ArraySubscriptExpr>( 2678 MC.getAssociatedExpression())); 2679 }); 2680 })) { 2681 bool IsFirstprivate = false; 2682 // By default lambdas are captured as firstprivates. 2683 if (const auto *RD = 2684 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2685 IsFirstprivate = RD->isLambda(); 2686 IsFirstprivate = 2687 IsFirstprivate || 2688 (VD->getType().getNonReferenceType()->isScalarType() && 2689 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2690 if (IsFirstprivate) 2691 ImplicitFirstprivate.emplace_back(E); 2692 else 2693 ImplicitMap.emplace_back(E); 2694 return; 2695 } 2696 } 2697 2698 // OpenMP [2.9.3.6, Restrictions, p.2] 2699 // A list item that appears in a reduction clause of the innermost 2700 // enclosing worksharing or parallel construct may not be accessed in an 2701 // explicit task. 2702 DVar = Stack->hasInnermostDSA( 2703 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2704 [](OpenMPDirectiveKind K) { 2705 return isOpenMPParallelDirective(K) || 2706 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2707 }, 2708 /*FromParent=*/true); 2709 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2710 ErrorFound = true; 2711 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2712 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2713 return; 2714 } 2715 2716 // Define implicit data-sharing attributes for task. 2717 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2718 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2719 !Stack->isLoopControlVariable(VD).first) { 2720 ImplicitFirstprivate.push_back(E); 2721 return; 2722 } 2723 2724 // Store implicitly used globals with declare target link for parent 2725 // target. 2726 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2727 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2728 Stack->addToParentTargetRegionLinkGlobals(E); 2729 return; 2730 } 2731 } 2732 } 2733 void VisitMemberExpr(MemberExpr *E) { 2734 if (E->isTypeDependent() || E->isValueDependent() || 2735 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2736 return; 2737 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2738 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2739 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2740 if (!FD) 2741 return; 2742 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2743 // Check if the variable has explicit DSA set and stop analysis if it 2744 // so. 2745 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2746 return; 2747 2748 if (isOpenMPTargetExecutionDirective(DKind) && 2749 !Stack->isLoopControlVariable(FD).first && 2750 !Stack->checkMappableExprComponentListsForDecl( 2751 FD, /*CurrentRegionOnly=*/true, 2752 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2753 StackComponents, 2754 OpenMPClauseKind) { 2755 return isa<CXXThisExpr>( 2756 cast<MemberExpr>( 2757 StackComponents.back().getAssociatedExpression()) 2758 ->getBase() 2759 ->IgnoreParens()); 2760 })) { 2761 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2762 // A bit-field cannot appear in a map clause. 2763 // 2764 if (FD->isBitField()) 2765 return; 2766 2767 // Check to see if the member expression is referencing a class that 2768 // has already been explicitly mapped 2769 if (Stack->isClassPreviouslyMapped(TE->getType())) 2770 return; 2771 2772 ImplicitMap.emplace_back(E); 2773 return; 2774 } 2775 2776 SourceLocation ELoc = E->getExprLoc(); 2777 // OpenMP [2.9.3.6, Restrictions, p.2] 2778 // A list item that appears in a reduction clause of the innermost 2779 // enclosing worksharing or parallel construct may not be accessed in 2780 // an explicit task. 2781 DVar = Stack->hasInnermostDSA( 2782 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2783 [](OpenMPDirectiveKind K) { 2784 return isOpenMPParallelDirective(K) || 2785 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2786 }, 2787 /*FromParent=*/true); 2788 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2789 ErrorFound = true; 2790 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2791 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2792 return; 2793 } 2794 2795 // Define implicit data-sharing attributes for task. 2796 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2797 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2798 !Stack->isLoopControlVariable(FD).first) { 2799 // Check if there is a captured expression for the current field in the 2800 // region. Do not mark it as firstprivate unless there is no captured 2801 // expression. 2802 // TODO: try to make it firstprivate. 2803 if (DVar.CKind != OMPC_unknown) 2804 ImplicitFirstprivate.push_back(E); 2805 } 2806 return; 2807 } 2808 if (isOpenMPTargetExecutionDirective(DKind)) { 2809 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2810 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2811 /*NoDiagnose=*/true)) 2812 return; 2813 const auto *VD = cast<ValueDecl>( 2814 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2815 if (!Stack->checkMappableExprComponentListsForDecl( 2816 VD, /*CurrentRegionOnly=*/true, 2817 [&CurComponents]( 2818 OMPClauseMappableExprCommon::MappableExprComponentListRef 2819 StackComponents, 2820 OpenMPClauseKind) { 2821 auto CCI = CurComponents.rbegin(); 2822 auto CCE = CurComponents.rend(); 2823 for (const auto &SC : llvm::reverse(StackComponents)) { 2824 // Do both expressions have the same kind? 2825 if (CCI->getAssociatedExpression()->getStmtClass() != 2826 SC.getAssociatedExpression()->getStmtClass()) 2827 if (!(isa<OMPArraySectionExpr>( 2828 SC.getAssociatedExpression()) && 2829 isa<ArraySubscriptExpr>( 2830 CCI->getAssociatedExpression()))) 2831 return false; 2832 2833 const Decl *CCD = CCI->getAssociatedDeclaration(); 2834 const Decl *SCD = SC.getAssociatedDeclaration(); 2835 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2836 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2837 if (SCD != CCD) 2838 return false; 2839 std::advance(CCI, 1); 2840 if (CCI == CCE) 2841 break; 2842 } 2843 return true; 2844 })) { 2845 Visit(E->getBase()); 2846 } 2847 } else { 2848 Visit(E->getBase()); 2849 } 2850 } 2851 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2852 for (OMPClause *C : S->clauses()) { 2853 // Skip analysis of arguments of implicitly defined firstprivate clause 2854 // for task|target directives. 2855 // Skip analysis of arguments of implicitly defined map clause for target 2856 // directives. 2857 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2858 C->isImplicit())) { 2859 for (Stmt *CC : C->children()) { 2860 if (CC) 2861 Visit(CC); 2862 } 2863 } 2864 } 2865 // Check implicitly captured variables. 2866 VisitSubCaptures(S); 2867 } 2868 void VisitStmt(Stmt *S) { 2869 for (Stmt *C : S->children()) { 2870 if (C) { 2871 // Check implicitly captured variables in the task-based directives to 2872 // check if they must be firstprivatized. 2873 Visit(C); 2874 } 2875 } 2876 } 2877 2878 void visitSubCaptures(CapturedStmt *S) { 2879 for (const CapturedStmt::Capture &Cap : S->captures()) { 2880 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 2881 continue; 2882 VarDecl *VD = Cap.getCapturedVar(); 2883 // Do not try to map the variable if it or its sub-component was mapped 2884 // already. 2885 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2886 Stack->checkMappableExprComponentListsForDecl( 2887 VD, /*CurrentRegionOnly=*/true, 2888 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2889 OpenMPClauseKind) { return true; })) 2890 continue; 2891 DeclRefExpr *DRE = buildDeclRefExpr( 2892 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2893 Cap.getLocation(), /*RefersToCapture=*/true); 2894 Visit(DRE); 2895 } 2896 } 2897 bool isErrorFound() const { return ErrorFound; } 2898 ArrayRef<Expr *> getImplicitFirstprivate() const { 2899 return ImplicitFirstprivate; 2900 } 2901 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2902 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2903 return VarsWithInheritedDSA; 2904 } 2905 2906 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2907 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2908 // Process declare target link variables for the target directives. 2909 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2910 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2911 Visit(E); 2912 } 2913 } 2914 }; 2915 } // namespace 2916 2917 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2918 switch (DKind) { 2919 case OMPD_parallel: 2920 case OMPD_parallel_for: 2921 case OMPD_parallel_for_simd: 2922 case OMPD_parallel_sections: 2923 case OMPD_teams: 2924 case OMPD_teams_distribute: 2925 case OMPD_teams_distribute_simd: { 2926 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2927 QualType KmpInt32PtrTy = 2928 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2929 Sema::CapturedParamNameType Params[] = { 2930 std::make_pair(".global_tid.", KmpInt32PtrTy), 2931 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2932 std::make_pair(StringRef(), QualType()) // __context with shared vars 2933 }; 2934 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2935 Params); 2936 break; 2937 } 2938 case OMPD_target_teams: 2939 case OMPD_target_parallel: 2940 case OMPD_target_parallel_for: 2941 case OMPD_target_parallel_for_simd: 2942 case OMPD_target_teams_distribute: 2943 case OMPD_target_teams_distribute_simd: { 2944 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2945 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2946 QualType KmpInt32PtrTy = 2947 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2948 QualType Args[] = {VoidPtrTy}; 2949 FunctionProtoType::ExtProtoInfo EPI; 2950 EPI.Variadic = true; 2951 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2952 Sema::CapturedParamNameType Params[] = { 2953 std::make_pair(".global_tid.", KmpInt32Ty), 2954 std::make_pair(".part_id.", KmpInt32PtrTy), 2955 std::make_pair(".privates.", VoidPtrTy), 2956 std::make_pair( 2957 ".copy_fn.", 2958 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2959 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2960 std::make_pair(StringRef(), QualType()) // __context with shared vars 2961 }; 2962 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2963 Params); 2964 // Mark this captured region as inlined, because we don't use outlined 2965 // function directly. 2966 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2967 AlwaysInlineAttr::CreateImplicit( 2968 Context, AlwaysInlineAttr::Keyword_forceinline)); 2969 Sema::CapturedParamNameType ParamsTarget[] = { 2970 std::make_pair(StringRef(), QualType()) // __context with shared vars 2971 }; 2972 // Start a captured region for 'target' with no implicit parameters. 2973 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2974 ParamsTarget); 2975 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2976 std::make_pair(".global_tid.", KmpInt32PtrTy), 2977 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2978 std::make_pair(StringRef(), QualType()) // __context with shared vars 2979 }; 2980 // Start a captured region for 'teams' or 'parallel'. Both regions have 2981 // the same implicit parameters. 2982 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2983 ParamsTeamsOrParallel); 2984 break; 2985 } 2986 case OMPD_target: 2987 case OMPD_target_simd: { 2988 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2989 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2990 QualType KmpInt32PtrTy = 2991 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2992 QualType Args[] = {VoidPtrTy}; 2993 FunctionProtoType::ExtProtoInfo EPI; 2994 EPI.Variadic = true; 2995 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2996 Sema::CapturedParamNameType Params[] = { 2997 std::make_pair(".global_tid.", KmpInt32Ty), 2998 std::make_pair(".part_id.", KmpInt32PtrTy), 2999 std::make_pair(".privates.", VoidPtrTy), 3000 std::make_pair( 3001 ".copy_fn.", 3002 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3003 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3004 std::make_pair(StringRef(), QualType()) // __context with shared vars 3005 }; 3006 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3007 Params); 3008 // Mark this captured region as inlined, because we don't use outlined 3009 // function directly. 3010 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3011 AlwaysInlineAttr::CreateImplicit( 3012 Context, AlwaysInlineAttr::Keyword_forceinline)); 3013 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3014 std::make_pair(StringRef(), QualType())); 3015 break; 3016 } 3017 case OMPD_simd: 3018 case OMPD_for: 3019 case OMPD_for_simd: 3020 case OMPD_sections: 3021 case OMPD_section: 3022 case OMPD_single: 3023 case OMPD_master: 3024 case OMPD_critical: 3025 case OMPD_taskgroup: 3026 case OMPD_distribute: 3027 case OMPD_distribute_simd: 3028 case OMPD_ordered: 3029 case OMPD_atomic: 3030 case OMPD_target_data: { 3031 Sema::CapturedParamNameType Params[] = { 3032 std::make_pair(StringRef(), QualType()) // __context with shared vars 3033 }; 3034 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3035 Params); 3036 break; 3037 } 3038 case OMPD_task: { 3039 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3040 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3041 QualType KmpInt32PtrTy = 3042 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3043 QualType Args[] = {VoidPtrTy}; 3044 FunctionProtoType::ExtProtoInfo EPI; 3045 EPI.Variadic = true; 3046 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3047 Sema::CapturedParamNameType Params[] = { 3048 std::make_pair(".global_tid.", KmpInt32Ty), 3049 std::make_pair(".part_id.", KmpInt32PtrTy), 3050 std::make_pair(".privates.", VoidPtrTy), 3051 std::make_pair( 3052 ".copy_fn.", 3053 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3054 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3055 std::make_pair(StringRef(), QualType()) // __context with shared vars 3056 }; 3057 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3058 Params); 3059 // Mark this captured region as inlined, because we don't use outlined 3060 // function directly. 3061 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3062 AlwaysInlineAttr::CreateImplicit( 3063 Context, AlwaysInlineAttr::Keyword_forceinline)); 3064 break; 3065 } 3066 case OMPD_taskloop: 3067 case OMPD_taskloop_simd: { 3068 QualType KmpInt32Ty = 3069 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3070 .withConst(); 3071 QualType KmpUInt64Ty = 3072 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3073 .withConst(); 3074 QualType KmpInt64Ty = 3075 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3076 .withConst(); 3077 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3078 QualType KmpInt32PtrTy = 3079 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3080 QualType Args[] = {VoidPtrTy}; 3081 FunctionProtoType::ExtProtoInfo EPI; 3082 EPI.Variadic = true; 3083 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3084 Sema::CapturedParamNameType Params[] = { 3085 std::make_pair(".global_tid.", KmpInt32Ty), 3086 std::make_pair(".part_id.", KmpInt32PtrTy), 3087 std::make_pair(".privates.", VoidPtrTy), 3088 std::make_pair( 3089 ".copy_fn.", 3090 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3091 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3092 std::make_pair(".lb.", KmpUInt64Ty), 3093 std::make_pair(".ub.", KmpUInt64Ty), 3094 std::make_pair(".st.", KmpInt64Ty), 3095 std::make_pair(".liter.", KmpInt32Ty), 3096 std::make_pair(".reductions.", VoidPtrTy), 3097 std::make_pair(StringRef(), QualType()) // __context with shared vars 3098 }; 3099 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3100 Params); 3101 // Mark this captured region as inlined, because we don't use outlined 3102 // function directly. 3103 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3104 AlwaysInlineAttr::CreateImplicit( 3105 Context, AlwaysInlineAttr::Keyword_forceinline)); 3106 break; 3107 } 3108 case OMPD_distribute_parallel_for_simd: 3109 case OMPD_distribute_parallel_for: { 3110 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3111 QualType KmpInt32PtrTy = 3112 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3113 Sema::CapturedParamNameType Params[] = { 3114 std::make_pair(".global_tid.", KmpInt32PtrTy), 3115 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3116 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3117 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3118 std::make_pair(StringRef(), QualType()) // __context with shared vars 3119 }; 3120 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3121 Params); 3122 break; 3123 } 3124 case OMPD_target_teams_distribute_parallel_for: 3125 case OMPD_target_teams_distribute_parallel_for_simd: { 3126 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3127 QualType KmpInt32PtrTy = 3128 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3129 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3130 3131 QualType Args[] = {VoidPtrTy}; 3132 FunctionProtoType::ExtProtoInfo EPI; 3133 EPI.Variadic = true; 3134 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3135 Sema::CapturedParamNameType Params[] = { 3136 std::make_pair(".global_tid.", KmpInt32Ty), 3137 std::make_pair(".part_id.", KmpInt32PtrTy), 3138 std::make_pair(".privates.", VoidPtrTy), 3139 std::make_pair( 3140 ".copy_fn.", 3141 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3142 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3143 std::make_pair(StringRef(), QualType()) // __context with shared vars 3144 }; 3145 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3146 Params); 3147 // Mark this captured region as inlined, because we don't use outlined 3148 // function directly. 3149 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3150 AlwaysInlineAttr::CreateImplicit( 3151 Context, AlwaysInlineAttr::Keyword_forceinline)); 3152 Sema::CapturedParamNameType ParamsTarget[] = { 3153 std::make_pair(StringRef(), QualType()) // __context with shared vars 3154 }; 3155 // Start a captured region for 'target' with no implicit parameters. 3156 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3157 ParamsTarget); 3158 3159 Sema::CapturedParamNameType ParamsTeams[] = { 3160 std::make_pair(".global_tid.", KmpInt32PtrTy), 3161 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3162 std::make_pair(StringRef(), QualType()) // __context with shared vars 3163 }; 3164 // Start a captured region for 'target' with no implicit parameters. 3165 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3166 ParamsTeams); 3167 3168 Sema::CapturedParamNameType ParamsParallel[] = { 3169 std::make_pair(".global_tid.", KmpInt32PtrTy), 3170 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3171 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3172 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3173 std::make_pair(StringRef(), QualType()) // __context with shared vars 3174 }; 3175 // Start a captured region for 'teams' or 'parallel'. Both regions have 3176 // the same implicit parameters. 3177 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3178 ParamsParallel); 3179 break; 3180 } 3181 3182 case OMPD_teams_distribute_parallel_for: 3183 case OMPD_teams_distribute_parallel_for_simd: { 3184 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3185 QualType KmpInt32PtrTy = 3186 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3187 3188 Sema::CapturedParamNameType ParamsTeams[] = { 3189 std::make_pair(".global_tid.", KmpInt32PtrTy), 3190 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3191 std::make_pair(StringRef(), QualType()) // __context with shared vars 3192 }; 3193 // Start a captured region for 'target' with no implicit parameters. 3194 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3195 ParamsTeams); 3196 3197 Sema::CapturedParamNameType ParamsParallel[] = { 3198 std::make_pair(".global_tid.", KmpInt32PtrTy), 3199 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3200 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3201 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3202 std::make_pair(StringRef(), QualType()) // __context with shared vars 3203 }; 3204 // Start a captured region for 'teams' or 'parallel'. Both regions have 3205 // the same implicit parameters. 3206 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3207 ParamsParallel); 3208 break; 3209 } 3210 case OMPD_target_update: 3211 case OMPD_target_enter_data: 3212 case OMPD_target_exit_data: { 3213 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3214 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3215 QualType KmpInt32PtrTy = 3216 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3217 QualType Args[] = {VoidPtrTy}; 3218 FunctionProtoType::ExtProtoInfo EPI; 3219 EPI.Variadic = true; 3220 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3221 Sema::CapturedParamNameType Params[] = { 3222 std::make_pair(".global_tid.", KmpInt32Ty), 3223 std::make_pair(".part_id.", KmpInt32PtrTy), 3224 std::make_pair(".privates.", VoidPtrTy), 3225 std::make_pair( 3226 ".copy_fn.", 3227 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3228 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3229 std::make_pair(StringRef(), QualType()) // __context with shared vars 3230 }; 3231 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3232 Params); 3233 // Mark this captured region as inlined, because we don't use outlined 3234 // function directly. 3235 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3236 AlwaysInlineAttr::CreateImplicit( 3237 Context, AlwaysInlineAttr::Keyword_forceinline)); 3238 break; 3239 } 3240 case OMPD_threadprivate: 3241 case OMPD_allocate: 3242 case OMPD_taskyield: 3243 case OMPD_barrier: 3244 case OMPD_taskwait: 3245 case OMPD_cancellation_point: 3246 case OMPD_cancel: 3247 case OMPD_flush: 3248 case OMPD_declare_reduction: 3249 case OMPD_declare_mapper: 3250 case OMPD_declare_simd: 3251 case OMPD_declare_target: 3252 case OMPD_end_declare_target: 3253 case OMPD_requires: 3254 llvm_unreachable("OpenMP Directive is not allowed"); 3255 case OMPD_unknown: 3256 llvm_unreachable("Unknown OpenMP directive"); 3257 } 3258 } 3259 3260 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3261 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3262 getOpenMPCaptureRegions(CaptureRegions, DKind); 3263 return CaptureRegions.size(); 3264 } 3265 3266 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3267 Expr *CaptureExpr, bool WithInit, 3268 bool AsExpression) { 3269 assert(CaptureExpr); 3270 ASTContext &C = S.getASTContext(); 3271 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3272 QualType Ty = Init->getType(); 3273 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3274 if (S.getLangOpts().CPlusPlus) { 3275 Ty = C.getLValueReferenceType(Ty); 3276 } else { 3277 Ty = C.getPointerType(Ty); 3278 ExprResult Res = 3279 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3280 if (!Res.isUsable()) 3281 return nullptr; 3282 Init = Res.get(); 3283 } 3284 WithInit = true; 3285 } 3286 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3287 CaptureExpr->getBeginLoc()); 3288 if (!WithInit) 3289 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3290 S.CurContext->addHiddenDecl(CED); 3291 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3292 return CED; 3293 } 3294 3295 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3296 bool WithInit) { 3297 OMPCapturedExprDecl *CD; 3298 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3299 CD = cast<OMPCapturedExprDecl>(VD); 3300 else 3301 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3302 /*AsExpression=*/false); 3303 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3304 CaptureExpr->getExprLoc()); 3305 } 3306 3307 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3308 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3309 if (!Ref) { 3310 OMPCapturedExprDecl *CD = buildCaptureDecl( 3311 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3312 /*WithInit=*/true, /*AsExpression=*/true); 3313 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3314 CaptureExpr->getExprLoc()); 3315 } 3316 ExprResult Res = Ref; 3317 if (!S.getLangOpts().CPlusPlus && 3318 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3319 Ref->getType()->isPointerType()) { 3320 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3321 if (!Res.isUsable()) 3322 return ExprError(); 3323 } 3324 return S.DefaultLvalueConversion(Res.get()); 3325 } 3326 3327 namespace { 3328 // OpenMP directives parsed in this section are represented as a 3329 // CapturedStatement with an associated statement. If a syntax error 3330 // is detected during the parsing of the associated statement, the 3331 // compiler must abort processing and close the CapturedStatement. 3332 // 3333 // Combined directives such as 'target parallel' have more than one 3334 // nested CapturedStatements. This RAII ensures that we unwind out 3335 // of all the nested CapturedStatements when an error is found. 3336 class CaptureRegionUnwinderRAII { 3337 private: 3338 Sema &S; 3339 bool &ErrorFound; 3340 OpenMPDirectiveKind DKind = OMPD_unknown; 3341 3342 public: 3343 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3344 OpenMPDirectiveKind DKind) 3345 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3346 ~CaptureRegionUnwinderRAII() { 3347 if (ErrorFound) { 3348 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3349 while (--ThisCaptureLevel >= 0) 3350 S.ActOnCapturedRegionError(); 3351 } 3352 } 3353 }; 3354 } // namespace 3355 3356 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3357 // Capture variables captured by reference in lambdas for target-based 3358 // directives. 3359 if (!CurContext->isDependentContext() && 3360 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3361 isOpenMPTargetDataManagementDirective( 3362 DSAStack->getCurrentDirective()))) { 3363 QualType Type = V->getType(); 3364 if (const auto *RD = Type.getCanonicalType() 3365 .getNonReferenceType() 3366 ->getAsCXXRecordDecl()) { 3367 bool SavedForceCaptureByReferenceInTargetExecutable = 3368 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3369 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3370 /*V=*/true); 3371 if (RD->isLambda()) { 3372 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3373 FieldDecl *ThisCapture; 3374 RD->getCaptureFields(Captures, ThisCapture); 3375 for (const LambdaCapture &LC : RD->captures()) { 3376 if (LC.getCaptureKind() == LCK_ByRef) { 3377 VarDecl *VD = LC.getCapturedVar(); 3378 DeclContext *VDC = VD->getDeclContext(); 3379 if (!VDC->Encloses(CurContext)) 3380 continue; 3381 MarkVariableReferenced(LC.getLocation(), VD); 3382 } else if (LC.getCaptureKind() == LCK_This) { 3383 QualType ThisTy = getCurrentThisType(); 3384 if (!ThisTy.isNull() && 3385 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3386 CheckCXXThisCapture(LC.getLocation()); 3387 } 3388 } 3389 } 3390 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3391 SavedForceCaptureByReferenceInTargetExecutable); 3392 } 3393 } 3394 } 3395 3396 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3397 ArrayRef<OMPClause *> Clauses) { 3398 bool ErrorFound = false; 3399 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3400 *this, ErrorFound, DSAStack->getCurrentDirective()); 3401 if (!S.isUsable()) { 3402 ErrorFound = true; 3403 return StmtError(); 3404 } 3405 3406 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3407 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3408 OMPOrderedClause *OC = nullptr; 3409 OMPScheduleClause *SC = nullptr; 3410 SmallVector<const OMPLinearClause *, 4> LCs; 3411 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3412 // This is required for proper codegen. 3413 for (OMPClause *Clause : Clauses) { 3414 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3415 Clause->getClauseKind() == OMPC_in_reduction) { 3416 // Capture taskgroup task_reduction descriptors inside the tasking regions 3417 // with the corresponding in_reduction items. 3418 auto *IRC = cast<OMPInReductionClause>(Clause); 3419 for (Expr *E : IRC->taskgroup_descriptors()) 3420 if (E) 3421 MarkDeclarationsReferencedInExpr(E); 3422 } 3423 if (isOpenMPPrivate(Clause->getClauseKind()) || 3424 Clause->getClauseKind() == OMPC_copyprivate || 3425 (getLangOpts().OpenMPUseTLS && 3426 getASTContext().getTargetInfo().isTLSSupported() && 3427 Clause->getClauseKind() == OMPC_copyin)) { 3428 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3429 // Mark all variables in private list clauses as used in inner region. 3430 for (Stmt *VarRef : Clause->children()) { 3431 if (auto *E = cast_or_null<Expr>(VarRef)) { 3432 MarkDeclarationsReferencedInExpr(E); 3433 } 3434 } 3435 DSAStack->setForceVarCapturing(/*V=*/false); 3436 } else if (CaptureRegions.size() > 1 || 3437 CaptureRegions.back() != OMPD_unknown) { 3438 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3439 PICs.push_back(C); 3440 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3441 if (Expr *E = C->getPostUpdateExpr()) 3442 MarkDeclarationsReferencedInExpr(E); 3443 } 3444 } 3445 if (Clause->getClauseKind() == OMPC_schedule) 3446 SC = cast<OMPScheduleClause>(Clause); 3447 else if (Clause->getClauseKind() == OMPC_ordered) 3448 OC = cast<OMPOrderedClause>(Clause); 3449 else if (Clause->getClauseKind() == OMPC_linear) 3450 LCs.push_back(cast<OMPLinearClause>(Clause)); 3451 } 3452 // OpenMP, 2.7.1 Loop Construct, Restrictions 3453 // The nonmonotonic modifier cannot be specified if an ordered clause is 3454 // specified. 3455 if (SC && 3456 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3457 SC->getSecondScheduleModifier() == 3458 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3459 OC) { 3460 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3461 ? SC->getFirstScheduleModifierLoc() 3462 : SC->getSecondScheduleModifierLoc(), 3463 diag::err_omp_schedule_nonmonotonic_ordered) 3464 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3465 ErrorFound = true; 3466 } 3467 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3468 for (const OMPLinearClause *C : LCs) { 3469 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3470 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3471 } 3472 ErrorFound = true; 3473 } 3474 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3475 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3476 OC->getNumForLoops()) { 3477 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3478 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3479 ErrorFound = true; 3480 } 3481 if (ErrorFound) { 3482 return StmtError(); 3483 } 3484 StmtResult SR = S; 3485 unsigned CompletedRegions = 0; 3486 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3487 // Mark all variables in private list clauses as used in inner region. 3488 // Required for proper codegen of combined directives. 3489 // TODO: add processing for other clauses. 3490 if (ThisCaptureRegion != OMPD_unknown) { 3491 for (const clang::OMPClauseWithPreInit *C : PICs) { 3492 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3493 // Find the particular capture region for the clause if the 3494 // directive is a combined one with multiple capture regions. 3495 // If the directive is not a combined one, the capture region 3496 // associated with the clause is OMPD_unknown and is generated 3497 // only once. 3498 if (CaptureRegion == ThisCaptureRegion || 3499 CaptureRegion == OMPD_unknown) { 3500 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3501 for (Decl *D : DS->decls()) 3502 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3503 } 3504 } 3505 } 3506 } 3507 if (++CompletedRegions == CaptureRegions.size()) 3508 DSAStack->setBodyComplete(); 3509 SR = ActOnCapturedRegionEnd(SR.get()); 3510 } 3511 return SR; 3512 } 3513 3514 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3515 OpenMPDirectiveKind CancelRegion, 3516 SourceLocation StartLoc) { 3517 // CancelRegion is only needed for cancel and cancellation_point. 3518 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3519 return false; 3520 3521 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3522 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3523 return false; 3524 3525 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3526 << getOpenMPDirectiveName(CancelRegion); 3527 return true; 3528 } 3529 3530 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3531 OpenMPDirectiveKind CurrentRegion, 3532 const DeclarationNameInfo &CurrentName, 3533 OpenMPDirectiveKind CancelRegion, 3534 SourceLocation StartLoc) { 3535 if (Stack->getCurScope()) { 3536 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3537 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3538 bool NestingProhibited = false; 3539 bool CloseNesting = true; 3540 bool OrphanSeen = false; 3541 enum { 3542 NoRecommend, 3543 ShouldBeInParallelRegion, 3544 ShouldBeInOrderedRegion, 3545 ShouldBeInTargetRegion, 3546 ShouldBeInTeamsRegion 3547 } Recommend = NoRecommend; 3548 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3549 // OpenMP [2.16, Nesting of Regions] 3550 // OpenMP constructs may not be nested inside a simd region. 3551 // OpenMP [2.8.1,simd Construct, Restrictions] 3552 // An ordered construct with the simd clause is the only OpenMP 3553 // construct that can appear in the simd region. 3554 // Allowing a SIMD construct nested in another SIMD construct is an 3555 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3556 // message. 3557 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3558 ? diag::err_omp_prohibited_region_simd 3559 : diag::warn_omp_nesting_simd); 3560 return CurrentRegion != OMPD_simd; 3561 } 3562 if (ParentRegion == OMPD_atomic) { 3563 // OpenMP [2.16, Nesting of Regions] 3564 // OpenMP constructs may not be nested inside an atomic region. 3565 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3566 return true; 3567 } 3568 if (CurrentRegion == OMPD_section) { 3569 // OpenMP [2.7.2, sections Construct, Restrictions] 3570 // Orphaned section directives are prohibited. That is, the section 3571 // directives must appear within the sections construct and must not be 3572 // encountered elsewhere in the sections region. 3573 if (ParentRegion != OMPD_sections && 3574 ParentRegion != OMPD_parallel_sections) { 3575 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3576 << (ParentRegion != OMPD_unknown) 3577 << getOpenMPDirectiveName(ParentRegion); 3578 return true; 3579 } 3580 return false; 3581 } 3582 // Allow some constructs (except teams and cancellation constructs) to be 3583 // orphaned (they could be used in functions, called from OpenMP regions 3584 // with the required preconditions). 3585 if (ParentRegion == OMPD_unknown && 3586 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3587 CurrentRegion != OMPD_cancellation_point && 3588 CurrentRegion != OMPD_cancel) 3589 return false; 3590 if (CurrentRegion == OMPD_cancellation_point || 3591 CurrentRegion == OMPD_cancel) { 3592 // OpenMP [2.16, Nesting of Regions] 3593 // A cancellation point construct for which construct-type-clause is 3594 // taskgroup must be nested inside a task construct. A cancellation 3595 // point construct for which construct-type-clause is not taskgroup must 3596 // be closely nested inside an OpenMP construct that matches the type 3597 // specified in construct-type-clause. 3598 // A cancel construct for which construct-type-clause is taskgroup must be 3599 // nested inside a task construct. A cancel construct for which 3600 // construct-type-clause is not taskgroup must be closely nested inside an 3601 // OpenMP construct that matches the type specified in 3602 // construct-type-clause. 3603 NestingProhibited = 3604 !((CancelRegion == OMPD_parallel && 3605 (ParentRegion == OMPD_parallel || 3606 ParentRegion == OMPD_target_parallel)) || 3607 (CancelRegion == OMPD_for && 3608 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3609 ParentRegion == OMPD_target_parallel_for || 3610 ParentRegion == OMPD_distribute_parallel_for || 3611 ParentRegion == OMPD_teams_distribute_parallel_for || 3612 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3613 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3614 (CancelRegion == OMPD_sections && 3615 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3616 ParentRegion == OMPD_parallel_sections))); 3617 OrphanSeen = ParentRegion == OMPD_unknown; 3618 } else if (CurrentRegion == OMPD_master) { 3619 // OpenMP [2.16, Nesting of Regions] 3620 // A master region may not be closely nested inside a worksharing, 3621 // atomic, or explicit task region. 3622 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3623 isOpenMPTaskingDirective(ParentRegion); 3624 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3625 // OpenMP [2.16, Nesting of Regions] 3626 // A critical region may not be nested (closely or otherwise) inside a 3627 // critical region with the same name. Note that this restriction is not 3628 // sufficient to prevent deadlock. 3629 SourceLocation PreviousCriticalLoc; 3630 bool DeadLock = Stack->hasDirective( 3631 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3632 const DeclarationNameInfo &DNI, 3633 SourceLocation Loc) { 3634 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3635 PreviousCriticalLoc = Loc; 3636 return true; 3637 } 3638 return false; 3639 }, 3640 false /* skip top directive */); 3641 if (DeadLock) { 3642 SemaRef.Diag(StartLoc, 3643 diag::err_omp_prohibited_region_critical_same_name) 3644 << CurrentName.getName(); 3645 if (PreviousCriticalLoc.isValid()) 3646 SemaRef.Diag(PreviousCriticalLoc, 3647 diag::note_omp_previous_critical_region); 3648 return true; 3649 } 3650 } else if (CurrentRegion == OMPD_barrier) { 3651 // OpenMP [2.16, Nesting of Regions] 3652 // A barrier region may not be closely nested inside a worksharing, 3653 // explicit task, critical, ordered, atomic, or master region. 3654 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3655 isOpenMPTaskingDirective(ParentRegion) || 3656 ParentRegion == OMPD_master || 3657 ParentRegion == OMPD_critical || 3658 ParentRegion == OMPD_ordered; 3659 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3660 !isOpenMPParallelDirective(CurrentRegion) && 3661 !isOpenMPTeamsDirective(CurrentRegion)) { 3662 // OpenMP [2.16, Nesting of Regions] 3663 // A worksharing region may not be closely nested inside a worksharing, 3664 // explicit task, critical, ordered, atomic, or master region. 3665 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3666 isOpenMPTaskingDirective(ParentRegion) || 3667 ParentRegion == OMPD_master || 3668 ParentRegion == OMPD_critical || 3669 ParentRegion == OMPD_ordered; 3670 Recommend = ShouldBeInParallelRegion; 3671 } else if (CurrentRegion == OMPD_ordered) { 3672 // OpenMP [2.16, Nesting of Regions] 3673 // An ordered region may not be closely nested inside a critical, 3674 // atomic, or explicit task region. 3675 // An ordered region must be closely nested inside a loop region (or 3676 // parallel loop region) with an ordered clause. 3677 // OpenMP [2.8.1,simd Construct, Restrictions] 3678 // An ordered construct with the simd clause is the only OpenMP construct 3679 // that can appear in the simd region. 3680 NestingProhibited = ParentRegion == OMPD_critical || 3681 isOpenMPTaskingDirective(ParentRegion) || 3682 !(isOpenMPSimdDirective(ParentRegion) || 3683 Stack->isParentOrderedRegion()); 3684 Recommend = ShouldBeInOrderedRegion; 3685 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3686 // OpenMP [2.16, Nesting of Regions] 3687 // If specified, a teams construct must be contained within a target 3688 // construct. 3689 NestingProhibited = ParentRegion != OMPD_target; 3690 OrphanSeen = ParentRegion == OMPD_unknown; 3691 Recommend = ShouldBeInTargetRegion; 3692 } 3693 if (!NestingProhibited && 3694 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3695 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3696 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3697 // OpenMP [2.16, Nesting of Regions] 3698 // distribute, parallel, parallel sections, parallel workshare, and the 3699 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3700 // constructs that can be closely nested in the teams region. 3701 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3702 !isOpenMPDistributeDirective(CurrentRegion); 3703 Recommend = ShouldBeInParallelRegion; 3704 } 3705 if (!NestingProhibited && 3706 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3707 // OpenMP 4.5 [2.17 Nesting of Regions] 3708 // The region associated with the distribute construct must be strictly 3709 // nested inside a teams region 3710 NestingProhibited = 3711 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3712 Recommend = ShouldBeInTeamsRegion; 3713 } 3714 if (!NestingProhibited && 3715 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3716 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3717 // OpenMP 4.5 [2.17 Nesting of Regions] 3718 // If a target, target update, target data, target enter data, or 3719 // target exit data construct is encountered during execution of a 3720 // target region, the behavior is unspecified. 3721 NestingProhibited = Stack->hasDirective( 3722 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3723 SourceLocation) { 3724 if (isOpenMPTargetExecutionDirective(K)) { 3725 OffendingRegion = K; 3726 return true; 3727 } 3728 return false; 3729 }, 3730 false /* don't skip top directive */); 3731 CloseNesting = false; 3732 } 3733 if (NestingProhibited) { 3734 if (OrphanSeen) { 3735 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3736 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3737 } else { 3738 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3739 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3740 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3741 } 3742 return true; 3743 } 3744 } 3745 return false; 3746 } 3747 3748 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3749 ArrayRef<OMPClause *> Clauses, 3750 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3751 bool ErrorFound = false; 3752 unsigned NamedModifiersNumber = 0; 3753 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3754 OMPD_unknown + 1); 3755 SmallVector<SourceLocation, 4> NameModifierLoc; 3756 for (const OMPClause *C : Clauses) { 3757 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3758 // At most one if clause without a directive-name-modifier can appear on 3759 // the directive. 3760 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3761 if (FoundNameModifiers[CurNM]) { 3762 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3763 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3764 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3765 ErrorFound = true; 3766 } else if (CurNM != OMPD_unknown) { 3767 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3768 ++NamedModifiersNumber; 3769 } 3770 FoundNameModifiers[CurNM] = IC; 3771 if (CurNM == OMPD_unknown) 3772 continue; 3773 // Check if the specified name modifier is allowed for the current 3774 // directive. 3775 // At most one if clause with the particular directive-name-modifier can 3776 // appear on the directive. 3777 bool MatchFound = false; 3778 for (auto NM : AllowedNameModifiers) { 3779 if (CurNM == NM) { 3780 MatchFound = true; 3781 break; 3782 } 3783 } 3784 if (!MatchFound) { 3785 S.Diag(IC->getNameModifierLoc(), 3786 diag::err_omp_wrong_if_directive_name_modifier) 3787 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3788 ErrorFound = true; 3789 } 3790 } 3791 } 3792 // If any if clause on the directive includes a directive-name-modifier then 3793 // all if clauses on the directive must include a directive-name-modifier. 3794 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3795 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3796 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3797 diag::err_omp_no_more_if_clause); 3798 } else { 3799 std::string Values; 3800 std::string Sep(", "); 3801 unsigned AllowedCnt = 0; 3802 unsigned TotalAllowedNum = 3803 AllowedNameModifiers.size() - NamedModifiersNumber; 3804 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3805 ++Cnt) { 3806 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3807 if (!FoundNameModifiers[NM]) { 3808 Values += "'"; 3809 Values += getOpenMPDirectiveName(NM); 3810 Values += "'"; 3811 if (AllowedCnt + 2 == TotalAllowedNum) 3812 Values += " or "; 3813 else if (AllowedCnt + 1 != TotalAllowedNum) 3814 Values += Sep; 3815 ++AllowedCnt; 3816 } 3817 } 3818 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3819 diag::err_omp_unnamed_if_clause) 3820 << (TotalAllowedNum > 1) << Values; 3821 } 3822 for (SourceLocation Loc : NameModifierLoc) { 3823 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3824 } 3825 ErrorFound = true; 3826 } 3827 return ErrorFound; 3828 } 3829 3830 static std::pair<ValueDecl *, bool> 3831 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 3832 SourceRange &ERange, bool AllowArraySection = false) { 3833 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 3834 RefExpr->containsUnexpandedParameterPack()) 3835 return std::make_pair(nullptr, true); 3836 3837 // OpenMP [3.1, C/C++] 3838 // A list item is a variable name. 3839 // OpenMP [2.9.3.3, Restrictions, p.1] 3840 // A variable that is part of another variable (as an array or 3841 // structure element) cannot appear in a private clause. 3842 RefExpr = RefExpr->IgnoreParens(); 3843 enum { 3844 NoArrayExpr = -1, 3845 ArraySubscript = 0, 3846 OMPArraySection = 1 3847 } IsArrayExpr = NoArrayExpr; 3848 if (AllowArraySection) { 3849 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 3850 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 3851 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3852 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3853 RefExpr = Base; 3854 IsArrayExpr = ArraySubscript; 3855 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 3856 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 3857 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 3858 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 3859 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3860 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3861 RefExpr = Base; 3862 IsArrayExpr = OMPArraySection; 3863 } 3864 } 3865 ELoc = RefExpr->getExprLoc(); 3866 ERange = RefExpr->getSourceRange(); 3867 RefExpr = RefExpr->IgnoreParenImpCasts(); 3868 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 3869 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 3870 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 3871 (S.getCurrentThisType().isNull() || !ME || 3872 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 3873 !isa<FieldDecl>(ME->getMemberDecl()))) { 3874 if (IsArrayExpr != NoArrayExpr) { 3875 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 3876 << ERange; 3877 } else { 3878 S.Diag(ELoc, 3879 AllowArraySection 3880 ? diag::err_omp_expected_var_name_member_expr_or_array_item 3881 : diag::err_omp_expected_var_name_member_expr) 3882 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 3883 } 3884 return std::make_pair(nullptr, false); 3885 } 3886 return std::make_pair( 3887 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 3888 } 3889 3890 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 3891 ArrayRef<OMPClause *> Clauses) { 3892 assert(!S.CurContext->isDependentContext() && 3893 "Expected non-dependent context."); 3894 auto AllocateRange = 3895 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 3896 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 3897 DeclToCopy; 3898 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 3899 return isOpenMPPrivate(C->getClauseKind()); 3900 }); 3901 for (OMPClause *Cl : PrivateRange) { 3902 MutableArrayRef<Expr *>::iterator I, It, Et; 3903 if (Cl->getClauseKind() == OMPC_private) { 3904 auto *PC = cast<OMPPrivateClause>(Cl); 3905 I = PC->private_copies().begin(); 3906 It = PC->varlist_begin(); 3907 Et = PC->varlist_end(); 3908 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 3909 auto *PC = cast<OMPFirstprivateClause>(Cl); 3910 I = PC->private_copies().begin(); 3911 It = PC->varlist_begin(); 3912 Et = PC->varlist_end(); 3913 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 3914 auto *PC = cast<OMPLastprivateClause>(Cl); 3915 I = PC->private_copies().begin(); 3916 It = PC->varlist_begin(); 3917 Et = PC->varlist_end(); 3918 } else if (Cl->getClauseKind() == OMPC_linear) { 3919 auto *PC = cast<OMPLinearClause>(Cl); 3920 I = PC->privates().begin(); 3921 It = PC->varlist_begin(); 3922 Et = PC->varlist_end(); 3923 } else if (Cl->getClauseKind() == OMPC_reduction) { 3924 auto *PC = cast<OMPReductionClause>(Cl); 3925 I = PC->privates().begin(); 3926 It = PC->varlist_begin(); 3927 Et = PC->varlist_end(); 3928 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 3929 auto *PC = cast<OMPTaskReductionClause>(Cl); 3930 I = PC->privates().begin(); 3931 It = PC->varlist_begin(); 3932 Et = PC->varlist_end(); 3933 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 3934 auto *PC = cast<OMPInReductionClause>(Cl); 3935 I = PC->privates().begin(); 3936 It = PC->varlist_begin(); 3937 Et = PC->varlist_end(); 3938 } else { 3939 llvm_unreachable("Expected private clause."); 3940 } 3941 for (Expr *E : llvm::make_range(It, Et)) { 3942 if (!*I) { 3943 ++I; 3944 continue; 3945 } 3946 SourceLocation ELoc; 3947 SourceRange ERange; 3948 Expr *SimpleRefExpr = E; 3949 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 3950 /*AllowArraySection=*/true); 3951 DeclToCopy.try_emplace(Res.first, 3952 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 3953 ++I; 3954 } 3955 } 3956 for (OMPClause *C : AllocateRange) { 3957 auto *AC = cast<OMPAllocateClause>(C); 3958 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3959 getAllocatorKind(S, Stack, AC->getAllocator()); 3960 // OpenMP, 2.11.4 allocate Clause, Restrictions. 3961 // For task, taskloop or target directives, allocation requests to memory 3962 // allocators with the trait access set to thread result in unspecified 3963 // behavior. 3964 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 3965 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 3966 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 3967 S.Diag(AC->getAllocator()->getExprLoc(), 3968 diag::warn_omp_allocate_thread_on_task_target_directive) 3969 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3970 } 3971 for (Expr *E : AC->varlists()) { 3972 SourceLocation ELoc; 3973 SourceRange ERange; 3974 Expr *SimpleRefExpr = E; 3975 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 3976 ValueDecl *VD = Res.first; 3977 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 3978 if (!isOpenMPPrivate(Data.CKind)) { 3979 S.Diag(E->getExprLoc(), 3980 diag::err_omp_expected_private_copy_for_allocate); 3981 continue; 3982 } 3983 VarDecl *PrivateVD = DeclToCopy[VD]; 3984 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 3985 AllocatorKind, AC->getAllocator())) 3986 continue; 3987 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 3988 E->getSourceRange()); 3989 } 3990 } 3991 } 3992 3993 StmtResult Sema::ActOnOpenMPExecutableDirective( 3994 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3995 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3996 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3997 StmtResult Res = StmtError(); 3998 // First check CancelRegion which is then used in checkNestingOfRegions. 3999 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4000 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4001 StartLoc)) 4002 return StmtError(); 4003 4004 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4005 VarsWithInheritedDSAType VarsWithInheritedDSA; 4006 bool ErrorFound = false; 4007 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4008 if (AStmt && !CurContext->isDependentContext()) { 4009 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4010 4011 // Check default data sharing attributes for referenced variables. 4012 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4013 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4014 Stmt *S = AStmt; 4015 while (--ThisCaptureLevel >= 0) 4016 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4017 DSAChecker.Visit(S); 4018 if (!isOpenMPTargetDataManagementDirective(Kind) && 4019 !isOpenMPTaskingDirective(Kind)) { 4020 // Visit subcaptures to generate implicit clauses for captured vars. 4021 auto *CS = cast<CapturedStmt>(AStmt); 4022 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4023 getOpenMPCaptureRegions(CaptureRegions, Kind); 4024 // Ignore outer tasking regions for target directives. 4025 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4026 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4027 DSAChecker.visitSubCaptures(CS); 4028 } 4029 if (DSAChecker.isErrorFound()) 4030 return StmtError(); 4031 // Generate list of implicitly defined firstprivate variables. 4032 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4033 4034 SmallVector<Expr *, 4> ImplicitFirstprivates( 4035 DSAChecker.getImplicitFirstprivate().begin(), 4036 DSAChecker.getImplicitFirstprivate().end()); 4037 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4038 DSAChecker.getImplicitMap().end()); 4039 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4040 for (OMPClause *C : Clauses) { 4041 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4042 for (Expr *E : IRC->taskgroup_descriptors()) 4043 if (E) 4044 ImplicitFirstprivates.emplace_back(E); 4045 } 4046 } 4047 if (!ImplicitFirstprivates.empty()) { 4048 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4049 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4050 SourceLocation())) { 4051 ClausesWithImplicit.push_back(Implicit); 4052 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4053 ImplicitFirstprivates.size(); 4054 } else { 4055 ErrorFound = true; 4056 } 4057 } 4058 if (!ImplicitMaps.empty()) { 4059 CXXScopeSpec MapperIdScopeSpec; 4060 DeclarationNameInfo MapperId; 4061 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4062 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4063 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4064 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4065 ClausesWithImplicit.emplace_back(Implicit); 4066 ErrorFound |= 4067 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4068 } else { 4069 ErrorFound = true; 4070 } 4071 } 4072 } 4073 4074 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4075 switch (Kind) { 4076 case OMPD_parallel: 4077 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4078 EndLoc); 4079 AllowedNameModifiers.push_back(OMPD_parallel); 4080 break; 4081 case OMPD_simd: 4082 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4083 VarsWithInheritedDSA); 4084 break; 4085 case OMPD_for: 4086 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4087 VarsWithInheritedDSA); 4088 break; 4089 case OMPD_for_simd: 4090 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4091 EndLoc, VarsWithInheritedDSA); 4092 break; 4093 case OMPD_sections: 4094 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4095 EndLoc); 4096 break; 4097 case OMPD_section: 4098 assert(ClausesWithImplicit.empty() && 4099 "No clauses are allowed for 'omp section' directive"); 4100 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4101 break; 4102 case OMPD_single: 4103 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4104 EndLoc); 4105 break; 4106 case OMPD_master: 4107 assert(ClausesWithImplicit.empty() && 4108 "No clauses are allowed for 'omp master' directive"); 4109 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4110 break; 4111 case OMPD_critical: 4112 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4113 StartLoc, EndLoc); 4114 break; 4115 case OMPD_parallel_for: 4116 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4117 EndLoc, VarsWithInheritedDSA); 4118 AllowedNameModifiers.push_back(OMPD_parallel); 4119 break; 4120 case OMPD_parallel_for_simd: 4121 Res = ActOnOpenMPParallelForSimdDirective( 4122 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4123 AllowedNameModifiers.push_back(OMPD_parallel); 4124 break; 4125 case OMPD_parallel_sections: 4126 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4127 StartLoc, EndLoc); 4128 AllowedNameModifiers.push_back(OMPD_parallel); 4129 break; 4130 case OMPD_task: 4131 Res = 4132 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4133 AllowedNameModifiers.push_back(OMPD_task); 4134 break; 4135 case OMPD_taskyield: 4136 assert(ClausesWithImplicit.empty() && 4137 "No clauses are allowed for 'omp taskyield' directive"); 4138 assert(AStmt == nullptr && 4139 "No associated statement allowed for 'omp taskyield' directive"); 4140 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4141 break; 4142 case OMPD_barrier: 4143 assert(ClausesWithImplicit.empty() && 4144 "No clauses are allowed for 'omp barrier' directive"); 4145 assert(AStmt == nullptr && 4146 "No associated statement allowed for 'omp barrier' directive"); 4147 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4148 break; 4149 case OMPD_taskwait: 4150 assert(ClausesWithImplicit.empty() && 4151 "No clauses are allowed for 'omp taskwait' directive"); 4152 assert(AStmt == nullptr && 4153 "No associated statement allowed for 'omp taskwait' directive"); 4154 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4155 break; 4156 case OMPD_taskgroup: 4157 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4158 EndLoc); 4159 break; 4160 case OMPD_flush: 4161 assert(AStmt == nullptr && 4162 "No associated statement allowed for 'omp flush' directive"); 4163 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4164 break; 4165 case OMPD_ordered: 4166 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4167 EndLoc); 4168 break; 4169 case OMPD_atomic: 4170 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4171 EndLoc); 4172 break; 4173 case OMPD_teams: 4174 Res = 4175 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4176 break; 4177 case OMPD_target: 4178 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4179 EndLoc); 4180 AllowedNameModifiers.push_back(OMPD_target); 4181 break; 4182 case OMPD_target_parallel: 4183 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4184 StartLoc, EndLoc); 4185 AllowedNameModifiers.push_back(OMPD_target); 4186 AllowedNameModifiers.push_back(OMPD_parallel); 4187 break; 4188 case OMPD_target_parallel_for: 4189 Res = ActOnOpenMPTargetParallelForDirective( 4190 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4191 AllowedNameModifiers.push_back(OMPD_target); 4192 AllowedNameModifiers.push_back(OMPD_parallel); 4193 break; 4194 case OMPD_cancellation_point: 4195 assert(ClausesWithImplicit.empty() && 4196 "No clauses are allowed for 'omp cancellation point' directive"); 4197 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4198 "cancellation point' directive"); 4199 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4200 break; 4201 case OMPD_cancel: 4202 assert(AStmt == nullptr && 4203 "No associated statement allowed for 'omp cancel' directive"); 4204 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4205 CancelRegion); 4206 AllowedNameModifiers.push_back(OMPD_cancel); 4207 break; 4208 case OMPD_target_data: 4209 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4210 EndLoc); 4211 AllowedNameModifiers.push_back(OMPD_target_data); 4212 break; 4213 case OMPD_target_enter_data: 4214 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4215 EndLoc, AStmt); 4216 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4217 break; 4218 case OMPD_target_exit_data: 4219 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4220 EndLoc, AStmt); 4221 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4222 break; 4223 case OMPD_taskloop: 4224 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4225 EndLoc, VarsWithInheritedDSA); 4226 AllowedNameModifiers.push_back(OMPD_taskloop); 4227 break; 4228 case OMPD_taskloop_simd: 4229 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4230 EndLoc, VarsWithInheritedDSA); 4231 AllowedNameModifiers.push_back(OMPD_taskloop); 4232 break; 4233 case OMPD_distribute: 4234 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4235 EndLoc, VarsWithInheritedDSA); 4236 break; 4237 case OMPD_target_update: 4238 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4239 EndLoc, AStmt); 4240 AllowedNameModifiers.push_back(OMPD_target_update); 4241 break; 4242 case OMPD_distribute_parallel_for: 4243 Res = ActOnOpenMPDistributeParallelForDirective( 4244 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4245 AllowedNameModifiers.push_back(OMPD_parallel); 4246 break; 4247 case OMPD_distribute_parallel_for_simd: 4248 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4249 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4250 AllowedNameModifiers.push_back(OMPD_parallel); 4251 break; 4252 case OMPD_distribute_simd: 4253 Res = ActOnOpenMPDistributeSimdDirective( 4254 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4255 break; 4256 case OMPD_target_parallel_for_simd: 4257 Res = ActOnOpenMPTargetParallelForSimdDirective( 4258 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4259 AllowedNameModifiers.push_back(OMPD_target); 4260 AllowedNameModifiers.push_back(OMPD_parallel); 4261 break; 4262 case OMPD_target_simd: 4263 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4264 EndLoc, VarsWithInheritedDSA); 4265 AllowedNameModifiers.push_back(OMPD_target); 4266 break; 4267 case OMPD_teams_distribute: 4268 Res = ActOnOpenMPTeamsDistributeDirective( 4269 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4270 break; 4271 case OMPD_teams_distribute_simd: 4272 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4273 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4274 break; 4275 case OMPD_teams_distribute_parallel_for_simd: 4276 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4277 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4278 AllowedNameModifiers.push_back(OMPD_parallel); 4279 break; 4280 case OMPD_teams_distribute_parallel_for: 4281 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4282 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4283 AllowedNameModifiers.push_back(OMPD_parallel); 4284 break; 4285 case OMPD_target_teams: 4286 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4287 EndLoc); 4288 AllowedNameModifiers.push_back(OMPD_target); 4289 break; 4290 case OMPD_target_teams_distribute: 4291 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4292 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4293 AllowedNameModifiers.push_back(OMPD_target); 4294 break; 4295 case OMPD_target_teams_distribute_parallel_for: 4296 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4297 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4298 AllowedNameModifiers.push_back(OMPD_target); 4299 AllowedNameModifiers.push_back(OMPD_parallel); 4300 break; 4301 case OMPD_target_teams_distribute_parallel_for_simd: 4302 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4303 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4304 AllowedNameModifiers.push_back(OMPD_target); 4305 AllowedNameModifiers.push_back(OMPD_parallel); 4306 break; 4307 case OMPD_target_teams_distribute_simd: 4308 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4309 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4310 AllowedNameModifiers.push_back(OMPD_target); 4311 break; 4312 case OMPD_declare_target: 4313 case OMPD_end_declare_target: 4314 case OMPD_threadprivate: 4315 case OMPD_allocate: 4316 case OMPD_declare_reduction: 4317 case OMPD_declare_mapper: 4318 case OMPD_declare_simd: 4319 case OMPD_requires: 4320 llvm_unreachable("OpenMP Directive is not allowed"); 4321 case OMPD_unknown: 4322 llvm_unreachable("Unknown OpenMP directive"); 4323 } 4324 4325 ErrorFound = Res.isInvalid() || ErrorFound; 4326 4327 // Check variables in the clauses if default(none) was specified. 4328 if (DSAStack->getDefaultDSA() == DSA_none) { 4329 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4330 for (OMPClause *C : Clauses) { 4331 switch (C->getClauseKind()) { 4332 case OMPC_num_threads: 4333 case OMPC_dist_schedule: 4334 // Do not analyse if no parent teams directive. 4335 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4336 break; 4337 continue; 4338 case OMPC_if: 4339 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4340 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4341 break; 4342 continue; 4343 case OMPC_schedule: 4344 break; 4345 case OMPC_ordered: 4346 case OMPC_device: 4347 case OMPC_num_teams: 4348 case OMPC_thread_limit: 4349 case OMPC_priority: 4350 case OMPC_grainsize: 4351 case OMPC_num_tasks: 4352 case OMPC_hint: 4353 case OMPC_collapse: 4354 case OMPC_safelen: 4355 case OMPC_simdlen: 4356 case OMPC_final: 4357 case OMPC_default: 4358 case OMPC_proc_bind: 4359 case OMPC_private: 4360 case OMPC_firstprivate: 4361 case OMPC_lastprivate: 4362 case OMPC_shared: 4363 case OMPC_reduction: 4364 case OMPC_task_reduction: 4365 case OMPC_in_reduction: 4366 case OMPC_linear: 4367 case OMPC_aligned: 4368 case OMPC_copyin: 4369 case OMPC_copyprivate: 4370 case OMPC_nowait: 4371 case OMPC_untied: 4372 case OMPC_mergeable: 4373 case OMPC_allocate: 4374 case OMPC_read: 4375 case OMPC_write: 4376 case OMPC_update: 4377 case OMPC_capture: 4378 case OMPC_seq_cst: 4379 case OMPC_depend: 4380 case OMPC_threads: 4381 case OMPC_simd: 4382 case OMPC_map: 4383 case OMPC_nogroup: 4384 case OMPC_defaultmap: 4385 case OMPC_to: 4386 case OMPC_from: 4387 case OMPC_use_device_ptr: 4388 case OMPC_is_device_ptr: 4389 continue; 4390 case OMPC_allocator: 4391 case OMPC_flush: 4392 case OMPC_threadprivate: 4393 case OMPC_uniform: 4394 case OMPC_unknown: 4395 case OMPC_unified_address: 4396 case OMPC_unified_shared_memory: 4397 case OMPC_reverse_offload: 4398 case OMPC_dynamic_allocators: 4399 case OMPC_atomic_default_mem_order: 4400 llvm_unreachable("Unexpected clause"); 4401 } 4402 for (Stmt *CC : C->children()) { 4403 if (CC) 4404 DSAChecker.Visit(CC); 4405 } 4406 } 4407 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4408 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4409 } 4410 for (const auto &P : VarsWithInheritedDSA) { 4411 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4412 continue; 4413 ErrorFound = true; 4414 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4415 << P.first << P.second->getSourceRange(); 4416 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4417 } 4418 4419 if (!AllowedNameModifiers.empty()) 4420 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4421 ErrorFound; 4422 4423 if (ErrorFound) 4424 return StmtError(); 4425 4426 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4427 Res.getAs<OMPExecutableDirective>() 4428 ->getStructuredBlock() 4429 ->setIsOMPStructuredBlock(true); 4430 } 4431 4432 if (!CurContext->isDependentContext() && 4433 isOpenMPTargetExecutionDirective(Kind) && 4434 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4435 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4436 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4437 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4438 // Register target to DSA Stack. 4439 DSAStack->addTargetDirLocation(StartLoc); 4440 } 4441 4442 return Res; 4443 } 4444 4445 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4446 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4447 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4448 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4449 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4450 assert(Aligneds.size() == Alignments.size()); 4451 assert(Linears.size() == LinModifiers.size()); 4452 assert(Linears.size() == Steps.size()); 4453 if (!DG || DG.get().isNull()) 4454 return DeclGroupPtrTy(); 4455 4456 if (!DG.get().isSingleDecl()) { 4457 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4458 return DG; 4459 } 4460 Decl *ADecl = DG.get().getSingleDecl(); 4461 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4462 ADecl = FTD->getTemplatedDecl(); 4463 4464 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4465 if (!FD) { 4466 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4467 return DeclGroupPtrTy(); 4468 } 4469 4470 // OpenMP [2.8.2, declare simd construct, Description] 4471 // The parameter of the simdlen clause must be a constant positive integer 4472 // expression. 4473 ExprResult SL; 4474 if (Simdlen) 4475 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4476 // OpenMP [2.8.2, declare simd construct, Description] 4477 // The special this pointer can be used as if was one of the arguments to the 4478 // function in any of the linear, aligned, or uniform clauses. 4479 // The uniform clause declares one or more arguments to have an invariant 4480 // value for all concurrent invocations of the function in the execution of a 4481 // single SIMD loop. 4482 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4483 const Expr *UniformedLinearThis = nullptr; 4484 for (const Expr *E : Uniforms) { 4485 E = E->IgnoreParenImpCasts(); 4486 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4487 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4488 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4489 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4490 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4491 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4492 continue; 4493 } 4494 if (isa<CXXThisExpr>(E)) { 4495 UniformedLinearThis = E; 4496 continue; 4497 } 4498 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4499 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4500 } 4501 // OpenMP [2.8.2, declare simd construct, Description] 4502 // The aligned clause declares that the object to which each list item points 4503 // is aligned to the number of bytes expressed in the optional parameter of 4504 // the aligned clause. 4505 // The special this pointer can be used as if was one of the arguments to the 4506 // function in any of the linear, aligned, or uniform clauses. 4507 // The type of list items appearing in the aligned clause must be array, 4508 // pointer, reference to array, or reference to pointer. 4509 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4510 const Expr *AlignedThis = nullptr; 4511 for (const Expr *E : Aligneds) { 4512 E = E->IgnoreParenImpCasts(); 4513 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4514 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4515 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4516 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4517 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4518 ->getCanonicalDecl() == CanonPVD) { 4519 // OpenMP [2.8.1, simd construct, Restrictions] 4520 // A list-item cannot appear in more than one aligned clause. 4521 if (AlignedArgs.count(CanonPVD) > 0) { 4522 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4523 << 1 << E->getSourceRange(); 4524 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4525 diag::note_omp_explicit_dsa) 4526 << getOpenMPClauseName(OMPC_aligned); 4527 continue; 4528 } 4529 AlignedArgs[CanonPVD] = E; 4530 QualType QTy = PVD->getType() 4531 .getNonReferenceType() 4532 .getUnqualifiedType() 4533 .getCanonicalType(); 4534 const Type *Ty = QTy.getTypePtrOrNull(); 4535 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4536 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4537 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4538 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4539 } 4540 continue; 4541 } 4542 } 4543 if (isa<CXXThisExpr>(E)) { 4544 if (AlignedThis) { 4545 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4546 << 2 << E->getSourceRange(); 4547 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4548 << getOpenMPClauseName(OMPC_aligned); 4549 } 4550 AlignedThis = E; 4551 continue; 4552 } 4553 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4554 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4555 } 4556 // The optional parameter of the aligned clause, alignment, must be a constant 4557 // positive integer expression. If no optional parameter is specified, 4558 // implementation-defined default alignments for SIMD instructions on the 4559 // target platforms are assumed. 4560 SmallVector<const Expr *, 4> NewAligns; 4561 for (Expr *E : Alignments) { 4562 ExprResult Align; 4563 if (E) 4564 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4565 NewAligns.push_back(Align.get()); 4566 } 4567 // OpenMP [2.8.2, declare simd construct, Description] 4568 // The linear clause declares one or more list items to be private to a SIMD 4569 // lane and to have a linear relationship with respect to the iteration space 4570 // of a loop. 4571 // The special this pointer can be used as if was one of the arguments to the 4572 // function in any of the linear, aligned, or uniform clauses. 4573 // When a linear-step expression is specified in a linear clause it must be 4574 // either a constant integer expression or an integer-typed parameter that is 4575 // specified in a uniform clause on the directive. 4576 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4577 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4578 auto MI = LinModifiers.begin(); 4579 for (const Expr *E : Linears) { 4580 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4581 ++MI; 4582 E = E->IgnoreParenImpCasts(); 4583 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4584 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4585 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4586 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4587 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4588 ->getCanonicalDecl() == CanonPVD) { 4589 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4590 // A list-item cannot appear in more than one linear clause. 4591 if (LinearArgs.count(CanonPVD) > 0) { 4592 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4593 << getOpenMPClauseName(OMPC_linear) 4594 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4595 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4596 diag::note_omp_explicit_dsa) 4597 << getOpenMPClauseName(OMPC_linear); 4598 continue; 4599 } 4600 // Each argument can appear in at most one uniform or linear clause. 4601 if (UniformedArgs.count(CanonPVD) > 0) { 4602 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4603 << getOpenMPClauseName(OMPC_linear) 4604 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4605 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4606 diag::note_omp_explicit_dsa) 4607 << getOpenMPClauseName(OMPC_uniform); 4608 continue; 4609 } 4610 LinearArgs[CanonPVD] = E; 4611 if (E->isValueDependent() || E->isTypeDependent() || 4612 E->isInstantiationDependent() || 4613 E->containsUnexpandedParameterPack()) 4614 continue; 4615 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4616 PVD->getOriginalType()); 4617 continue; 4618 } 4619 } 4620 if (isa<CXXThisExpr>(E)) { 4621 if (UniformedLinearThis) { 4622 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4623 << getOpenMPClauseName(OMPC_linear) 4624 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4625 << E->getSourceRange(); 4626 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4627 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4628 : OMPC_linear); 4629 continue; 4630 } 4631 UniformedLinearThis = E; 4632 if (E->isValueDependent() || E->isTypeDependent() || 4633 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4634 continue; 4635 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4636 E->getType()); 4637 continue; 4638 } 4639 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4640 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4641 } 4642 Expr *Step = nullptr; 4643 Expr *NewStep = nullptr; 4644 SmallVector<Expr *, 4> NewSteps; 4645 for (Expr *E : Steps) { 4646 // Skip the same step expression, it was checked already. 4647 if (Step == E || !E) { 4648 NewSteps.push_back(E ? NewStep : nullptr); 4649 continue; 4650 } 4651 Step = E; 4652 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4653 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4654 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4655 if (UniformedArgs.count(CanonPVD) == 0) { 4656 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4657 << Step->getSourceRange(); 4658 } else if (E->isValueDependent() || E->isTypeDependent() || 4659 E->isInstantiationDependent() || 4660 E->containsUnexpandedParameterPack() || 4661 CanonPVD->getType()->hasIntegerRepresentation()) { 4662 NewSteps.push_back(Step); 4663 } else { 4664 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4665 << Step->getSourceRange(); 4666 } 4667 continue; 4668 } 4669 NewStep = Step; 4670 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4671 !Step->isInstantiationDependent() && 4672 !Step->containsUnexpandedParameterPack()) { 4673 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4674 .get(); 4675 if (NewStep) 4676 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4677 } 4678 NewSteps.push_back(NewStep); 4679 } 4680 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4681 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4682 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4683 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4684 const_cast<Expr **>(Linears.data()), Linears.size(), 4685 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4686 NewSteps.data(), NewSteps.size(), SR); 4687 ADecl->addAttr(NewAttr); 4688 return ConvertDeclToDeclGroup(ADecl); 4689 } 4690 4691 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4692 Stmt *AStmt, 4693 SourceLocation StartLoc, 4694 SourceLocation EndLoc) { 4695 if (!AStmt) 4696 return StmtError(); 4697 4698 auto *CS = cast<CapturedStmt>(AStmt); 4699 // 1.2.2 OpenMP Language Terminology 4700 // Structured block - An executable statement with a single entry at the 4701 // top and a single exit at the bottom. 4702 // The point of exit cannot be a branch out of the structured block. 4703 // longjmp() and throw() must not violate the entry/exit criteria. 4704 CS->getCapturedDecl()->setNothrow(); 4705 4706 setFunctionHasBranchProtectedScope(); 4707 4708 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4709 DSAStack->isCancelRegion()); 4710 } 4711 4712 namespace { 4713 /// Iteration space of a single for loop. 4714 struct LoopIterationSpace final { 4715 /// True if the condition operator is the strict compare operator (<, > or 4716 /// !=). 4717 bool IsStrictCompare = false; 4718 /// Condition of the loop. 4719 Expr *PreCond = nullptr; 4720 /// This expression calculates the number of iterations in the loop. 4721 /// It is always possible to calculate it before starting the loop. 4722 Expr *NumIterations = nullptr; 4723 /// The loop counter variable. 4724 Expr *CounterVar = nullptr; 4725 /// Private loop counter variable. 4726 Expr *PrivateCounterVar = nullptr; 4727 /// This is initializer for the initial value of #CounterVar. 4728 Expr *CounterInit = nullptr; 4729 /// This is step for the #CounterVar used to generate its update: 4730 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4731 Expr *CounterStep = nullptr; 4732 /// Should step be subtracted? 4733 bool Subtract = false; 4734 /// Source range of the loop init. 4735 SourceRange InitSrcRange; 4736 /// Source range of the loop condition. 4737 SourceRange CondSrcRange; 4738 /// Source range of the loop increment. 4739 SourceRange IncSrcRange; 4740 /// Minimum value that can have the loop control variable. Used to support 4741 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 4742 /// since only such variables can be used in non-loop invariant expressions. 4743 Expr *MinValue = nullptr; 4744 /// Maximum value that can have the loop control variable. Used to support 4745 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 4746 /// since only such variables can be used in non-loop invariant expressions. 4747 Expr *MaxValue = nullptr; 4748 /// true, if the lower bound depends on the outer loop control var. 4749 bool IsNonRectangularLB = false; 4750 /// true, if the upper bound depends on the outer loop control var. 4751 bool IsNonRectangularUB = false; 4752 /// Index of the loop this loop depends on and forms non-rectangular loop 4753 /// nest. 4754 unsigned LoopDependentIdx = 0; 4755 /// Final condition for the non-rectangular loop nest support. It is used to 4756 /// check that the number of iterations for this particular counter must be 4757 /// finished. 4758 Expr *FinalCondition = nullptr; 4759 }; 4760 4761 /// Helper class for checking canonical form of the OpenMP loops and 4762 /// extracting iteration space of each loop in the loop nest, that will be used 4763 /// for IR generation. 4764 class OpenMPIterationSpaceChecker { 4765 /// Reference to Sema. 4766 Sema &SemaRef; 4767 /// Data-sharing stack. 4768 DSAStackTy &Stack; 4769 /// A location for diagnostics (when there is no some better location). 4770 SourceLocation DefaultLoc; 4771 /// A location for diagnostics (when increment is not compatible). 4772 SourceLocation ConditionLoc; 4773 /// A source location for referring to loop init later. 4774 SourceRange InitSrcRange; 4775 /// A source location for referring to condition later. 4776 SourceRange ConditionSrcRange; 4777 /// A source location for referring to increment later. 4778 SourceRange IncrementSrcRange; 4779 /// Loop variable. 4780 ValueDecl *LCDecl = nullptr; 4781 /// Reference to loop variable. 4782 Expr *LCRef = nullptr; 4783 /// Lower bound (initializer for the var). 4784 Expr *LB = nullptr; 4785 /// Upper bound. 4786 Expr *UB = nullptr; 4787 /// Loop step (increment). 4788 Expr *Step = nullptr; 4789 /// This flag is true when condition is one of: 4790 /// Var < UB 4791 /// Var <= UB 4792 /// UB > Var 4793 /// UB >= Var 4794 /// This will have no value when the condition is != 4795 llvm::Optional<bool> TestIsLessOp; 4796 /// This flag is true when condition is strict ( < or > ). 4797 bool TestIsStrictOp = false; 4798 /// This flag is true when step is subtracted on each iteration. 4799 bool SubtractStep = false; 4800 /// The outer loop counter this loop depends on (if any). 4801 const ValueDecl *DepDecl = nullptr; 4802 /// Contains number of loop (starts from 1) on which loop counter init 4803 /// expression of this loop depends on. 4804 Optional<unsigned> InitDependOnLC; 4805 /// Contains number of loop (starts from 1) on which loop counter condition 4806 /// expression of this loop depends on. 4807 Optional<unsigned> CondDependOnLC; 4808 /// Checks if the provide statement depends on the loop counter. 4809 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 4810 /// Original condition required for checking of the exit condition for 4811 /// non-rectangular loop. 4812 Expr *Condition = nullptr; 4813 4814 public: 4815 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 4816 SourceLocation DefaultLoc) 4817 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 4818 ConditionLoc(DefaultLoc) {} 4819 /// Check init-expr for canonical loop form and save loop counter 4820 /// variable - #Var and its initialization value - #LB. 4821 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4822 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4823 /// for less/greater and for strict/non-strict comparison. 4824 bool checkAndSetCond(Expr *S); 4825 /// Check incr-expr for canonical loop form and return true if it 4826 /// does not conform, otherwise save loop step (#Step). 4827 bool checkAndSetInc(Expr *S); 4828 /// Return the loop counter variable. 4829 ValueDecl *getLoopDecl() const { return LCDecl; } 4830 /// Return the reference expression to loop counter variable. 4831 Expr *getLoopDeclRefExpr() const { return LCRef; } 4832 /// Source range of the loop init. 4833 SourceRange getInitSrcRange() const { return InitSrcRange; } 4834 /// Source range of the loop condition. 4835 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4836 /// Source range of the loop increment. 4837 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4838 /// True if the step should be subtracted. 4839 bool shouldSubtractStep() const { return SubtractStep; } 4840 /// True, if the compare operator is strict (<, > or !=). 4841 bool isStrictTestOp() const { return TestIsStrictOp; } 4842 /// Build the expression to calculate the number of iterations. 4843 Expr *buildNumIterations( 4844 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 4845 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4846 /// Build the precondition expression for the loops. 4847 Expr * 4848 buildPreCond(Scope *S, Expr *Cond, 4849 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4850 /// Build reference expression to the counter be used for codegen. 4851 DeclRefExpr * 4852 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4853 DSAStackTy &DSA) const; 4854 /// Build reference expression to the private counter be used for 4855 /// codegen. 4856 Expr *buildPrivateCounterVar() const; 4857 /// Build initialization of the counter be used for codegen. 4858 Expr *buildCounterInit() const; 4859 /// Build step of the counter be used for codegen. 4860 Expr *buildCounterStep() const; 4861 /// Build loop data with counter value for depend clauses in ordered 4862 /// directives. 4863 Expr * 4864 buildOrderedLoopData(Scope *S, Expr *Counter, 4865 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4866 SourceLocation Loc, Expr *Inc = nullptr, 4867 OverloadedOperatorKind OOK = OO_Amp); 4868 /// Builds the minimum value for the loop counter. 4869 std::pair<Expr *, Expr *> buildMinMaxValues( 4870 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4871 /// Builds final condition for the non-rectangular loops. 4872 Expr *buildFinalCondition(Scope *S) const; 4873 /// Return true if any expression is dependent. 4874 bool dependent() const; 4875 /// Returns true if the initializer forms non-rectangular loop. 4876 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 4877 /// Returns true if the condition forms non-rectangular loop. 4878 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 4879 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 4880 unsigned getLoopDependentIdx() const { 4881 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 4882 } 4883 4884 private: 4885 /// Check the right-hand side of an assignment in the increment 4886 /// expression. 4887 bool checkAndSetIncRHS(Expr *RHS); 4888 /// Helper to set loop counter variable and its initializer. 4889 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 4890 bool EmitDiags); 4891 /// Helper to set upper bound. 4892 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4893 SourceRange SR, SourceLocation SL); 4894 /// Helper to set loop increment. 4895 bool setStep(Expr *NewStep, bool Subtract); 4896 }; 4897 4898 bool OpenMPIterationSpaceChecker::dependent() const { 4899 if (!LCDecl) { 4900 assert(!LB && !UB && !Step); 4901 return false; 4902 } 4903 return LCDecl->getType()->isDependentType() || 4904 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4905 (Step && Step->isValueDependent()); 4906 } 4907 4908 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4909 Expr *NewLCRefExpr, 4910 Expr *NewLB, bool EmitDiags) { 4911 // State consistency checking to ensure correct usage. 4912 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4913 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4914 if (!NewLCDecl || !NewLB) 4915 return true; 4916 LCDecl = getCanonicalDecl(NewLCDecl); 4917 LCRef = NewLCRefExpr; 4918 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4919 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4920 if ((Ctor->isCopyOrMoveConstructor() || 4921 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4922 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4923 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4924 LB = NewLB; 4925 if (EmitDiags) 4926 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 4927 return false; 4928 } 4929 4930 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4931 llvm::Optional<bool> LessOp, 4932 bool StrictOp, SourceRange SR, 4933 SourceLocation SL) { 4934 // State consistency checking to ensure correct usage. 4935 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4936 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4937 if (!NewUB) 4938 return true; 4939 UB = NewUB; 4940 if (LessOp) 4941 TestIsLessOp = LessOp; 4942 TestIsStrictOp = StrictOp; 4943 ConditionSrcRange = SR; 4944 ConditionLoc = SL; 4945 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 4946 return false; 4947 } 4948 4949 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4950 // State consistency checking to ensure correct usage. 4951 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4952 if (!NewStep) 4953 return true; 4954 if (!NewStep->isValueDependent()) { 4955 // Check that the step is integer expression. 4956 SourceLocation StepLoc = NewStep->getBeginLoc(); 4957 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4958 StepLoc, getExprAsWritten(NewStep)); 4959 if (Val.isInvalid()) 4960 return true; 4961 NewStep = Val.get(); 4962 4963 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4964 // If test-expr is of form var relational-op b and relational-op is < or 4965 // <= then incr-expr must cause var to increase on each iteration of the 4966 // loop. If test-expr is of form var relational-op b and relational-op is 4967 // > or >= then incr-expr must cause var to decrease on each iteration of 4968 // the loop. 4969 // If test-expr is of form b relational-op var and relational-op is < or 4970 // <= then incr-expr must cause var to decrease on each iteration of the 4971 // loop. If test-expr is of form b relational-op var and relational-op is 4972 // > or >= then incr-expr must cause var to increase on each iteration of 4973 // the loop. 4974 llvm::APSInt Result; 4975 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4976 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4977 bool IsConstNeg = 4978 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4979 bool IsConstPos = 4980 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4981 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4982 4983 // != with increment is treated as <; != with decrement is treated as > 4984 if (!TestIsLessOp.hasValue()) 4985 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4986 if (UB && (IsConstZero || 4987 (TestIsLessOp.getValue() ? 4988 (IsConstNeg || (IsUnsigned && Subtract)) : 4989 (IsConstPos || (IsUnsigned && !Subtract))))) { 4990 SemaRef.Diag(NewStep->getExprLoc(), 4991 diag::err_omp_loop_incr_not_compatible) 4992 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4993 SemaRef.Diag(ConditionLoc, 4994 diag::note_omp_loop_cond_requres_compatible_incr) 4995 << TestIsLessOp.getValue() << ConditionSrcRange; 4996 return true; 4997 } 4998 if (TestIsLessOp.getValue() == Subtract) { 4999 NewStep = 5000 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5001 .get(); 5002 Subtract = !Subtract; 5003 } 5004 } 5005 5006 Step = NewStep; 5007 SubtractStep = Subtract; 5008 return false; 5009 } 5010 5011 namespace { 5012 /// Checker for the non-rectangular loops. Checks if the initializer or 5013 /// condition expression references loop counter variable. 5014 class LoopCounterRefChecker final 5015 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5016 Sema &SemaRef; 5017 DSAStackTy &Stack; 5018 const ValueDecl *CurLCDecl = nullptr; 5019 const ValueDecl *DepDecl = nullptr; 5020 const ValueDecl *PrevDepDecl = nullptr; 5021 bool IsInitializer = true; 5022 unsigned BaseLoopId = 0; 5023 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5024 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5025 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5026 << (IsInitializer ? 0 : 1); 5027 return false; 5028 } 5029 const auto &&Data = Stack.isLoopControlVariable(VD); 5030 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5031 // The type of the loop iterator on which we depend may not have a random 5032 // access iterator type. 5033 if (Data.first && VD->getType()->isRecordType()) { 5034 SmallString<128> Name; 5035 llvm::raw_svector_ostream OS(Name); 5036 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5037 /*Qualified=*/true); 5038 SemaRef.Diag(E->getExprLoc(), 5039 diag::err_omp_wrong_dependency_iterator_type) 5040 << OS.str(); 5041 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5042 return false; 5043 } 5044 if (Data.first && 5045 (DepDecl || (PrevDepDecl && 5046 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5047 if (!DepDecl && PrevDepDecl) 5048 DepDecl = PrevDepDecl; 5049 SmallString<128> Name; 5050 llvm::raw_svector_ostream OS(Name); 5051 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5052 /*Qualified=*/true); 5053 SemaRef.Diag(E->getExprLoc(), 5054 diag::err_omp_invariant_or_linear_dependency) 5055 << OS.str(); 5056 return false; 5057 } 5058 if (Data.first) { 5059 DepDecl = VD; 5060 BaseLoopId = Data.first; 5061 } 5062 return Data.first; 5063 } 5064 5065 public: 5066 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5067 const ValueDecl *VD = E->getDecl(); 5068 if (isa<VarDecl>(VD)) 5069 return checkDecl(E, VD); 5070 return false; 5071 } 5072 bool VisitMemberExpr(const MemberExpr *E) { 5073 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5074 const ValueDecl *VD = E->getMemberDecl(); 5075 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5076 return checkDecl(E, VD); 5077 } 5078 return false; 5079 } 5080 bool VisitStmt(const Stmt *S) { 5081 bool Res = false; 5082 for (const Stmt *Child : S->children()) 5083 Res = (Child && Visit(Child)) || Res; 5084 return Res; 5085 } 5086 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5087 const ValueDecl *CurLCDecl, bool IsInitializer, 5088 const ValueDecl *PrevDepDecl = nullptr) 5089 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5090 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5091 unsigned getBaseLoopId() const { 5092 assert(CurLCDecl && "Expected loop dependency."); 5093 return BaseLoopId; 5094 } 5095 const ValueDecl *getDepDecl() const { 5096 assert(CurLCDecl && "Expected loop dependency."); 5097 return DepDecl; 5098 } 5099 }; 5100 } // namespace 5101 5102 Optional<unsigned> 5103 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5104 bool IsInitializer) { 5105 // Check for the non-rectangular loops. 5106 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5107 DepDecl); 5108 if (LoopStmtChecker.Visit(S)) { 5109 DepDecl = LoopStmtChecker.getDepDecl(); 5110 return LoopStmtChecker.getBaseLoopId(); 5111 } 5112 return llvm::None; 5113 } 5114 5115 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5116 // Check init-expr for canonical loop form and save loop counter 5117 // variable - #Var and its initialization value - #LB. 5118 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5119 // var = lb 5120 // integer-type var = lb 5121 // random-access-iterator-type var = lb 5122 // pointer-type var = lb 5123 // 5124 if (!S) { 5125 if (EmitDiags) { 5126 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5127 } 5128 return true; 5129 } 5130 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5131 if (!ExprTemp->cleanupsHaveSideEffects()) 5132 S = ExprTemp->getSubExpr(); 5133 5134 InitSrcRange = S->getSourceRange(); 5135 if (Expr *E = dyn_cast<Expr>(S)) 5136 S = E->IgnoreParens(); 5137 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5138 if (BO->getOpcode() == BO_Assign) { 5139 Expr *LHS = BO->getLHS()->IgnoreParens(); 5140 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5141 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5142 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5143 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5144 EmitDiags); 5145 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5146 } 5147 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5148 if (ME->isArrow() && 5149 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5150 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5151 EmitDiags); 5152 } 5153 } 5154 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5155 if (DS->isSingleDecl()) { 5156 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5157 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5158 // Accept non-canonical init form here but emit ext. warning. 5159 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5160 SemaRef.Diag(S->getBeginLoc(), 5161 diag::ext_omp_loop_not_canonical_init) 5162 << S->getSourceRange(); 5163 return setLCDeclAndLB( 5164 Var, 5165 buildDeclRefExpr(SemaRef, Var, 5166 Var->getType().getNonReferenceType(), 5167 DS->getBeginLoc()), 5168 Var->getInit(), EmitDiags); 5169 } 5170 } 5171 } 5172 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5173 if (CE->getOperator() == OO_Equal) { 5174 Expr *LHS = CE->getArg(0); 5175 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5176 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5177 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5178 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5179 EmitDiags); 5180 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5181 } 5182 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5183 if (ME->isArrow() && 5184 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5185 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5186 EmitDiags); 5187 } 5188 } 5189 } 5190 5191 if (dependent() || SemaRef.CurContext->isDependentContext()) 5192 return false; 5193 if (EmitDiags) { 5194 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5195 << S->getSourceRange(); 5196 } 5197 return true; 5198 } 5199 5200 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5201 /// variable (which may be the loop variable) if possible. 5202 static const ValueDecl *getInitLCDecl(const Expr *E) { 5203 if (!E) 5204 return nullptr; 5205 E = getExprAsWritten(E); 5206 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5207 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5208 if ((Ctor->isCopyOrMoveConstructor() || 5209 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5210 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5211 E = CE->getArg(0)->IgnoreParenImpCasts(); 5212 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5213 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5214 return getCanonicalDecl(VD); 5215 } 5216 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5217 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5218 return getCanonicalDecl(ME->getMemberDecl()); 5219 return nullptr; 5220 } 5221 5222 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5223 // Check test-expr for canonical form, save upper-bound UB, flags for 5224 // less/greater and for strict/non-strict comparison. 5225 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5226 // var relational-op b 5227 // b relational-op var 5228 // 5229 if (!S) { 5230 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 5231 return true; 5232 } 5233 Condition = S; 5234 S = getExprAsWritten(S); 5235 SourceLocation CondLoc = S->getBeginLoc(); 5236 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5237 if (BO->isRelationalOp()) { 5238 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5239 return setUB(BO->getRHS(), 5240 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5241 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5242 BO->getSourceRange(), BO->getOperatorLoc()); 5243 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5244 return setUB(BO->getLHS(), 5245 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5246 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5247 BO->getSourceRange(), BO->getOperatorLoc()); 5248 } else if (BO->getOpcode() == BO_NE) 5249 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 5250 BO->getRHS() : BO->getLHS(), 5251 /*LessOp=*/llvm::None, 5252 /*StrictOp=*/true, 5253 BO->getSourceRange(), BO->getOperatorLoc()); 5254 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5255 if (CE->getNumArgs() == 2) { 5256 auto Op = CE->getOperator(); 5257 switch (Op) { 5258 case OO_Greater: 5259 case OO_GreaterEqual: 5260 case OO_Less: 5261 case OO_LessEqual: 5262 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5263 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5264 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5265 CE->getOperatorLoc()); 5266 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5267 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5268 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5269 CE->getOperatorLoc()); 5270 break; 5271 case OO_ExclaimEqual: 5272 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 5273 CE->getArg(1) : CE->getArg(0), 5274 /*LessOp=*/llvm::None, 5275 /*StrictOp=*/true, 5276 CE->getSourceRange(), 5277 CE->getOperatorLoc()); 5278 break; 5279 default: 5280 break; 5281 } 5282 } 5283 } 5284 if (dependent() || SemaRef.CurContext->isDependentContext()) 5285 return false; 5286 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5287 << S->getSourceRange() << LCDecl; 5288 return true; 5289 } 5290 5291 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5292 // RHS of canonical loop form increment can be: 5293 // var + incr 5294 // incr + var 5295 // var - incr 5296 // 5297 RHS = RHS->IgnoreParenImpCasts(); 5298 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5299 if (BO->isAdditiveOp()) { 5300 bool IsAdd = BO->getOpcode() == BO_Add; 5301 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5302 return setStep(BO->getRHS(), !IsAdd); 5303 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5304 return setStep(BO->getLHS(), /*Subtract=*/false); 5305 } 5306 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5307 bool IsAdd = CE->getOperator() == OO_Plus; 5308 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5309 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5310 return setStep(CE->getArg(1), !IsAdd); 5311 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5312 return setStep(CE->getArg(0), /*Subtract=*/false); 5313 } 5314 } 5315 if (dependent() || SemaRef.CurContext->isDependentContext()) 5316 return false; 5317 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5318 << RHS->getSourceRange() << LCDecl; 5319 return true; 5320 } 5321 5322 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5323 // Check incr-expr for canonical loop form and return true if it 5324 // does not conform. 5325 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5326 // ++var 5327 // var++ 5328 // --var 5329 // var-- 5330 // var += incr 5331 // var -= incr 5332 // var = var + incr 5333 // var = incr + var 5334 // var = var - incr 5335 // 5336 if (!S) { 5337 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5338 return true; 5339 } 5340 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5341 if (!ExprTemp->cleanupsHaveSideEffects()) 5342 S = ExprTemp->getSubExpr(); 5343 5344 IncrementSrcRange = S->getSourceRange(); 5345 S = S->IgnoreParens(); 5346 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5347 if (UO->isIncrementDecrementOp() && 5348 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5349 return setStep(SemaRef 5350 .ActOnIntegerConstant(UO->getBeginLoc(), 5351 (UO->isDecrementOp() ? -1 : 1)) 5352 .get(), 5353 /*Subtract=*/false); 5354 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5355 switch (BO->getOpcode()) { 5356 case BO_AddAssign: 5357 case BO_SubAssign: 5358 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5359 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5360 break; 5361 case BO_Assign: 5362 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5363 return checkAndSetIncRHS(BO->getRHS()); 5364 break; 5365 default: 5366 break; 5367 } 5368 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5369 switch (CE->getOperator()) { 5370 case OO_PlusPlus: 5371 case OO_MinusMinus: 5372 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5373 return setStep(SemaRef 5374 .ActOnIntegerConstant( 5375 CE->getBeginLoc(), 5376 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5377 .get(), 5378 /*Subtract=*/false); 5379 break; 5380 case OO_PlusEqual: 5381 case OO_MinusEqual: 5382 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5383 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5384 break; 5385 case OO_Equal: 5386 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5387 return checkAndSetIncRHS(CE->getArg(1)); 5388 break; 5389 default: 5390 break; 5391 } 5392 } 5393 if (dependent() || SemaRef.CurContext->isDependentContext()) 5394 return false; 5395 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5396 << S->getSourceRange() << LCDecl; 5397 return true; 5398 } 5399 5400 static ExprResult 5401 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5402 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5403 if (SemaRef.CurContext->isDependentContext()) 5404 return ExprResult(Capture); 5405 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5406 return SemaRef.PerformImplicitConversion( 5407 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5408 /*AllowExplicit=*/true); 5409 auto I = Captures.find(Capture); 5410 if (I != Captures.end()) 5411 return buildCapture(SemaRef, Capture, I->second); 5412 DeclRefExpr *Ref = nullptr; 5413 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5414 Captures[Capture] = Ref; 5415 return Res; 5416 } 5417 5418 /// Build the expression to calculate the number of iterations. 5419 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5420 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5421 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5422 ExprResult Diff; 5423 QualType VarType = LCDecl->getType().getNonReferenceType(); 5424 if (VarType->isIntegerType() || VarType->isPointerType() || 5425 SemaRef.getLangOpts().CPlusPlus) { 5426 Expr *LBVal = LB; 5427 Expr *UBVal = UB; 5428 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5429 // max(LB(MinVal), LB(MaxVal)) 5430 if (InitDependOnLC) { 5431 const LoopIterationSpace &IS = 5432 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5433 InitDependOnLC.getValueOr( 5434 CondDependOnLC.getValueOr(0))]; 5435 if (!IS.MinValue || !IS.MaxValue) 5436 return nullptr; 5437 // OuterVar = Min 5438 ExprResult MinValue = 5439 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5440 if (!MinValue.isUsable()) 5441 return nullptr; 5442 5443 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5444 IS.CounterVar, MinValue.get()); 5445 if (!LBMinVal.isUsable()) 5446 return nullptr; 5447 // OuterVar = Min, LBVal 5448 LBMinVal = 5449 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5450 if (!LBMinVal.isUsable()) 5451 return nullptr; 5452 // (OuterVar = Min, LBVal) 5453 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5454 if (!LBMinVal.isUsable()) 5455 return nullptr; 5456 5457 // OuterVar = Max 5458 ExprResult MaxValue = 5459 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5460 if (!MaxValue.isUsable()) 5461 return nullptr; 5462 5463 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5464 IS.CounterVar, MaxValue.get()); 5465 if (!LBMaxVal.isUsable()) 5466 return nullptr; 5467 // OuterVar = Max, LBVal 5468 LBMaxVal = 5469 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5470 if (!LBMaxVal.isUsable()) 5471 return nullptr; 5472 // (OuterVar = Max, LBVal) 5473 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5474 if (!LBMaxVal.isUsable()) 5475 return nullptr; 5476 5477 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5478 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5479 if (!LBMin || !LBMax) 5480 return nullptr; 5481 // LB(MinVal) < LB(MaxVal) 5482 ExprResult MinLessMaxRes = 5483 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 5484 if (!MinLessMaxRes.isUsable()) 5485 return nullptr; 5486 Expr *MinLessMax = 5487 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 5488 if (!MinLessMax) 5489 return nullptr; 5490 if (TestIsLessOp.getValue()) { 5491 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 5492 // LB(MaxVal)) 5493 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5494 MinLessMax, LBMin, LBMax); 5495 if (!MinLB.isUsable()) 5496 return nullptr; 5497 LBVal = MinLB.get(); 5498 } else { 5499 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 5500 // LB(MaxVal)) 5501 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5502 MinLessMax, LBMax, LBMin); 5503 if (!MaxLB.isUsable()) 5504 return nullptr; 5505 LBVal = MaxLB.get(); 5506 } 5507 } 5508 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 5509 // min(UB(MinVal), UB(MaxVal)) 5510 if (CondDependOnLC) { 5511 const LoopIterationSpace &IS = 5512 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5513 InitDependOnLC.getValueOr( 5514 CondDependOnLC.getValueOr(0))]; 5515 if (!IS.MinValue || !IS.MaxValue) 5516 return nullptr; 5517 // OuterVar = Min 5518 ExprResult MinValue = 5519 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5520 if (!MinValue.isUsable()) 5521 return nullptr; 5522 5523 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5524 IS.CounterVar, MinValue.get()); 5525 if (!UBMinVal.isUsable()) 5526 return nullptr; 5527 // OuterVar = Min, UBVal 5528 UBMinVal = 5529 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 5530 if (!UBMinVal.isUsable()) 5531 return nullptr; 5532 // (OuterVar = Min, UBVal) 5533 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 5534 if (!UBMinVal.isUsable()) 5535 return nullptr; 5536 5537 // OuterVar = Max 5538 ExprResult MaxValue = 5539 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5540 if (!MaxValue.isUsable()) 5541 return nullptr; 5542 5543 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5544 IS.CounterVar, MaxValue.get()); 5545 if (!UBMaxVal.isUsable()) 5546 return nullptr; 5547 // OuterVar = Max, UBVal 5548 UBMaxVal = 5549 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 5550 if (!UBMaxVal.isUsable()) 5551 return nullptr; 5552 // (OuterVar = Max, UBVal) 5553 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 5554 if (!UBMaxVal.isUsable()) 5555 return nullptr; 5556 5557 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 5558 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 5559 if (!UBMin || !UBMax) 5560 return nullptr; 5561 // UB(MinVal) > UB(MaxVal) 5562 ExprResult MinGreaterMaxRes = 5563 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 5564 if (!MinGreaterMaxRes.isUsable()) 5565 return nullptr; 5566 Expr *MinGreaterMax = 5567 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 5568 if (!MinGreaterMax) 5569 return nullptr; 5570 if (TestIsLessOp.getValue()) { 5571 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 5572 // UB(MaxVal)) 5573 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 5574 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 5575 if (!MaxUB.isUsable()) 5576 return nullptr; 5577 UBVal = MaxUB.get(); 5578 } else { 5579 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 5580 // UB(MaxVal)) 5581 ExprResult MinUB = SemaRef.ActOnConditionalOp( 5582 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 5583 if (!MinUB.isUsable()) 5584 return nullptr; 5585 UBVal = MinUB.get(); 5586 } 5587 } 5588 // Upper - Lower 5589 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 5590 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 5591 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5592 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5593 if (!Upper || !Lower) 5594 return nullptr; 5595 5596 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5597 5598 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5599 // BuildBinOp already emitted error, this one is to point user to upper 5600 // and lower bound, and to tell what is passed to 'operator-'. 5601 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5602 << Upper->getSourceRange() << Lower->getSourceRange(); 5603 return nullptr; 5604 } 5605 } 5606 5607 if (!Diff.isUsable()) 5608 return nullptr; 5609 5610 // Upper - Lower [- 1] 5611 if (TestIsStrictOp) 5612 Diff = SemaRef.BuildBinOp( 5613 S, DefaultLoc, BO_Sub, Diff.get(), 5614 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5615 if (!Diff.isUsable()) 5616 return nullptr; 5617 5618 // Upper - Lower [- 1] + Step 5619 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5620 if (!NewStep.isUsable()) 5621 return nullptr; 5622 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5623 if (!Diff.isUsable()) 5624 return nullptr; 5625 5626 // Parentheses (for dumping/debugging purposes only). 5627 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5628 if (!Diff.isUsable()) 5629 return nullptr; 5630 5631 // (Upper - Lower [- 1] + Step) / Step 5632 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5633 if (!Diff.isUsable()) 5634 return nullptr; 5635 5636 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5637 QualType Type = Diff.get()->getType(); 5638 ASTContext &C = SemaRef.Context; 5639 bool UseVarType = VarType->hasIntegerRepresentation() && 5640 C.getTypeSize(Type) > C.getTypeSize(VarType); 5641 if (!Type->isIntegerType() || UseVarType) { 5642 unsigned NewSize = 5643 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5644 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5645 : Type->hasSignedIntegerRepresentation(); 5646 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5647 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5648 Diff = SemaRef.PerformImplicitConversion( 5649 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5650 if (!Diff.isUsable()) 5651 return nullptr; 5652 } 5653 } 5654 if (LimitedType) { 5655 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5656 if (NewSize != C.getTypeSize(Type)) { 5657 if (NewSize < C.getTypeSize(Type)) { 5658 assert(NewSize == 64 && "incorrect loop var size"); 5659 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5660 << InitSrcRange << ConditionSrcRange; 5661 } 5662 QualType NewType = C.getIntTypeForBitwidth( 5663 NewSize, Type->hasSignedIntegerRepresentation() || 5664 C.getTypeSize(Type) < NewSize); 5665 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5666 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5667 Sema::AA_Converting, true); 5668 if (!Diff.isUsable()) 5669 return nullptr; 5670 } 5671 } 5672 } 5673 5674 return Diff.get(); 5675 } 5676 5677 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 5678 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5679 // Do not build for iterators, they cannot be used in non-rectangular loop 5680 // nests. 5681 if (LCDecl->getType()->isRecordType()) 5682 return std::make_pair(nullptr, nullptr); 5683 // If we subtract, the min is in the condition, otherwise the min is in the 5684 // init value. 5685 Expr *MinExpr = nullptr; 5686 Expr *MaxExpr = nullptr; 5687 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5688 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5689 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 5690 : CondDependOnLC.hasValue(); 5691 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 5692 : InitDependOnLC.hasValue(); 5693 Expr *Lower = 5694 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5695 Expr *Upper = 5696 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5697 if (!Upper || !Lower) 5698 return std::make_pair(nullptr, nullptr); 5699 5700 if (TestIsLessOp.getValue()) 5701 MinExpr = Lower; 5702 else 5703 MaxExpr = Upper; 5704 5705 // Build minimum/maximum value based on number of iterations. 5706 ExprResult Diff; 5707 QualType VarType = LCDecl->getType().getNonReferenceType(); 5708 5709 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5710 if (!Diff.isUsable()) 5711 return std::make_pair(nullptr, nullptr); 5712 5713 // Upper - Lower [- 1] 5714 if (TestIsStrictOp) 5715 Diff = SemaRef.BuildBinOp( 5716 S, DefaultLoc, BO_Sub, Diff.get(), 5717 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5718 if (!Diff.isUsable()) 5719 return std::make_pair(nullptr, nullptr); 5720 5721 // Upper - Lower [- 1] + Step 5722 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5723 if (!NewStep.isUsable()) 5724 return std::make_pair(nullptr, nullptr); 5725 5726 // Parentheses (for dumping/debugging purposes only). 5727 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5728 if (!Diff.isUsable()) 5729 return std::make_pair(nullptr, nullptr); 5730 5731 // (Upper - Lower [- 1]) / Step 5732 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5733 if (!Diff.isUsable()) 5734 return std::make_pair(nullptr, nullptr); 5735 5736 // ((Upper - Lower [- 1]) / Step) * Step 5737 // Parentheses (for dumping/debugging purposes only). 5738 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5739 if (!Diff.isUsable()) 5740 return std::make_pair(nullptr, nullptr); 5741 5742 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 5743 if (!Diff.isUsable()) 5744 return std::make_pair(nullptr, nullptr); 5745 5746 // Convert to the original type or ptrdiff_t, if original type is pointer. 5747 if (!VarType->isAnyPointerType() && 5748 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 5749 Diff = SemaRef.PerformImplicitConversion( 5750 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 5751 } else if (VarType->isAnyPointerType() && 5752 !SemaRef.Context.hasSameType( 5753 Diff.get()->getType(), 5754 SemaRef.Context.getUnsignedPointerDiffType())) { 5755 Diff = SemaRef.PerformImplicitConversion( 5756 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 5757 Sema::AA_Converting, /*AllowExplicit=*/true); 5758 } 5759 if (!Diff.isUsable()) 5760 return std::make_pair(nullptr, nullptr); 5761 5762 // Parentheses (for dumping/debugging purposes only). 5763 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5764 if (!Diff.isUsable()) 5765 return std::make_pair(nullptr, nullptr); 5766 5767 if (TestIsLessOp.getValue()) { 5768 // MinExpr = Lower; 5769 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 5770 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 5771 if (!Diff.isUsable()) 5772 return std::make_pair(nullptr, nullptr); 5773 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5774 if (!Diff.isUsable()) 5775 return std::make_pair(nullptr, nullptr); 5776 MaxExpr = Diff.get(); 5777 } else { 5778 // MaxExpr = Upper; 5779 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 5780 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 5781 if (!Diff.isUsable()) 5782 return std::make_pair(nullptr, nullptr); 5783 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 5784 if (!Diff.isUsable()) 5785 return std::make_pair(nullptr, nullptr); 5786 MinExpr = Diff.get(); 5787 } 5788 5789 return std::make_pair(MinExpr, MaxExpr); 5790 } 5791 5792 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 5793 if (InitDependOnLC || CondDependOnLC) 5794 return Condition; 5795 return nullptr; 5796 } 5797 5798 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5799 Scope *S, Expr *Cond, 5800 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5801 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5802 Sema::TentativeAnalysisScope Trap(SemaRef); 5803 5804 ExprResult NewLB = 5805 InitDependOnLC ? LB : tryBuildCapture(SemaRef, LB, Captures); 5806 ExprResult NewUB = 5807 CondDependOnLC ? UB : tryBuildCapture(SemaRef, UB, Captures); 5808 if (!NewLB.isUsable() || !NewUB.isUsable()) 5809 return nullptr; 5810 5811 ExprResult CondExpr = 5812 SemaRef.BuildBinOp(S, DefaultLoc, 5813 TestIsLessOp.getValue() ? 5814 (TestIsStrictOp ? BO_LT : BO_LE) : 5815 (TestIsStrictOp ? BO_GT : BO_GE), 5816 NewLB.get(), NewUB.get()); 5817 if (CondExpr.isUsable()) { 5818 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 5819 SemaRef.Context.BoolTy)) 5820 CondExpr = SemaRef.PerformImplicitConversion( 5821 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 5822 /*AllowExplicit=*/true); 5823 } 5824 5825 // Otherwise use original loop condition and evaluate it in runtime. 5826 return CondExpr.isUsable() ? CondExpr.get() : Cond; 5827 } 5828 5829 /// Build reference expression to the counter be used for codegen. 5830 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 5831 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5832 DSAStackTy &DSA) const { 5833 auto *VD = dyn_cast<VarDecl>(LCDecl); 5834 if (!VD) { 5835 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 5836 DeclRefExpr *Ref = buildDeclRefExpr( 5837 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 5838 const DSAStackTy::DSAVarData Data = 5839 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 5840 // If the loop control decl is explicitly marked as private, do not mark it 5841 // as captured again. 5842 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 5843 Captures.insert(std::make_pair(LCRef, Ref)); 5844 return Ref; 5845 } 5846 return cast<DeclRefExpr>(LCRef); 5847 } 5848 5849 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 5850 if (LCDecl && !LCDecl->isInvalidDecl()) { 5851 QualType Type = LCDecl->getType().getNonReferenceType(); 5852 VarDecl *PrivateVar = buildVarDecl( 5853 SemaRef, DefaultLoc, Type, LCDecl->getName(), 5854 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 5855 isa<VarDecl>(LCDecl) 5856 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 5857 : nullptr); 5858 if (PrivateVar->isInvalidDecl()) 5859 return nullptr; 5860 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 5861 } 5862 return nullptr; 5863 } 5864 5865 /// Build initialization of the counter to be used for codegen. 5866 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 5867 5868 /// Build step of the counter be used for codegen. 5869 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 5870 5871 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 5872 Scope *S, Expr *Counter, 5873 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 5874 Expr *Inc, OverloadedOperatorKind OOK) { 5875 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 5876 if (!Cnt) 5877 return nullptr; 5878 if (Inc) { 5879 assert((OOK == OO_Plus || OOK == OO_Minus) && 5880 "Expected only + or - operations for depend clauses."); 5881 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 5882 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 5883 if (!Cnt) 5884 return nullptr; 5885 } 5886 ExprResult Diff; 5887 QualType VarType = LCDecl->getType().getNonReferenceType(); 5888 if (VarType->isIntegerType() || VarType->isPointerType() || 5889 SemaRef.getLangOpts().CPlusPlus) { 5890 // Upper - Lower 5891 Expr *Upper = TestIsLessOp.getValue() 5892 ? Cnt 5893 : tryBuildCapture(SemaRef, UB, Captures).get(); 5894 Expr *Lower = TestIsLessOp.getValue() 5895 ? tryBuildCapture(SemaRef, LB, Captures).get() 5896 : Cnt; 5897 if (!Upper || !Lower) 5898 return nullptr; 5899 5900 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5901 5902 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5903 // BuildBinOp already emitted error, this one is to point user to upper 5904 // and lower bound, and to tell what is passed to 'operator-'. 5905 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5906 << Upper->getSourceRange() << Lower->getSourceRange(); 5907 return nullptr; 5908 } 5909 } 5910 5911 if (!Diff.isUsable()) 5912 return nullptr; 5913 5914 // Parentheses (for dumping/debugging purposes only). 5915 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5916 if (!Diff.isUsable()) 5917 return nullptr; 5918 5919 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5920 if (!NewStep.isUsable()) 5921 return nullptr; 5922 // (Upper - Lower) / Step 5923 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5924 if (!Diff.isUsable()) 5925 return nullptr; 5926 5927 return Diff.get(); 5928 } 5929 } // namespace 5930 5931 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5932 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5933 assert(Init && "Expected loop in canonical form."); 5934 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5935 if (AssociatedLoops > 0 && 5936 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5937 DSAStack->loopStart(); 5938 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 5939 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5940 if (ValueDecl *D = ISC.getLoopDecl()) { 5941 auto *VD = dyn_cast<VarDecl>(D); 5942 DeclRefExpr *PrivateRef = nullptr; 5943 if (!VD) { 5944 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5945 VD = Private; 5946 } else { 5947 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5948 /*WithInit=*/false); 5949 VD = cast<VarDecl>(PrivateRef->getDecl()); 5950 } 5951 } 5952 DSAStack->addLoopControlVariable(D, VD); 5953 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5954 if (LD != D->getCanonicalDecl()) { 5955 DSAStack->resetPossibleLoopCounter(); 5956 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5957 MarkDeclarationsReferencedInExpr( 5958 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5959 Var->getType().getNonLValueExprType(Context), 5960 ForLoc, /*RefersToCapture=*/true)); 5961 } 5962 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 5963 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 5964 // Referenced in a Construct, C/C++]. The loop iteration variable in the 5965 // associated for-loop of a simd construct with just one associated 5966 // for-loop may be listed in a linear clause with a constant-linear-step 5967 // that is the increment of the associated for-loop. The loop iteration 5968 // variable(s) in the associated for-loop(s) of a for or parallel for 5969 // construct may be listed in a private or lastprivate clause. 5970 DSAStackTy::DSAVarData DVar = 5971 DSAStack->getTopDSA(D, /*FromParent=*/false); 5972 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 5973 // is declared in the loop and it is predetermined as a private. 5974 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5975 OpenMPClauseKind PredeterminedCKind = 5976 isOpenMPSimdDirective(DKind) 5977 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 5978 : OMPC_private; 5979 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5980 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 5981 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 5982 DVar.CKind != OMPC_private))) || 5983 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5984 isOpenMPDistributeDirective(DKind)) && 5985 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5986 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5987 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 5988 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5989 << getOpenMPClauseName(DVar.CKind) 5990 << getOpenMPDirectiveName(DKind) 5991 << getOpenMPClauseName(PredeterminedCKind); 5992 if (DVar.RefExpr == nullptr) 5993 DVar.CKind = PredeterminedCKind; 5994 reportOriginalDsa(*this, DSAStack, D, DVar, 5995 /*IsLoopIterVar=*/true); 5996 } else if (LoopDeclRefExpr) { 5997 // Make the loop iteration variable private (for worksharing 5998 // constructs), linear (for simd directives with the only one 5999 // associated loop) or lastprivate (for simd directives with several 6000 // collapsed or ordered loops). 6001 if (DVar.CKind == OMPC_unknown) 6002 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6003 PrivateRef); 6004 } 6005 } 6006 } 6007 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6008 } 6009 } 6010 6011 /// Called on a for stmt to check and extract its iteration space 6012 /// for further processing (such as collapsing). 6013 static bool checkOpenMPIterationSpace( 6014 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6015 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6016 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6017 Expr *OrderedLoopCountExpr, 6018 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6019 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6020 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6021 // OpenMP [2.6, Canonical Loop Form] 6022 // for (init-expr; test-expr; incr-expr) structured-block 6023 auto *For = dyn_cast_or_null<ForStmt>(S); 6024 if (!For) { 6025 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6026 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6027 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6028 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6029 if (TotalNestedLoopCount > 1) { 6030 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6031 SemaRef.Diag(DSA.getConstructLoc(), 6032 diag::note_omp_collapse_ordered_expr) 6033 << 2 << CollapseLoopCountExpr->getSourceRange() 6034 << OrderedLoopCountExpr->getSourceRange(); 6035 else if (CollapseLoopCountExpr) 6036 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6037 diag::note_omp_collapse_ordered_expr) 6038 << 0 << CollapseLoopCountExpr->getSourceRange(); 6039 else 6040 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6041 diag::note_omp_collapse_ordered_expr) 6042 << 1 << OrderedLoopCountExpr->getSourceRange(); 6043 } 6044 return true; 6045 } 6046 assert(For->getBody()); 6047 6048 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 6049 6050 // Check init. 6051 Stmt *Init = For->getInit(); 6052 if (ISC.checkAndSetInit(Init)) 6053 return true; 6054 6055 bool HasErrors = false; 6056 6057 // Check loop variable's type. 6058 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6059 // OpenMP [2.6, Canonical Loop Form] 6060 // Var is one of the following: 6061 // A variable of signed or unsigned integer type. 6062 // For C++, a variable of a random access iterator type. 6063 // For C, a variable of a pointer type. 6064 QualType VarType = LCDecl->getType().getNonReferenceType(); 6065 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6066 !VarType->isPointerType() && 6067 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6068 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6069 << SemaRef.getLangOpts().CPlusPlus; 6070 HasErrors = true; 6071 } 6072 6073 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6074 // a Construct 6075 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6076 // parallel for construct is (are) private. 6077 // The loop iteration variable in the associated for-loop of a simd 6078 // construct with just one associated for-loop is linear with a 6079 // constant-linear-step that is the increment of the associated for-loop. 6080 // Exclude loop var from the list of variables with implicitly defined data 6081 // sharing attributes. 6082 VarsWithImplicitDSA.erase(LCDecl); 6083 6084 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6085 6086 // Check test-expr. 6087 HasErrors |= ISC.checkAndSetCond(For->getCond()); 6088 6089 // Check incr-expr. 6090 HasErrors |= ISC.checkAndSetInc(For->getInc()); 6091 } 6092 6093 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6094 return HasErrors; 6095 6096 // Build the loop's iteration space representation. 6097 ResultIterSpaces[CurrentNestedLoopCount].PreCond = 6098 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 6099 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6100 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6101 (isOpenMPWorksharingDirective(DKind) || 6102 isOpenMPTaskLoopDirective(DKind) || 6103 isOpenMPDistributeDirective(DKind)), 6104 Captures); 6105 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6106 ISC.buildCounterVar(Captures, DSA); 6107 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6108 ISC.buildPrivateCounterVar(); 6109 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6110 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6111 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6112 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6113 ISC.getConditionSrcRange(); 6114 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6115 ISC.getIncrementSrcRange(); 6116 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6117 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6118 ISC.isStrictTestOp(); 6119 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6120 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6121 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6122 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6123 ISC.buildFinalCondition(DSA.getCurScope()); 6124 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6125 ISC.doesInitDependOnLC(); 6126 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6127 ISC.doesCondDependOnLC(); 6128 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6129 ISC.getLoopDependentIdx(); 6130 6131 HasErrors |= 6132 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6133 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6134 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6135 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6136 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6137 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6138 if (!HasErrors && DSA.isOrderedRegion()) { 6139 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6140 if (CurrentNestedLoopCount < 6141 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6142 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6143 CurrentNestedLoopCount, 6144 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6145 DSA.getOrderedRegionParam().second->setLoopCounter( 6146 CurrentNestedLoopCount, 6147 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6148 } 6149 } 6150 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6151 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6152 // Erroneous case - clause has some problems. 6153 continue; 6154 } 6155 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6156 Pair.second.size() <= CurrentNestedLoopCount) { 6157 // Erroneous case - clause has some problems. 6158 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6159 continue; 6160 } 6161 Expr *CntValue; 6162 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6163 CntValue = ISC.buildOrderedLoopData( 6164 DSA.getCurScope(), 6165 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6166 Pair.first->getDependencyLoc()); 6167 else 6168 CntValue = ISC.buildOrderedLoopData( 6169 DSA.getCurScope(), 6170 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6171 Pair.first->getDependencyLoc(), 6172 Pair.second[CurrentNestedLoopCount].first, 6173 Pair.second[CurrentNestedLoopCount].second); 6174 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6175 } 6176 } 6177 6178 return HasErrors; 6179 } 6180 6181 /// Build 'VarRef = Start. 6182 static ExprResult 6183 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6184 ExprResult Start, bool IsNonRectangularLB, 6185 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6186 // Build 'VarRef = Start. 6187 ExprResult NewStart = IsNonRectangularLB 6188 ? Start.get() 6189 : tryBuildCapture(SemaRef, Start.get(), Captures); 6190 if (!NewStart.isUsable()) 6191 return ExprError(); 6192 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6193 VarRef.get()->getType())) { 6194 NewStart = SemaRef.PerformImplicitConversion( 6195 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6196 /*AllowExplicit=*/true); 6197 if (!NewStart.isUsable()) 6198 return ExprError(); 6199 } 6200 6201 ExprResult Init = 6202 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6203 return Init; 6204 } 6205 6206 /// Build 'VarRef = Start + Iter * Step'. 6207 static ExprResult buildCounterUpdate( 6208 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6209 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6210 bool IsNonRectangularLB, 6211 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6212 // Add parentheses (for debugging purposes only). 6213 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6214 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6215 !Step.isUsable()) 6216 return ExprError(); 6217 6218 ExprResult NewStep = Step; 6219 if (Captures) 6220 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6221 if (NewStep.isInvalid()) 6222 return ExprError(); 6223 ExprResult Update = 6224 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6225 if (!Update.isUsable()) 6226 return ExprError(); 6227 6228 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6229 // 'VarRef = Start (+|-) Iter * Step'. 6230 if (!Start.isUsable()) 6231 return ExprError(); 6232 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6233 if (!NewStart.isUsable()) 6234 return ExprError(); 6235 if (Captures && !IsNonRectangularLB) 6236 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6237 if (NewStart.isInvalid()) 6238 return ExprError(); 6239 6240 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6241 ExprResult SavedUpdate = Update; 6242 ExprResult UpdateVal; 6243 if (VarRef.get()->getType()->isOverloadableType() || 6244 NewStart.get()->getType()->isOverloadableType() || 6245 Update.get()->getType()->isOverloadableType()) { 6246 Sema::TentativeAnalysisScope Trap(SemaRef); 6247 6248 Update = 6249 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6250 if (Update.isUsable()) { 6251 UpdateVal = 6252 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6253 VarRef.get(), SavedUpdate.get()); 6254 if (UpdateVal.isUsable()) { 6255 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6256 UpdateVal.get()); 6257 } 6258 } 6259 } 6260 6261 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6262 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6263 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6264 NewStart.get(), SavedUpdate.get()); 6265 if (!Update.isUsable()) 6266 return ExprError(); 6267 6268 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6269 VarRef.get()->getType())) { 6270 Update = SemaRef.PerformImplicitConversion( 6271 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6272 if (!Update.isUsable()) 6273 return ExprError(); 6274 } 6275 6276 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6277 } 6278 return Update; 6279 } 6280 6281 /// Convert integer expression \a E to make it have at least \a Bits 6282 /// bits. 6283 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6284 if (E == nullptr) 6285 return ExprError(); 6286 ASTContext &C = SemaRef.Context; 6287 QualType OldType = E->getType(); 6288 unsigned HasBits = C.getTypeSize(OldType); 6289 if (HasBits >= Bits) 6290 return ExprResult(E); 6291 // OK to convert to signed, because new type has more bits than old. 6292 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6293 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6294 true); 6295 } 6296 6297 /// Check if the given expression \a E is a constant integer that fits 6298 /// into \a Bits bits. 6299 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6300 if (E == nullptr) 6301 return false; 6302 llvm::APSInt Result; 6303 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6304 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6305 return false; 6306 } 6307 6308 /// Build preinits statement for the given declarations. 6309 static Stmt *buildPreInits(ASTContext &Context, 6310 MutableArrayRef<Decl *> PreInits) { 6311 if (!PreInits.empty()) { 6312 return new (Context) DeclStmt( 6313 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6314 SourceLocation(), SourceLocation()); 6315 } 6316 return nullptr; 6317 } 6318 6319 /// Build preinits statement for the given declarations. 6320 static Stmt * 6321 buildPreInits(ASTContext &Context, 6322 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6323 if (!Captures.empty()) { 6324 SmallVector<Decl *, 16> PreInits; 6325 for (const auto &Pair : Captures) 6326 PreInits.push_back(Pair.second->getDecl()); 6327 return buildPreInits(Context, PreInits); 6328 } 6329 return nullptr; 6330 } 6331 6332 /// Build postupdate expression for the given list of postupdates expressions. 6333 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6334 Expr *PostUpdate = nullptr; 6335 if (!PostUpdates.empty()) { 6336 for (Expr *E : PostUpdates) { 6337 Expr *ConvE = S.BuildCStyleCastExpr( 6338 E->getExprLoc(), 6339 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6340 E->getExprLoc(), E) 6341 .get(); 6342 PostUpdate = PostUpdate 6343 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6344 PostUpdate, ConvE) 6345 .get() 6346 : ConvE; 6347 } 6348 } 6349 return PostUpdate; 6350 } 6351 6352 /// Called on a for stmt to check itself and nested loops (if any). 6353 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6354 /// number of collapsed loops otherwise. 6355 static unsigned 6356 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6357 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6358 DSAStackTy &DSA, 6359 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6360 OMPLoopDirective::HelperExprs &Built) { 6361 unsigned NestedLoopCount = 1; 6362 if (CollapseLoopCountExpr) { 6363 // Found 'collapse' clause - calculate collapse number. 6364 Expr::EvalResult Result; 6365 if (!CollapseLoopCountExpr->isValueDependent() && 6366 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6367 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6368 } else { 6369 Built.clear(/*Size=*/1); 6370 return 1; 6371 } 6372 } 6373 unsigned OrderedLoopCount = 1; 6374 if (OrderedLoopCountExpr) { 6375 // Found 'ordered' clause - calculate collapse number. 6376 Expr::EvalResult EVResult; 6377 if (!OrderedLoopCountExpr->isValueDependent() && 6378 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6379 SemaRef.getASTContext())) { 6380 llvm::APSInt Result = EVResult.Val.getInt(); 6381 if (Result.getLimitedValue() < NestedLoopCount) { 6382 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6383 diag::err_omp_wrong_ordered_loop_count) 6384 << OrderedLoopCountExpr->getSourceRange(); 6385 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6386 diag::note_collapse_loop_count) 6387 << CollapseLoopCountExpr->getSourceRange(); 6388 } 6389 OrderedLoopCount = Result.getLimitedValue(); 6390 } else { 6391 Built.clear(/*Size=*/1); 6392 return 1; 6393 } 6394 } 6395 // This is helper routine for loop directives (e.g., 'for', 'simd', 6396 // 'for simd', etc.). 6397 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6398 SmallVector<LoopIterationSpace, 4> IterSpaces( 6399 std::max(OrderedLoopCount, NestedLoopCount)); 6400 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6401 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6402 if (checkOpenMPIterationSpace( 6403 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6404 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6405 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6406 return 0; 6407 // Move on to the next nested for loop, or to the loop body. 6408 // OpenMP [2.8.1, simd construct, Restrictions] 6409 // All loops associated with the construct must be perfectly nested; that 6410 // is, there must be no intervening code nor any OpenMP directive between 6411 // any two loops. 6412 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6413 } 6414 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6415 if (checkOpenMPIterationSpace( 6416 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6417 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6418 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6419 return 0; 6420 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6421 // Handle initialization of captured loop iterator variables. 6422 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6423 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6424 Captures[DRE] = DRE; 6425 } 6426 } 6427 // Move on to the next nested for loop, or to the loop body. 6428 // OpenMP [2.8.1, simd construct, Restrictions] 6429 // All loops associated with the construct must be perfectly nested; that 6430 // is, there must be no intervening code nor any OpenMP directive between 6431 // any two loops. 6432 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6433 } 6434 6435 Built.clear(/* size */ NestedLoopCount); 6436 6437 if (SemaRef.CurContext->isDependentContext()) 6438 return NestedLoopCount; 6439 6440 // An example of what is generated for the following code: 6441 // 6442 // #pragma omp simd collapse(2) ordered(2) 6443 // for (i = 0; i < NI; ++i) 6444 // for (k = 0; k < NK; ++k) 6445 // for (j = J0; j < NJ; j+=2) { 6446 // <loop body> 6447 // } 6448 // 6449 // We generate the code below. 6450 // Note: the loop body may be outlined in CodeGen. 6451 // Note: some counters may be C++ classes, operator- is used to find number of 6452 // iterations and operator+= to calculate counter value. 6453 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6454 // or i64 is currently supported). 6455 // 6456 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6457 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6458 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6459 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6460 // // similar updates for vars in clauses (e.g. 'linear') 6461 // <loop body (using local i and j)> 6462 // } 6463 // i = NI; // assign final values of counters 6464 // j = NJ; 6465 // 6466 6467 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6468 // the iteration counts of the collapsed for loops. 6469 // Precondition tests if there is at least one iteration (all conditions are 6470 // true). 6471 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6472 Expr *N0 = IterSpaces[0].NumIterations; 6473 ExprResult LastIteration32 = 6474 widenIterationCount(/*Bits=*/32, 6475 SemaRef 6476 .PerformImplicitConversion( 6477 N0->IgnoreImpCasts(), N0->getType(), 6478 Sema::AA_Converting, /*AllowExplicit=*/true) 6479 .get(), 6480 SemaRef); 6481 ExprResult LastIteration64 = widenIterationCount( 6482 /*Bits=*/64, 6483 SemaRef 6484 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6485 Sema::AA_Converting, 6486 /*AllowExplicit=*/true) 6487 .get(), 6488 SemaRef); 6489 6490 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6491 return NestedLoopCount; 6492 6493 ASTContext &C = SemaRef.Context; 6494 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6495 6496 Scope *CurScope = DSA.getCurScope(); 6497 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6498 if (PreCond.isUsable()) { 6499 PreCond = 6500 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6501 PreCond.get(), IterSpaces[Cnt].PreCond); 6502 } 6503 Expr *N = IterSpaces[Cnt].NumIterations; 6504 SourceLocation Loc = N->getExprLoc(); 6505 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6506 if (LastIteration32.isUsable()) 6507 LastIteration32 = SemaRef.BuildBinOp( 6508 CurScope, Loc, BO_Mul, LastIteration32.get(), 6509 SemaRef 6510 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6511 Sema::AA_Converting, 6512 /*AllowExplicit=*/true) 6513 .get()); 6514 if (LastIteration64.isUsable()) 6515 LastIteration64 = SemaRef.BuildBinOp( 6516 CurScope, Loc, BO_Mul, LastIteration64.get(), 6517 SemaRef 6518 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6519 Sema::AA_Converting, 6520 /*AllowExplicit=*/true) 6521 .get()); 6522 } 6523 6524 // Choose either the 32-bit or 64-bit version. 6525 ExprResult LastIteration = LastIteration64; 6526 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6527 (LastIteration32.isUsable() && 6528 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6529 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6530 fitsInto( 6531 /*Bits=*/32, 6532 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6533 LastIteration64.get(), SemaRef)))) 6534 LastIteration = LastIteration32; 6535 QualType VType = LastIteration.get()->getType(); 6536 QualType RealVType = VType; 6537 QualType StrideVType = VType; 6538 if (isOpenMPTaskLoopDirective(DKind)) { 6539 VType = 6540 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6541 StrideVType = 6542 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6543 } 6544 6545 if (!LastIteration.isUsable()) 6546 return 0; 6547 6548 // Save the number of iterations. 6549 ExprResult NumIterations = LastIteration; 6550 { 6551 LastIteration = SemaRef.BuildBinOp( 6552 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6553 LastIteration.get(), 6554 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6555 if (!LastIteration.isUsable()) 6556 return 0; 6557 } 6558 6559 // Calculate the last iteration number beforehand instead of doing this on 6560 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6561 llvm::APSInt Result; 6562 bool IsConstant = 6563 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6564 ExprResult CalcLastIteration; 6565 if (!IsConstant) { 6566 ExprResult SaveRef = 6567 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6568 LastIteration = SaveRef; 6569 6570 // Prepare SaveRef + 1. 6571 NumIterations = SemaRef.BuildBinOp( 6572 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6573 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6574 if (!NumIterations.isUsable()) 6575 return 0; 6576 } 6577 6578 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6579 6580 // Build variables passed into runtime, necessary for worksharing directives. 6581 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6582 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6583 isOpenMPDistributeDirective(DKind)) { 6584 // Lower bound variable, initialized with zero. 6585 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6586 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6587 SemaRef.AddInitializerToDecl(LBDecl, 6588 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6589 /*DirectInit*/ false); 6590 6591 // Upper bound variable, initialized with last iteration number. 6592 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6593 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6594 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6595 /*DirectInit*/ false); 6596 6597 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6598 // This will be used to implement clause 'lastprivate'. 6599 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6600 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6601 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6602 SemaRef.AddInitializerToDecl(ILDecl, 6603 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6604 /*DirectInit*/ false); 6605 6606 // Stride variable returned by runtime (we initialize it to 1 by default). 6607 VarDecl *STDecl = 6608 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6609 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6610 SemaRef.AddInitializerToDecl(STDecl, 6611 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6612 /*DirectInit*/ false); 6613 6614 // Build expression: UB = min(UB, LastIteration) 6615 // It is necessary for CodeGen of directives with static scheduling. 6616 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6617 UB.get(), LastIteration.get()); 6618 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6619 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6620 LastIteration.get(), UB.get()); 6621 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6622 CondOp.get()); 6623 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6624 6625 // If we have a combined directive that combines 'distribute', 'for' or 6626 // 'simd' we need to be able to access the bounds of the schedule of the 6627 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6628 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6629 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6630 // Lower bound variable, initialized with zero. 6631 VarDecl *CombLBDecl = 6632 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6633 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6634 SemaRef.AddInitializerToDecl( 6635 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6636 /*DirectInit*/ false); 6637 6638 // Upper bound variable, initialized with last iteration number. 6639 VarDecl *CombUBDecl = 6640 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6641 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6642 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6643 /*DirectInit*/ false); 6644 6645 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6646 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6647 ExprResult CombCondOp = 6648 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6649 LastIteration.get(), CombUB.get()); 6650 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6651 CombCondOp.get()); 6652 CombEUB = 6653 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6654 6655 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6656 // We expect to have at least 2 more parameters than the 'parallel' 6657 // directive does - the lower and upper bounds of the previous schedule. 6658 assert(CD->getNumParams() >= 4 && 6659 "Unexpected number of parameters in loop combined directive"); 6660 6661 // Set the proper type for the bounds given what we learned from the 6662 // enclosed loops. 6663 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6664 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6665 6666 // Previous lower and upper bounds are obtained from the region 6667 // parameters. 6668 PrevLB = 6669 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6670 PrevUB = 6671 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6672 } 6673 } 6674 6675 // Build the iteration variable and its initialization before loop. 6676 ExprResult IV; 6677 ExprResult Init, CombInit; 6678 { 6679 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6680 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6681 Expr *RHS = 6682 (isOpenMPWorksharingDirective(DKind) || 6683 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6684 ? LB.get() 6685 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6686 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6687 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6688 6689 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6690 Expr *CombRHS = 6691 (isOpenMPWorksharingDirective(DKind) || 6692 isOpenMPTaskLoopDirective(DKind) || 6693 isOpenMPDistributeDirective(DKind)) 6694 ? CombLB.get() 6695 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6696 CombInit = 6697 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6698 CombInit = 6699 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6700 } 6701 } 6702 6703 bool UseStrictCompare = 6704 RealVType->hasUnsignedIntegerRepresentation() && 6705 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6706 return LIS.IsStrictCompare; 6707 }); 6708 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6709 // unsigned IV)) for worksharing loops. 6710 SourceLocation CondLoc = AStmt->getBeginLoc(); 6711 Expr *BoundUB = UB.get(); 6712 if (UseStrictCompare) { 6713 BoundUB = 6714 SemaRef 6715 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6716 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6717 .get(); 6718 BoundUB = 6719 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6720 } 6721 ExprResult Cond = 6722 (isOpenMPWorksharingDirective(DKind) || 6723 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6724 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6725 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6726 BoundUB) 6727 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6728 NumIterations.get()); 6729 ExprResult CombDistCond; 6730 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6731 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6732 NumIterations.get()); 6733 } 6734 6735 ExprResult CombCond; 6736 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6737 Expr *BoundCombUB = CombUB.get(); 6738 if (UseStrictCompare) { 6739 BoundCombUB = 6740 SemaRef 6741 .BuildBinOp( 6742 CurScope, CondLoc, BO_Add, BoundCombUB, 6743 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6744 .get(); 6745 BoundCombUB = 6746 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6747 .get(); 6748 } 6749 CombCond = 6750 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6751 IV.get(), BoundCombUB); 6752 } 6753 // Loop increment (IV = IV + 1) 6754 SourceLocation IncLoc = AStmt->getBeginLoc(); 6755 ExprResult Inc = 6756 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6757 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6758 if (!Inc.isUsable()) 6759 return 0; 6760 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6761 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6762 if (!Inc.isUsable()) 6763 return 0; 6764 6765 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6766 // Used for directives with static scheduling. 6767 // In combined construct, add combined version that use CombLB and CombUB 6768 // base variables for the update 6769 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6770 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6771 isOpenMPDistributeDirective(DKind)) { 6772 // LB + ST 6773 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6774 if (!NextLB.isUsable()) 6775 return 0; 6776 // LB = LB + ST 6777 NextLB = 6778 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6779 NextLB = 6780 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6781 if (!NextLB.isUsable()) 6782 return 0; 6783 // UB + ST 6784 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6785 if (!NextUB.isUsable()) 6786 return 0; 6787 // UB = UB + ST 6788 NextUB = 6789 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6790 NextUB = 6791 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6792 if (!NextUB.isUsable()) 6793 return 0; 6794 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6795 CombNextLB = 6796 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6797 if (!NextLB.isUsable()) 6798 return 0; 6799 // LB = LB + ST 6800 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6801 CombNextLB.get()); 6802 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6803 /*DiscardedValue*/ false); 6804 if (!CombNextLB.isUsable()) 6805 return 0; 6806 // UB + ST 6807 CombNextUB = 6808 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 6809 if (!CombNextUB.isUsable()) 6810 return 0; 6811 // UB = UB + ST 6812 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 6813 CombNextUB.get()); 6814 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 6815 /*DiscardedValue*/ false); 6816 if (!CombNextUB.isUsable()) 6817 return 0; 6818 } 6819 } 6820 6821 // Create increment expression for distribute loop when combined in a same 6822 // directive with for as IV = IV + ST; ensure upper bound expression based 6823 // on PrevUB instead of NumIterations - used to implement 'for' when found 6824 // in combination with 'distribute', like in 'distribute parallel for' 6825 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 6826 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 6827 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6828 DistCond = SemaRef.BuildBinOp( 6829 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 6830 assert(DistCond.isUsable() && "distribute cond expr was not built"); 6831 6832 DistInc = 6833 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 6834 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6835 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 6836 DistInc.get()); 6837 DistInc = 6838 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 6839 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6840 6841 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 6842 // construct 6843 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 6844 ExprResult IsUBGreater = 6845 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 6846 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6847 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 6848 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 6849 CondOp.get()); 6850 PrevEUB = 6851 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 6852 6853 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 6854 // parallel for is in combination with a distribute directive with 6855 // schedule(static, 1) 6856 Expr *BoundPrevUB = PrevUB.get(); 6857 if (UseStrictCompare) { 6858 BoundPrevUB = 6859 SemaRef 6860 .BuildBinOp( 6861 CurScope, CondLoc, BO_Add, BoundPrevUB, 6862 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6863 .get(); 6864 BoundPrevUB = 6865 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 6866 .get(); 6867 } 6868 ParForInDistCond = 6869 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6870 IV.get(), BoundPrevUB); 6871 } 6872 6873 // Build updates and final values of the loop counters. 6874 bool HasErrors = false; 6875 Built.Counters.resize(NestedLoopCount); 6876 Built.Inits.resize(NestedLoopCount); 6877 Built.Updates.resize(NestedLoopCount); 6878 Built.Finals.resize(NestedLoopCount); 6879 Built.DependentCounters.resize(NestedLoopCount); 6880 Built.DependentInits.resize(NestedLoopCount); 6881 Built.FinalsConditions.resize(NestedLoopCount); 6882 { 6883 // We implement the following algorithm for obtaining the 6884 // original loop iteration variable values based on the 6885 // value of the collapsed loop iteration variable IV. 6886 // 6887 // Let n+1 be the number of collapsed loops in the nest. 6888 // Iteration variables (I0, I1, .... In) 6889 // Iteration counts (N0, N1, ... Nn) 6890 // 6891 // Acc = IV; 6892 // 6893 // To compute Ik for loop k, 0 <= k <= n, generate: 6894 // Prod = N(k+1) * N(k+2) * ... * Nn; 6895 // Ik = Acc / Prod; 6896 // Acc -= Ik * Prod; 6897 // 6898 ExprResult Acc = IV; 6899 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6900 LoopIterationSpace &IS = IterSpaces[Cnt]; 6901 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 6902 ExprResult Iter; 6903 6904 // Compute prod 6905 ExprResult Prod = 6906 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6907 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 6908 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 6909 IterSpaces[K].NumIterations); 6910 6911 // Iter = Acc / Prod 6912 // If there is at least one more inner loop to avoid 6913 // multiplication by 1. 6914 if (Cnt + 1 < NestedLoopCount) 6915 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 6916 Acc.get(), Prod.get()); 6917 else 6918 Iter = Acc; 6919 if (!Iter.isUsable()) { 6920 HasErrors = true; 6921 break; 6922 } 6923 6924 // Update Acc: 6925 // Acc -= Iter * Prod 6926 // Check if there is at least one more inner loop to avoid 6927 // multiplication by 1. 6928 if (Cnt + 1 < NestedLoopCount) 6929 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 6930 Iter.get(), Prod.get()); 6931 else 6932 Prod = Iter; 6933 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 6934 Acc.get(), Prod.get()); 6935 6936 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 6937 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 6938 DeclRefExpr *CounterVar = buildDeclRefExpr( 6939 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 6940 /*RefersToCapture=*/true); 6941 ExprResult Init = 6942 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 6943 IS.CounterInit, IS.IsNonRectangularLB, Captures); 6944 if (!Init.isUsable()) { 6945 HasErrors = true; 6946 break; 6947 } 6948 ExprResult Update = buildCounterUpdate( 6949 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 6950 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 6951 if (!Update.isUsable()) { 6952 HasErrors = true; 6953 break; 6954 } 6955 6956 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6957 ExprResult Final = 6958 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 6959 IS.CounterInit, IS.NumIterations, IS.CounterStep, 6960 IS.Subtract, IS.IsNonRectangularLB, &Captures); 6961 if (!Final.isUsable()) { 6962 HasErrors = true; 6963 break; 6964 } 6965 6966 if (!Update.isUsable() || !Final.isUsable()) { 6967 HasErrors = true; 6968 break; 6969 } 6970 // Save results 6971 Built.Counters[Cnt] = IS.CounterVar; 6972 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6973 Built.Inits[Cnt] = Init.get(); 6974 Built.Updates[Cnt] = Update.get(); 6975 Built.Finals[Cnt] = Final.get(); 6976 Built.DependentCounters[Cnt] = nullptr; 6977 Built.DependentInits[Cnt] = nullptr; 6978 Built.FinalsConditions[Cnt] = nullptr; 6979 if (IS.IsNonRectangularLB) { 6980 Built.DependentCounters[Cnt] = 6981 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 6982 Built.DependentInits[Cnt] = 6983 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 6984 Built.FinalsConditions[Cnt] = IS.FinalCondition; 6985 } 6986 } 6987 } 6988 6989 if (HasErrors) 6990 return 0; 6991 6992 // Save results 6993 Built.IterationVarRef = IV.get(); 6994 Built.LastIteration = LastIteration.get(); 6995 Built.NumIterations = NumIterations.get(); 6996 Built.CalcLastIteration = SemaRef 6997 .ActOnFinishFullExpr(CalcLastIteration.get(), 6998 /*DiscardedValue=*/false) 6999 .get(); 7000 Built.PreCond = PreCond.get(); 7001 Built.PreInits = buildPreInits(C, Captures); 7002 Built.Cond = Cond.get(); 7003 Built.Init = Init.get(); 7004 Built.Inc = Inc.get(); 7005 Built.LB = LB.get(); 7006 Built.UB = UB.get(); 7007 Built.IL = IL.get(); 7008 Built.ST = ST.get(); 7009 Built.EUB = EUB.get(); 7010 Built.NLB = NextLB.get(); 7011 Built.NUB = NextUB.get(); 7012 Built.PrevLB = PrevLB.get(); 7013 Built.PrevUB = PrevUB.get(); 7014 Built.DistInc = DistInc.get(); 7015 Built.PrevEUB = PrevEUB.get(); 7016 Built.DistCombinedFields.LB = CombLB.get(); 7017 Built.DistCombinedFields.UB = CombUB.get(); 7018 Built.DistCombinedFields.EUB = CombEUB.get(); 7019 Built.DistCombinedFields.Init = CombInit.get(); 7020 Built.DistCombinedFields.Cond = CombCond.get(); 7021 Built.DistCombinedFields.NLB = CombNextLB.get(); 7022 Built.DistCombinedFields.NUB = CombNextUB.get(); 7023 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7024 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7025 7026 return NestedLoopCount; 7027 } 7028 7029 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7030 auto CollapseClauses = 7031 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7032 if (CollapseClauses.begin() != CollapseClauses.end()) 7033 return (*CollapseClauses.begin())->getNumForLoops(); 7034 return nullptr; 7035 } 7036 7037 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7038 auto OrderedClauses = 7039 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7040 if (OrderedClauses.begin() != OrderedClauses.end()) 7041 return (*OrderedClauses.begin())->getNumForLoops(); 7042 return nullptr; 7043 } 7044 7045 static bool checkSimdlenSafelenSpecified(Sema &S, 7046 const ArrayRef<OMPClause *> Clauses) { 7047 const OMPSafelenClause *Safelen = nullptr; 7048 const OMPSimdlenClause *Simdlen = nullptr; 7049 7050 for (const OMPClause *Clause : Clauses) { 7051 if (Clause->getClauseKind() == OMPC_safelen) 7052 Safelen = cast<OMPSafelenClause>(Clause); 7053 else if (Clause->getClauseKind() == OMPC_simdlen) 7054 Simdlen = cast<OMPSimdlenClause>(Clause); 7055 if (Safelen && Simdlen) 7056 break; 7057 } 7058 7059 if (Simdlen && Safelen) { 7060 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7061 const Expr *SafelenLength = Safelen->getSafelen(); 7062 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7063 SimdlenLength->isInstantiationDependent() || 7064 SimdlenLength->containsUnexpandedParameterPack()) 7065 return false; 7066 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7067 SafelenLength->isInstantiationDependent() || 7068 SafelenLength->containsUnexpandedParameterPack()) 7069 return false; 7070 Expr::EvalResult SimdlenResult, SafelenResult; 7071 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7072 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7073 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7074 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7075 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7076 // If both simdlen and safelen clauses are specified, the value of the 7077 // simdlen parameter must be less than or equal to the value of the safelen 7078 // parameter. 7079 if (SimdlenRes > SafelenRes) { 7080 S.Diag(SimdlenLength->getExprLoc(), 7081 diag::err_omp_wrong_simdlen_safelen_values) 7082 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7083 return true; 7084 } 7085 } 7086 return false; 7087 } 7088 7089 StmtResult 7090 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7091 SourceLocation StartLoc, SourceLocation EndLoc, 7092 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7093 if (!AStmt) 7094 return StmtError(); 7095 7096 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7097 OMPLoopDirective::HelperExprs B; 7098 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7099 // define the nested loops number. 7100 unsigned NestedLoopCount = checkOpenMPLoop( 7101 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7102 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7103 if (NestedLoopCount == 0) 7104 return StmtError(); 7105 7106 assert((CurContext->isDependentContext() || B.builtAll()) && 7107 "omp simd loop exprs were not built"); 7108 7109 if (!CurContext->isDependentContext()) { 7110 // Finalize the clauses that need pre-built expressions for CodeGen. 7111 for (OMPClause *C : Clauses) { 7112 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7113 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7114 B.NumIterations, *this, CurScope, 7115 DSAStack)) 7116 return StmtError(); 7117 } 7118 } 7119 7120 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7121 return StmtError(); 7122 7123 setFunctionHasBranchProtectedScope(); 7124 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7125 Clauses, AStmt, B); 7126 } 7127 7128 StmtResult 7129 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7130 SourceLocation StartLoc, SourceLocation EndLoc, 7131 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7132 if (!AStmt) 7133 return StmtError(); 7134 7135 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7136 OMPLoopDirective::HelperExprs B; 7137 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7138 // define the nested loops number. 7139 unsigned NestedLoopCount = checkOpenMPLoop( 7140 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7141 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7142 if (NestedLoopCount == 0) 7143 return StmtError(); 7144 7145 assert((CurContext->isDependentContext() || B.builtAll()) && 7146 "omp for loop exprs were not built"); 7147 7148 if (!CurContext->isDependentContext()) { 7149 // Finalize the clauses that need pre-built expressions for CodeGen. 7150 for (OMPClause *C : Clauses) { 7151 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7152 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7153 B.NumIterations, *this, CurScope, 7154 DSAStack)) 7155 return StmtError(); 7156 } 7157 } 7158 7159 setFunctionHasBranchProtectedScope(); 7160 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7161 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7162 } 7163 7164 StmtResult Sema::ActOnOpenMPForSimdDirective( 7165 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7166 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7167 if (!AStmt) 7168 return StmtError(); 7169 7170 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7171 OMPLoopDirective::HelperExprs B; 7172 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7173 // define the nested loops number. 7174 unsigned NestedLoopCount = 7175 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7176 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7177 VarsWithImplicitDSA, B); 7178 if (NestedLoopCount == 0) 7179 return StmtError(); 7180 7181 assert((CurContext->isDependentContext() || B.builtAll()) && 7182 "omp for simd loop exprs were not built"); 7183 7184 if (!CurContext->isDependentContext()) { 7185 // Finalize the clauses that need pre-built expressions for CodeGen. 7186 for (OMPClause *C : Clauses) { 7187 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7188 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7189 B.NumIterations, *this, CurScope, 7190 DSAStack)) 7191 return StmtError(); 7192 } 7193 } 7194 7195 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7196 return StmtError(); 7197 7198 setFunctionHasBranchProtectedScope(); 7199 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7200 Clauses, AStmt, B); 7201 } 7202 7203 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7204 Stmt *AStmt, 7205 SourceLocation StartLoc, 7206 SourceLocation EndLoc) { 7207 if (!AStmt) 7208 return StmtError(); 7209 7210 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7211 auto BaseStmt = AStmt; 7212 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7213 BaseStmt = CS->getCapturedStmt(); 7214 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7215 auto S = C->children(); 7216 if (S.begin() == S.end()) 7217 return StmtError(); 7218 // All associated statements must be '#pragma omp section' except for 7219 // the first one. 7220 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7221 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7222 if (SectionStmt) 7223 Diag(SectionStmt->getBeginLoc(), 7224 diag::err_omp_sections_substmt_not_section); 7225 return StmtError(); 7226 } 7227 cast<OMPSectionDirective>(SectionStmt) 7228 ->setHasCancel(DSAStack->isCancelRegion()); 7229 } 7230 } else { 7231 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7232 return StmtError(); 7233 } 7234 7235 setFunctionHasBranchProtectedScope(); 7236 7237 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7238 DSAStack->isCancelRegion()); 7239 } 7240 7241 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7242 SourceLocation StartLoc, 7243 SourceLocation EndLoc) { 7244 if (!AStmt) 7245 return StmtError(); 7246 7247 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7248 7249 setFunctionHasBranchProtectedScope(); 7250 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7251 7252 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7253 DSAStack->isCancelRegion()); 7254 } 7255 7256 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7257 Stmt *AStmt, 7258 SourceLocation StartLoc, 7259 SourceLocation EndLoc) { 7260 if (!AStmt) 7261 return StmtError(); 7262 7263 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7264 7265 setFunctionHasBranchProtectedScope(); 7266 7267 // OpenMP [2.7.3, single Construct, Restrictions] 7268 // The copyprivate clause must not be used with the nowait clause. 7269 const OMPClause *Nowait = nullptr; 7270 const OMPClause *Copyprivate = nullptr; 7271 for (const OMPClause *Clause : Clauses) { 7272 if (Clause->getClauseKind() == OMPC_nowait) 7273 Nowait = Clause; 7274 else if (Clause->getClauseKind() == OMPC_copyprivate) 7275 Copyprivate = Clause; 7276 if (Copyprivate && Nowait) { 7277 Diag(Copyprivate->getBeginLoc(), 7278 diag::err_omp_single_copyprivate_with_nowait); 7279 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7280 return StmtError(); 7281 } 7282 } 7283 7284 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7285 } 7286 7287 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7288 SourceLocation StartLoc, 7289 SourceLocation EndLoc) { 7290 if (!AStmt) 7291 return StmtError(); 7292 7293 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7294 7295 setFunctionHasBranchProtectedScope(); 7296 7297 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7298 } 7299 7300 StmtResult Sema::ActOnOpenMPCriticalDirective( 7301 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7302 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7303 if (!AStmt) 7304 return StmtError(); 7305 7306 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7307 7308 bool ErrorFound = false; 7309 llvm::APSInt Hint; 7310 SourceLocation HintLoc; 7311 bool DependentHint = false; 7312 for (const OMPClause *C : Clauses) { 7313 if (C->getClauseKind() == OMPC_hint) { 7314 if (!DirName.getName()) { 7315 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7316 ErrorFound = true; 7317 } 7318 Expr *E = cast<OMPHintClause>(C)->getHint(); 7319 if (E->isTypeDependent() || E->isValueDependent() || 7320 E->isInstantiationDependent()) { 7321 DependentHint = true; 7322 } else { 7323 Hint = E->EvaluateKnownConstInt(Context); 7324 HintLoc = C->getBeginLoc(); 7325 } 7326 } 7327 } 7328 if (ErrorFound) 7329 return StmtError(); 7330 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7331 if (Pair.first && DirName.getName() && !DependentHint) { 7332 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7333 Diag(StartLoc, diag::err_omp_critical_with_hint); 7334 if (HintLoc.isValid()) 7335 Diag(HintLoc, diag::note_omp_critical_hint_here) 7336 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7337 else 7338 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7339 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7340 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7341 << 1 7342 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7343 /*Radix=*/10, /*Signed=*/false); 7344 } else { 7345 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7346 } 7347 } 7348 } 7349 7350 setFunctionHasBranchProtectedScope(); 7351 7352 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7353 Clauses, AStmt); 7354 if (!Pair.first && DirName.getName() && !DependentHint) 7355 DSAStack->addCriticalWithHint(Dir, Hint); 7356 return Dir; 7357 } 7358 7359 StmtResult Sema::ActOnOpenMPParallelForDirective( 7360 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7361 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7362 if (!AStmt) 7363 return StmtError(); 7364 7365 auto *CS = cast<CapturedStmt>(AStmt); 7366 // 1.2.2 OpenMP Language Terminology 7367 // Structured block - An executable statement with a single entry at the 7368 // top and a single exit at the bottom. 7369 // The point of exit cannot be a branch out of the structured block. 7370 // longjmp() and throw() must not violate the entry/exit criteria. 7371 CS->getCapturedDecl()->setNothrow(); 7372 7373 OMPLoopDirective::HelperExprs B; 7374 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7375 // define the nested loops number. 7376 unsigned NestedLoopCount = 7377 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7378 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7379 VarsWithImplicitDSA, B); 7380 if (NestedLoopCount == 0) 7381 return StmtError(); 7382 7383 assert((CurContext->isDependentContext() || B.builtAll()) && 7384 "omp parallel for loop exprs were not built"); 7385 7386 if (!CurContext->isDependentContext()) { 7387 // Finalize the clauses that need pre-built expressions for CodeGen. 7388 for (OMPClause *C : Clauses) { 7389 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7390 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7391 B.NumIterations, *this, CurScope, 7392 DSAStack)) 7393 return StmtError(); 7394 } 7395 } 7396 7397 setFunctionHasBranchProtectedScope(); 7398 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7399 NestedLoopCount, Clauses, AStmt, B, 7400 DSAStack->isCancelRegion()); 7401 } 7402 7403 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7404 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7405 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7406 if (!AStmt) 7407 return StmtError(); 7408 7409 auto *CS = cast<CapturedStmt>(AStmt); 7410 // 1.2.2 OpenMP Language Terminology 7411 // Structured block - An executable statement with a single entry at the 7412 // top and a single exit at the bottom. 7413 // The point of exit cannot be a branch out of the structured block. 7414 // longjmp() and throw() must not violate the entry/exit criteria. 7415 CS->getCapturedDecl()->setNothrow(); 7416 7417 OMPLoopDirective::HelperExprs B; 7418 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7419 // define the nested loops number. 7420 unsigned NestedLoopCount = 7421 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7422 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7423 VarsWithImplicitDSA, B); 7424 if (NestedLoopCount == 0) 7425 return StmtError(); 7426 7427 if (!CurContext->isDependentContext()) { 7428 // Finalize the clauses that need pre-built expressions for CodeGen. 7429 for (OMPClause *C : Clauses) { 7430 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7431 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7432 B.NumIterations, *this, CurScope, 7433 DSAStack)) 7434 return StmtError(); 7435 } 7436 } 7437 7438 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7439 return StmtError(); 7440 7441 setFunctionHasBranchProtectedScope(); 7442 return OMPParallelForSimdDirective::Create( 7443 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7444 } 7445 7446 StmtResult 7447 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7448 Stmt *AStmt, SourceLocation StartLoc, 7449 SourceLocation EndLoc) { 7450 if (!AStmt) 7451 return StmtError(); 7452 7453 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7454 auto BaseStmt = AStmt; 7455 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7456 BaseStmt = CS->getCapturedStmt(); 7457 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7458 auto S = C->children(); 7459 if (S.begin() == S.end()) 7460 return StmtError(); 7461 // All associated statements must be '#pragma omp section' except for 7462 // the first one. 7463 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7464 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7465 if (SectionStmt) 7466 Diag(SectionStmt->getBeginLoc(), 7467 diag::err_omp_parallel_sections_substmt_not_section); 7468 return StmtError(); 7469 } 7470 cast<OMPSectionDirective>(SectionStmt) 7471 ->setHasCancel(DSAStack->isCancelRegion()); 7472 } 7473 } else { 7474 Diag(AStmt->getBeginLoc(), 7475 diag::err_omp_parallel_sections_not_compound_stmt); 7476 return StmtError(); 7477 } 7478 7479 setFunctionHasBranchProtectedScope(); 7480 7481 return OMPParallelSectionsDirective::Create( 7482 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7483 } 7484 7485 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7486 Stmt *AStmt, SourceLocation StartLoc, 7487 SourceLocation EndLoc) { 7488 if (!AStmt) 7489 return StmtError(); 7490 7491 auto *CS = cast<CapturedStmt>(AStmt); 7492 // 1.2.2 OpenMP Language Terminology 7493 // Structured block - An executable statement with a single entry at the 7494 // top and a single exit at the bottom. 7495 // The point of exit cannot be a branch out of the structured block. 7496 // longjmp() and throw() must not violate the entry/exit criteria. 7497 CS->getCapturedDecl()->setNothrow(); 7498 7499 setFunctionHasBranchProtectedScope(); 7500 7501 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7502 DSAStack->isCancelRegion()); 7503 } 7504 7505 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7506 SourceLocation EndLoc) { 7507 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7508 } 7509 7510 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7511 SourceLocation EndLoc) { 7512 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7513 } 7514 7515 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7516 SourceLocation EndLoc) { 7517 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7518 } 7519 7520 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7521 Stmt *AStmt, 7522 SourceLocation StartLoc, 7523 SourceLocation EndLoc) { 7524 if (!AStmt) 7525 return StmtError(); 7526 7527 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7528 7529 setFunctionHasBranchProtectedScope(); 7530 7531 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7532 AStmt, 7533 DSAStack->getTaskgroupReductionRef()); 7534 } 7535 7536 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7537 SourceLocation StartLoc, 7538 SourceLocation EndLoc) { 7539 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7540 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7541 } 7542 7543 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7544 Stmt *AStmt, 7545 SourceLocation StartLoc, 7546 SourceLocation EndLoc) { 7547 const OMPClause *DependFound = nullptr; 7548 const OMPClause *DependSourceClause = nullptr; 7549 const OMPClause *DependSinkClause = nullptr; 7550 bool ErrorFound = false; 7551 const OMPThreadsClause *TC = nullptr; 7552 const OMPSIMDClause *SC = nullptr; 7553 for (const OMPClause *C : Clauses) { 7554 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7555 DependFound = C; 7556 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7557 if (DependSourceClause) { 7558 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7559 << getOpenMPDirectiveName(OMPD_ordered) 7560 << getOpenMPClauseName(OMPC_depend) << 2; 7561 ErrorFound = true; 7562 } else { 7563 DependSourceClause = C; 7564 } 7565 if (DependSinkClause) { 7566 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7567 << 0; 7568 ErrorFound = true; 7569 } 7570 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7571 if (DependSourceClause) { 7572 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7573 << 1; 7574 ErrorFound = true; 7575 } 7576 DependSinkClause = C; 7577 } 7578 } else if (C->getClauseKind() == OMPC_threads) { 7579 TC = cast<OMPThreadsClause>(C); 7580 } else if (C->getClauseKind() == OMPC_simd) { 7581 SC = cast<OMPSIMDClause>(C); 7582 } 7583 } 7584 if (!ErrorFound && !SC && 7585 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7586 // OpenMP [2.8.1,simd Construct, Restrictions] 7587 // An ordered construct with the simd clause is the only OpenMP construct 7588 // that can appear in the simd region. 7589 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7590 ErrorFound = true; 7591 } else if (DependFound && (TC || SC)) { 7592 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7593 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7594 ErrorFound = true; 7595 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7596 Diag(DependFound->getBeginLoc(), 7597 diag::err_omp_ordered_directive_without_param); 7598 ErrorFound = true; 7599 } else if (TC || Clauses.empty()) { 7600 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7601 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7602 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7603 << (TC != nullptr); 7604 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7605 ErrorFound = true; 7606 } 7607 } 7608 if ((!AStmt && !DependFound) || ErrorFound) 7609 return StmtError(); 7610 7611 if (AStmt) { 7612 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7613 7614 setFunctionHasBranchProtectedScope(); 7615 } 7616 7617 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7618 } 7619 7620 namespace { 7621 /// Helper class for checking expression in 'omp atomic [update]' 7622 /// construct. 7623 class OpenMPAtomicUpdateChecker { 7624 /// Error results for atomic update expressions. 7625 enum ExprAnalysisErrorCode { 7626 /// A statement is not an expression statement. 7627 NotAnExpression, 7628 /// Expression is not builtin binary or unary operation. 7629 NotABinaryOrUnaryExpression, 7630 /// Unary operation is not post-/pre- increment/decrement operation. 7631 NotAnUnaryIncDecExpression, 7632 /// An expression is not of scalar type. 7633 NotAScalarType, 7634 /// A binary operation is not an assignment operation. 7635 NotAnAssignmentOp, 7636 /// RHS part of the binary operation is not a binary expression. 7637 NotABinaryExpression, 7638 /// RHS part is not additive/multiplicative/shift/biwise binary 7639 /// expression. 7640 NotABinaryOperator, 7641 /// RHS binary operation does not have reference to the updated LHS 7642 /// part. 7643 NotAnUpdateExpression, 7644 /// No errors is found. 7645 NoError 7646 }; 7647 /// Reference to Sema. 7648 Sema &SemaRef; 7649 /// A location for note diagnostics (when error is found). 7650 SourceLocation NoteLoc; 7651 /// 'x' lvalue part of the source atomic expression. 7652 Expr *X; 7653 /// 'expr' rvalue part of the source atomic expression. 7654 Expr *E; 7655 /// Helper expression of the form 7656 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7657 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7658 Expr *UpdateExpr; 7659 /// Is 'x' a LHS in a RHS part of full update expression. It is 7660 /// important for non-associative operations. 7661 bool IsXLHSInRHSPart; 7662 BinaryOperatorKind Op; 7663 SourceLocation OpLoc; 7664 /// true if the source expression is a postfix unary operation, false 7665 /// if it is a prefix unary operation. 7666 bool IsPostfixUpdate; 7667 7668 public: 7669 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7670 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7671 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7672 /// Check specified statement that it is suitable for 'atomic update' 7673 /// constructs and extract 'x', 'expr' and Operation from the original 7674 /// expression. If DiagId and NoteId == 0, then only check is performed 7675 /// without error notification. 7676 /// \param DiagId Diagnostic which should be emitted if error is found. 7677 /// \param NoteId Diagnostic note for the main error message. 7678 /// \return true if statement is not an update expression, false otherwise. 7679 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7680 /// Return the 'x' lvalue part of the source atomic expression. 7681 Expr *getX() const { return X; } 7682 /// Return the 'expr' rvalue part of the source atomic expression. 7683 Expr *getExpr() const { return E; } 7684 /// Return the update expression used in calculation of the updated 7685 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7686 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7687 Expr *getUpdateExpr() const { return UpdateExpr; } 7688 /// Return true if 'x' is LHS in RHS part of full update expression, 7689 /// false otherwise. 7690 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7691 7692 /// true if the source expression is a postfix unary operation, false 7693 /// if it is a prefix unary operation. 7694 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7695 7696 private: 7697 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7698 unsigned NoteId = 0); 7699 }; 7700 } // namespace 7701 7702 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7703 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7704 ExprAnalysisErrorCode ErrorFound = NoError; 7705 SourceLocation ErrorLoc, NoteLoc; 7706 SourceRange ErrorRange, NoteRange; 7707 // Allowed constructs are: 7708 // x = x binop expr; 7709 // x = expr binop x; 7710 if (AtomicBinOp->getOpcode() == BO_Assign) { 7711 X = AtomicBinOp->getLHS(); 7712 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7713 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7714 if (AtomicInnerBinOp->isMultiplicativeOp() || 7715 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7716 AtomicInnerBinOp->isBitwiseOp()) { 7717 Op = AtomicInnerBinOp->getOpcode(); 7718 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7719 Expr *LHS = AtomicInnerBinOp->getLHS(); 7720 Expr *RHS = AtomicInnerBinOp->getRHS(); 7721 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7722 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7723 /*Canonical=*/true); 7724 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7725 /*Canonical=*/true); 7726 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7727 /*Canonical=*/true); 7728 if (XId == LHSId) { 7729 E = RHS; 7730 IsXLHSInRHSPart = true; 7731 } else if (XId == RHSId) { 7732 E = LHS; 7733 IsXLHSInRHSPart = false; 7734 } else { 7735 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7736 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7737 NoteLoc = X->getExprLoc(); 7738 NoteRange = X->getSourceRange(); 7739 ErrorFound = NotAnUpdateExpression; 7740 } 7741 } else { 7742 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7743 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7744 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7745 NoteRange = SourceRange(NoteLoc, NoteLoc); 7746 ErrorFound = NotABinaryOperator; 7747 } 7748 } else { 7749 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7750 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7751 ErrorFound = NotABinaryExpression; 7752 } 7753 } else { 7754 ErrorLoc = AtomicBinOp->getExprLoc(); 7755 ErrorRange = AtomicBinOp->getSourceRange(); 7756 NoteLoc = AtomicBinOp->getOperatorLoc(); 7757 NoteRange = SourceRange(NoteLoc, NoteLoc); 7758 ErrorFound = NotAnAssignmentOp; 7759 } 7760 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7761 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7762 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7763 return true; 7764 } 7765 if (SemaRef.CurContext->isDependentContext()) 7766 E = X = UpdateExpr = nullptr; 7767 return ErrorFound != NoError; 7768 } 7769 7770 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7771 unsigned NoteId) { 7772 ExprAnalysisErrorCode ErrorFound = NoError; 7773 SourceLocation ErrorLoc, NoteLoc; 7774 SourceRange ErrorRange, NoteRange; 7775 // Allowed constructs are: 7776 // x++; 7777 // x--; 7778 // ++x; 7779 // --x; 7780 // x binop= expr; 7781 // x = x binop expr; 7782 // x = expr binop x; 7783 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7784 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7785 if (AtomicBody->getType()->isScalarType() || 7786 AtomicBody->isInstantiationDependent()) { 7787 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7788 AtomicBody->IgnoreParenImpCasts())) { 7789 // Check for Compound Assignment Operation 7790 Op = BinaryOperator::getOpForCompoundAssignment( 7791 AtomicCompAssignOp->getOpcode()); 7792 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7793 E = AtomicCompAssignOp->getRHS(); 7794 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7795 IsXLHSInRHSPart = true; 7796 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7797 AtomicBody->IgnoreParenImpCasts())) { 7798 // Check for Binary Operation 7799 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7800 return true; 7801 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7802 AtomicBody->IgnoreParenImpCasts())) { 7803 // Check for Unary Operation 7804 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7805 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7806 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7807 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7808 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 7809 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 7810 IsXLHSInRHSPart = true; 7811 } else { 7812 ErrorFound = NotAnUnaryIncDecExpression; 7813 ErrorLoc = AtomicUnaryOp->getExprLoc(); 7814 ErrorRange = AtomicUnaryOp->getSourceRange(); 7815 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 7816 NoteRange = SourceRange(NoteLoc, NoteLoc); 7817 } 7818 } else if (!AtomicBody->isInstantiationDependent()) { 7819 ErrorFound = NotABinaryOrUnaryExpression; 7820 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 7821 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 7822 } 7823 } else { 7824 ErrorFound = NotAScalarType; 7825 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 7826 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7827 } 7828 } else { 7829 ErrorFound = NotAnExpression; 7830 NoteLoc = ErrorLoc = S->getBeginLoc(); 7831 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7832 } 7833 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7834 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7835 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7836 return true; 7837 } 7838 if (SemaRef.CurContext->isDependentContext()) 7839 E = X = UpdateExpr = nullptr; 7840 if (ErrorFound == NoError && E && X) { 7841 // Build an update expression of form 'OpaqueValueExpr(x) binop 7842 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 7843 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 7844 auto *OVEX = new (SemaRef.getASTContext()) 7845 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 7846 auto *OVEExpr = new (SemaRef.getASTContext()) 7847 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 7848 ExprResult Update = 7849 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 7850 IsXLHSInRHSPart ? OVEExpr : OVEX); 7851 if (Update.isInvalid()) 7852 return true; 7853 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 7854 Sema::AA_Casting); 7855 if (Update.isInvalid()) 7856 return true; 7857 UpdateExpr = Update.get(); 7858 } 7859 return ErrorFound != NoError; 7860 } 7861 7862 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 7863 Stmt *AStmt, 7864 SourceLocation StartLoc, 7865 SourceLocation EndLoc) { 7866 if (!AStmt) 7867 return StmtError(); 7868 7869 auto *CS = cast<CapturedStmt>(AStmt); 7870 // 1.2.2 OpenMP Language Terminology 7871 // Structured block - An executable statement with a single entry at the 7872 // top and a single exit at the bottom. 7873 // The point of exit cannot be a branch out of the structured block. 7874 // longjmp() and throw() must not violate the entry/exit criteria. 7875 OpenMPClauseKind AtomicKind = OMPC_unknown; 7876 SourceLocation AtomicKindLoc; 7877 for (const OMPClause *C : Clauses) { 7878 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 7879 C->getClauseKind() == OMPC_update || 7880 C->getClauseKind() == OMPC_capture) { 7881 if (AtomicKind != OMPC_unknown) { 7882 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 7883 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 7884 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 7885 << getOpenMPClauseName(AtomicKind); 7886 } else { 7887 AtomicKind = C->getClauseKind(); 7888 AtomicKindLoc = C->getBeginLoc(); 7889 } 7890 } 7891 } 7892 7893 Stmt *Body = CS->getCapturedStmt(); 7894 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 7895 Body = EWC->getSubExpr(); 7896 7897 Expr *X = nullptr; 7898 Expr *V = nullptr; 7899 Expr *E = nullptr; 7900 Expr *UE = nullptr; 7901 bool IsXLHSInRHSPart = false; 7902 bool IsPostfixUpdate = false; 7903 // OpenMP [2.12.6, atomic Construct] 7904 // In the next expressions: 7905 // * x and v (as applicable) are both l-value expressions with scalar type. 7906 // * During the execution of an atomic region, multiple syntactic 7907 // occurrences of x must designate the same storage location. 7908 // * Neither of v and expr (as applicable) may access the storage location 7909 // designated by x. 7910 // * Neither of x and expr (as applicable) may access the storage location 7911 // designated by v. 7912 // * expr is an expression with scalar type. 7913 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 7914 // * binop, binop=, ++, and -- are not overloaded operators. 7915 // * The expression x binop expr must be numerically equivalent to x binop 7916 // (expr). This requirement is satisfied if the operators in expr have 7917 // precedence greater than binop, or by using parentheses around expr or 7918 // subexpressions of expr. 7919 // * The expression expr binop x must be numerically equivalent to (expr) 7920 // binop x. This requirement is satisfied if the operators in expr have 7921 // precedence equal to or greater than binop, or by using parentheses around 7922 // expr or subexpressions of expr. 7923 // * For forms that allow multiple occurrences of x, the number of times 7924 // that x is evaluated is unspecified. 7925 if (AtomicKind == OMPC_read) { 7926 enum { 7927 NotAnExpression, 7928 NotAnAssignmentOp, 7929 NotAScalarType, 7930 NotAnLValue, 7931 NoError 7932 } ErrorFound = NoError; 7933 SourceLocation ErrorLoc, NoteLoc; 7934 SourceRange ErrorRange, NoteRange; 7935 // If clause is read: 7936 // v = x; 7937 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7938 const auto *AtomicBinOp = 7939 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7940 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7941 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7942 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 7943 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7944 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 7945 if (!X->isLValue() || !V->isLValue()) { 7946 const Expr *NotLValueExpr = X->isLValue() ? V : X; 7947 ErrorFound = NotAnLValue; 7948 ErrorLoc = AtomicBinOp->getExprLoc(); 7949 ErrorRange = AtomicBinOp->getSourceRange(); 7950 NoteLoc = NotLValueExpr->getExprLoc(); 7951 NoteRange = NotLValueExpr->getSourceRange(); 7952 } 7953 } else if (!X->isInstantiationDependent() || 7954 !V->isInstantiationDependent()) { 7955 const Expr *NotScalarExpr = 7956 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7957 ? V 7958 : X; 7959 ErrorFound = NotAScalarType; 7960 ErrorLoc = AtomicBinOp->getExprLoc(); 7961 ErrorRange = AtomicBinOp->getSourceRange(); 7962 NoteLoc = NotScalarExpr->getExprLoc(); 7963 NoteRange = NotScalarExpr->getSourceRange(); 7964 } 7965 } else if (!AtomicBody->isInstantiationDependent()) { 7966 ErrorFound = NotAnAssignmentOp; 7967 ErrorLoc = AtomicBody->getExprLoc(); 7968 ErrorRange = AtomicBody->getSourceRange(); 7969 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7970 : AtomicBody->getExprLoc(); 7971 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7972 : AtomicBody->getSourceRange(); 7973 } 7974 } else { 7975 ErrorFound = NotAnExpression; 7976 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7977 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7978 } 7979 if (ErrorFound != NoError) { 7980 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7981 << ErrorRange; 7982 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7983 << NoteRange; 7984 return StmtError(); 7985 } 7986 if (CurContext->isDependentContext()) 7987 V = X = nullptr; 7988 } else if (AtomicKind == OMPC_write) { 7989 enum { 7990 NotAnExpression, 7991 NotAnAssignmentOp, 7992 NotAScalarType, 7993 NotAnLValue, 7994 NoError 7995 } ErrorFound = NoError; 7996 SourceLocation ErrorLoc, NoteLoc; 7997 SourceRange ErrorRange, NoteRange; 7998 // If clause is write: 7999 // x = expr; 8000 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8001 const auto *AtomicBinOp = 8002 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8003 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8004 X = AtomicBinOp->getLHS(); 8005 E = AtomicBinOp->getRHS(); 8006 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8007 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8008 if (!X->isLValue()) { 8009 ErrorFound = NotAnLValue; 8010 ErrorLoc = AtomicBinOp->getExprLoc(); 8011 ErrorRange = AtomicBinOp->getSourceRange(); 8012 NoteLoc = X->getExprLoc(); 8013 NoteRange = X->getSourceRange(); 8014 } 8015 } else if (!X->isInstantiationDependent() || 8016 !E->isInstantiationDependent()) { 8017 const Expr *NotScalarExpr = 8018 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8019 ? E 8020 : X; 8021 ErrorFound = NotAScalarType; 8022 ErrorLoc = AtomicBinOp->getExprLoc(); 8023 ErrorRange = AtomicBinOp->getSourceRange(); 8024 NoteLoc = NotScalarExpr->getExprLoc(); 8025 NoteRange = NotScalarExpr->getSourceRange(); 8026 } 8027 } else if (!AtomicBody->isInstantiationDependent()) { 8028 ErrorFound = NotAnAssignmentOp; 8029 ErrorLoc = AtomicBody->getExprLoc(); 8030 ErrorRange = AtomicBody->getSourceRange(); 8031 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8032 : AtomicBody->getExprLoc(); 8033 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8034 : AtomicBody->getSourceRange(); 8035 } 8036 } else { 8037 ErrorFound = NotAnExpression; 8038 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8039 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8040 } 8041 if (ErrorFound != NoError) { 8042 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8043 << ErrorRange; 8044 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8045 << NoteRange; 8046 return StmtError(); 8047 } 8048 if (CurContext->isDependentContext()) 8049 E = X = nullptr; 8050 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8051 // If clause is update: 8052 // x++; 8053 // x--; 8054 // ++x; 8055 // --x; 8056 // x binop= expr; 8057 // x = x binop expr; 8058 // x = expr binop x; 8059 OpenMPAtomicUpdateChecker Checker(*this); 8060 if (Checker.checkStatement( 8061 Body, (AtomicKind == OMPC_update) 8062 ? diag::err_omp_atomic_update_not_expression_statement 8063 : diag::err_omp_atomic_not_expression_statement, 8064 diag::note_omp_atomic_update)) 8065 return StmtError(); 8066 if (!CurContext->isDependentContext()) { 8067 E = Checker.getExpr(); 8068 X = Checker.getX(); 8069 UE = Checker.getUpdateExpr(); 8070 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8071 } 8072 } else if (AtomicKind == OMPC_capture) { 8073 enum { 8074 NotAnAssignmentOp, 8075 NotACompoundStatement, 8076 NotTwoSubstatements, 8077 NotASpecificExpression, 8078 NoError 8079 } ErrorFound = NoError; 8080 SourceLocation ErrorLoc, NoteLoc; 8081 SourceRange ErrorRange, NoteRange; 8082 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8083 // If clause is a capture: 8084 // v = x++; 8085 // v = x--; 8086 // v = ++x; 8087 // v = --x; 8088 // v = x binop= expr; 8089 // v = x = x binop expr; 8090 // v = x = expr binop x; 8091 const auto *AtomicBinOp = 8092 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8093 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8094 V = AtomicBinOp->getLHS(); 8095 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8096 OpenMPAtomicUpdateChecker Checker(*this); 8097 if (Checker.checkStatement( 8098 Body, diag::err_omp_atomic_capture_not_expression_statement, 8099 diag::note_omp_atomic_update)) 8100 return StmtError(); 8101 E = Checker.getExpr(); 8102 X = Checker.getX(); 8103 UE = Checker.getUpdateExpr(); 8104 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8105 IsPostfixUpdate = Checker.isPostfixUpdate(); 8106 } else if (!AtomicBody->isInstantiationDependent()) { 8107 ErrorLoc = AtomicBody->getExprLoc(); 8108 ErrorRange = AtomicBody->getSourceRange(); 8109 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8110 : AtomicBody->getExprLoc(); 8111 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8112 : AtomicBody->getSourceRange(); 8113 ErrorFound = NotAnAssignmentOp; 8114 } 8115 if (ErrorFound != NoError) { 8116 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8117 << ErrorRange; 8118 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8119 return StmtError(); 8120 } 8121 if (CurContext->isDependentContext()) 8122 UE = V = E = X = nullptr; 8123 } else { 8124 // If clause is a capture: 8125 // { v = x; x = expr; } 8126 // { v = x; x++; } 8127 // { v = x; x--; } 8128 // { v = x; ++x; } 8129 // { v = x; --x; } 8130 // { v = x; x binop= expr; } 8131 // { v = x; x = x binop expr; } 8132 // { v = x; x = expr binop x; } 8133 // { x++; v = x; } 8134 // { x--; v = x; } 8135 // { ++x; v = x; } 8136 // { --x; v = x; } 8137 // { x binop= expr; v = x; } 8138 // { x = x binop expr; v = x; } 8139 // { x = expr binop x; v = x; } 8140 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8141 // Check that this is { expr1; expr2; } 8142 if (CS->size() == 2) { 8143 Stmt *First = CS->body_front(); 8144 Stmt *Second = CS->body_back(); 8145 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8146 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8147 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8148 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8149 // Need to find what subexpression is 'v' and what is 'x'. 8150 OpenMPAtomicUpdateChecker Checker(*this); 8151 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8152 BinaryOperator *BinOp = nullptr; 8153 if (IsUpdateExprFound) { 8154 BinOp = dyn_cast<BinaryOperator>(First); 8155 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8156 } 8157 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8158 // { v = x; x++; } 8159 // { v = x; x--; } 8160 // { v = x; ++x; } 8161 // { v = x; --x; } 8162 // { v = x; x binop= expr; } 8163 // { v = x; x = x binop expr; } 8164 // { v = x; x = expr binop x; } 8165 // Check that the first expression has form v = x. 8166 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8167 llvm::FoldingSetNodeID XId, PossibleXId; 8168 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8169 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8170 IsUpdateExprFound = XId == PossibleXId; 8171 if (IsUpdateExprFound) { 8172 V = BinOp->getLHS(); 8173 X = Checker.getX(); 8174 E = Checker.getExpr(); 8175 UE = Checker.getUpdateExpr(); 8176 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8177 IsPostfixUpdate = true; 8178 } 8179 } 8180 if (!IsUpdateExprFound) { 8181 IsUpdateExprFound = !Checker.checkStatement(First); 8182 BinOp = nullptr; 8183 if (IsUpdateExprFound) { 8184 BinOp = dyn_cast<BinaryOperator>(Second); 8185 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8186 } 8187 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8188 // { x++; v = x; } 8189 // { x--; v = x; } 8190 // { ++x; v = x; } 8191 // { --x; v = x; } 8192 // { x binop= expr; v = x; } 8193 // { x = x binop expr; v = x; } 8194 // { x = expr binop x; v = x; } 8195 // Check that the second expression has form v = x. 8196 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8197 llvm::FoldingSetNodeID XId, PossibleXId; 8198 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8199 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8200 IsUpdateExprFound = XId == PossibleXId; 8201 if (IsUpdateExprFound) { 8202 V = BinOp->getLHS(); 8203 X = Checker.getX(); 8204 E = Checker.getExpr(); 8205 UE = Checker.getUpdateExpr(); 8206 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8207 IsPostfixUpdate = false; 8208 } 8209 } 8210 } 8211 if (!IsUpdateExprFound) { 8212 // { v = x; x = expr; } 8213 auto *FirstExpr = dyn_cast<Expr>(First); 8214 auto *SecondExpr = dyn_cast<Expr>(Second); 8215 if (!FirstExpr || !SecondExpr || 8216 !(FirstExpr->isInstantiationDependent() || 8217 SecondExpr->isInstantiationDependent())) { 8218 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8219 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8220 ErrorFound = NotAnAssignmentOp; 8221 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8222 : First->getBeginLoc(); 8223 NoteRange = ErrorRange = FirstBinOp 8224 ? FirstBinOp->getSourceRange() 8225 : SourceRange(ErrorLoc, ErrorLoc); 8226 } else { 8227 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8228 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8229 ErrorFound = NotAnAssignmentOp; 8230 NoteLoc = ErrorLoc = SecondBinOp 8231 ? SecondBinOp->getOperatorLoc() 8232 : Second->getBeginLoc(); 8233 NoteRange = ErrorRange = 8234 SecondBinOp ? SecondBinOp->getSourceRange() 8235 : SourceRange(ErrorLoc, ErrorLoc); 8236 } else { 8237 Expr *PossibleXRHSInFirst = 8238 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8239 Expr *PossibleXLHSInSecond = 8240 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8241 llvm::FoldingSetNodeID X1Id, X2Id; 8242 PossibleXRHSInFirst->Profile(X1Id, Context, 8243 /*Canonical=*/true); 8244 PossibleXLHSInSecond->Profile(X2Id, Context, 8245 /*Canonical=*/true); 8246 IsUpdateExprFound = X1Id == X2Id; 8247 if (IsUpdateExprFound) { 8248 V = FirstBinOp->getLHS(); 8249 X = SecondBinOp->getLHS(); 8250 E = SecondBinOp->getRHS(); 8251 UE = nullptr; 8252 IsXLHSInRHSPart = false; 8253 IsPostfixUpdate = true; 8254 } else { 8255 ErrorFound = NotASpecificExpression; 8256 ErrorLoc = FirstBinOp->getExprLoc(); 8257 ErrorRange = FirstBinOp->getSourceRange(); 8258 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8259 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8260 } 8261 } 8262 } 8263 } 8264 } 8265 } else { 8266 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8267 NoteRange = ErrorRange = 8268 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8269 ErrorFound = NotTwoSubstatements; 8270 } 8271 } else { 8272 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8273 NoteRange = ErrorRange = 8274 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8275 ErrorFound = NotACompoundStatement; 8276 } 8277 if (ErrorFound != NoError) { 8278 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8279 << ErrorRange; 8280 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8281 return StmtError(); 8282 } 8283 if (CurContext->isDependentContext()) 8284 UE = V = E = X = nullptr; 8285 } 8286 } 8287 8288 setFunctionHasBranchProtectedScope(); 8289 8290 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8291 X, V, E, UE, IsXLHSInRHSPart, 8292 IsPostfixUpdate); 8293 } 8294 8295 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8296 Stmt *AStmt, 8297 SourceLocation StartLoc, 8298 SourceLocation EndLoc) { 8299 if (!AStmt) 8300 return StmtError(); 8301 8302 auto *CS = cast<CapturedStmt>(AStmt); 8303 // 1.2.2 OpenMP Language Terminology 8304 // Structured block - An executable statement with a single entry at the 8305 // top and a single exit at the bottom. 8306 // The point of exit cannot be a branch out of the structured block. 8307 // longjmp() and throw() must not violate the entry/exit criteria. 8308 CS->getCapturedDecl()->setNothrow(); 8309 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8310 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8311 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8312 // 1.2.2 OpenMP Language Terminology 8313 // Structured block - An executable statement with a single entry at the 8314 // top and a single exit at the bottom. 8315 // The point of exit cannot be a branch out of the structured block. 8316 // longjmp() and throw() must not violate the entry/exit criteria. 8317 CS->getCapturedDecl()->setNothrow(); 8318 } 8319 8320 // OpenMP [2.16, Nesting of Regions] 8321 // If specified, a teams construct must be contained within a target 8322 // construct. That target construct must contain no statements or directives 8323 // outside of the teams construct. 8324 if (DSAStack->hasInnerTeamsRegion()) { 8325 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8326 bool OMPTeamsFound = true; 8327 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8328 auto I = CS->body_begin(); 8329 while (I != CS->body_end()) { 8330 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8331 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8332 OMPTeamsFound) { 8333 8334 OMPTeamsFound = false; 8335 break; 8336 } 8337 ++I; 8338 } 8339 assert(I != CS->body_end() && "Not found statement"); 8340 S = *I; 8341 } else { 8342 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8343 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8344 } 8345 if (!OMPTeamsFound) { 8346 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8347 Diag(DSAStack->getInnerTeamsRegionLoc(), 8348 diag::note_omp_nested_teams_construct_here); 8349 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8350 << isa<OMPExecutableDirective>(S); 8351 return StmtError(); 8352 } 8353 } 8354 8355 setFunctionHasBranchProtectedScope(); 8356 8357 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8358 } 8359 8360 StmtResult 8361 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8362 Stmt *AStmt, SourceLocation StartLoc, 8363 SourceLocation EndLoc) { 8364 if (!AStmt) 8365 return StmtError(); 8366 8367 auto *CS = cast<CapturedStmt>(AStmt); 8368 // 1.2.2 OpenMP Language Terminology 8369 // Structured block - An executable statement with a single entry at the 8370 // top and a single exit at the bottom. 8371 // The point of exit cannot be a branch out of the structured block. 8372 // longjmp() and throw() must not violate the entry/exit criteria. 8373 CS->getCapturedDecl()->setNothrow(); 8374 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8375 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8376 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8377 // 1.2.2 OpenMP Language Terminology 8378 // Structured block - An executable statement with a single entry at the 8379 // top and a single exit at the bottom. 8380 // The point of exit cannot be a branch out of the structured block. 8381 // longjmp() and throw() must not violate the entry/exit criteria. 8382 CS->getCapturedDecl()->setNothrow(); 8383 } 8384 8385 setFunctionHasBranchProtectedScope(); 8386 8387 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8388 AStmt); 8389 } 8390 8391 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8392 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8393 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8394 if (!AStmt) 8395 return StmtError(); 8396 8397 auto *CS = cast<CapturedStmt>(AStmt); 8398 // 1.2.2 OpenMP Language Terminology 8399 // Structured block - An executable statement with a single entry at the 8400 // top and a single exit at the bottom. 8401 // The point of exit cannot be a branch out of the structured block. 8402 // longjmp() and throw() must not violate the entry/exit criteria. 8403 CS->getCapturedDecl()->setNothrow(); 8404 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8405 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8406 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8407 // 1.2.2 OpenMP Language Terminology 8408 // Structured block - An executable statement with a single entry at the 8409 // top and a single exit at the bottom. 8410 // The point of exit cannot be a branch out of the structured block. 8411 // longjmp() and throw() must not violate the entry/exit criteria. 8412 CS->getCapturedDecl()->setNothrow(); 8413 } 8414 8415 OMPLoopDirective::HelperExprs B; 8416 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8417 // define the nested loops number. 8418 unsigned NestedLoopCount = 8419 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8420 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8421 VarsWithImplicitDSA, B); 8422 if (NestedLoopCount == 0) 8423 return StmtError(); 8424 8425 assert((CurContext->isDependentContext() || B.builtAll()) && 8426 "omp target parallel for loop exprs were not built"); 8427 8428 if (!CurContext->isDependentContext()) { 8429 // Finalize the clauses that need pre-built expressions for CodeGen. 8430 for (OMPClause *C : Clauses) { 8431 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8432 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8433 B.NumIterations, *this, CurScope, 8434 DSAStack)) 8435 return StmtError(); 8436 } 8437 } 8438 8439 setFunctionHasBranchProtectedScope(); 8440 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8441 NestedLoopCount, Clauses, AStmt, 8442 B, DSAStack->isCancelRegion()); 8443 } 8444 8445 /// Check for existence of a map clause in the list of clauses. 8446 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8447 const OpenMPClauseKind K) { 8448 return llvm::any_of( 8449 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8450 } 8451 8452 template <typename... Params> 8453 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8454 const Params... ClauseTypes) { 8455 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8456 } 8457 8458 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8459 Stmt *AStmt, 8460 SourceLocation StartLoc, 8461 SourceLocation EndLoc) { 8462 if (!AStmt) 8463 return StmtError(); 8464 8465 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8466 8467 // OpenMP [2.10.1, Restrictions, p. 97] 8468 // At least one map clause must appear on the directive. 8469 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8470 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8471 << "'map' or 'use_device_ptr'" 8472 << getOpenMPDirectiveName(OMPD_target_data); 8473 return StmtError(); 8474 } 8475 8476 setFunctionHasBranchProtectedScope(); 8477 8478 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8479 AStmt); 8480 } 8481 8482 StmtResult 8483 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8484 SourceLocation StartLoc, 8485 SourceLocation EndLoc, Stmt *AStmt) { 8486 if (!AStmt) 8487 return StmtError(); 8488 8489 auto *CS = cast<CapturedStmt>(AStmt); 8490 // 1.2.2 OpenMP Language Terminology 8491 // Structured block - An executable statement with a single entry at the 8492 // top and a single exit at the bottom. 8493 // The point of exit cannot be a branch out of the structured block. 8494 // longjmp() and throw() must not violate the entry/exit criteria. 8495 CS->getCapturedDecl()->setNothrow(); 8496 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8497 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8498 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8499 // 1.2.2 OpenMP Language Terminology 8500 // Structured block - An executable statement with a single entry at the 8501 // top and a single exit at the bottom. 8502 // The point of exit cannot be a branch out of the structured block. 8503 // longjmp() and throw() must not violate the entry/exit criteria. 8504 CS->getCapturedDecl()->setNothrow(); 8505 } 8506 8507 // OpenMP [2.10.2, Restrictions, p. 99] 8508 // At least one map clause must appear on the directive. 8509 if (!hasClauses(Clauses, OMPC_map)) { 8510 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8511 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8512 return StmtError(); 8513 } 8514 8515 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8516 AStmt); 8517 } 8518 8519 StmtResult 8520 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8521 SourceLocation StartLoc, 8522 SourceLocation EndLoc, Stmt *AStmt) { 8523 if (!AStmt) 8524 return StmtError(); 8525 8526 auto *CS = cast<CapturedStmt>(AStmt); 8527 // 1.2.2 OpenMP Language Terminology 8528 // Structured block - An executable statement with a single entry at the 8529 // top and a single exit at the bottom. 8530 // The point of exit cannot be a branch out of the structured block. 8531 // longjmp() and throw() must not violate the entry/exit criteria. 8532 CS->getCapturedDecl()->setNothrow(); 8533 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8534 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8535 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8536 // 1.2.2 OpenMP Language Terminology 8537 // Structured block - An executable statement with a single entry at the 8538 // top and a single exit at the bottom. 8539 // The point of exit cannot be a branch out of the structured block. 8540 // longjmp() and throw() must not violate the entry/exit criteria. 8541 CS->getCapturedDecl()->setNothrow(); 8542 } 8543 8544 // OpenMP [2.10.3, Restrictions, p. 102] 8545 // At least one map clause must appear on the directive. 8546 if (!hasClauses(Clauses, OMPC_map)) { 8547 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8548 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8549 return StmtError(); 8550 } 8551 8552 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8553 AStmt); 8554 } 8555 8556 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8557 SourceLocation StartLoc, 8558 SourceLocation EndLoc, 8559 Stmt *AStmt) { 8560 if (!AStmt) 8561 return StmtError(); 8562 8563 auto *CS = cast<CapturedStmt>(AStmt); 8564 // 1.2.2 OpenMP Language Terminology 8565 // Structured block - An executable statement with a single entry at the 8566 // top and a single exit at the bottom. 8567 // The point of exit cannot be a branch out of the structured block. 8568 // longjmp() and throw() must not violate the entry/exit criteria. 8569 CS->getCapturedDecl()->setNothrow(); 8570 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8571 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8572 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8573 // 1.2.2 OpenMP Language Terminology 8574 // Structured block - An executable statement with a single entry at the 8575 // top and a single exit at the bottom. 8576 // The point of exit cannot be a branch out of the structured block. 8577 // longjmp() and throw() must not violate the entry/exit criteria. 8578 CS->getCapturedDecl()->setNothrow(); 8579 } 8580 8581 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8582 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8583 return StmtError(); 8584 } 8585 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8586 AStmt); 8587 } 8588 8589 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8590 Stmt *AStmt, SourceLocation StartLoc, 8591 SourceLocation EndLoc) { 8592 if (!AStmt) 8593 return StmtError(); 8594 8595 auto *CS = cast<CapturedStmt>(AStmt); 8596 // 1.2.2 OpenMP Language Terminology 8597 // Structured block - An executable statement with a single entry at the 8598 // top and a single exit at the bottom. 8599 // The point of exit cannot be a branch out of the structured block. 8600 // longjmp() and throw() must not violate the entry/exit criteria. 8601 CS->getCapturedDecl()->setNothrow(); 8602 8603 setFunctionHasBranchProtectedScope(); 8604 8605 DSAStack->setParentTeamsRegionLoc(StartLoc); 8606 8607 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8608 } 8609 8610 StmtResult 8611 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8612 SourceLocation EndLoc, 8613 OpenMPDirectiveKind CancelRegion) { 8614 if (DSAStack->isParentNowaitRegion()) { 8615 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8616 return StmtError(); 8617 } 8618 if (DSAStack->isParentOrderedRegion()) { 8619 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8620 return StmtError(); 8621 } 8622 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8623 CancelRegion); 8624 } 8625 8626 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8627 SourceLocation StartLoc, 8628 SourceLocation EndLoc, 8629 OpenMPDirectiveKind CancelRegion) { 8630 if (DSAStack->isParentNowaitRegion()) { 8631 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8632 return StmtError(); 8633 } 8634 if (DSAStack->isParentOrderedRegion()) { 8635 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8636 return StmtError(); 8637 } 8638 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8639 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8640 CancelRegion); 8641 } 8642 8643 static bool checkGrainsizeNumTasksClauses(Sema &S, 8644 ArrayRef<OMPClause *> Clauses) { 8645 const OMPClause *PrevClause = nullptr; 8646 bool ErrorFound = false; 8647 for (const OMPClause *C : Clauses) { 8648 if (C->getClauseKind() == OMPC_grainsize || 8649 C->getClauseKind() == OMPC_num_tasks) { 8650 if (!PrevClause) 8651 PrevClause = C; 8652 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8653 S.Diag(C->getBeginLoc(), 8654 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8655 << getOpenMPClauseName(C->getClauseKind()) 8656 << getOpenMPClauseName(PrevClause->getClauseKind()); 8657 S.Diag(PrevClause->getBeginLoc(), 8658 diag::note_omp_previous_grainsize_num_tasks) 8659 << getOpenMPClauseName(PrevClause->getClauseKind()); 8660 ErrorFound = true; 8661 } 8662 } 8663 } 8664 return ErrorFound; 8665 } 8666 8667 static bool checkReductionClauseWithNogroup(Sema &S, 8668 ArrayRef<OMPClause *> Clauses) { 8669 const OMPClause *ReductionClause = nullptr; 8670 const OMPClause *NogroupClause = nullptr; 8671 for (const OMPClause *C : Clauses) { 8672 if (C->getClauseKind() == OMPC_reduction) { 8673 ReductionClause = C; 8674 if (NogroupClause) 8675 break; 8676 continue; 8677 } 8678 if (C->getClauseKind() == OMPC_nogroup) { 8679 NogroupClause = C; 8680 if (ReductionClause) 8681 break; 8682 continue; 8683 } 8684 } 8685 if (ReductionClause && NogroupClause) { 8686 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8687 << SourceRange(NogroupClause->getBeginLoc(), 8688 NogroupClause->getEndLoc()); 8689 return true; 8690 } 8691 return false; 8692 } 8693 8694 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8695 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8696 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8697 if (!AStmt) 8698 return StmtError(); 8699 8700 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8701 OMPLoopDirective::HelperExprs B; 8702 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8703 // define the nested loops number. 8704 unsigned NestedLoopCount = 8705 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8706 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8707 VarsWithImplicitDSA, B); 8708 if (NestedLoopCount == 0) 8709 return StmtError(); 8710 8711 assert((CurContext->isDependentContext() || B.builtAll()) && 8712 "omp for loop exprs were not built"); 8713 8714 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8715 // The grainsize clause and num_tasks clause are mutually exclusive and may 8716 // not appear on the same taskloop directive. 8717 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8718 return StmtError(); 8719 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8720 // If a reduction clause is present on the taskloop directive, the nogroup 8721 // clause must not be specified. 8722 if (checkReductionClauseWithNogroup(*this, Clauses)) 8723 return StmtError(); 8724 8725 setFunctionHasBranchProtectedScope(); 8726 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8727 NestedLoopCount, Clauses, AStmt, B); 8728 } 8729 8730 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8731 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8732 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8733 if (!AStmt) 8734 return StmtError(); 8735 8736 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8737 OMPLoopDirective::HelperExprs B; 8738 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8739 // define the nested loops number. 8740 unsigned NestedLoopCount = 8741 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8742 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8743 VarsWithImplicitDSA, B); 8744 if (NestedLoopCount == 0) 8745 return StmtError(); 8746 8747 assert((CurContext->isDependentContext() || B.builtAll()) && 8748 "omp for loop exprs were not built"); 8749 8750 if (!CurContext->isDependentContext()) { 8751 // Finalize the clauses that need pre-built expressions for CodeGen. 8752 for (OMPClause *C : Clauses) { 8753 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8754 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8755 B.NumIterations, *this, CurScope, 8756 DSAStack)) 8757 return StmtError(); 8758 } 8759 } 8760 8761 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8762 // The grainsize clause and num_tasks clause are mutually exclusive and may 8763 // not appear on the same taskloop directive. 8764 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8765 return StmtError(); 8766 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8767 // If a reduction clause is present on the taskloop directive, the nogroup 8768 // clause must not be specified. 8769 if (checkReductionClauseWithNogroup(*this, Clauses)) 8770 return StmtError(); 8771 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8772 return StmtError(); 8773 8774 setFunctionHasBranchProtectedScope(); 8775 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8776 NestedLoopCount, Clauses, AStmt, B); 8777 } 8778 8779 StmtResult Sema::ActOnOpenMPDistributeDirective( 8780 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8781 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8782 if (!AStmt) 8783 return StmtError(); 8784 8785 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8786 OMPLoopDirective::HelperExprs B; 8787 // In presence of clause 'collapse' with number of loops, it will 8788 // define the nested loops number. 8789 unsigned NestedLoopCount = 8790 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8791 nullptr /*ordered not a clause on distribute*/, AStmt, 8792 *this, *DSAStack, VarsWithImplicitDSA, B); 8793 if (NestedLoopCount == 0) 8794 return StmtError(); 8795 8796 assert((CurContext->isDependentContext() || B.builtAll()) && 8797 "omp for loop exprs were not built"); 8798 8799 setFunctionHasBranchProtectedScope(); 8800 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8801 NestedLoopCount, Clauses, AStmt, B); 8802 } 8803 8804 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8805 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8806 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8807 if (!AStmt) 8808 return StmtError(); 8809 8810 auto *CS = cast<CapturedStmt>(AStmt); 8811 // 1.2.2 OpenMP Language Terminology 8812 // Structured block - An executable statement with a single entry at the 8813 // top and a single exit at the bottom. 8814 // The point of exit cannot be a branch out of the structured block. 8815 // longjmp() and throw() must not violate the entry/exit criteria. 8816 CS->getCapturedDecl()->setNothrow(); 8817 for (int ThisCaptureLevel = 8818 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 8819 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8820 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8821 // 1.2.2 OpenMP Language Terminology 8822 // Structured block - An executable statement with a single entry at the 8823 // top and a single exit at the bottom. 8824 // The point of exit cannot be a branch out of the structured block. 8825 // longjmp() and throw() must not violate the entry/exit criteria. 8826 CS->getCapturedDecl()->setNothrow(); 8827 } 8828 8829 OMPLoopDirective::HelperExprs B; 8830 // In presence of clause 'collapse' with number of loops, it will 8831 // define the nested loops number. 8832 unsigned NestedLoopCount = checkOpenMPLoop( 8833 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8834 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8835 VarsWithImplicitDSA, B); 8836 if (NestedLoopCount == 0) 8837 return StmtError(); 8838 8839 assert((CurContext->isDependentContext() || B.builtAll()) && 8840 "omp for loop exprs were not built"); 8841 8842 setFunctionHasBranchProtectedScope(); 8843 return OMPDistributeParallelForDirective::Create( 8844 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8845 DSAStack->isCancelRegion()); 8846 } 8847 8848 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 8849 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8850 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8851 if (!AStmt) 8852 return StmtError(); 8853 8854 auto *CS = cast<CapturedStmt>(AStmt); 8855 // 1.2.2 OpenMP Language Terminology 8856 // Structured block - An executable statement with a single entry at the 8857 // top and a single exit at the bottom. 8858 // The point of exit cannot be a branch out of the structured block. 8859 // longjmp() and throw() must not violate the entry/exit criteria. 8860 CS->getCapturedDecl()->setNothrow(); 8861 for (int ThisCaptureLevel = 8862 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 8863 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8864 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8865 // 1.2.2 OpenMP Language Terminology 8866 // Structured block - An executable statement with a single entry at the 8867 // top and a single exit at the bottom. 8868 // The point of exit cannot be a branch out of the structured block. 8869 // longjmp() and throw() must not violate the entry/exit criteria. 8870 CS->getCapturedDecl()->setNothrow(); 8871 } 8872 8873 OMPLoopDirective::HelperExprs B; 8874 // In presence of clause 'collapse' with number of loops, it will 8875 // define the nested loops number. 8876 unsigned NestedLoopCount = checkOpenMPLoop( 8877 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8878 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8879 VarsWithImplicitDSA, B); 8880 if (NestedLoopCount == 0) 8881 return StmtError(); 8882 8883 assert((CurContext->isDependentContext() || B.builtAll()) && 8884 "omp for loop exprs were not built"); 8885 8886 if (!CurContext->isDependentContext()) { 8887 // Finalize the clauses that need pre-built expressions for CodeGen. 8888 for (OMPClause *C : Clauses) { 8889 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8890 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8891 B.NumIterations, *this, CurScope, 8892 DSAStack)) 8893 return StmtError(); 8894 } 8895 } 8896 8897 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8898 return StmtError(); 8899 8900 setFunctionHasBranchProtectedScope(); 8901 return OMPDistributeParallelForSimdDirective::Create( 8902 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8903 } 8904 8905 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 8906 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8907 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8908 if (!AStmt) 8909 return StmtError(); 8910 8911 auto *CS = cast<CapturedStmt>(AStmt); 8912 // 1.2.2 OpenMP Language Terminology 8913 // Structured block - An executable statement with a single entry at the 8914 // top and a single exit at the bottom. 8915 // The point of exit cannot be a branch out of the structured block. 8916 // longjmp() and throw() must not violate the entry/exit criteria. 8917 CS->getCapturedDecl()->setNothrow(); 8918 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 8919 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8920 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8921 // 1.2.2 OpenMP Language Terminology 8922 // Structured block - An executable statement with a single entry at the 8923 // top and a single exit at the bottom. 8924 // The point of exit cannot be a branch out of the structured block. 8925 // longjmp() and throw() must not violate the entry/exit criteria. 8926 CS->getCapturedDecl()->setNothrow(); 8927 } 8928 8929 OMPLoopDirective::HelperExprs B; 8930 // In presence of clause 'collapse' with number of loops, it will 8931 // define the nested loops number. 8932 unsigned NestedLoopCount = 8933 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 8934 nullptr /*ordered not a clause on distribute*/, CS, *this, 8935 *DSAStack, VarsWithImplicitDSA, B); 8936 if (NestedLoopCount == 0) 8937 return StmtError(); 8938 8939 assert((CurContext->isDependentContext() || B.builtAll()) && 8940 "omp for loop exprs were not built"); 8941 8942 if (!CurContext->isDependentContext()) { 8943 // Finalize the clauses that need pre-built expressions for CodeGen. 8944 for (OMPClause *C : Clauses) { 8945 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8946 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8947 B.NumIterations, *this, CurScope, 8948 DSAStack)) 8949 return StmtError(); 8950 } 8951 } 8952 8953 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8954 return StmtError(); 8955 8956 setFunctionHasBranchProtectedScope(); 8957 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 8958 NestedLoopCount, Clauses, AStmt, B); 8959 } 8960 8961 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 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 = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8975 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8976 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8977 // 1.2.2 OpenMP Language Terminology 8978 // Structured block - An executable statement with a single entry at the 8979 // top and a single exit at the bottom. 8980 // The point of exit cannot be a branch out of the structured block. 8981 // longjmp() and throw() must not violate the entry/exit criteria. 8982 CS->getCapturedDecl()->setNothrow(); 8983 } 8984 8985 OMPLoopDirective::HelperExprs B; 8986 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8987 // define the nested loops number. 8988 unsigned NestedLoopCount = checkOpenMPLoop( 8989 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8990 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8991 VarsWithImplicitDSA, B); 8992 if (NestedLoopCount == 0) 8993 return StmtError(); 8994 8995 assert((CurContext->isDependentContext() || B.builtAll()) && 8996 "omp target parallel for simd loop exprs were not built"); 8997 8998 if (!CurContext->isDependentContext()) { 8999 // Finalize the clauses that need pre-built expressions for CodeGen. 9000 for (OMPClause *C : Clauses) { 9001 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9002 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9003 B.NumIterations, *this, CurScope, 9004 DSAStack)) 9005 return StmtError(); 9006 } 9007 } 9008 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9009 return StmtError(); 9010 9011 setFunctionHasBranchProtectedScope(); 9012 return OMPTargetParallelForSimdDirective::Create( 9013 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9014 } 9015 9016 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 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(OMPD_target_simd); 9030 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9031 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9032 // 1.2.2 OpenMP Language Terminology 9033 // Structured block - An executable statement with a single entry at the 9034 // top and a single exit at the bottom. 9035 // The point of exit cannot be a branch out of the structured block. 9036 // longjmp() and throw() must not violate the entry/exit criteria. 9037 CS->getCapturedDecl()->setNothrow(); 9038 } 9039 9040 OMPLoopDirective::HelperExprs B; 9041 // In presence of clause 'collapse' with number of loops, it will define the 9042 // nested loops number. 9043 unsigned NestedLoopCount = 9044 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9045 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9046 VarsWithImplicitDSA, B); 9047 if (NestedLoopCount == 0) 9048 return StmtError(); 9049 9050 assert((CurContext->isDependentContext() || B.builtAll()) && 9051 "omp target simd loop exprs were not built"); 9052 9053 if (!CurContext->isDependentContext()) { 9054 // Finalize the clauses that need pre-built expressions for CodeGen. 9055 for (OMPClause *C : Clauses) { 9056 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9057 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9058 B.NumIterations, *this, CurScope, 9059 DSAStack)) 9060 return StmtError(); 9061 } 9062 } 9063 9064 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9065 return StmtError(); 9066 9067 setFunctionHasBranchProtectedScope(); 9068 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9069 NestedLoopCount, Clauses, AStmt, B); 9070 } 9071 9072 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9073 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9074 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9075 if (!AStmt) 9076 return StmtError(); 9077 9078 auto *CS = cast<CapturedStmt>(AStmt); 9079 // 1.2.2 OpenMP Language Terminology 9080 // Structured block - An executable statement with a single entry at the 9081 // top and a single exit at the bottom. 9082 // The point of exit cannot be a branch out of the structured block. 9083 // longjmp() and throw() must not violate the entry/exit criteria. 9084 CS->getCapturedDecl()->setNothrow(); 9085 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9086 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9087 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9088 // 1.2.2 OpenMP Language Terminology 9089 // Structured block - An executable statement with a single entry at the 9090 // top and a single exit at the bottom. 9091 // The point of exit cannot be a branch out of the structured block. 9092 // longjmp() and throw() must not violate the entry/exit criteria. 9093 CS->getCapturedDecl()->setNothrow(); 9094 } 9095 9096 OMPLoopDirective::HelperExprs B; 9097 // In presence of clause 'collapse' with number of loops, it will 9098 // define the nested loops number. 9099 unsigned NestedLoopCount = 9100 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9101 nullptr /*ordered not a clause on distribute*/, CS, *this, 9102 *DSAStack, VarsWithImplicitDSA, B); 9103 if (NestedLoopCount == 0) 9104 return StmtError(); 9105 9106 assert((CurContext->isDependentContext() || B.builtAll()) && 9107 "omp teams distribute loop exprs were not built"); 9108 9109 setFunctionHasBranchProtectedScope(); 9110 9111 DSAStack->setParentTeamsRegionLoc(StartLoc); 9112 9113 return OMPTeamsDistributeDirective::Create( 9114 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9115 } 9116 9117 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9118 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9119 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9120 if (!AStmt) 9121 return StmtError(); 9122 9123 auto *CS = cast<CapturedStmt>(AStmt); 9124 // 1.2.2 OpenMP Language Terminology 9125 // Structured block - An executable statement with a single entry at the 9126 // top and a single exit at the bottom. 9127 // The point of exit cannot be a branch out of the structured block. 9128 // longjmp() and throw() must not violate the entry/exit criteria. 9129 CS->getCapturedDecl()->setNothrow(); 9130 for (int ThisCaptureLevel = 9131 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9132 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9133 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9134 // 1.2.2 OpenMP Language Terminology 9135 // Structured block - An executable statement with a single entry at the 9136 // top and a single exit at the bottom. 9137 // The point of exit cannot be a branch out of the structured block. 9138 // longjmp() and throw() must not violate the entry/exit criteria. 9139 CS->getCapturedDecl()->setNothrow(); 9140 } 9141 9142 9143 OMPLoopDirective::HelperExprs B; 9144 // In presence of clause 'collapse' with number of loops, it will 9145 // define the nested loops number. 9146 unsigned NestedLoopCount = checkOpenMPLoop( 9147 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9148 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9149 VarsWithImplicitDSA, B); 9150 9151 if (NestedLoopCount == 0) 9152 return StmtError(); 9153 9154 assert((CurContext->isDependentContext() || B.builtAll()) && 9155 "omp teams distribute simd loop exprs were not built"); 9156 9157 if (!CurContext->isDependentContext()) { 9158 // Finalize the clauses that need pre-built expressions for CodeGen. 9159 for (OMPClause *C : Clauses) { 9160 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9161 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9162 B.NumIterations, *this, CurScope, 9163 DSAStack)) 9164 return StmtError(); 9165 } 9166 } 9167 9168 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9169 return StmtError(); 9170 9171 setFunctionHasBranchProtectedScope(); 9172 9173 DSAStack->setParentTeamsRegionLoc(StartLoc); 9174 9175 return OMPTeamsDistributeSimdDirective::Create( 9176 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9177 } 9178 9179 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9180 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9181 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9182 if (!AStmt) 9183 return StmtError(); 9184 9185 auto *CS = cast<CapturedStmt>(AStmt); 9186 // 1.2.2 OpenMP Language Terminology 9187 // Structured block - An executable statement with a single entry at the 9188 // top and a single exit at the bottom. 9189 // The point of exit cannot be a branch out of the structured block. 9190 // longjmp() and throw() must not violate the entry/exit criteria. 9191 CS->getCapturedDecl()->setNothrow(); 9192 9193 for (int ThisCaptureLevel = 9194 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9195 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9196 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9197 // 1.2.2 OpenMP Language Terminology 9198 // Structured block - An executable statement with a single entry at the 9199 // top and a single exit at the bottom. 9200 // The point of exit cannot be a branch out of the structured block. 9201 // longjmp() and throw() must not violate the entry/exit criteria. 9202 CS->getCapturedDecl()->setNothrow(); 9203 } 9204 9205 OMPLoopDirective::HelperExprs B; 9206 // In presence of clause 'collapse' with number of loops, it will 9207 // define the nested loops number. 9208 unsigned NestedLoopCount = checkOpenMPLoop( 9209 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9210 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9211 VarsWithImplicitDSA, B); 9212 9213 if (NestedLoopCount == 0) 9214 return StmtError(); 9215 9216 assert((CurContext->isDependentContext() || B.builtAll()) && 9217 "omp for loop exprs were not built"); 9218 9219 if (!CurContext->isDependentContext()) { 9220 // Finalize the clauses that need pre-built expressions for CodeGen. 9221 for (OMPClause *C : Clauses) { 9222 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9223 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9224 B.NumIterations, *this, CurScope, 9225 DSAStack)) 9226 return StmtError(); 9227 } 9228 } 9229 9230 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9231 return StmtError(); 9232 9233 setFunctionHasBranchProtectedScope(); 9234 9235 DSAStack->setParentTeamsRegionLoc(StartLoc); 9236 9237 return OMPTeamsDistributeParallelForSimdDirective::Create( 9238 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9239 } 9240 9241 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9242 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9243 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9244 if (!AStmt) 9245 return StmtError(); 9246 9247 auto *CS = cast<CapturedStmt>(AStmt); 9248 // 1.2.2 OpenMP Language Terminology 9249 // Structured block - An executable statement with a single entry at the 9250 // top and a single exit at the bottom. 9251 // The point of exit cannot be a branch out of the structured block. 9252 // longjmp() and throw() must not violate the entry/exit criteria. 9253 CS->getCapturedDecl()->setNothrow(); 9254 9255 for (int ThisCaptureLevel = 9256 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9257 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9258 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9259 // 1.2.2 OpenMP Language Terminology 9260 // Structured block - An executable statement with a single entry at the 9261 // top and a single exit at the bottom. 9262 // The point of exit cannot be a branch out of the structured block. 9263 // longjmp() and throw() must not violate the entry/exit criteria. 9264 CS->getCapturedDecl()->setNothrow(); 9265 } 9266 9267 OMPLoopDirective::HelperExprs B; 9268 // In presence of clause 'collapse' with number of loops, it will 9269 // define the nested loops number. 9270 unsigned NestedLoopCount = checkOpenMPLoop( 9271 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9272 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9273 VarsWithImplicitDSA, B); 9274 9275 if (NestedLoopCount == 0) 9276 return StmtError(); 9277 9278 assert((CurContext->isDependentContext() || B.builtAll()) && 9279 "omp for loop exprs were not built"); 9280 9281 setFunctionHasBranchProtectedScope(); 9282 9283 DSAStack->setParentTeamsRegionLoc(StartLoc); 9284 9285 return OMPTeamsDistributeParallelForDirective::Create( 9286 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9287 DSAStack->isCancelRegion()); 9288 } 9289 9290 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9291 Stmt *AStmt, 9292 SourceLocation StartLoc, 9293 SourceLocation EndLoc) { 9294 if (!AStmt) 9295 return StmtError(); 9296 9297 auto *CS = cast<CapturedStmt>(AStmt); 9298 // 1.2.2 OpenMP Language Terminology 9299 // Structured block - An executable statement with a single entry at the 9300 // top and a single exit at the bottom. 9301 // The point of exit cannot be a branch out of the structured block. 9302 // longjmp() and throw() must not violate the entry/exit criteria. 9303 CS->getCapturedDecl()->setNothrow(); 9304 9305 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9306 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9307 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9308 // 1.2.2 OpenMP Language Terminology 9309 // Structured block - An executable statement with a single entry at the 9310 // top and a single exit at the bottom. 9311 // The point of exit cannot be a branch out of the structured block. 9312 // longjmp() and throw() must not violate the entry/exit criteria. 9313 CS->getCapturedDecl()->setNothrow(); 9314 } 9315 setFunctionHasBranchProtectedScope(); 9316 9317 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9318 AStmt); 9319 } 9320 9321 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9322 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9323 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9324 if (!AStmt) 9325 return StmtError(); 9326 9327 auto *CS = cast<CapturedStmt>(AStmt); 9328 // 1.2.2 OpenMP Language Terminology 9329 // Structured block - An executable statement with a single entry at the 9330 // top and a single exit at the bottom. 9331 // The point of exit cannot be a branch out of the structured block. 9332 // longjmp() and throw() must not violate the entry/exit criteria. 9333 CS->getCapturedDecl()->setNothrow(); 9334 for (int ThisCaptureLevel = 9335 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9336 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9337 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9338 // 1.2.2 OpenMP Language Terminology 9339 // Structured block - An executable statement with a single entry at the 9340 // top and a single exit at the bottom. 9341 // The point of exit cannot be a branch out of the structured block. 9342 // longjmp() and throw() must not violate the entry/exit criteria. 9343 CS->getCapturedDecl()->setNothrow(); 9344 } 9345 9346 OMPLoopDirective::HelperExprs B; 9347 // In presence of clause 'collapse' with number of loops, it will 9348 // define the nested loops number. 9349 unsigned NestedLoopCount = checkOpenMPLoop( 9350 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9351 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9352 VarsWithImplicitDSA, B); 9353 if (NestedLoopCount == 0) 9354 return StmtError(); 9355 9356 assert((CurContext->isDependentContext() || B.builtAll()) && 9357 "omp target teams distribute loop exprs were not built"); 9358 9359 setFunctionHasBranchProtectedScope(); 9360 return OMPTargetTeamsDistributeDirective::Create( 9361 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9362 } 9363 9364 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9365 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9366 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9367 if (!AStmt) 9368 return StmtError(); 9369 9370 auto *CS = cast<CapturedStmt>(AStmt); 9371 // 1.2.2 OpenMP Language Terminology 9372 // Structured block - An executable statement with a single entry at the 9373 // top and a single exit at the bottom. 9374 // The point of exit cannot be a branch out of the structured block. 9375 // longjmp() and throw() must not violate the entry/exit criteria. 9376 CS->getCapturedDecl()->setNothrow(); 9377 for (int ThisCaptureLevel = 9378 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9379 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9380 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9381 // 1.2.2 OpenMP Language Terminology 9382 // Structured block - An executable statement with a single entry at the 9383 // top and a single exit at the bottom. 9384 // The point of exit cannot be a branch out of the structured block. 9385 // longjmp() and throw() must not violate the entry/exit criteria. 9386 CS->getCapturedDecl()->setNothrow(); 9387 } 9388 9389 OMPLoopDirective::HelperExprs B; 9390 // In presence of clause 'collapse' with number of loops, it will 9391 // define the nested loops number. 9392 unsigned NestedLoopCount = checkOpenMPLoop( 9393 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9394 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9395 VarsWithImplicitDSA, B); 9396 if (NestedLoopCount == 0) 9397 return StmtError(); 9398 9399 assert((CurContext->isDependentContext() || B.builtAll()) && 9400 "omp target teams distribute parallel for loop exprs were not built"); 9401 9402 if (!CurContext->isDependentContext()) { 9403 // Finalize the clauses that need pre-built expressions for CodeGen. 9404 for (OMPClause *C : Clauses) { 9405 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9406 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9407 B.NumIterations, *this, CurScope, 9408 DSAStack)) 9409 return StmtError(); 9410 } 9411 } 9412 9413 setFunctionHasBranchProtectedScope(); 9414 return OMPTargetTeamsDistributeParallelForDirective::Create( 9415 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9416 DSAStack->isCancelRegion()); 9417 } 9418 9419 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9420 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9421 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9422 if (!AStmt) 9423 return StmtError(); 9424 9425 auto *CS = cast<CapturedStmt>(AStmt); 9426 // 1.2.2 OpenMP Language Terminology 9427 // Structured block - An executable statement with a single entry at the 9428 // top and a single exit at the bottom. 9429 // The point of exit cannot be a branch out of the structured block. 9430 // longjmp() and throw() must not violate the entry/exit criteria. 9431 CS->getCapturedDecl()->setNothrow(); 9432 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9433 OMPD_target_teams_distribute_parallel_for_simd); 9434 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9435 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9436 // 1.2.2 OpenMP Language Terminology 9437 // Structured block - An executable statement with a single entry at the 9438 // top and a single exit at the bottom. 9439 // The point of exit cannot be a branch out of the structured block. 9440 // longjmp() and throw() must not violate the entry/exit criteria. 9441 CS->getCapturedDecl()->setNothrow(); 9442 } 9443 9444 OMPLoopDirective::HelperExprs B; 9445 // In presence of clause 'collapse' with number of loops, it will 9446 // define the nested loops number. 9447 unsigned NestedLoopCount = 9448 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9449 getCollapseNumberExpr(Clauses), 9450 nullptr /*ordered not a clause on distribute*/, CS, *this, 9451 *DSAStack, VarsWithImplicitDSA, B); 9452 if (NestedLoopCount == 0) 9453 return StmtError(); 9454 9455 assert((CurContext->isDependentContext() || B.builtAll()) && 9456 "omp target teams distribute parallel for simd loop exprs were not " 9457 "built"); 9458 9459 if (!CurContext->isDependentContext()) { 9460 // Finalize the clauses that need pre-built expressions for CodeGen. 9461 for (OMPClause *C : Clauses) { 9462 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9463 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9464 B.NumIterations, *this, CurScope, 9465 DSAStack)) 9466 return StmtError(); 9467 } 9468 } 9469 9470 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9471 return StmtError(); 9472 9473 setFunctionHasBranchProtectedScope(); 9474 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9475 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9476 } 9477 9478 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9479 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9480 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9481 if (!AStmt) 9482 return StmtError(); 9483 9484 auto *CS = cast<CapturedStmt>(AStmt); 9485 // 1.2.2 OpenMP Language Terminology 9486 // Structured block - An executable statement with a single entry at the 9487 // top and a single exit at the bottom. 9488 // The point of exit cannot be a branch out of the structured block. 9489 // longjmp() and throw() must not violate the entry/exit criteria. 9490 CS->getCapturedDecl()->setNothrow(); 9491 for (int ThisCaptureLevel = 9492 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9493 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9494 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9495 // 1.2.2 OpenMP Language Terminology 9496 // Structured block - An executable statement with a single entry at the 9497 // top and a single exit at the bottom. 9498 // The point of exit cannot be a branch out of the structured block. 9499 // longjmp() and throw() must not violate the entry/exit criteria. 9500 CS->getCapturedDecl()->setNothrow(); 9501 } 9502 9503 OMPLoopDirective::HelperExprs B; 9504 // In presence of clause 'collapse' with number of loops, it will 9505 // define the nested loops number. 9506 unsigned NestedLoopCount = checkOpenMPLoop( 9507 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9508 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9509 VarsWithImplicitDSA, B); 9510 if (NestedLoopCount == 0) 9511 return StmtError(); 9512 9513 assert((CurContext->isDependentContext() || B.builtAll()) && 9514 "omp target teams distribute simd loop exprs were not built"); 9515 9516 if (!CurContext->isDependentContext()) { 9517 // Finalize the clauses that need pre-built expressions for CodeGen. 9518 for (OMPClause *C : Clauses) { 9519 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9520 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9521 B.NumIterations, *this, CurScope, 9522 DSAStack)) 9523 return StmtError(); 9524 } 9525 } 9526 9527 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9528 return StmtError(); 9529 9530 setFunctionHasBranchProtectedScope(); 9531 return OMPTargetTeamsDistributeSimdDirective::Create( 9532 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9533 } 9534 9535 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9536 SourceLocation StartLoc, 9537 SourceLocation LParenLoc, 9538 SourceLocation EndLoc) { 9539 OMPClause *Res = nullptr; 9540 switch (Kind) { 9541 case OMPC_final: 9542 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9543 break; 9544 case OMPC_num_threads: 9545 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9546 break; 9547 case OMPC_safelen: 9548 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9549 break; 9550 case OMPC_simdlen: 9551 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9552 break; 9553 case OMPC_allocator: 9554 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9555 break; 9556 case OMPC_collapse: 9557 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9558 break; 9559 case OMPC_ordered: 9560 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9561 break; 9562 case OMPC_device: 9563 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9564 break; 9565 case OMPC_num_teams: 9566 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9567 break; 9568 case OMPC_thread_limit: 9569 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9570 break; 9571 case OMPC_priority: 9572 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9573 break; 9574 case OMPC_grainsize: 9575 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9576 break; 9577 case OMPC_num_tasks: 9578 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9579 break; 9580 case OMPC_hint: 9581 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9582 break; 9583 case OMPC_if: 9584 case OMPC_default: 9585 case OMPC_proc_bind: 9586 case OMPC_schedule: 9587 case OMPC_private: 9588 case OMPC_firstprivate: 9589 case OMPC_lastprivate: 9590 case OMPC_shared: 9591 case OMPC_reduction: 9592 case OMPC_task_reduction: 9593 case OMPC_in_reduction: 9594 case OMPC_linear: 9595 case OMPC_aligned: 9596 case OMPC_copyin: 9597 case OMPC_copyprivate: 9598 case OMPC_nowait: 9599 case OMPC_untied: 9600 case OMPC_mergeable: 9601 case OMPC_threadprivate: 9602 case OMPC_allocate: 9603 case OMPC_flush: 9604 case OMPC_read: 9605 case OMPC_write: 9606 case OMPC_update: 9607 case OMPC_capture: 9608 case OMPC_seq_cst: 9609 case OMPC_depend: 9610 case OMPC_threads: 9611 case OMPC_simd: 9612 case OMPC_map: 9613 case OMPC_nogroup: 9614 case OMPC_dist_schedule: 9615 case OMPC_defaultmap: 9616 case OMPC_unknown: 9617 case OMPC_uniform: 9618 case OMPC_to: 9619 case OMPC_from: 9620 case OMPC_use_device_ptr: 9621 case OMPC_is_device_ptr: 9622 case OMPC_unified_address: 9623 case OMPC_unified_shared_memory: 9624 case OMPC_reverse_offload: 9625 case OMPC_dynamic_allocators: 9626 case OMPC_atomic_default_mem_order: 9627 llvm_unreachable("Clause is not allowed."); 9628 } 9629 return Res; 9630 } 9631 9632 // An OpenMP directive such as 'target parallel' has two captured regions: 9633 // for the 'target' and 'parallel' respectively. This function returns 9634 // the region in which to capture expressions associated with a clause. 9635 // A return value of OMPD_unknown signifies that the expression should not 9636 // be captured. 9637 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9638 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9639 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9640 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9641 switch (CKind) { 9642 case OMPC_if: 9643 switch (DKind) { 9644 case OMPD_target_parallel: 9645 case OMPD_target_parallel_for: 9646 case OMPD_target_parallel_for_simd: 9647 // If this clause applies to the nested 'parallel' region, capture within 9648 // the 'target' region, otherwise do not capture. 9649 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9650 CaptureRegion = OMPD_target; 9651 break; 9652 case OMPD_target_teams_distribute_parallel_for: 9653 case OMPD_target_teams_distribute_parallel_for_simd: 9654 // If this clause applies to the nested 'parallel' region, capture within 9655 // the 'teams' region, otherwise do not capture. 9656 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9657 CaptureRegion = OMPD_teams; 9658 break; 9659 case OMPD_teams_distribute_parallel_for: 9660 case OMPD_teams_distribute_parallel_for_simd: 9661 CaptureRegion = OMPD_teams; 9662 break; 9663 case OMPD_target_update: 9664 case OMPD_target_enter_data: 9665 case OMPD_target_exit_data: 9666 CaptureRegion = OMPD_task; 9667 break; 9668 case OMPD_cancel: 9669 case OMPD_parallel: 9670 case OMPD_parallel_sections: 9671 case OMPD_parallel_for: 9672 case OMPD_parallel_for_simd: 9673 case OMPD_target: 9674 case OMPD_target_simd: 9675 case OMPD_target_teams: 9676 case OMPD_target_teams_distribute: 9677 case OMPD_target_teams_distribute_simd: 9678 case OMPD_distribute_parallel_for: 9679 case OMPD_distribute_parallel_for_simd: 9680 case OMPD_task: 9681 case OMPD_taskloop: 9682 case OMPD_taskloop_simd: 9683 case OMPD_target_data: 9684 // Do not capture if-clause expressions. 9685 break; 9686 case OMPD_threadprivate: 9687 case OMPD_allocate: 9688 case OMPD_taskyield: 9689 case OMPD_barrier: 9690 case OMPD_taskwait: 9691 case OMPD_cancellation_point: 9692 case OMPD_flush: 9693 case OMPD_declare_reduction: 9694 case OMPD_declare_mapper: 9695 case OMPD_declare_simd: 9696 case OMPD_declare_target: 9697 case OMPD_end_declare_target: 9698 case OMPD_teams: 9699 case OMPD_simd: 9700 case OMPD_for: 9701 case OMPD_for_simd: 9702 case OMPD_sections: 9703 case OMPD_section: 9704 case OMPD_single: 9705 case OMPD_master: 9706 case OMPD_critical: 9707 case OMPD_taskgroup: 9708 case OMPD_distribute: 9709 case OMPD_ordered: 9710 case OMPD_atomic: 9711 case OMPD_distribute_simd: 9712 case OMPD_teams_distribute: 9713 case OMPD_teams_distribute_simd: 9714 case OMPD_requires: 9715 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9716 case OMPD_unknown: 9717 llvm_unreachable("Unknown OpenMP directive"); 9718 } 9719 break; 9720 case OMPC_num_threads: 9721 switch (DKind) { 9722 case OMPD_target_parallel: 9723 case OMPD_target_parallel_for: 9724 case OMPD_target_parallel_for_simd: 9725 CaptureRegion = OMPD_target; 9726 break; 9727 case OMPD_teams_distribute_parallel_for: 9728 case OMPD_teams_distribute_parallel_for_simd: 9729 case OMPD_target_teams_distribute_parallel_for: 9730 case OMPD_target_teams_distribute_parallel_for_simd: 9731 CaptureRegion = OMPD_teams; 9732 break; 9733 case OMPD_parallel: 9734 case OMPD_parallel_sections: 9735 case OMPD_parallel_for: 9736 case OMPD_parallel_for_simd: 9737 case OMPD_distribute_parallel_for: 9738 case OMPD_distribute_parallel_for_simd: 9739 // Do not capture num_threads-clause expressions. 9740 break; 9741 case OMPD_target_data: 9742 case OMPD_target_enter_data: 9743 case OMPD_target_exit_data: 9744 case OMPD_target_update: 9745 case OMPD_target: 9746 case OMPD_target_simd: 9747 case OMPD_target_teams: 9748 case OMPD_target_teams_distribute: 9749 case OMPD_target_teams_distribute_simd: 9750 case OMPD_cancel: 9751 case OMPD_task: 9752 case OMPD_taskloop: 9753 case OMPD_taskloop_simd: 9754 case OMPD_threadprivate: 9755 case OMPD_allocate: 9756 case OMPD_taskyield: 9757 case OMPD_barrier: 9758 case OMPD_taskwait: 9759 case OMPD_cancellation_point: 9760 case OMPD_flush: 9761 case OMPD_declare_reduction: 9762 case OMPD_declare_mapper: 9763 case OMPD_declare_simd: 9764 case OMPD_declare_target: 9765 case OMPD_end_declare_target: 9766 case OMPD_teams: 9767 case OMPD_simd: 9768 case OMPD_for: 9769 case OMPD_for_simd: 9770 case OMPD_sections: 9771 case OMPD_section: 9772 case OMPD_single: 9773 case OMPD_master: 9774 case OMPD_critical: 9775 case OMPD_taskgroup: 9776 case OMPD_distribute: 9777 case OMPD_ordered: 9778 case OMPD_atomic: 9779 case OMPD_distribute_simd: 9780 case OMPD_teams_distribute: 9781 case OMPD_teams_distribute_simd: 9782 case OMPD_requires: 9783 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9784 case OMPD_unknown: 9785 llvm_unreachable("Unknown OpenMP directive"); 9786 } 9787 break; 9788 case OMPC_num_teams: 9789 switch (DKind) { 9790 case OMPD_target_teams: 9791 case OMPD_target_teams_distribute: 9792 case OMPD_target_teams_distribute_simd: 9793 case OMPD_target_teams_distribute_parallel_for: 9794 case OMPD_target_teams_distribute_parallel_for_simd: 9795 CaptureRegion = OMPD_target; 9796 break; 9797 case OMPD_teams_distribute_parallel_for: 9798 case OMPD_teams_distribute_parallel_for_simd: 9799 case OMPD_teams: 9800 case OMPD_teams_distribute: 9801 case OMPD_teams_distribute_simd: 9802 // Do not capture num_teams-clause expressions. 9803 break; 9804 case OMPD_distribute_parallel_for: 9805 case OMPD_distribute_parallel_for_simd: 9806 case OMPD_task: 9807 case OMPD_taskloop: 9808 case OMPD_taskloop_simd: 9809 case OMPD_target_data: 9810 case OMPD_target_enter_data: 9811 case OMPD_target_exit_data: 9812 case OMPD_target_update: 9813 case OMPD_cancel: 9814 case OMPD_parallel: 9815 case OMPD_parallel_sections: 9816 case OMPD_parallel_for: 9817 case OMPD_parallel_for_simd: 9818 case OMPD_target: 9819 case OMPD_target_simd: 9820 case OMPD_target_parallel: 9821 case OMPD_target_parallel_for: 9822 case OMPD_target_parallel_for_simd: 9823 case OMPD_threadprivate: 9824 case OMPD_allocate: 9825 case OMPD_taskyield: 9826 case OMPD_barrier: 9827 case OMPD_taskwait: 9828 case OMPD_cancellation_point: 9829 case OMPD_flush: 9830 case OMPD_declare_reduction: 9831 case OMPD_declare_mapper: 9832 case OMPD_declare_simd: 9833 case OMPD_declare_target: 9834 case OMPD_end_declare_target: 9835 case OMPD_simd: 9836 case OMPD_for: 9837 case OMPD_for_simd: 9838 case OMPD_sections: 9839 case OMPD_section: 9840 case OMPD_single: 9841 case OMPD_master: 9842 case OMPD_critical: 9843 case OMPD_taskgroup: 9844 case OMPD_distribute: 9845 case OMPD_ordered: 9846 case OMPD_atomic: 9847 case OMPD_distribute_simd: 9848 case OMPD_requires: 9849 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9850 case OMPD_unknown: 9851 llvm_unreachable("Unknown OpenMP directive"); 9852 } 9853 break; 9854 case OMPC_thread_limit: 9855 switch (DKind) { 9856 case OMPD_target_teams: 9857 case OMPD_target_teams_distribute: 9858 case OMPD_target_teams_distribute_simd: 9859 case OMPD_target_teams_distribute_parallel_for: 9860 case OMPD_target_teams_distribute_parallel_for_simd: 9861 CaptureRegion = OMPD_target; 9862 break; 9863 case OMPD_teams_distribute_parallel_for: 9864 case OMPD_teams_distribute_parallel_for_simd: 9865 case OMPD_teams: 9866 case OMPD_teams_distribute: 9867 case OMPD_teams_distribute_simd: 9868 // Do not capture thread_limit-clause expressions. 9869 break; 9870 case OMPD_distribute_parallel_for: 9871 case OMPD_distribute_parallel_for_simd: 9872 case OMPD_task: 9873 case OMPD_taskloop: 9874 case OMPD_taskloop_simd: 9875 case OMPD_target_data: 9876 case OMPD_target_enter_data: 9877 case OMPD_target_exit_data: 9878 case OMPD_target_update: 9879 case OMPD_cancel: 9880 case OMPD_parallel: 9881 case OMPD_parallel_sections: 9882 case OMPD_parallel_for: 9883 case OMPD_parallel_for_simd: 9884 case OMPD_target: 9885 case OMPD_target_simd: 9886 case OMPD_target_parallel: 9887 case OMPD_target_parallel_for: 9888 case OMPD_target_parallel_for_simd: 9889 case OMPD_threadprivate: 9890 case OMPD_allocate: 9891 case OMPD_taskyield: 9892 case OMPD_barrier: 9893 case OMPD_taskwait: 9894 case OMPD_cancellation_point: 9895 case OMPD_flush: 9896 case OMPD_declare_reduction: 9897 case OMPD_declare_mapper: 9898 case OMPD_declare_simd: 9899 case OMPD_declare_target: 9900 case OMPD_end_declare_target: 9901 case OMPD_simd: 9902 case OMPD_for: 9903 case OMPD_for_simd: 9904 case OMPD_sections: 9905 case OMPD_section: 9906 case OMPD_single: 9907 case OMPD_master: 9908 case OMPD_critical: 9909 case OMPD_taskgroup: 9910 case OMPD_distribute: 9911 case OMPD_ordered: 9912 case OMPD_atomic: 9913 case OMPD_distribute_simd: 9914 case OMPD_requires: 9915 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 9916 case OMPD_unknown: 9917 llvm_unreachable("Unknown OpenMP directive"); 9918 } 9919 break; 9920 case OMPC_schedule: 9921 switch (DKind) { 9922 case OMPD_parallel_for: 9923 case OMPD_parallel_for_simd: 9924 case OMPD_distribute_parallel_for: 9925 case OMPD_distribute_parallel_for_simd: 9926 case OMPD_teams_distribute_parallel_for: 9927 case OMPD_teams_distribute_parallel_for_simd: 9928 case OMPD_target_parallel_for: 9929 case OMPD_target_parallel_for_simd: 9930 case OMPD_target_teams_distribute_parallel_for: 9931 case OMPD_target_teams_distribute_parallel_for_simd: 9932 CaptureRegion = OMPD_parallel; 9933 break; 9934 case OMPD_for: 9935 case OMPD_for_simd: 9936 // Do not capture schedule-clause expressions. 9937 break; 9938 case OMPD_task: 9939 case OMPD_taskloop: 9940 case OMPD_taskloop_simd: 9941 case OMPD_target_data: 9942 case OMPD_target_enter_data: 9943 case OMPD_target_exit_data: 9944 case OMPD_target_update: 9945 case OMPD_teams: 9946 case OMPD_teams_distribute: 9947 case OMPD_teams_distribute_simd: 9948 case OMPD_target_teams_distribute: 9949 case OMPD_target_teams_distribute_simd: 9950 case OMPD_target: 9951 case OMPD_target_simd: 9952 case OMPD_target_parallel: 9953 case OMPD_cancel: 9954 case OMPD_parallel: 9955 case OMPD_parallel_sections: 9956 case OMPD_threadprivate: 9957 case OMPD_allocate: 9958 case OMPD_taskyield: 9959 case OMPD_barrier: 9960 case OMPD_taskwait: 9961 case OMPD_cancellation_point: 9962 case OMPD_flush: 9963 case OMPD_declare_reduction: 9964 case OMPD_declare_mapper: 9965 case OMPD_declare_simd: 9966 case OMPD_declare_target: 9967 case OMPD_end_declare_target: 9968 case OMPD_simd: 9969 case OMPD_sections: 9970 case OMPD_section: 9971 case OMPD_single: 9972 case OMPD_master: 9973 case OMPD_critical: 9974 case OMPD_taskgroup: 9975 case OMPD_distribute: 9976 case OMPD_ordered: 9977 case OMPD_atomic: 9978 case OMPD_distribute_simd: 9979 case OMPD_target_teams: 9980 case OMPD_requires: 9981 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9982 case OMPD_unknown: 9983 llvm_unreachable("Unknown OpenMP directive"); 9984 } 9985 break; 9986 case OMPC_dist_schedule: 9987 switch (DKind) { 9988 case OMPD_teams_distribute_parallel_for: 9989 case OMPD_teams_distribute_parallel_for_simd: 9990 case OMPD_teams_distribute: 9991 case OMPD_teams_distribute_simd: 9992 case OMPD_target_teams_distribute_parallel_for: 9993 case OMPD_target_teams_distribute_parallel_for_simd: 9994 case OMPD_target_teams_distribute: 9995 case OMPD_target_teams_distribute_simd: 9996 CaptureRegion = OMPD_teams; 9997 break; 9998 case OMPD_distribute_parallel_for: 9999 case OMPD_distribute_parallel_for_simd: 10000 case OMPD_distribute: 10001 case OMPD_distribute_simd: 10002 // Do not capture thread_limit-clause expressions. 10003 break; 10004 case OMPD_parallel_for: 10005 case OMPD_parallel_for_simd: 10006 case OMPD_target_parallel_for_simd: 10007 case OMPD_target_parallel_for: 10008 case OMPD_task: 10009 case OMPD_taskloop: 10010 case OMPD_taskloop_simd: 10011 case OMPD_target_data: 10012 case OMPD_target_enter_data: 10013 case OMPD_target_exit_data: 10014 case OMPD_target_update: 10015 case OMPD_teams: 10016 case OMPD_target: 10017 case OMPD_target_simd: 10018 case OMPD_target_parallel: 10019 case OMPD_cancel: 10020 case OMPD_parallel: 10021 case OMPD_parallel_sections: 10022 case OMPD_threadprivate: 10023 case OMPD_allocate: 10024 case OMPD_taskyield: 10025 case OMPD_barrier: 10026 case OMPD_taskwait: 10027 case OMPD_cancellation_point: 10028 case OMPD_flush: 10029 case OMPD_declare_reduction: 10030 case OMPD_declare_mapper: 10031 case OMPD_declare_simd: 10032 case OMPD_declare_target: 10033 case OMPD_end_declare_target: 10034 case OMPD_simd: 10035 case OMPD_for: 10036 case OMPD_for_simd: 10037 case OMPD_sections: 10038 case OMPD_section: 10039 case OMPD_single: 10040 case OMPD_master: 10041 case OMPD_critical: 10042 case OMPD_taskgroup: 10043 case OMPD_ordered: 10044 case OMPD_atomic: 10045 case OMPD_target_teams: 10046 case OMPD_requires: 10047 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10048 case OMPD_unknown: 10049 llvm_unreachable("Unknown OpenMP directive"); 10050 } 10051 break; 10052 case OMPC_device: 10053 switch (DKind) { 10054 case OMPD_target_update: 10055 case OMPD_target_enter_data: 10056 case OMPD_target_exit_data: 10057 case OMPD_target: 10058 case OMPD_target_simd: 10059 case OMPD_target_teams: 10060 case OMPD_target_parallel: 10061 case OMPD_target_teams_distribute: 10062 case OMPD_target_teams_distribute_simd: 10063 case OMPD_target_parallel_for: 10064 case OMPD_target_parallel_for_simd: 10065 case OMPD_target_teams_distribute_parallel_for: 10066 case OMPD_target_teams_distribute_parallel_for_simd: 10067 CaptureRegion = OMPD_task; 10068 break; 10069 case OMPD_target_data: 10070 // Do not capture device-clause expressions. 10071 break; 10072 case OMPD_teams_distribute_parallel_for: 10073 case OMPD_teams_distribute_parallel_for_simd: 10074 case OMPD_teams: 10075 case OMPD_teams_distribute: 10076 case OMPD_teams_distribute_simd: 10077 case OMPD_distribute_parallel_for: 10078 case OMPD_distribute_parallel_for_simd: 10079 case OMPD_task: 10080 case OMPD_taskloop: 10081 case OMPD_taskloop_simd: 10082 case OMPD_cancel: 10083 case OMPD_parallel: 10084 case OMPD_parallel_sections: 10085 case OMPD_parallel_for: 10086 case OMPD_parallel_for_simd: 10087 case OMPD_threadprivate: 10088 case OMPD_allocate: 10089 case OMPD_taskyield: 10090 case OMPD_barrier: 10091 case OMPD_taskwait: 10092 case OMPD_cancellation_point: 10093 case OMPD_flush: 10094 case OMPD_declare_reduction: 10095 case OMPD_declare_mapper: 10096 case OMPD_declare_simd: 10097 case OMPD_declare_target: 10098 case OMPD_end_declare_target: 10099 case OMPD_simd: 10100 case OMPD_for: 10101 case OMPD_for_simd: 10102 case OMPD_sections: 10103 case OMPD_section: 10104 case OMPD_single: 10105 case OMPD_master: 10106 case OMPD_critical: 10107 case OMPD_taskgroup: 10108 case OMPD_distribute: 10109 case OMPD_ordered: 10110 case OMPD_atomic: 10111 case OMPD_distribute_simd: 10112 case OMPD_requires: 10113 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10114 case OMPD_unknown: 10115 llvm_unreachable("Unknown OpenMP directive"); 10116 } 10117 break; 10118 case OMPC_firstprivate: 10119 case OMPC_lastprivate: 10120 case OMPC_reduction: 10121 case OMPC_task_reduction: 10122 case OMPC_in_reduction: 10123 case OMPC_linear: 10124 case OMPC_default: 10125 case OMPC_proc_bind: 10126 case OMPC_final: 10127 case OMPC_safelen: 10128 case OMPC_simdlen: 10129 case OMPC_allocator: 10130 case OMPC_collapse: 10131 case OMPC_private: 10132 case OMPC_shared: 10133 case OMPC_aligned: 10134 case OMPC_copyin: 10135 case OMPC_copyprivate: 10136 case OMPC_ordered: 10137 case OMPC_nowait: 10138 case OMPC_untied: 10139 case OMPC_mergeable: 10140 case OMPC_threadprivate: 10141 case OMPC_allocate: 10142 case OMPC_flush: 10143 case OMPC_read: 10144 case OMPC_write: 10145 case OMPC_update: 10146 case OMPC_capture: 10147 case OMPC_seq_cst: 10148 case OMPC_depend: 10149 case OMPC_threads: 10150 case OMPC_simd: 10151 case OMPC_map: 10152 case OMPC_priority: 10153 case OMPC_grainsize: 10154 case OMPC_nogroup: 10155 case OMPC_num_tasks: 10156 case OMPC_hint: 10157 case OMPC_defaultmap: 10158 case OMPC_unknown: 10159 case OMPC_uniform: 10160 case OMPC_to: 10161 case OMPC_from: 10162 case OMPC_use_device_ptr: 10163 case OMPC_is_device_ptr: 10164 case OMPC_unified_address: 10165 case OMPC_unified_shared_memory: 10166 case OMPC_reverse_offload: 10167 case OMPC_dynamic_allocators: 10168 case OMPC_atomic_default_mem_order: 10169 llvm_unreachable("Unexpected OpenMP clause."); 10170 } 10171 return CaptureRegion; 10172 } 10173 10174 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10175 Expr *Condition, SourceLocation StartLoc, 10176 SourceLocation LParenLoc, 10177 SourceLocation NameModifierLoc, 10178 SourceLocation ColonLoc, 10179 SourceLocation EndLoc) { 10180 Expr *ValExpr = Condition; 10181 Stmt *HelperValStmt = nullptr; 10182 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10183 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10184 !Condition->isInstantiationDependent() && 10185 !Condition->containsUnexpandedParameterPack()) { 10186 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10187 if (Val.isInvalid()) 10188 return nullptr; 10189 10190 ValExpr = Val.get(); 10191 10192 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10193 CaptureRegion = 10194 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10195 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10196 ValExpr = MakeFullExpr(ValExpr).get(); 10197 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10198 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10199 HelperValStmt = buildPreInits(Context, Captures); 10200 } 10201 } 10202 10203 return new (Context) 10204 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10205 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10206 } 10207 10208 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10209 SourceLocation StartLoc, 10210 SourceLocation LParenLoc, 10211 SourceLocation EndLoc) { 10212 Expr *ValExpr = Condition; 10213 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10214 !Condition->isInstantiationDependent() && 10215 !Condition->containsUnexpandedParameterPack()) { 10216 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10217 if (Val.isInvalid()) 10218 return nullptr; 10219 10220 ValExpr = MakeFullExpr(Val.get()).get(); 10221 } 10222 10223 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10224 } 10225 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10226 Expr *Op) { 10227 if (!Op) 10228 return ExprError(); 10229 10230 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10231 public: 10232 IntConvertDiagnoser() 10233 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10234 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10235 QualType T) override { 10236 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10237 } 10238 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10239 QualType T) override { 10240 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10241 } 10242 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10243 QualType T, 10244 QualType ConvTy) override { 10245 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10246 } 10247 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10248 QualType ConvTy) override { 10249 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10250 << ConvTy->isEnumeralType() << ConvTy; 10251 } 10252 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10253 QualType T) override { 10254 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10255 } 10256 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 10257 QualType ConvTy) override { 10258 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10259 << ConvTy->isEnumeralType() << ConvTy; 10260 } 10261 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 10262 QualType) override { 10263 llvm_unreachable("conversion functions are permitted"); 10264 } 10265 } ConvertDiagnoser; 10266 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 10267 } 10268 10269 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 10270 OpenMPClauseKind CKind, 10271 bool StrictlyPositive) { 10272 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 10273 !ValExpr->isInstantiationDependent()) { 10274 SourceLocation Loc = ValExpr->getExprLoc(); 10275 ExprResult Value = 10276 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 10277 if (Value.isInvalid()) 10278 return false; 10279 10280 ValExpr = Value.get(); 10281 // The expression must evaluate to a non-negative integer value. 10282 llvm::APSInt Result; 10283 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 10284 Result.isSigned() && 10285 !((!StrictlyPositive && Result.isNonNegative()) || 10286 (StrictlyPositive && Result.isStrictlyPositive()))) { 10287 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 10288 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10289 << ValExpr->getSourceRange(); 10290 return false; 10291 } 10292 } 10293 return true; 10294 } 10295 10296 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 10297 SourceLocation StartLoc, 10298 SourceLocation LParenLoc, 10299 SourceLocation EndLoc) { 10300 Expr *ValExpr = NumThreads; 10301 Stmt *HelperValStmt = nullptr; 10302 10303 // OpenMP [2.5, Restrictions] 10304 // The num_threads expression must evaluate to a positive integer value. 10305 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 10306 /*StrictlyPositive=*/true)) 10307 return nullptr; 10308 10309 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10310 OpenMPDirectiveKind CaptureRegion = 10311 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 10312 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10313 ValExpr = MakeFullExpr(ValExpr).get(); 10314 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10315 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10316 HelperValStmt = buildPreInits(Context, Captures); 10317 } 10318 10319 return new (Context) OMPNumThreadsClause( 10320 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 10321 } 10322 10323 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 10324 OpenMPClauseKind CKind, 10325 bool StrictlyPositive) { 10326 if (!E) 10327 return ExprError(); 10328 if (E->isValueDependent() || E->isTypeDependent() || 10329 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 10330 return E; 10331 llvm::APSInt Result; 10332 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 10333 if (ICE.isInvalid()) 10334 return ExprError(); 10335 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 10336 (!StrictlyPositive && !Result.isNonNegative())) { 10337 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 10338 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10339 << E->getSourceRange(); 10340 return ExprError(); 10341 } 10342 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 10343 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 10344 << E->getSourceRange(); 10345 return ExprError(); 10346 } 10347 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 10348 DSAStack->setAssociatedLoops(Result.getExtValue()); 10349 else if (CKind == OMPC_ordered) 10350 DSAStack->setAssociatedLoops(Result.getExtValue()); 10351 return ICE; 10352 } 10353 10354 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 10355 SourceLocation LParenLoc, 10356 SourceLocation EndLoc) { 10357 // OpenMP [2.8.1, simd construct, Description] 10358 // The parameter of the safelen clause must be a constant 10359 // positive integer expression. 10360 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10361 if (Safelen.isInvalid()) 10362 return nullptr; 10363 return new (Context) 10364 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10365 } 10366 10367 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10368 SourceLocation LParenLoc, 10369 SourceLocation EndLoc) { 10370 // OpenMP [2.8.1, simd construct, Description] 10371 // The parameter of the simdlen clause must be a constant 10372 // positive integer expression. 10373 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10374 if (Simdlen.isInvalid()) 10375 return nullptr; 10376 return new (Context) 10377 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10378 } 10379 10380 /// Tries to find omp_allocator_handle_t type. 10381 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10382 DSAStackTy *Stack) { 10383 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10384 if (!OMPAllocatorHandleT.isNull()) 10385 return true; 10386 // Build the predefined allocator expressions. 10387 bool ErrorFound = false; 10388 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10389 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10390 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10391 StringRef Allocator = 10392 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10393 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10394 auto *VD = dyn_cast_or_null<ValueDecl>( 10395 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10396 if (!VD) { 10397 ErrorFound = true; 10398 break; 10399 } 10400 QualType AllocatorType = 10401 VD->getType().getNonLValueExprType(S.getASTContext()); 10402 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10403 if (!Res.isUsable()) { 10404 ErrorFound = true; 10405 break; 10406 } 10407 if (OMPAllocatorHandleT.isNull()) 10408 OMPAllocatorHandleT = AllocatorType; 10409 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10410 ErrorFound = true; 10411 break; 10412 } 10413 Stack->setAllocator(AllocatorKind, Res.get()); 10414 } 10415 if (ErrorFound) { 10416 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10417 return false; 10418 } 10419 OMPAllocatorHandleT.addConst(); 10420 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10421 return true; 10422 } 10423 10424 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10425 SourceLocation LParenLoc, 10426 SourceLocation EndLoc) { 10427 // OpenMP [2.11.3, allocate Directive, Description] 10428 // allocator is an expression of omp_allocator_handle_t type. 10429 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10430 return nullptr; 10431 10432 ExprResult Allocator = DefaultLvalueConversion(A); 10433 if (Allocator.isInvalid()) 10434 return nullptr; 10435 Allocator = PerformImplicitConversion(Allocator.get(), 10436 DSAStack->getOMPAllocatorHandleT(), 10437 Sema::AA_Initializing, 10438 /*AllowExplicit=*/true); 10439 if (Allocator.isInvalid()) 10440 return nullptr; 10441 return new (Context) 10442 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10443 } 10444 10445 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10446 SourceLocation StartLoc, 10447 SourceLocation LParenLoc, 10448 SourceLocation EndLoc) { 10449 // OpenMP [2.7.1, loop construct, Description] 10450 // OpenMP [2.8.1, simd construct, Description] 10451 // OpenMP [2.9.6, distribute construct, Description] 10452 // The parameter of the collapse clause must be a constant 10453 // positive integer expression. 10454 ExprResult NumForLoopsResult = 10455 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10456 if (NumForLoopsResult.isInvalid()) 10457 return nullptr; 10458 return new (Context) 10459 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10460 } 10461 10462 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10463 SourceLocation EndLoc, 10464 SourceLocation LParenLoc, 10465 Expr *NumForLoops) { 10466 // OpenMP [2.7.1, loop construct, Description] 10467 // OpenMP [2.8.1, simd construct, Description] 10468 // OpenMP [2.9.6, distribute construct, Description] 10469 // The parameter of the ordered clause must be a constant 10470 // positive integer expression if any. 10471 if (NumForLoops && LParenLoc.isValid()) { 10472 ExprResult NumForLoopsResult = 10473 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10474 if (NumForLoopsResult.isInvalid()) 10475 return nullptr; 10476 NumForLoops = NumForLoopsResult.get(); 10477 } else { 10478 NumForLoops = nullptr; 10479 } 10480 auto *Clause = OMPOrderedClause::Create( 10481 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10482 StartLoc, LParenLoc, EndLoc); 10483 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10484 return Clause; 10485 } 10486 10487 OMPClause *Sema::ActOnOpenMPSimpleClause( 10488 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10489 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10490 OMPClause *Res = nullptr; 10491 switch (Kind) { 10492 case OMPC_default: 10493 Res = 10494 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10495 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10496 break; 10497 case OMPC_proc_bind: 10498 Res = ActOnOpenMPProcBindClause( 10499 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10500 LParenLoc, EndLoc); 10501 break; 10502 case OMPC_atomic_default_mem_order: 10503 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10504 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10505 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10506 break; 10507 case OMPC_if: 10508 case OMPC_final: 10509 case OMPC_num_threads: 10510 case OMPC_safelen: 10511 case OMPC_simdlen: 10512 case OMPC_allocator: 10513 case OMPC_collapse: 10514 case OMPC_schedule: 10515 case OMPC_private: 10516 case OMPC_firstprivate: 10517 case OMPC_lastprivate: 10518 case OMPC_shared: 10519 case OMPC_reduction: 10520 case OMPC_task_reduction: 10521 case OMPC_in_reduction: 10522 case OMPC_linear: 10523 case OMPC_aligned: 10524 case OMPC_copyin: 10525 case OMPC_copyprivate: 10526 case OMPC_ordered: 10527 case OMPC_nowait: 10528 case OMPC_untied: 10529 case OMPC_mergeable: 10530 case OMPC_threadprivate: 10531 case OMPC_allocate: 10532 case OMPC_flush: 10533 case OMPC_read: 10534 case OMPC_write: 10535 case OMPC_update: 10536 case OMPC_capture: 10537 case OMPC_seq_cst: 10538 case OMPC_depend: 10539 case OMPC_device: 10540 case OMPC_threads: 10541 case OMPC_simd: 10542 case OMPC_map: 10543 case OMPC_num_teams: 10544 case OMPC_thread_limit: 10545 case OMPC_priority: 10546 case OMPC_grainsize: 10547 case OMPC_nogroup: 10548 case OMPC_num_tasks: 10549 case OMPC_hint: 10550 case OMPC_dist_schedule: 10551 case OMPC_defaultmap: 10552 case OMPC_unknown: 10553 case OMPC_uniform: 10554 case OMPC_to: 10555 case OMPC_from: 10556 case OMPC_use_device_ptr: 10557 case OMPC_is_device_ptr: 10558 case OMPC_unified_address: 10559 case OMPC_unified_shared_memory: 10560 case OMPC_reverse_offload: 10561 case OMPC_dynamic_allocators: 10562 llvm_unreachable("Clause is not allowed."); 10563 } 10564 return Res; 10565 } 10566 10567 static std::string 10568 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10569 ArrayRef<unsigned> Exclude = llvm::None) { 10570 SmallString<256> Buffer; 10571 llvm::raw_svector_ostream Out(Buffer); 10572 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10573 unsigned Skipped = Exclude.size(); 10574 auto S = Exclude.begin(), E = Exclude.end(); 10575 for (unsigned I = First; I < Last; ++I) { 10576 if (std::find(S, E, I) != E) { 10577 --Skipped; 10578 continue; 10579 } 10580 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10581 if (I == Bound - Skipped) 10582 Out << " or "; 10583 else if (I != Bound + 1 - Skipped) 10584 Out << ", "; 10585 } 10586 return Out.str(); 10587 } 10588 10589 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10590 SourceLocation KindKwLoc, 10591 SourceLocation StartLoc, 10592 SourceLocation LParenLoc, 10593 SourceLocation EndLoc) { 10594 if (Kind == OMPC_DEFAULT_unknown) { 10595 static_assert(OMPC_DEFAULT_unknown > 0, 10596 "OMPC_DEFAULT_unknown not greater than 0"); 10597 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10598 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10599 /*Last=*/OMPC_DEFAULT_unknown) 10600 << getOpenMPClauseName(OMPC_default); 10601 return nullptr; 10602 } 10603 switch (Kind) { 10604 case OMPC_DEFAULT_none: 10605 DSAStack->setDefaultDSANone(KindKwLoc); 10606 break; 10607 case OMPC_DEFAULT_shared: 10608 DSAStack->setDefaultDSAShared(KindKwLoc); 10609 break; 10610 case OMPC_DEFAULT_unknown: 10611 llvm_unreachable("Clause kind is not allowed."); 10612 break; 10613 } 10614 return new (Context) 10615 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10616 } 10617 10618 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10619 SourceLocation KindKwLoc, 10620 SourceLocation StartLoc, 10621 SourceLocation LParenLoc, 10622 SourceLocation EndLoc) { 10623 if (Kind == OMPC_PROC_BIND_unknown) { 10624 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10625 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10626 /*Last=*/OMPC_PROC_BIND_unknown) 10627 << getOpenMPClauseName(OMPC_proc_bind); 10628 return nullptr; 10629 } 10630 return new (Context) 10631 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10632 } 10633 10634 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10635 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10636 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10637 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10638 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10639 << getListOfPossibleValues( 10640 OMPC_atomic_default_mem_order, /*First=*/0, 10641 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10642 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10643 return nullptr; 10644 } 10645 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10646 LParenLoc, EndLoc); 10647 } 10648 10649 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10650 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10651 SourceLocation StartLoc, SourceLocation LParenLoc, 10652 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10653 SourceLocation EndLoc) { 10654 OMPClause *Res = nullptr; 10655 switch (Kind) { 10656 case OMPC_schedule: 10657 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10658 assert(Argument.size() == NumberOfElements && 10659 ArgumentLoc.size() == NumberOfElements); 10660 Res = ActOnOpenMPScheduleClause( 10661 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10662 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10663 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10664 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10665 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10666 break; 10667 case OMPC_if: 10668 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10669 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10670 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10671 DelimLoc, EndLoc); 10672 break; 10673 case OMPC_dist_schedule: 10674 Res = ActOnOpenMPDistScheduleClause( 10675 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10676 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10677 break; 10678 case OMPC_defaultmap: 10679 enum { Modifier, DefaultmapKind }; 10680 Res = ActOnOpenMPDefaultmapClause( 10681 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10682 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10683 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10684 EndLoc); 10685 break; 10686 case OMPC_final: 10687 case OMPC_num_threads: 10688 case OMPC_safelen: 10689 case OMPC_simdlen: 10690 case OMPC_allocator: 10691 case OMPC_collapse: 10692 case OMPC_default: 10693 case OMPC_proc_bind: 10694 case OMPC_private: 10695 case OMPC_firstprivate: 10696 case OMPC_lastprivate: 10697 case OMPC_shared: 10698 case OMPC_reduction: 10699 case OMPC_task_reduction: 10700 case OMPC_in_reduction: 10701 case OMPC_linear: 10702 case OMPC_aligned: 10703 case OMPC_copyin: 10704 case OMPC_copyprivate: 10705 case OMPC_ordered: 10706 case OMPC_nowait: 10707 case OMPC_untied: 10708 case OMPC_mergeable: 10709 case OMPC_threadprivate: 10710 case OMPC_allocate: 10711 case OMPC_flush: 10712 case OMPC_read: 10713 case OMPC_write: 10714 case OMPC_update: 10715 case OMPC_capture: 10716 case OMPC_seq_cst: 10717 case OMPC_depend: 10718 case OMPC_device: 10719 case OMPC_threads: 10720 case OMPC_simd: 10721 case OMPC_map: 10722 case OMPC_num_teams: 10723 case OMPC_thread_limit: 10724 case OMPC_priority: 10725 case OMPC_grainsize: 10726 case OMPC_nogroup: 10727 case OMPC_num_tasks: 10728 case OMPC_hint: 10729 case OMPC_unknown: 10730 case OMPC_uniform: 10731 case OMPC_to: 10732 case OMPC_from: 10733 case OMPC_use_device_ptr: 10734 case OMPC_is_device_ptr: 10735 case OMPC_unified_address: 10736 case OMPC_unified_shared_memory: 10737 case OMPC_reverse_offload: 10738 case OMPC_dynamic_allocators: 10739 case OMPC_atomic_default_mem_order: 10740 llvm_unreachable("Clause is not allowed."); 10741 } 10742 return Res; 10743 } 10744 10745 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10746 OpenMPScheduleClauseModifier M2, 10747 SourceLocation M1Loc, SourceLocation M2Loc) { 10748 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10749 SmallVector<unsigned, 2> Excluded; 10750 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10751 Excluded.push_back(M2); 10752 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10753 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10754 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10755 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10756 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10757 << getListOfPossibleValues(OMPC_schedule, 10758 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10759 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10760 Excluded) 10761 << getOpenMPClauseName(OMPC_schedule); 10762 return true; 10763 } 10764 return false; 10765 } 10766 10767 OMPClause *Sema::ActOnOpenMPScheduleClause( 10768 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10769 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10770 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10771 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10772 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10773 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10774 return nullptr; 10775 // OpenMP, 2.7.1, Loop Construct, Restrictions 10776 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10777 // but not both. 10778 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10779 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10780 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10781 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10782 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10783 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10784 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10785 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10786 return nullptr; 10787 } 10788 if (Kind == OMPC_SCHEDULE_unknown) { 10789 std::string Values; 10790 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10791 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10792 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10793 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10794 Exclude); 10795 } else { 10796 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10797 /*Last=*/OMPC_SCHEDULE_unknown); 10798 } 10799 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10800 << Values << getOpenMPClauseName(OMPC_schedule); 10801 return nullptr; 10802 } 10803 // OpenMP, 2.7.1, Loop Construct, Restrictions 10804 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 10805 // schedule(guided). 10806 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 10807 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 10808 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 10809 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 10810 diag::err_omp_schedule_nonmonotonic_static); 10811 return nullptr; 10812 } 10813 Expr *ValExpr = ChunkSize; 10814 Stmt *HelperValStmt = nullptr; 10815 if (ChunkSize) { 10816 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10817 !ChunkSize->isInstantiationDependent() && 10818 !ChunkSize->containsUnexpandedParameterPack()) { 10819 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 10820 ExprResult Val = 10821 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10822 if (Val.isInvalid()) 10823 return nullptr; 10824 10825 ValExpr = Val.get(); 10826 10827 // OpenMP [2.7.1, Restrictions] 10828 // chunk_size must be a loop invariant integer expression with a positive 10829 // value. 10830 llvm::APSInt Result; 10831 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10832 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10833 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10834 << "schedule" << 1 << ChunkSize->getSourceRange(); 10835 return nullptr; 10836 } 10837 } else if (getOpenMPCaptureRegionForClause( 10838 DSAStack->getCurrentDirective(), OMPC_schedule) != 10839 OMPD_unknown && 10840 !CurContext->isDependentContext()) { 10841 ValExpr = MakeFullExpr(ValExpr).get(); 10842 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10843 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10844 HelperValStmt = buildPreInits(Context, Captures); 10845 } 10846 } 10847 } 10848 10849 return new (Context) 10850 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 10851 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 10852 } 10853 10854 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 10855 SourceLocation StartLoc, 10856 SourceLocation EndLoc) { 10857 OMPClause *Res = nullptr; 10858 switch (Kind) { 10859 case OMPC_ordered: 10860 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 10861 break; 10862 case OMPC_nowait: 10863 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 10864 break; 10865 case OMPC_untied: 10866 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 10867 break; 10868 case OMPC_mergeable: 10869 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 10870 break; 10871 case OMPC_read: 10872 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 10873 break; 10874 case OMPC_write: 10875 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 10876 break; 10877 case OMPC_update: 10878 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 10879 break; 10880 case OMPC_capture: 10881 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 10882 break; 10883 case OMPC_seq_cst: 10884 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 10885 break; 10886 case OMPC_threads: 10887 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 10888 break; 10889 case OMPC_simd: 10890 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 10891 break; 10892 case OMPC_nogroup: 10893 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 10894 break; 10895 case OMPC_unified_address: 10896 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 10897 break; 10898 case OMPC_unified_shared_memory: 10899 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10900 break; 10901 case OMPC_reverse_offload: 10902 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 10903 break; 10904 case OMPC_dynamic_allocators: 10905 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 10906 break; 10907 case OMPC_if: 10908 case OMPC_final: 10909 case OMPC_num_threads: 10910 case OMPC_safelen: 10911 case OMPC_simdlen: 10912 case OMPC_allocator: 10913 case OMPC_collapse: 10914 case OMPC_schedule: 10915 case OMPC_private: 10916 case OMPC_firstprivate: 10917 case OMPC_lastprivate: 10918 case OMPC_shared: 10919 case OMPC_reduction: 10920 case OMPC_task_reduction: 10921 case OMPC_in_reduction: 10922 case OMPC_linear: 10923 case OMPC_aligned: 10924 case OMPC_copyin: 10925 case OMPC_copyprivate: 10926 case OMPC_default: 10927 case OMPC_proc_bind: 10928 case OMPC_threadprivate: 10929 case OMPC_allocate: 10930 case OMPC_flush: 10931 case OMPC_depend: 10932 case OMPC_device: 10933 case OMPC_map: 10934 case OMPC_num_teams: 10935 case OMPC_thread_limit: 10936 case OMPC_priority: 10937 case OMPC_grainsize: 10938 case OMPC_num_tasks: 10939 case OMPC_hint: 10940 case OMPC_dist_schedule: 10941 case OMPC_defaultmap: 10942 case OMPC_unknown: 10943 case OMPC_uniform: 10944 case OMPC_to: 10945 case OMPC_from: 10946 case OMPC_use_device_ptr: 10947 case OMPC_is_device_ptr: 10948 case OMPC_atomic_default_mem_order: 10949 llvm_unreachable("Clause is not allowed."); 10950 } 10951 return Res; 10952 } 10953 10954 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 10955 SourceLocation EndLoc) { 10956 DSAStack->setNowaitRegion(); 10957 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 10958 } 10959 10960 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 10961 SourceLocation EndLoc) { 10962 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 10963 } 10964 10965 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 10966 SourceLocation EndLoc) { 10967 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10968 } 10969 10970 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10971 SourceLocation EndLoc) { 10972 return new (Context) OMPReadClause(StartLoc, EndLoc); 10973 } 10974 10975 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10976 SourceLocation EndLoc) { 10977 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10978 } 10979 10980 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10981 SourceLocation EndLoc) { 10982 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10983 } 10984 10985 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10986 SourceLocation EndLoc) { 10987 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10988 } 10989 10990 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10991 SourceLocation EndLoc) { 10992 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10993 } 10994 10995 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10996 SourceLocation EndLoc) { 10997 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10998 } 10999 11000 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11001 SourceLocation EndLoc) { 11002 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11003 } 11004 11005 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11006 SourceLocation EndLoc) { 11007 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11008 } 11009 11010 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11011 SourceLocation EndLoc) { 11012 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11013 } 11014 11015 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11016 SourceLocation EndLoc) { 11017 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11018 } 11019 11020 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11021 SourceLocation EndLoc) { 11022 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11023 } 11024 11025 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11026 SourceLocation EndLoc) { 11027 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11028 } 11029 11030 OMPClause *Sema::ActOnOpenMPVarListClause( 11031 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11032 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11033 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11034 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11035 OpenMPLinearClauseKind LinKind, 11036 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11037 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11038 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11039 SourceLocation StartLoc = Locs.StartLoc; 11040 SourceLocation LParenLoc = Locs.LParenLoc; 11041 SourceLocation EndLoc = Locs.EndLoc; 11042 OMPClause *Res = nullptr; 11043 switch (Kind) { 11044 case OMPC_private: 11045 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11046 break; 11047 case OMPC_firstprivate: 11048 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11049 break; 11050 case OMPC_lastprivate: 11051 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11052 break; 11053 case OMPC_shared: 11054 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11055 break; 11056 case OMPC_reduction: 11057 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11058 EndLoc, ReductionOrMapperIdScopeSpec, 11059 ReductionOrMapperId); 11060 break; 11061 case OMPC_task_reduction: 11062 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11063 EndLoc, ReductionOrMapperIdScopeSpec, 11064 ReductionOrMapperId); 11065 break; 11066 case OMPC_in_reduction: 11067 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11068 EndLoc, ReductionOrMapperIdScopeSpec, 11069 ReductionOrMapperId); 11070 break; 11071 case OMPC_linear: 11072 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11073 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11074 break; 11075 case OMPC_aligned: 11076 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11077 ColonLoc, EndLoc); 11078 break; 11079 case OMPC_copyin: 11080 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11081 break; 11082 case OMPC_copyprivate: 11083 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11084 break; 11085 case OMPC_flush: 11086 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11087 break; 11088 case OMPC_depend: 11089 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11090 StartLoc, LParenLoc, EndLoc); 11091 break; 11092 case OMPC_map: 11093 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11094 ReductionOrMapperIdScopeSpec, 11095 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11096 DepLinMapLoc, ColonLoc, VarList, Locs); 11097 break; 11098 case OMPC_to: 11099 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11100 ReductionOrMapperId, Locs); 11101 break; 11102 case OMPC_from: 11103 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11104 ReductionOrMapperId, Locs); 11105 break; 11106 case OMPC_use_device_ptr: 11107 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11108 break; 11109 case OMPC_is_device_ptr: 11110 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11111 break; 11112 case OMPC_allocate: 11113 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11114 ColonLoc, EndLoc); 11115 break; 11116 case OMPC_if: 11117 case OMPC_final: 11118 case OMPC_num_threads: 11119 case OMPC_safelen: 11120 case OMPC_simdlen: 11121 case OMPC_allocator: 11122 case OMPC_collapse: 11123 case OMPC_default: 11124 case OMPC_proc_bind: 11125 case OMPC_schedule: 11126 case OMPC_ordered: 11127 case OMPC_nowait: 11128 case OMPC_untied: 11129 case OMPC_mergeable: 11130 case OMPC_threadprivate: 11131 case OMPC_read: 11132 case OMPC_write: 11133 case OMPC_update: 11134 case OMPC_capture: 11135 case OMPC_seq_cst: 11136 case OMPC_device: 11137 case OMPC_threads: 11138 case OMPC_simd: 11139 case OMPC_num_teams: 11140 case OMPC_thread_limit: 11141 case OMPC_priority: 11142 case OMPC_grainsize: 11143 case OMPC_nogroup: 11144 case OMPC_num_tasks: 11145 case OMPC_hint: 11146 case OMPC_dist_schedule: 11147 case OMPC_defaultmap: 11148 case OMPC_unknown: 11149 case OMPC_uniform: 11150 case OMPC_unified_address: 11151 case OMPC_unified_shared_memory: 11152 case OMPC_reverse_offload: 11153 case OMPC_dynamic_allocators: 11154 case OMPC_atomic_default_mem_order: 11155 llvm_unreachable("Clause is not allowed."); 11156 } 11157 return Res; 11158 } 11159 11160 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11161 ExprObjectKind OK, SourceLocation Loc) { 11162 ExprResult Res = BuildDeclRefExpr( 11163 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11164 if (!Res.isUsable()) 11165 return ExprError(); 11166 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11167 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11168 if (!Res.isUsable()) 11169 return ExprError(); 11170 } 11171 if (VK != VK_LValue && Res.get()->isGLValue()) { 11172 Res = DefaultLvalueConversion(Res.get()); 11173 if (!Res.isUsable()) 11174 return ExprError(); 11175 } 11176 return Res; 11177 } 11178 11179 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11180 SourceLocation StartLoc, 11181 SourceLocation LParenLoc, 11182 SourceLocation EndLoc) { 11183 SmallVector<Expr *, 8> Vars; 11184 SmallVector<Expr *, 8> PrivateCopies; 11185 for (Expr *RefExpr : VarList) { 11186 assert(RefExpr && "NULL expr in OpenMP private clause."); 11187 SourceLocation ELoc; 11188 SourceRange ERange; 11189 Expr *SimpleRefExpr = RefExpr; 11190 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11191 if (Res.second) { 11192 // It will be analyzed later. 11193 Vars.push_back(RefExpr); 11194 PrivateCopies.push_back(nullptr); 11195 } 11196 ValueDecl *D = Res.first; 11197 if (!D) 11198 continue; 11199 11200 QualType Type = D->getType(); 11201 auto *VD = dyn_cast<VarDecl>(D); 11202 11203 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11204 // A variable that appears in a private clause must not have an incomplete 11205 // type or a reference type. 11206 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11207 continue; 11208 Type = Type.getNonReferenceType(); 11209 11210 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11211 // A variable that is privatized must not have a const-qualified type 11212 // unless it is of class type with a mutable member. This restriction does 11213 // not apply to the firstprivate clause. 11214 // 11215 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11216 // A variable that appears in a private clause must not have a 11217 // const-qualified type unless it is of class type with a mutable member. 11218 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11219 continue; 11220 11221 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11222 // in a Construct] 11223 // Variables with the predetermined data-sharing attributes may not be 11224 // listed in data-sharing attributes clauses, except for the cases 11225 // listed below. For these exceptions only, listing a predetermined 11226 // variable in a data-sharing attribute clause is allowed and overrides 11227 // the variable's predetermined data-sharing attributes. 11228 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11229 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11230 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11231 << getOpenMPClauseName(OMPC_private); 11232 reportOriginalDsa(*this, DSAStack, D, DVar); 11233 continue; 11234 } 11235 11236 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11237 // Variably modified types are not supported for tasks. 11238 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11239 isOpenMPTaskingDirective(CurrDir)) { 11240 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11241 << getOpenMPClauseName(OMPC_private) << Type 11242 << getOpenMPDirectiveName(CurrDir); 11243 bool IsDecl = 11244 !VD || 11245 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11246 Diag(D->getLocation(), 11247 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11248 << D; 11249 continue; 11250 } 11251 11252 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11253 // A list item cannot appear in both a map clause and a data-sharing 11254 // attribute clause on the same construct 11255 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11256 OpenMPClauseKind ConflictKind; 11257 if (DSAStack->checkMappableExprComponentListsForDecl( 11258 VD, /*CurrentRegionOnly=*/true, 11259 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 11260 OpenMPClauseKind WhereFoundClauseKind) -> bool { 11261 ConflictKind = WhereFoundClauseKind; 11262 return true; 11263 })) { 11264 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11265 << getOpenMPClauseName(OMPC_private) 11266 << getOpenMPClauseName(ConflictKind) 11267 << getOpenMPDirectiveName(CurrDir); 11268 reportOriginalDsa(*this, DSAStack, D, DVar); 11269 continue; 11270 } 11271 } 11272 11273 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 11274 // A variable of class type (or array thereof) that appears in a private 11275 // clause requires an accessible, unambiguous default constructor for the 11276 // class type. 11277 // Generate helper private variable and initialize it with the default 11278 // value. The address of the original variable is replaced by the address of 11279 // the new private variable in CodeGen. This new variable is not added to 11280 // IdResolver, so the code in the OpenMP region uses original variable for 11281 // proper diagnostics. 11282 Type = Type.getUnqualifiedType(); 11283 VarDecl *VDPrivate = 11284 buildVarDecl(*this, ELoc, Type, D->getName(), 11285 D->hasAttrs() ? &D->getAttrs() : nullptr, 11286 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11287 ActOnUninitializedDecl(VDPrivate); 11288 if (VDPrivate->isInvalidDecl()) 11289 continue; 11290 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11291 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11292 11293 DeclRefExpr *Ref = nullptr; 11294 if (!VD && !CurContext->isDependentContext()) 11295 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11296 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 11297 Vars.push_back((VD || CurContext->isDependentContext()) 11298 ? RefExpr->IgnoreParens() 11299 : Ref); 11300 PrivateCopies.push_back(VDPrivateRefExpr); 11301 } 11302 11303 if (Vars.empty()) 11304 return nullptr; 11305 11306 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11307 PrivateCopies); 11308 } 11309 11310 namespace { 11311 class DiagsUninitializedSeveretyRAII { 11312 private: 11313 DiagnosticsEngine &Diags; 11314 SourceLocation SavedLoc; 11315 bool IsIgnored = false; 11316 11317 public: 11318 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 11319 bool IsIgnored) 11320 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 11321 if (!IsIgnored) { 11322 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 11323 /*Map*/ diag::Severity::Ignored, Loc); 11324 } 11325 } 11326 ~DiagsUninitializedSeveretyRAII() { 11327 if (!IsIgnored) 11328 Diags.popMappings(SavedLoc); 11329 } 11330 }; 11331 } 11332 11333 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 11334 SourceLocation StartLoc, 11335 SourceLocation LParenLoc, 11336 SourceLocation EndLoc) { 11337 SmallVector<Expr *, 8> Vars; 11338 SmallVector<Expr *, 8> PrivateCopies; 11339 SmallVector<Expr *, 8> Inits; 11340 SmallVector<Decl *, 4> ExprCaptures; 11341 bool IsImplicitClause = 11342 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 11343 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 11344 11345 for (Expr *RefExpr : VarList) { 11346 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 11347 SourceLocation ELoc; 11348 SourceRange ERange; 11349 Expr *SimpleRefExpr = RefExpr; 11350 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11351 if (Res.second) { 11352 // It will be analyzed later. 11353 Vars.push_back(RefExpr); 11354 PrivateCopies.push_back(nullptr); 11355 Inits.push_back(nullptr); 11356 } 11357 ValueDecl *D = Res.first; 11358 if (!D) 11359 continue; 11360 11361 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11362 QualType Type = D->getType(); 11363 auto *VD = dyn_cast<VarDecl>(D); 11364 11365 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11366 // A variable that appears in a private clause must not have an incomplete 11367 // type or a reference type. 11368 if (RequireCompleteType(ELoc, Type, 11369 diag::err_omp_firstprivate_incomplete_type)) 11370 continue; 11371 Type = Type.getNonReferenceType(); 11372 11373 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11374 // A variable of class type (or array thereof) that appears in a private 11375 // clause requires an accessible, unambiguous copy constructor for the 11376 // class type. 11377 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11378 11379 // If an implicit firstprivate variable found it was checked already. 11380 DSAStackTy::DSAVarData TopDVar; 11381 if (!IsImplicitClause) { 11382 DSAStackTy::DSAVarData DVar = 11383 DSAStack->getTopDSA(D, /*FromParent=*/false); 11384 TopDVar = DVar; 11385 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11386 bool IsConstant = ElemType.isConstant(Context); 11387 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11388 // A list item that specifies a given variable may not appear in more 11389 // than one clause on the same directive, except that a variable may be 11390 // specified in both firstprivate and lastprivate clauses. 11391 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11392 // A list item may appear in a firstprivate or lastprivate clause but not 11393 // both. 11394 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11395 (isOpenMPDistributeDirective(CurrDir) || 11396 DVar.CKind != OMPC_lastprivate) && 11397 DVar.RefExpr) { 11398 Diag(ELoc, diag::err_omp_wrong_dsa) 11399 << getOpenMPClauseName(DVar.CKind) 11400 << getOpenMPClauseName(OMPC_firstprivate); 11401 reportOriginalDsa(*this, DSAStack, D, DVar); 11402 continue; 11403 } 11404 11405 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11406 // in a Construct] 11407 // Variables with the predetermined data-sharing attributes may not be 11408 // listed in data-sharing attributes clauses, except for the cases 11409 // listed below. For these exceptions only, listing a predetermined 11410 // variable in a data-sharing attribute clause is allowed and overrides 11411 // the variable's predetermined data-sharing attributes. 11412 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11413 // in a Construct, C/C++, p.2] 11414 // Variables with const-qualified type having no mutable member may be 11415 // listed in a firstprivate clause, even if they are static data members. 11416 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11417 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11418 Diag(ELoc, diag::err_omp_wrong_dsa) 11419 << getOpenMPClauseName(DVar.CKind) 11420 << getOpenMPClauseName(OMPC_firstprivate); 11421 reportOriginalDsa(*this, DSAStack, D, DVar); 11422 continue; 11423 } 11424 11425 // OpenMP [2.9.3.4, Restrictions, p.2] 11426 // A list item that is private within a parallel region must not appear 11427 // in a firstprivate clause on a worksharing construct if any of the 11428 // worksharing regions arising from the worksharing construct ever bind 11429 // to any of the parallel regions arising from the parallel construct. 11430 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11431 // A list item that is private within a teams region must not appear in a 11432 // firstprivate clause on a distribute construct if any of the distribute 11433 // regions arising from the distribute construct ever bind to any of the 11434 // teams regions arising from the teams construct. 11435 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11436 // A list item that appears in a reduction clause of a teams construct 11437 // must not appear in a firstprivate clause on a distribute construct if 11438 // any of the distribute regions arising from the distribute construct 11439 // ever bind to any of the teams regions arising from the teams construct. 11440 if ((isOpenMPWorksharingDirective(CurrDir) || 11441 isOpenMPDistributeDirective(CurrDir)) && 11442 !isOpenMPParallelDirective(CurrDir) && 11443 !isOpenMPTeamsDirective(CurrDir)) { 11444 DVar = DSAStack->getImplicitDSA(D, true); 11445 if (DVar.CKind != OMPC_shared && 11446 (isOpenMPParallelDirective(DVar.DKind) || 11447 isOpenMPTeamsDirective(DVar.DKind) || 11448 DVar.DKind == OMPD_unknown)) { 11449 Diag(ELoc, diag::err_omp_required_access) 11450 << getOpenMPClauseName(OMPC_firstprivate) 11451 << getOpenMPClauseName(OMPC_shared); 11452 reportOriginalDsa(*this, DSAStack, D, DVar); 11453 continue; 11454 } 11455 } 11456 // OpenMP [2.9.3.4, Restrictions, p.3] 11457 // A list item that appears in a reduction clause of a parallel construct 11458 // must not appear in a firstprivate clause on a worksharing or task 11459 // construct if any of the worksharing or task regions arising from the 11460 // worksharing or task construct ever bind to any of the parallel regions 11461 // arising from the parallel construct. 11462 // OpenMP [2.9.3.4, Restrictions, p.4] 11463 // A list item that appears in a reduction clause in worksharing 11464 // construct must not appear in a firstprivate clause in a task construct 11465 // encountered during execution of any of the worksharing regions arising 11466 // from the worksharing construct. 11467 if (isOpenMPTaskingDirective(CurrDir)) { 11468 DVar = DSAStack->hasInnermostDSA( 11469 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11470 [](OpenMPDirectiveKind K) { 11471 return isOpenMPParallelDirective(K) || 11472 isOpenMPWorksharingDirective(K) || 11473 isOpenMPTeamsDirective(K); 11474 }, 11475 /*FromParent=*/true); 11476 if (DVar.CKind == OMPC_reduction && 11477 (isOpenMPParallelDirective(DVar.DKind) || 11478 isOpenMPWorksharingDirective(DVar.DKind) || 11479 isOpenMPTeamsDirective(DVar.DKind))) { 11480 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11481 << getOpenMPDirectiveName(DVar.DKind); 11482 reportOriginalDsa(*this, DSAStack, D, DVar); 11483 continue; 11484 } 11485 } 11486 11487 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11488 // A list item cannot appear in both a map clause and a data-sharing 11489 // attribute clause on the same construct 11490 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11491 OpenMPClauseKind ConflictKind; 11492 if (DSAStack->checkMappableExprComponentListsForDecl( 11493 VD, /*CurrentRegionOnly=*/true, 11494 [&ConflictKind]( 11495 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11496 OpenMPClauseKind WhereFoundClauseKind) { 11497 ConflictKind = WhereFoundClauseKind; 11498 return true; 11499 })) { 11500 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11501 << getOpenMPClauseName(OMPC_firstprivate) 11502 << getOpenMPClauseName(ConflictKind) 11503 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11504 reportOriginalDsa(*this, DSAStack, D, DVar); 11505 continue; 11506 } 11507 } 11508 } 11509 11510 // Variably modified types are not supported for tasks. 11511 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11512 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11513 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11514 << getOpenMPClauseName(OMPC_firstprivate) << Type 11515 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11516 bool IsDecl = 11517 !VD || 11518 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11519 Diag(D->getLocation(), 11520 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11521 << D; 11522 continue; 11523 } 11524 11525 Type = Type.getUnqualifiedType(); 11526 VarDecl *VDPrivate = 11527 buildVarDecl(*this, ELoc, Type, D->getName(), 11528 D->hasAttrs() ? &D->getAttrs() : nullptr, 11529 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11530 // Generate helper private variable and initialize it with the value of the 11531 // original variable. The address of the original variable is replaced by 11532 // the address of the new private variable in the CodeGen. This new variable 11533 // is not added to IdResolver, so the code in the OpenMP region uses 11534 // original variable for proper diagnostics and variable capturing. 11535 Expr *VDInitRefExpr = nullptr; 11536 // For arrays generate initializer for single element and replace it by the 11537 // original array element in CodeGen. 11538 if (Type->isArrayType()) { 11539 VarDecl *VDInit = 11540 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11541 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11542 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11543 ElemType = ElemType.getUnqualifiedType(); 11544 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11545 ".firstprivate.temp"); 11546 InitializedEntity Entity = 11547 InitializedEntity::InitializeVariable(VDInitTemp); 11548 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11549 11550 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11551 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11552 if (Result.isInvalid()) 11553 VDPrivate->setInvalidDecl(); 11554 else 11555 VDPrivate->setInit(Result.getAs<Expr>()); 11556 // Remove temp variable declaration. 11557 Context.Deallocate(VDInitTemp); 11558 } else { 11559 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11560 ".firstprivate.temp"); 11561 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11562 RefExpr->getExprLoc()); 11563 AddInitializerToDecl(VDPrivate, 11564 DefaultLvalueConversion(VDInitRefExpr).get(), 11565 /*DirectInit=*/false); 11566 } 11567 if (VDPrivate->isInvalidDecl()) { 11568 if (IsImplicitClause) { 11569 Diag(RefExpr->getExprLoc(), 11570 diag::note_omp_task_predetermined_firstprivate_here); 11571 } 11572 continue; 11573 } 11574 CurContext->addDecl(VDPrivate); 11575 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11576 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11577 RefExpr->getExprLoc()); 11578 DeclRefExpr *Ref = nullptr; 11579 if (!VD && !CurContext->isDependentContext()) { 11580 if (TopDVar.CKind == OMPC_lastprivate) { 11581 Ref = TopDVar.PrivateCopy; 11582 } else { 11583 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11584 if (!isOpenMPCapturedDecl(D)) 11585 ExprCaptures.push_back(Ref->getDecl()); 11586 } 11587 } 11588 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11589 Vars.push_back((VD || CurContext->isDependentContext()) 11590 ? RefExpr->IgnoreParens() 11591 : Ref); 11592 PrivateCopies.push_back(VDPrivateRefExpr); 11593 Inits.push_back(VDInitRefExpr); 11594 } 11595 11596 if (Vars.empty()) 11597 return nullptr; 11598 11599 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11600 Vars, PrivateCopies, Inits, 11601 buildPreInits(Context, ExprCaptures)); 11602 } 11603 11604 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11605 SourceLocation StartLoc, 11606 SourceLocation LParenLoc, 11607 SourceLocation EndLoc) { 11608 SmallVector<Expr *, 8> Vars; 11609 SmallVector<Expr *, 8> SrcExprs; 11610 SmallVector<Expr *, 8> DstExprs; 11611 SmallVector<Expr *, 8> AssignmentOps; 11612 SmallVector<Decl *, 4> ExprCaptures; 11613 SmallVector<Expr *, 4> ExprPostUpdates; 11614 for (Expr *RefExpr : VarList) { 11615 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11616 SourceLocation ELoc; 11617 SourceRange ERange; 11618 Expr *SimpleRefExpr = RefExpr; 11619 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11620 if (Res.second) { 11621 // It will be analyzed later. 11622 Vars.push_back(RefExpr); 11623 SrcExprs.push_back(nullptr); 11624 DstExprs.push_back(nullptr); 11625 AssignmentOps.push_back(nullptr); 11626 } 11627 ValueDecl *D = Res.first; 11628 if (!D) 11629 continue; 11630 11631 QualType Type = D->getType(); 11632 auto *VD = dyn_cast<VarDecl>(D); 11633 11634 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11635 // A variable that appears in a lastprivate clause must not have an 11636 // incomplete type or a reference type. 11637 if (RequireCompleteType(ELoc, Type, 11638 diag::err_omp_lastprivate_incomplete_type)) 11639 continue; 11640 Type = Type.getNonReferenceType(); 11641 11642 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11643 // A variable that is privatized must not have a const-qualified type 11644 // unless it is of class type with a mutable member. This restriction does 11645 // not apply to the firstprivate clause. 11646 // 11647 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11648 // A variable that appears in a lastprivate clause must not have a 11649 // const-qualified type unless it is of class type with a mutable member. 11650 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11651 continue; 11652 11653 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11654 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11655 // in a Construct] 11656 // Variables with the predetermined data-sharing attributes may not be 11657 // listed in data-sharing attributes clauses, except for the cases 11658 // listed below. 11659 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11660 // A list item may appear in a firstprivate or lastprivate clause but not 11661 // both. 11662 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11663 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11664 (isOpenMPDistributeDirective(CurrDir) || 11665 DVar.CKind != OMPC_firstprivate) && 11666 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11667 Diag(ELoc, diag::err_omp_wrong_dsa) 11668 << getOpenMPClauseName(DVar.CKind) 11669 << getOpenMPClauseName(OMPC_lastprivate); 11670 reportOriginalDsa(*this, DSAStack, D, DVar); 11671 continue; 11672 } 11673 11674 // OpenMP [2.14.3.5, Restrictions, p.2] 11675 // A list item that is private within a parallel region, or that appears in 11676 // the reduction clause of a parallel construct, must not appear in a 11677 // lastprivate clause on a worksharing construct if any of the corresponding 11678 // worksharing regions ever binds to any of the corresponding parallel 11679 // regions. 11680 DSAStackTy::DSAVarData TopDVar = DVar; 11681 if (isOpenMPWorksharingDirective(CurrDir) && 11682 !isOpenMPParallelDirective(CurrDir) && 11683 !isOpenMPTeamsDirective(CurrDir)) { 11684 DVar = DSAStack->getImplicitDSA(D, true); 11685 if (DVar.CKind != OMPC_shared) { 11686 Diag(ELoc, diag::err_omp_required_access) 11687 << getOpenMPClauseName(OMPC_lastprivate) 11688 << getOpenMPClauseName(OMPC_shared); 11689 reportOriginalDsa(*this, DSAStack, D, DVar); 11690 continue; 11691 } 11692 } 11693 11694 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11695 // A variable of class type (or array thereof) that appears in a 11696 // lastprivate clause requires an accessible, unambiguous default 11697 // constructor for the class type, unless the list item is also specified 11698 // in a firstprivate clause. 11699 // A variable of class type (or array thereof) that appears in a 11700 // lastprivate clause requires an accessible, unambiguous copy assignment 11701 // operator for the class type. 11702 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11703 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11704 Type.getUnqualifiedType(), ".lastprivate.src", 11705 D->hasAttrs() ? &D->getAttrs() : nullptr); 11706 DeclRefExpr *PseudoSrcExpr = 11707 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11708 VarDecl *DstVD = 11709 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11710 D->hasAttrs() ? &D->getAttrs() : nullptr); 11711 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11712 // For arrays generate assignment operation for single element and replace 11713 // it by the original array element in CodeGen. 11714 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11715 PseudoDstExpr, PseudoSrcExpr); 11716 if (AssignmentOp.isInvalid()) 11717 continue; 11718 AssignmentOp = 11719 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11720 if (AssignmentOp.isInvalid()) 11721 continue; 11722 11723 DeclRefExpr *Ref = nullptr; 11724 if (!VD && !CurContext->isDependentContext()) { 11725 if (TopDVar.CKind == OMPC_firstprivate) { 11726 Ref = TopDVar.PrivateCopy; 11727 } else { 11728 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11729 if (!isOpenMPCapturedDecl(D)) 11730 ExprCaptures.push_back(Ref->getDecl()); 11731 } 11732 if (TopDVar.CKind == OMPC_firstprivate || 11733 (!isOpenMPCapturedDecl(D) && 11734 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11735 ExprResult RefRes = DefaultLvalueConversion(Ref); 11736 if (!RefRes.isUsable()) 11737 continue; 11738 ExprResult PostUpdateRes = 11739 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11740 RefRes.get()); 11741 if (!PostUpdateRes.isUsable()) 11742 continue; 11743 ExprPostUpdates.push_back( 11744 IgnoredValueConversions(PostUpdateRes.get()).get()); 11745 } 11746 } 11747 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11748 Vars.push_back((VD || CurContext->isDependentContext()) 11749 ? RefExpr->IgnoreParens() 11750 : Ref); 11751 SrcExprs.push_back(PseudoSrcExpr); 11752 DstExprs.push_back(PseudoDstExpr); 11753 AssignmentOps.push_back(AssignmentOp.get()); 11754 } 11755 11756 if (Vars.empty()) 11757 return nullptr; 11758 11759 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11760 Vars, SrcExprs, DstExprs, AssignmentOps, 11761 buildPreInits(Context, ExprCaptures), 11762 buildPostUpdate(*this, ExprPostUpdates)); 11763 } 11764 11765 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11766 SourceLocation StartLoc, 11767 SourceLocation LParenLoc, 11768 SourceLocation EndLoc) { 11769 SmallVector<Expr *, 8> Vars; 11770 for (Expr *RefExpr : VarList) { 11771 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11772 SourceLocation ELoc; 11773 SourceRange ERange; 11774 Expr *SimpleRefExpr = RefExpr; 11775 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11776 if (Res.second) { 11777 // It will be analyzed later. 11778 Vars.push_back(RefExpr); 11779 } 11780 ValueDecl *D = Res.first; 11781 if (!D) 11782 continue; 11783 11784 auto *VD = dyn_cast<VarDecl>(D); 11785 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11786 // in a Construct] 11787 // Variables with the predetermined data-sharing attributes may not be 11788 // listed in data-sharing attributes clauses, except for the cases 11789 // listed below. For these exceptions only, listing a predetermined 11790 // variable in a data-sharing attribute clause is allowed and overrides 11791 // the variable's predetermined data-sharing attributes. 11792 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11793 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 11794 DVar.RefExpr) { 11795 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11796 << getOpenMPClauseName(OMPC_shared); 11797 reportOriginalDsa(*this, DSAStack, D, DVar); 11798 continue; 11799 } 11800 11801 DeclRefExpr *Ref = nullptr; 11802 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 11803 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11804 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 11805 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 11806 ? RefExpr->IgnoreParens() 11807 : Ref); 11808 } 11809 11810 if (Vars.empty()) 11811 return nullptr; 11812 11813 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 11814 } 11815 11816 namespace { 11817 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 11818 DSAStackTy *Stack; 11819 11820 public: 11821 bool VisitDeclRefExpr(DeclRefExpr *E) { 11822 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 11823 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 11824 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 11825 return false; 11826 if (DVar.CKind != OMPC_unknown) 11827 return true; 11828 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 11829 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 11830 /*FromParent=*/true); 11831 return DVarPrivate.CKind != OMPC_unknown; 11832 } 11833 return false; 11834 } 11835 bool VisitStmt(Stmt *S) { 11836 for (Stmt *Child : S->children()) { 11837 if (Child && Visit(Child)) 11838 return true; 11839 } 11840 return false; 11841 } 11842 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 11843 }; 11844 } // namespace 11845 11846 namespace { 11847 // Transform MemberExpression for specified FieldDecl of current class to 11848 // DeclRefExpr to specified OMPCapturedExprDecl. 11849 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 11850 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 11851 ValueDecl *Field = nullptr; 11852 DeclRefExpr *CapturedExpr = nullptr; 11853 11854 public: 11855 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 11856 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 11857 11858 ExprResult TransformMemberExpr(MemberExpr *E) { 11859 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 11860 E->getMemberDecl() == Field) { 11861 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 11862 return CapturedExpr; 11863 } 11864 return BaseTransform::TransformMemberExpr(E); 11865 } 11866 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 11867 }; 11868 } // namespace 11869 11870 template <typename T, typename U> 11871 static T filterLookupForUDReductionAndMapper( 11872 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 11873 for (U &Set : Lookups) { 11874 for (auto *D : Set) { 11875 if (T Res = Gen(cast<ValueDecl>(D))) 11876 return Res; 11877 } 11878 } 11879 return T(); 11880 } 11881 11882 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 11883 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 11884 11885 for (auto RD : D->redecls()) { 11886 // Don't bother with extra checks if we already know this one isn't visible. 11887 if (RD == D) 11888 continue; 11889 11890 auto ND = cast<NamedDecl>(RD); 11891 if (LookupResult::isVisible(SemaRef, ND)) 11892 return ND; 11893 } 11894 11895 return nullptr; 11896 } 11897 11898 static void 11899 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 11900 SourceLocation Loc, QualType Ty, 11901 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 11902 // Find all of the associated namespaces and classes based on the 11903 // arguments we have. 11904 Sema::AssociatedNamespaceSet AssociatedNamespaces; 11905 Sema::AssociatedClassSet AssociatedClasses; 11906 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 11907 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 11908 AssociatedClasses); 11909 11910 // C++ [basic.lookup.argdep]p3: 11911 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11912 // and let Y be the lookup set produced by argument dependent 11913 // lookup (defined as follows). If X contains [...] then Y is 11914 // empty. Otherwise Y is the set of declarations found in the 11915 // namespaces associated with the argument types as described 11916 // below. The set of declarations found by the lookup of the name 11917 // is the union of X and Y. 11918 // 11919 // Here, we compute Y and add its members to the overloaded 11920 // candidate set. 11921 for (auto *NS : AssociatedNamespaces) { 11922 // When considering an associated namespace, the lookup is the 11923 // same as the lookup performed when the associated namespace is 11924 // used as a qualifier (3.4.3.2) except that: 11925 // 11926 // -- Any using-directives in the associated namespace are 11927 // ignored. 11928 // 11929 // -- Any namespace-scope friend functions declared in 11930 // associated classes are visible within their respective 11931 // namespaces even if they are not visible during an ordinary 11932 // lookup (11.4). 11933 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11934 for (auto *D : R) { 11935 auto *Underlying = D; 11936 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11937 Underlying = USD->getTargetDecl(); 11938 11939 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11940 !isa<OMPDeclareMapperDecl>(Underlying)) 11941 continue; 11942 11943 if (!SemaRef.isVisible(D)) { 11944 D = findAcceptableDecl(SemaRef, D); 11945 if (!D) 11946 continue; 11947 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11948 Underlying = USD->getTargetDecl(); 11949 } 11950 Lookups.emplace_back(); 11951 Lookups.back().addDecl(Underlying); 11952 } 11953 } 11954 } 11955 11956 static ExprResult 11957 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11958 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11959 const DeclarationNameInfo &ReductionId, QualType Ty, 11960 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11961 if (ReductionIdScopeSpec.isInvalid()) 11962 return ExprError(); 11963 SmallVector<UnresolvedSet<8>, 4> Lookups; 11964 if (S) { 11965 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11966 Lookup.suppressDiagnostics(); 11967 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11968 NamedDecl *D = Lookup.getRepresentativeDecl(); 11969 do { 11970 S = S->getParent(); 11971 } while (S && !S->isDeclScope(D)); 11972 if (S) 11973 S = S->getParent(); 11974 Lookups.emplace_back(); 11975 Lookups.back().append(Lookup.begin(), Lookup.end()); 11976 Lookup.clear(); 11977 } 11978 } else if (auto *ULE = 11979 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11980 Lookups.push_back(UnresolvedSet<8>()); 11981 Decl *PrevD = nullptr; 11982 for (NamedDecl *D : ULE->decls()) { 11983 if (D == PrevD) 11984 Lookups.push_back(UnresolvedSet<8>()); 11985 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11986 Lookups.back().addDecl(DRD); 11987 PrevD = D; 11988 } 11989 } 11990 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11991 Ty->isInstantiationDependentType() || 11992 Ty->containsUnexpandedParameterPack() || 11993 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11994 return !D->isInvalidDecl() && 11995 (D->getType()->isDependentType() || 11996 D->getType()->isInstantiationDependentType() || 11997 D->getType()->containsUnexpandedParameterPack()); 11998 })) { 11999 UnresolvedSet<8> ResSet; 12000 for (const UnresolvedSet<8> &Set : Lookups) { 12001 if (Set.empty()) 12002 continue; 12003 ResSet.append(Set.begin(), Set.end()); 12004 // The last item marks the end of all declarations at the specified scope. 12005 ResSet.addDecl(Set[Set.size() - 1]); 12006 } 12007 return UnresolvedLookupExpr::Create( 12008 SemaRef.Context, /*NamingClass=*/nullptr, 12009 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12010 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12011 } 12012 // Lookup inside the classes. 12013 // C++ [over.match.oper]p3: 12014 // For a unary operator @ with an operand of a type whose 12015 // cv-unqualified version is T1, and for a binary operator @ with 12016 // a left operand of a type whose cv-unqualified version is T1 and 12017 // a right operand of a type whose cv-unqualified version is T2, 12018 // three sets of candidate functions, designated member 12019 // candidates, non-member candidates and built-in candidates, are 12020 // constructed as follows: 12021 // -- If T1 is a complete class type or a class currently being 12022 // defined, the set of member candidates is the result of the 12023 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12024 // the set of member candidates is empty. 12025 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12026 Lookup.suppressDiagnostics(); 12027 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12028 // Complete the type if it can be completed. 12029 // If the type is neither complete nor being defined, bail out now. 12030 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12031 TyRec->getDecl()->getDefinition()) { 12032 Lookup.clear(); 12033 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12034 if (Lookup.empty()) { 12035 Lookups.emplace_back(); 12036 Lookups.back().append(Lookup.begin(), Lookup.end()); 12037 } 12038 } 12039 } 12040 // Perform ADL. 12041 if (SemaRef.getLangOpts().CPlusPlus) 12042 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12043 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12044 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12045 if (!D->isInvalidDecl() && 12046 SemaRef.Context.hasSameType(D->getType(), Ty)) 12047 return D; 12048 return nullptr; 12049 })) 12050 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12051 VK_LValue, Loc); 12052 if (SemaRef.getLangOpts().CPlusPlus) { 12053 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12054 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12055 if (!D->isInvalidDecl() && 12056 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12057 !Ty.isMoreQualifiedThan(D->getType())) 12058 return D; 12059 return nullptr; 12060 })) { 12061 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12062 /*DetectVirtual=*/false); 12063 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12064 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12065 VD->getType().getUnqualifiedType()))) { 12066 if (SemaRef.CheckBaseClassAccess( 12067 Loc, VD->getType(), Ty, Paths.front(), 12068 /*DiagID=*/0) != Sema::AR_inaccessible) { 12069 SemaRef.BuildBasePathArray(Paths, BasePath); 12070 return SemaRef.BuildDeclRefExpr( 12071 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12072 } 12073 } 12074 } 12075 } 12076 } 12077 if (ReductionIdScopeSpec.isSet()) { 12078 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12079 return ExprError(); 12080 } 12081 return ExprEmpty(); 12082 } 12083 12084 namespace { 12085 /// Data for the reduction-based clauses. 12086 struct ReductionData { 12087 /// List of original reduction items. 12088 SmallVector<Expr *, 8> Vars; 12089 /// List of private copies of the reduction items. 12090 SmallVector<Expr *, 8> Privates; 12091 /// LHS expressions for the reduction_op expressions. 12092 SmallVector<Expr *, 8> LHSs; 12093 /// RHS expressions for the reduction_op expressions. 12094 SmallVector<Expr *, 8> RHSs; 12095 /// Reduction operation expression. 12096 SmallVector<Expr *, 8> ReductionOps; 12097 /// Taskgroup descriptors for the corresponding reduction items in 12098 /// in_reduction clauses. 12099 SmallVector<Expr *, 8> TaskgroupDescriptors; 12100 /// List of captures for clause. 12101 SmallVector<Decl *, 4> ExprCaptures; 12102 /// List of postupdate expressions. 12103 SmallVector<Expr *, 4> ExprPostUpdates; 12104 ReductionData() = delete; 12105 /// Reserves required memory for the reduction data. 12106 ReductionData(unsigned Size) { 12107 Vars.reserve(Size); 12108 Privates.reserve(Size); 12109 LHSs.reserve(Size); 12110 RHSs.reserve(Size); 12111 ReductionOps.reserve(Size); 12112 TaskgroupDescriptors.reserve(Size); 12113 ExprCaptures.reserve(Size); 12114 ExprPostUpdates.reserve(Size); 12115 } 12116 /// Stores reduction item and reduction operation only (required for dependent 12117 /// reduction item). 12118 void push(Expr *Item, Expr *ReductionOp) { 12119 Vars.emplace_back(Item); 12120 Privates.emplace_back(nullptr); 12121 LHSs.emplace_back(nullptr); 12122 RHSs.emplace_back(nullptr); 12123 ReductionOps.emplace_back(ReductionOp); 12124 TaskgroupDescriptors.emplace_back(nullptr); 12125 } 12126 /// Stores reduction data. 12127 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12128 Expr *TaskgroupDescriptor) { 12129 Vars.emplace_back(Item); 12130 Privates.emplace_back(Private); 12131 LHSs.emplace_back(LHS); 12132 RHSs.emplace_back(RHS); 12133 ReductionOps.emplace_back(ReductionOp); 12134 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12135 } 12136 }; 12137 } // namespace 12138 12139 static bool checkOMPArraySectionConstantForReduction( 12140 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12141 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12142 const Expr *Length = OASE->getLength(); 12143 if (Length == nullptr) { 12144 // For array sections of the form [1:] or [:], we would need to analyze 12145 // the lower bound... 12146 if (OASE->getColonLoc().isValid()) 12147 return false; 12148 12149 // This is an array subscript which has implicit length 1! 12150 SingleElement = true; 12151 ArraySizes.push_back(llvm::APSInt::get(1)); 12152 } else { 12153 Expr::EvalResult Result; 12154 if (!Length->EvaluateAsInt(Result, Context)) 12155 return false; 12156 12157 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12158 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12159 ArraySizes.push_back(ConstantLengthValue); 12160 } 12161 12162 // Get the base of this array section and walk up from there. 12163 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12164 12165 // We require length = 1 for all array sections except the right-most to 12166 // guarantee that the memory region is contiguous and has no holes in it. 12167 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12168 Length = TempOASE->getLength(); 12169 if (Length == nullptr) { 12170 // For array sections of the form [1:] or [:], we would need to analyze 12171 // the lower bound... 12172 if (OASE->getColonLoc().isValid()) 12173 return false; 12174 12175 // This is an array subscript which has implicit length 1! 12176 ArraySizes.push_back(llvm::APSInt::get(1)); 12177 } else { 12178 Expr::EvalResult Result; 12179 if (!Length->EvaluateAsInt(Result, Context)) 12180 return false; 12181 12182 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12183 if (ConstantLengthValue.getSExtValue() != 1) 12184 return false; 12185 12186 ArraySizes.push_back(ConstantLengthValue); 12187 } 12188 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12189 } 12190 12191 // If we have a single element, we don't need to add the implicit lengths. 12192 if (!SingleElement) { 12193 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12194 // Has implicit length 1! 12195 ArraySizes.push_back(llvm::APSInt::get(1)); 12196 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12197 } 12198 } 12199 12200 // This array section can be privatized as a single value or as a constant 12201 // sized array. 12202 return true; 12203 } 12204 12205 static bool actOnOMPReductionKindClause( 12206 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12207 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12208 SourceLocation ColonLoc, SourceLocation EndLoc, 12209 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12210 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12211 DeclarationName DN = ReductionId.getName(); 12212 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12213 BinaryOperatorKind BOK = BO_Comma; 12214 12215 ASTContext &Context = S.Context; 12216 // OpenMP [2.14.3.6, reduction clause] 12217 // C 12218 // reduction-identifier is either an identifier or one of the following 12219 // operators: +, -, *, &, |, ^, && and || 12220 // C++ 12221 // reduction-identifier is either an id-expression or one of the following 12222 // operators: +, -, *, &, |, ^, && and || 12223 switch (OOK) { 12224 case OO_Plus: 12225 case OO_Minus: 12226 BOK = BO_Add; 12227 break; 12228 case OO_Star: 12229 BOK = BO_Mul; 12230 break; 12231 case OO_Amp: 12232 BOK = BO_And; 12233 break; 12234 case OO_Pipe: 12235 BOK = BO_Or; 12236 break; 12237 case OO_Caret: 12238 BOK = BO_Xor; 12239 break; 12240 case OO_AmpAmp: 12241 BOK = BO_LAnd; 12242 break; 12243 case OO_PipePipe: 12244 BOK = BO_LOr; 12245 break; 12246 case OO_New: 12247 case OO_Delete: 12248 case OO_Array_New: 12249 case OO_Array_Delete: 12250 case OO_Slash: 12251 case OO_Percent: 12252 case OO_Tilde: 12253 case OO_Exclaim: 12254 case OO_Equal: 12255 case OO_Less: 12256 case OO_Greater: 12257 case OO_LessEqual: 12258 case OO_GreaterEqual: 12259 case OO_PlusEqual: 12260 case OO_MinusEqual: 12261 case OO_StarEqual: 12262 case OO_SlashEqual: 12263 case OO_PercentEqual: 12264 case OO_CaretEqual: 12265 case OO_AmpEqual: 12266 case OO_PipeEqual: 12267 case OO_LessLess: 12268 case OO_GreaterGreater: 12269 case OO_LessLessEqual: 12270 case OO_GreaterGreaterEqual: 12271 case OO_EqualEqual: 12272 case OO_ExclaimEqual: 12273 case OO_Spaceship: 12274 case OO_PlusPlus: 12275 case OO_MinusMinus: 12276 case OO_Comma: 12277 case OO_ArrowStar: 12278 case OO_Arrow: 12279 case OO_Call: 12280 case OO_Subscript: 12281 case OO_Conditional: 12282 case OO_Coawait: 12283 case NUM_OVERLOADED_OPERATORS: 12284 llvm_unreachable("Unexpected reduction identifier"); 12285 case OO_None: 12286 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 12287 if (II->isStr("max")) 12288 BOK = BO_GT; 12289 else if (II->isStr("min")) 12290 BOK = BO_LT; 12291 } 12292 break; 12293 } 12294 SourceRange ReductionIdRange; 12295 if (ReductionIdScopeSpec.isValid()) 12296 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 12297 else 12298 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 12299 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 12300 12301 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 12302 bool FirstIter = true; 12303 for (Expr *RefExpr : VarList) { 12304 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 12305 // OpenMP [2.1, C/C++] 12306 // A list item is a variable or array section, subject to the restrictions 12307 // specified in Section 2.4 on page 42 and in each of the sections 12308 // describing clauses and directives for which a list appears. 12309 // OpenMP [2.14.3.3, Restrictions, p.1] 12310 // A variable that is part of another variable (as an array or 12311 // structure element) cannot appear in a private clause. 12312 if (!FirstIter && IR != ER) 12313 ++IR; 12314 FirstIter = false; 12315 SourceLocation ELoc; 12316 SourceRange ERange; 12317 Expr *SimpleRefExpr = RefExpr; 12318 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 12319 /*AllowArraySection=*/true); 12320 if (Res.second) { 12321 // Try to find 'declare reduction' corresponding construct before using 12322 // builtin/overloaded operators. 12323 QualType Type = Context.DependentTy; 12324 CXXCastPath BasePath; 12325 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12326 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12327 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12328 Expr *ReductionOp = nullptr; 12329 if (S.CurContext->isDependentContext() && 12330 (DeclareReductionRef.isUnset() || 12331 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 12332 ReductionOp = DeclareReductionRef.get(); 12333 // It will be analyzed later. 12334 RD.push(RefExpr, ReductionOp); 12335 } 12336 ValueDecl *D = Res.first; 12337 if (!D) 12338 continue; 12339 12340 Expr *TaskgroupDescriptor = nullptr; 12341 QualType Type; 12342 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 12343 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 12344 if (ASE) { 12345 Type = ASE->getType().getNonReferenceType(); 12346 } else if (OASE) { 12347 QualType BaseType = 12348 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 12349 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 12350 Type = ATy->getElementType(); 12351 else 12352 Type = BaseType->getPointeeType(); 12353 Type = Type.getNonReferenceType(); 12354 } else { 12355 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 12356 } 12357 auto *VD = dyn_cast<VarDecl>(D); 12358 12359 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12360 // A variable that appears in a private clause must not have an incomplete 12361 // type or a reference type. 12362 if (S.RequireCompleteType(ELoc, D->getType(), 12363 diag::err_omp_reduction_incomplete_type)) 12364 continue; 12365 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12366 // A list item that appears in a reduction clause must not be 12367 // const-qualified. 12368 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12369 /*AcceptIfMutable*/ false, ASE || OASE)) 12370 continue; 12371 12372 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12373 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12374 // If a list-item is a reference type then it must bind to the same object 12375 // for all threads of the team. 12376 if (!ASE && !OASE) { 12377 if (VD) { 12378 VarDecl *VDDef = VD->getDefinition(); 12379 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12380 DSARefChecker Check(Stack); 12381 if (Check.Visit(VDDef->getInit())) { 12382 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12383 << getOpenMPClauseName(ClauseKind) << ERange; 12384 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12385 continue; 12386 } 12387 } 12388 } 12389 12390 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12391 // in a Construct] 12392 // Variables with the predetermined data-sharing attributes may not be 12393 // listed in data-sharing attributes clauses, except for the cases 12394 // listed below. For these exceptions only, listing a predetermined 12395 // variable in a data-sharing attribute clause is allowed and overrides 12396 // the variable's predetermined data-sharing attributes. 12397 // OpenMP [2.14.3.6, Restrictions, p.3] 12398 // Any number of reduction clauses can be specified on the directive, 12399 // but a list item can appear only once in the reduction clauses for that 12400 // directive. 12401 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12402 if (DVar.CKind == OMPC_reduction) { 12403 S.Diag(ELoc, diag::err_omp_once_referenced) 12404 << getOpenMPClauseName(ClauseKind); 12405 if (DVar.RefExpr) 12406 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12407 continue; 12408 } 12409 if (DVar.CKind != OMPC_unknown) { 12410 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12411 << getOpenMPClauseName(DVar.CKind) 12412 << getOpenMPClauseName(OMPC_reduction); 12413 reportOriginalDsa(S, Stack, D, DVar); 12414 continue; 12415 } 12416 12417 // OpenMP [2.14.3.6, Restrictions, p.1] 12418 // A list item that appears in a reduction clause of a worksharing 12419 // construct must be shared in the parallel regions to which any of the 12420 // worksharing regions arising from the worksharing construct bind. 12421 if (isOpenMPWorksharingDirective(CurrDir) && 12422 !isOpenMPParallelDirective(CurrDir) && 12423 !isOpenMPTeamsDirective(CurrDir)) { 12424 DVar = Stack->getImplicitDSA(D, true); 12425 if (DVar.CKind != OMPC_shared) { 12426 S.Diag(ELoc, diag::err_omp_required_access) 12427 << getOpenMPClauseName(OMPC_reduction) 12428 << getOpenMPClauseName(OMPC_shared); 12429 reportOriginalDsa(S, Stack, D, DVar); 12430 continue; 12431 } 12432 } 12433 } 12434 12435 // Try to find 'declare reduction' corresponding construct before using 12436 // builtin/overloaded operators. 12437 CXXCastPath BasePath; 12438 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12439 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12440 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12441 if (DeclareReductionRef.isInvalid()) 12442 continue; 12443 if (S.CurContext->isDependentContext() && 12444 (DeclareReductionRef.isUnset() || 12445 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12446 RD.push(RefExpr, DeclareReductionRef.get()); 12447 continue; 12448 } 12449 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12450 // Not allowed reduction identifier is found. 12451 S.Diag(ReductionId.getBeginLoc(), 12452 diag::err_omp_unknown_reduction_identifier) 12453 << Type << ReductionIdRange; 12454 continue; 12455 } 12456 12457 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12458 // The type of a list item that appears in a reduction clause must be valid 12459 // for the reduction-identifier. For a max or min reduction in C, the type 12460 // of the list item must be an allowed arithmetic data type: char, int, 12461 // float, double, or _Bool, possibly modified with long, short, signed, or 12462 // unsigned. For a max or min reduction in C++, the type of the list item 12463 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12464 // double, or bool, possibly modified with long, short, signed, or unsigned. 12465 if (DeclareReductionRef.isUnset()) { 12466 if ((BOK == BO_GT || BOK == BO_LT) && 12467 !(Type->isScalarType() || 12468 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12469 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12470 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12471 if (!ASE && !OASE) { 12472 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12473 VarDecl::DeclarationOnly; 12474 S.Diag(D->getLocation(), 12475 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12476 << D; 12477 } 12478 continue; 12479 } 12480 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12481 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12482 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12483 << getOpenMPClauseName(ClauseKind); 12484 if (!ASE && !OASE) { 12485 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12486 VarDecl::DeclarationOnly; 12487 S.Diag(D->getLocation(), 12488 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12489 << D; 12490 } 12491 continue; 12492 } 12493 } 12494 12495 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12496 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12497 D->hasAttrs() ? &D->getAttrs() : nullptr); 12498 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12499 D->hasAttrs() ? &D->getAttrs() : nullptr); 12500 QualType PrivateTy = Type; 12501 12502 // Try if we can determine constant lengths for all array sections and avoid 12503 // the VLA. 12504 bool ConstantLengthOASE = false; 12505 if (OASE) { 12506 bool SingleElement; 12507 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12508 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12509 Context, OASE, SingleElement, ArraySizes); 12510 12511 // If we don't have a single element, we must emit a constant array type. 12512 if (ConstantLengthOASE && !SingleElement) { 12513 for (llvm::APSInt &Size : ArraySizes) 12514 PrivateTy = Context.getConstantArrayType( 12515 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12516 } 12517 } 12518 12519 if ((OASE && !ConstantLengthOASE) || 12520 (!OASE && !ASE && 12521 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12522 if (!Context.getTargetInfo().isVLASupported()) { 12523 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 12524 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12525 S.Diag(ELoc, diag::note_vla_unsupported); 12526 } else { 12527 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12528 S.targetDiag(ELoc, diag::note_vla_unsupported); 12529 } 12530 continue; 12531 } 12532 // For arrays/array sections only: 12533 // Create pseudo array type for private copy. The size for this array will 12534 // be generated during codegen. 12535 // For array subscripts or single variables Private Ty is the same as Type 12536 // (type of the variable or single array element). 12537 PrivateTy = Context.getVariableArrayType( 12538 Type, 12539 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12540 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12541 } else if (!ASE && !OASE && 12542 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12543 PrivateTy = D->getType().getNonReferenceType(); 12544 } 12545 // Private copy. 12546 VarDecl *PrivateVD = 12547 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12548 D->hasAttrs() ? &D->getAttrs() : nullptr, 12549 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12550 // Add initializer for private variable. 12551 Expr *Init = nullptr; 12552 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12553 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12554 if (DeclareReductionRef.isUsable()) { 12555 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12556 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12557 if (DRD->getInitializer()) { 12558 Init = DRDRef; 12559 RHSVD->setInit(DRDRef); 12560 RHSVD->setInitStyle(VarDecl::CallInit); 12561 } 12562 } else { 12563 switch (BOK) { 12564 case BO_Add: 12565 case BO_Xor: 12566 case BO_Or: 12567 case BO_LOr: 12568 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12569 if (Type->isScalarType() || Type->isAnyComplexType()) 12570 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12571 break; 12572 case BO_Mul: 12573 case BO_LAnd: 12574 if (Type->isScalarType() || Type->isAnyComplexType()) { 12575 // '*' and '&&' reduction ops - initializer is '1'. 12576 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12577 } 12578 break; 12579 case BO_And: { 12580 // '&' reduction op - initializer is '~0'. 12581 QualType OrigType = Type; 12582 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12583 Type = ComplexTy->getElementType(); 12584 if (Type->isRealFloatingType()) { 12585 llvm::APFloat InitValue = 12586 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12587 /*isIEEE=*/true); 12588 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12589 Type, ELoc); 12590 } else if (Type->isScalarType()) { 12591 uint64_t Size = Context.getTypeSize(Type); 12592 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12593 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12594 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12595 } 12596 if (Init && OrigType->isAnyComplexType()) { 12597 // Init = 0xFFFF + 0xFFFFi; 12598 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12599 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12600 } 12601 Type = OrigType; 12602 break; 12603 } 12604 case BO_LT: 12605 case BO_GT: { 12606 // 'min' reduction op - initializer is 'Largest representable number in 12607 // the reduction list item type'. 12608 // 'max' reduction op - initializer is 'Least representable number in 12609 // the reduction list item type'. 12610 if (Type->isIntegerType() || Type->isPointerType()) { 12611 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12612 uint64_t Size = Context.getTypeSize(Type); 12613 QualType IntTy = 12614 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12615 llvm::APInt InitValue = 12616 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12617 : llvm::APInt::getMinValue(Size) 12618 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12619 : llvm::APInt::getMaxValue(Size); 12620 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12621 if (Type->isPointerType()) { 12622 // Cast to pointer type. 12623 ExprResult CastExpr = S.BuildCStyleCastExpr( 12624 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12625 if (CastExpr.isInvalid()) 12626 continue; 12627 Init = CastExpr.get(); 12628 } 12629 } else if (Type->isRealFloatingType()) { 12630 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12631 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12632 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12633 Type, ELoc); 12634 } 12635 break; 12636 } 12637 case BO_PtrMemD: 12638 case BO_PtrMemI: 12639 case BO_MulAssign: 12640 case BO_Div: 12641 case BO_Rem: 12642 case BO_Sub: 12643 case BO_Shl: 12644 case BO_Shr: 12645 case BO_LE: 12646 case BO_GE: 12647 case BO_EQ: 12648 case BO_NE: 12649 case BO_Cmp: 12650 case BO_AndAssign: 12651 case BO_XorAssign: 12652 case BO_OrAssign: 12653 case BO_Assign: 12654 case BO_AddAssign: 12655 case BO_SubAssign: 12656 case BO_DivAssign: 12657 case BO_RemAssign: 12658 case BO_ShlAssign: 12659 case BO_ShrAssign: 12660 case BO_Comma: 12661 llvm_unreachable("Unexpected reduction operation"); 12662 } 12663 } 12664 if (Init && DeclareReductionRef.isUnset()) 12665 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12666 else if (!Init) 12667 S.ActOnUninitializedDecl(RHSVD); 12668 if (RHSVD->isInvalidDecl()) 12669 continue; 12670 if (!RHSVD->hasInit() && 12671 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12672 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12673 << Type << ReductionIdRange; 12674 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12675 VarDecl::DeclarationOnly; 12676 S.Diag(D->getLocation(), 12677 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12678 << D; 12679 continue; 12680 } 12681 // Store initializer for single element in private copy. Will be used during 12682 // codegen. 12683 PrivateVD->setInit(RHSVD->getInit()); 12684 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12685 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12686 ExprResult ReductionOp; 12687 if (DeclareReductionRef.isUsable()) { 12688 QualType RedTy = DeclareReductionRef.get()->getType(); 12689 QualType PtrRedTy = Context.getPointerType(RedTy); 12690 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12691 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12692 if (!BasePath.empty()) { 12693 LHS = S.DefaultLvalueConversion(LHS.get()); 12694 RHS = S.DefaultLvalueConversion(RHS.get()); 12695 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12696 CK_UncheckedDerivedToBase, LHS.get(), 12697 &BasePath, LHS.get()->getValueKind()); 12698 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12699 CK_UncheckedDerivedToBase, RHS.get(), 12700 &BasePath, RHS.get()->getValueKind()); 12701 } 12702 FunctionProtoType::ExtProtoInfo EPI; 12703 QualType Params[] = {PtrRedTy, PtrRedTy}; 12704 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12705 auto *OVE = new (Context) OpaqueValueExpr( 12706 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12707 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12708 Expr *Args[] = {LHS.get(), RHS.get()}; 12709 ReductionOp = 12710 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12711 } else { 12712 ReductionOp = S.BuildBinOp( 12713 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12714 if (ReductionOp.isUsable()) { 12715 if (BOK != BO_LT && BOK != BO_GT) { 12716 ReductionOp = 12717 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12718 BO_Assign, LHSDRE, ReductionOp.get()); 12719 } else { 12720 auto *ConditionalOp = new (Context) 12721 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12722 Type, VK_LValue, OK_Ordinary); 12723 ReductionOp = 12724 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12725 BO_Assign, LHSDRE, ConditionalOp); 12726 } 12727 if (ReductionOp.isUsable()) 12728 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12729 /*DiscardedValue*/ false); 12730 } 12731 if (!ReductionOp.isUsable()) 12732 continue; 12733 } 12734 12735 // OpenMP [2.15.4.6, Restrictions, p.2] 12736 // A list item that appears in an in_reduction clause of a task construct 12737 // must appear in a task_reduction clause of a construct associated with a 12738 // taskgroup region that includes the participating task in its taskgroup 12739 // set. The construct associated with the innermost region that meets this 12740 // condition must specify the same reduction-identifier as the in_reduction 12741 // clause. 12742 if (ClauseKind == OMPC_in_reduction) { 12743 SourceRange ParentSR; 12744 BinaryOperatorKind ParentBOK; 12745 const Expr *ParentReductionOp; 12746 Expr *ParentBOKTD, *ParentReductionOpTD; 12747 DSAStackTy::DSAVarData ParentBOKDSA = 12748 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12749 ParentBOKTD); 12750 DSAStackTy::DSAVarData ParentReductionOpDSA = 12751 Stack->getTopMostTaskgroupReductionData( 12752 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12753 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12754 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12755 if (!IsParentBOK && !IsParentReductionOp) { 12756 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12757 continue; 12758 } 12759 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12760 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12761 IsParentReductionOp) { 12762 bool EmitError = true; 12763 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12764 llvm::FoldingSetNodeID RedId, ParentRedId; 12765 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12766 DeclareReductionRef.get()->Profile(RedId, Context, 12767 /*Canonical=*/true); 12768 EmitError = RedId != ParentRedId; 12769 } 12770 if (EmitError) { 12771 S.Diag(ReductionId.getBeginLoc(), 12772 diag::err_omp_reduction_identifier_mismatch) 12773 << ReductionIdRange << RefExpr->getSourceRange(); 12774 S.Diag(ParentSR.getBegin(), 12775 diag::note_omp_previous_reduction_identifier) 12776 << ParentSR 12777 << (IsParentBOK ? ParentBOKDSA.RefExpr 12778 : ParentReductionOpDSA.RefExpr) 12779 ->getSourceRange(); 12780 continue; 12781 } 12782 } 12783 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12784 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12785 } 12786 12787 DeclRefExpr *Ref = nullptr; 12788 Expr *VarsExpr = RefExpr->IgnoreParens(); 12789 if (!VD && !S.CurContext->isDependentContext()) { 12790 if (ASE || OASE) { 12791 TransformExprToCaptures RebuildToCapture(S, D); 12792 VarsExpr = 12793 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 12794 Ref = RebuildToCapture.getCapturedExpr(); 12795 } else { 12796 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 12797 } 12798 if (!S.isOpenMPCapturedDecl(D)) { 12799 RD.ExprCaptures.emplace_back(Ref->getDecl()); 12800 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12801 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 12802 if (!RefRes.isUsable()) 12803 continue; 12804 ExprResult PostUpdateRes = 12805 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12806 RefRes.get()); 12807 if (!PostUpdateRes.isUsable()) 12808 continue; 12809 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 12810 Stack->getCurrentDirective() == OMPD_taskgroup) { 12811 S.Diag(RefExpr->getExprLoc(), 12812 diag::err_omp_reduction_non_addressable_expression) 12813 << RefExpr->getSourceRange(); 12814 continue; 12815 } 12816 RD.ExprPostUpdates.emplace_back( 12817 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 12818 } 12819 } 12820 } 12821 // All reduction items are still marked as reduction (to do not increase 12822 // code base size). 12823 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 12824 if (CurrDir == OMPD_taskgroup) { 12825 if (DeclareReductionRef.isUsable()) 12826 Stack->addTaskgroupReductionData(D, ReductionIdRange, 12827 DeclareReductionRef.get()); 12828 else 12829 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 12830 } 12831 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 12832 TaskgroupDescriptor); 12833 } 12834 return RD.Vars.empty(); 12835 } 12836 12837 OMPClause *Sema::ActOnOpenMPReductionClause( 12838 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12839 SourceLocation ColonLoc, SourceLocation EndLoc, 12840 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12841 ArrayRef<Expr *> UnresolvedReductions) { 12842 ReductionData RD(VarList.size()); 12843 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 12844 StartLoc, LParenLoc, ColonLoc, EndLoc, 12845 ReductionIdScopeSpec, ReductionId, 12846 UnresolvedReductions, RD)) 12847 return nullptr; 12848 12849 return OMPReductionClause::Create( 12850 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12851 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12852 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12853 buildPreInits(Context, RD.ExprCaptures), 12854 buildPostUpdate(*this, RD.ExprPostUpdates)); 12855 } 12856 12857 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 12858 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12859 SourceLocation ColonLoc, SourceLocation EndLoc, 12860 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12861 ArrayRef<Expr *> UnresolvedReductions) { 12862 ReductionData RD(VarList.size()); 12863 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 12864 StartLoc, LParenLoc, ColonLoc, EndLoc, 12865 ReductionIdScopeSpec, ReductionId, 12866 UnresolvedReductions, RD)) 12867 return nullptr; 12868 12869 return OMPTaskReductionClause::Create( 12870 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12871 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12872 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12873 buildPreInits(Context, RD.ExprCaptures), 12874 buildPostUpdate(*this, RD.ExprPostUpdates)); 12875 } 12876 12877 OMPClause *Sema::ActOnOpenMPInReductionClause( 12878 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12879 SourceLocation ColonLoc, SourceLocation EndLoc, 12880 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12881 ArrayRef<Expr *> UnresolvedReductions) { 12882 ReductionData RD(VarList.size()); 12883 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 12884 StartLoc, LParenLoc, ColonLoc, EndLoc, 12885 ReductionIdScopeSpec, ReductionId, 12886 UnresolvedReductions, RD)) 12887 return nullptr; 12888 12889 return OMPInReductionClause::Create( 12890 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12891 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12892 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 12893 buildPreInits(Context, RD.ExprCaptures), 12894 buildPostUpdate(*this, RD.ExprPostUpdates)); 12895 } 12896 12897 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 12898 SourceLocation LinLoc) { 12899 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 12900 LinKind == OMPC_LINEAR_unknown) { 12901 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 12902 return true; 12903 } 12904 return false; 12905 } 12906 12907 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 12908 OpenMPLinearClauseKind LinKind, 12909 QualType Type) { 12910 const auto *VD = dyn_cast_or_null<VarDecl>(D); 12911 // A variable must not have an incomplete type or a reference type. 12912 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 12913 return true; 12914 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 12915 !Type->isReferenceType()) { 12916 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12917 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12918 return true; 12919 } 12920 Type = Type.getNonReferenceType(); 12921 12922 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12923 // A variable that is privatized must not have a const-qualified type 12924 // unless it is of class type with a mutable member. This restriction does 12925 // not apply to the firstprivate clause. 12926 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12927 return true; 12928 12929 // A list item must be of integral or pointer type. 12930 Type = Type.getUnqualifiedType().getCanonicalType(); 12931 const auto *Ty = Type.getTypePtrOrNull(); 12932 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12933 !Ty->isPointerType())) { 12934 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12935 if (D) { 12936 bool IsDecl = 12937 !VD || 12938 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12939 Diag(D->getLocation(), 12940 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12941 << D; 12942 } 12943 return true; 12944 } 12945 return false; 12946 } 12947 12948 OMPClause *Sema::ActOnOpenMPLinearClause( 12949 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12950 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12951 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12952 SmallVector<Expr *, 8> Vars; 12953 SmallVector<Expr *, 8> Privates; 12954 SmallVector<Expr *, 8> Inits; 12955 SmallVector<Decl *, 4> ExprCaptures; 12956 SmallVector<Expr *, 4> ExprPostUpdates; 12957 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12958 LinKind = OMPC_LINEAR_val; 12959 for (Expr *RefExpr : VarList) { 12960 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12961 SourceLocation ELoc; 12962 SourceRange ERange; 12963 Expr *SimpleRefExpr = RefExpr; 12964 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12965 if (Res.second) { 12966 // It will be analyzed later. 12967 Vars.push_back(RefExpr); 12968 Privates.push_back(nullptr); 12969 Inits.push_back(nullptr); 12970 } 12971 ValueDecl *D = Res.first; 12972 if (!D) 12973 continue; 12974 12975 QualType Type = D->getType(); 12976 auto *VD = dyn_cast<VarDecl>(D); 12977 12978 // OpenMP [2.14.3.7, linear clause] 12979 // A list-item cannot appear in more than one linear clause. 12980 // A list-item that appears in a linear clause cannot appear in any 12981 // other data-sharing attribute clause. 12982 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12983 if (DVar.RefExpr) { 12984 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12985 << getOpenMPClauseName(OMPC_linear); 12986 reportOriginalDsa(*this, DSAStack, D, DVar); 12987 continue; 12988 } 12989 12990 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12991 continue; 12992 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12993 12994 // Build private copy of original var. 12995 VarDecl *Private = 12996 buildVarDecl(*this, ELoc, Type, D->getName(), 12997 D->hasAttrs() ? &D->getAttrs() : nullptr, 12998 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12999 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13000 // Build var to save initial value. 13001 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13002 Expr *InitExpr; 13003 DeclRefExpr *Ref = nullptr; 13004 if (!VD && !CurContext->isDependentContext()) { 13005 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13006 if (!isOpenMPCapturedDecl(D)) { 13007 ExprCaptures.push_back(Ref->getDecl()); 13008 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13009 ExprResult RefRes = DefaultLvalueConversion(Ref); 13010 if (!RefRes.isUsable()) 13011 continue; 13012 ExprResult PostUpdateRes = 13013 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13014 SimpleRefExpr, RefRes.get()); 13015 if (!PostUpdateRes.isUsable()) 13016 continue; 13017 ExprPostUpdates.push_back( 13018 IgnoredValueConversions(PostUpdateRes.get()).get()); 13019 } 13020 } 13021 } 13022 if (LinKind == OMPC_LINEAR_uval) 13023 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13024 else 13025 InitExpr = VD ? SimpleRefExpr : Ref; 13026 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13027 /*DirectInit=*/false); 13028 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13029 13030 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13031 Vars.push_back((VD || CurContext->isDependentContext()) 13032 ? RefExpr->IgnoreParens() 13033 : Ref); 13034 Privates.push_back(PrivateRef); 13035 Inits.push_back(InitRef); 13036 } 13037 13038 if (Vars.empty()) 13039 return nullptr; 13040 13041 Expr *StepExpr = Step; 13042 Expr *CalcStepExpr = nullptr; 13043 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13044 !Step->isInstantiationDependent() && 13045 !Step->containsUnexpandedParameterPack()) { 13046 SourceLocation StepLoc = Step->getBeginLoc(); 13047 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13048 if (Val.isInvalid()) 13049 return nullptr; 13050 StepExpr = Val.get(); 13051 13052 // Build var to save the step value. 13053 VarDecl *SaveVar = 13054 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13055 ExprResult SaveRef = 13056 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13057 ExprResult CalcStep = 13058 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13059 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13060 13061 // Warn about zero linear step (it would be probably better specified as 13062 // making corresponding variables 'const'). 13063 llvm::APSInt Result; 13064 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13065 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13066 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13067 << (Vars.size() > 1); 13068 if (!IsConstant && CalcStep.isUsable()) { 13069 // Calculate the step beforehand instead of doing this on each iteration. 13070 // (This is not used if the number of iterations may be kfold-ed). 13071 CalcStepExpr = CalcStep.get(); 13072 } 13073 } 13074 13075 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13076 ColonLoc, EndLoc, Vars, Privates, Inits, 13077 StepExpr, CalcStepExpr, 13078 buildPreInits(Context, ExprCaptures), 13079 buildPostUpdate(*this, ExprPostUpdates)); 13080 } 13081 13082 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13083 Expr *NumIterations, Sema &SemaRef, 13084 Scope *S, DSAStackTy *Stack) { 13085 // Walk the vars and build update/final expressions for the CodeGen. 13086 SmallVector<Expr *, 8> Updates; 13087 SmallVector<Expr *, 8> Finals; 13088 SmallVector<Expr *, 8> UsedExprs; 13089 Expr *Step = Clause.getStep(); 13090 Expr *CalcStep = Clause.getCalcStep(); 13091 // OpenMP [2.14.3.7, linear clause] 13092 // If linear-step is not specified it is assumed to be 1. 13093 if (!Step) 13094 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13095 else if (CalcStep) 13096 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13097 bool HasErrors = false; 13098 auto CurInit = Clause.inits().begin(); 13099 auto CurPrivate = Clause.privates().begin(); 13100 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13101 for (Expr *RefExpr : Clause.varlists()) { 13102 SourceLocation ELoc; 13103 SourceRange ERange; 13104 Expr *SimpleRefExpr = RefExpr; 13105 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13106 ValueDecl *D = Res.first; 13107 if (Res.second || !D) { 13108 Updates.push_back(nullptr); 13109 Finals.push_back(nullptr); 13110 HasErrors = true; 13111 continue; 13112 } 13113 auto &&Info = Stack->isLoopControlVariable(D); 13114 // OpenMP [2.15.11, distribute simd Construct] 13115 // A list item may not appear in a linear clause, unless it is the loop 13116 // iteration variable. 13117 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13118 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13119 SemaRef.Diag(ELoc, 13120 diag::err_omp_linear_distribute_var_non_loop_iteration); 13121 Updates.push_back(nullptr); 13122 Finals.push_back(nullptr); 13123 HasErrors = true; 13124 continue; 13125 } 13126 Expr *InitExpr = *CurInit; 13127 13128 // Build privatized reference to the current linear var. 13129 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13130 Expr *CapturedRef; 13131 if (LinKind == OMPC_LINEAR_uval) 13132 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13133 else 13134 CapturedRef = 13135 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13136 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13137 /*RefersToCapture=*/true); 13138 13139 // Build update: Var = InitExpr + IV * Step 13140 ExprResult Update; 13141 if (!Info.first) 13142 Update = buildCounterUpdate( 13143 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13144 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13145 else 13146 Update = *CurPrivate; 13147 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13148 /*DiscardedValue*/ false); 13149 13150 // Build final: Var = InitExpr + NumIterations * Step 13151 ExprResult Final; 13152 if (!Info.first) 13153 Final = 13154 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13155 InitExpr, NumIterations, Step, /*Subtract=*/false, 13156 /*IsNonRectangularLB=*/false); 13157 else 13158 Final = *CurPrivate; 13159 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13160 /*DiscardedValue*/ false); 13161 13162 if (!Update.isUsable() || !Final.isUsable()) { 13163 Updates.push_back(nullptr); 13164 Finals.push_back(nullptr); 13165 UsedExprs.push_back(nullptr); 13166 HasErrors = true; 13167 } else { 13168 Updates.push_back(Update.get()); 13169 Finals.push_back(Final.get()); 13170 if (!Info.first) 13171 UsedExprs.push_back(SimpleRefExpr); 13172 } 13173 ++CurInit; 13174 ++CurPrivate; 13175 } 13176 if (Expr *S = Clause.getStep()) 13177 UsedExprs.push_back(S); 13178 // Fill the remaining part with the nullptr. 13179 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13180 Clause.setUpdates(Updates); 13181 Clause.setFinals(Finals); 13182 Clause.setUsedExprs(UsedExprs); 13183 return HasErrors; 13184 } 13185 13186 OMPClause *Sema::ActOnOpenMPAlignedClause( 13187 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13188 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13189 SmallVector<Expr *, 8> Vars; 13190 for (Expr *RefExpr : VarList) { 13191 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13192 SourceLocation ELoc; 13193 SourceRange ERange; 13194 Expr *SimpleRefExpr = RefExpr; 13195 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13196 if (Res.second) { 13197 // It will be analyzed later. 13198 Vars.push_back(RefExpr); 13199 } 13200 ValueDecl *D = Res.first; 13201 if (!D) 13202 continue; 13203 13204 QualType QType = D->getType(); 13205 auto *VD = dyn_cast<VarDecl>(D); 13206 13207 // OpenMP [2.8.1, simd construct, Restrictions] 13208 // The type of list items appearing in the aligned clause must be 13209 // array, pointer, reference to array, or reference to pointer. 13210 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13211 const Type *Ty = QType.getTypePtrOrNull(); 13212 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13213 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13214 << QType << getLangOpts().CPlusPlus << ERange; 13215 bool IsDecl = 13216 !VD || 13217 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13218 Diag(D->getLocation(), 13219 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13220 << D; 13221 continue; 13222 } 13223 13224 // OpenMP [2.8.1, simd construct, Restrictions] 13225 // A list-item cannot appear in more than one aligned clause. 13226 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 13227 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 13228 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 13229 << getOpenMPClauseName(OMPC_aligned); 13230 continue; 13231 } 13232 13233 DeclRefExpr *Ref = nullptr; 13234 if (!VD && isOpenMPCapturedDecl(D)) 13235 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13236 Vars.push_back(DefaultFunctionArrayConversion( 13237 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 13238 .get()); 13239 } 13240 13241 // OpenMP [2.8.1, simd construct, Description] 13242 // The parameter of the aligned clause, alignment, must be a constant 13243 // positive integer expression. 13244 // If no optional parameter is specified, implementation-defined default 13245 // alignments for SIMD instructions on the target platforms are assumed. 13246 if (Alignment != nullptr) { 13247 ExprResult AlignResult = 13248 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 13249 if (AlignResult.isInvalid()) 13250 return nullptr; 13251 Alignment = AlignResult.get(); 13252 } 13253 if (Vars.empty()) 13254 return nullptr; 13255 13256 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 13257 EndLoc, Vars, Alignment); 13258 } 13259 13260 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 13261 SourceLocation StartLoc, 13262 SourceLocation LParenLoc, 13263 SourceLocation EndLoc) { 13264 SmallVector<Expr *, 8> Vars; 13265 SmallVector<Expr *, 8> SrcExprs; 13266 SmallVector<Expr *, 8> DstExprs; 13267 SmallVector<Expr *, 8> AssignmentOps; 13268 for (Expr *RefExpr : VarList) { 13269 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 13270 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13271 // It will be analyzed later. 13272 Vars.push_back(RefExpr); 13273 SrcExprs.push_back(nullptr); 13274 DstExprs.push_back(nullptr); 13275 AssignmentOps.push_back(nullptr); 13276 continue; 13277 } 13278 13279 SourceLocation ELoc = RefExpr->getExprLoc(); 13280 // OpenMP [2.1, C/C++] 13281 // A list item is a variable name. 13282 // OpenMP [2.14.4.1, Restrictions, p.1] 13283 // A list item that appears in a copyin clause must be threadprivate. 13284 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 13285 if (!DE || !isa<VarDecl>(DE->getDecl())) { 13286 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 13287 << 0 << RefExpr->getSourceRange(); 13288 continue; 13289 } 13290 13291 Decl *D = DE->getDecl(); 13292 auto *VD = cast<VarDecl>(D); 13293 13294 QualType Type = VD->getType(); 13295 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 13296 // It will be analyzed later. 13297 Vars.push_back(DE); 13298 SrcExprs.push_back(nullptr); 13299 DstExprs.push_back(nullptr); 13300 AssignmentOps.push_back(nullptr); 13301 continue; 13302 } 13303 13304 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 13305 // A list item that appears in a copyin clause must be threadprivate. 13306 if (!DSAStack->isThreadPrivate(VD)) { 13307 Diag(ELoc, diag::err_omp_required_access) 13308 << getOpenMPClauseName(OMPC_copyin) 13309 << getOpenMPDirectiveName(OMPD_threadprivate); 13310 continue; 13311 } 13312 13313 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13314 // A variable of class type (or array thereof) that appears in a 13315 // copyin clause requires an accessible, unambiguous copy assignment 13316 // operator for the class type. 13317 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13318 VarDecl *SrcVD = 13319 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 13320 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13321 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 13322 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 13323 VarDecl *DstVD = 13324 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 13325 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13326 DeclRefExpr *PseudoDstExpr = 13327 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 13328 // For arrays generate assignment operation for single element and replace 13329 // it by the original array element in CodeGen. 13330 ExprResult AssignmentOp = 13331 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 13332 PseudoSrcExpr); 13333 if (AssignmentOp.isInvalid()) 13334 continue; 13335 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 13336 /*DiscardedValue*/ false); 13337 if (AssignmentOp.isInvalid()) 13338 continue; 13339 13340 DSAStack->addDSA(VD, DE, OMPC_copyin); 13341 Vars.push_back(DE); 13342 SrcExprs.push_back(PseudoSrcExpr); 13343 DstExprs.push_back(PseudoDstExpr); 13344 AssignmentOps.push_back(AssignmentOp.get()); 13345 } 13346 13347 if (Vars.empty()) 13348 return nullptr; 13349 13350 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13351 SrcExprs, DstExprs, AssignmentOps); 13352 } 13353 13354 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 13355 SourceLocation StartLoc, 13356 SourceLocation LParenLoc, 13357 SourceLocation EndLoc) { 13358 SmallVector<Expr *, 8> Vars; 13359 SmallVector<Expr *, 8> SrcExprs; 13360 SmallVector<Expr *, 8> DstExprs; 13361 SmallVector<Expr *, 8> AssignmentOps; 13362 for (Expr *RefExpr : VarList) { 13363 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13364 SourceLocation ELoc; 13365 SourceRange ERange; 13366 Expr *SimpleRefExpr = RefExpr; 13367 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13368 if (Res.second) { 13369 // It will be analyzed later. 13370 Vars.push_back(RefExpr); 13371 SrcExprs.push_back(nullptr); 13372 DstExprs.push_back(nullptr); 13373 AssignmentOps.push_back(nullptr); 13374 } 13375 ValueDecl *D = Res.first; 13376 if (!D) 13377 continue; 13378 13379 QualType Type = D->getType(); 13380 auto *VD = dyn_cast<VarDecl>(D); 13381 13382 // OpenMP [2.14.4.2, Restrictions, p.2] 13383 // A list item that appears in a copyprivate clause may not appear in a 13384 // private or firstprivate clause on the single construct. 13385 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13386 DSAStackTy::DSAVarData DVar = 13387 DSAStack->getTopDSA(D, /*FromParent=*/false); 13388 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13389 DVar.RefExpr) { 13390 Diag(ELoc, diag::err_omp_wrong_dsa) 13391 << getOpenMPClauseName(DVar.CKind) 13392 << getOpenMPClauseName(OMPC_copyprivate); 13393 reportOriginalDsa(*this, DSAStack, D, DVar); 13394 continue; 13395 } 13396 13397 // OpenMP [2.11.4.2, Restrictions, p.1] 13398 // All list items that appear in a copyprivate clause must be either 13399 // threadprivate or private in the enclosing context. 13400 if (DVar.CKind == OMPC_unknown) { 13401 DVar = DSAStack->getImplicitDSA(D, false); 13402 if (DVar.CKind == OMPC_shared) { 13403 Diag(ELoc, diag::err_omp_required_access) 13404 << getOpenMPClauseName(OMPC_copyprivate) 13405 << "threadprivate or private in the enclosing context"; 13406 reportOriginalDsa(*this, DSAStack, D, DVar); 13407 continue; 13408 } 13409 } 13410 } 13411 13412 // Variably modified types are not supported. 13413 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13414 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13415 << getOpenMPClauseName(OMPC_copyprivate) << Type 13416 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13417 bool IsDecl = 13418 !VD || 13419 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13420 Diag(D->getLocation(), 13421 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13422 << D; 13423 continue; 13424 } 13425 13426 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13427 // A variable of class type (or array thereof) that appears in a 13428 // copyin clause requires an accessible, unambiguous copy assignment 13429 // operator for the class type. 13430 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13431 .getUnqualifiedType(); 13432 VarDecl *SrcVD = 13433 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13434 D->hasAttrs() ? &D->getAttrs() : nullptr); 13435 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13436 VarDecl *DstVD = 13437 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13438 D->hasAttrs() ? &D->getAttrs() : nullptr); 13439 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13440 ExprResult AssignmentOp = BuildBinOp( 13441 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13442 if (AssignmentOp.isInvalid()) 13443 continue; 13444 AssignmentOp = 13445 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13446 if (AssignmentOp.isInvalid()) 13447 continue; 13448 13449 // No need to mark vars as copyprivate, they are already threadprivate or 13450 // implicitly private. 13451 assert(VD || isOpenMPCapturedDecl(D)); 13452 Vars.push_back( 13453 VD ? RefExpr->IgnoreParens() 13454 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13455 SrcExprs.push_back(PseudoSrcExpr); 13456 DstExprs.push_back(PseudoDstExpr); 13457 AssignmentOps.push_back(AssignmentOp.get()); 13458 } 13459 13460 if (Vars.empty()) 13461 return nullptr; 13462 13463 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13464 Vars, SrcExprs, DstExprs, AssignmentOps); 13465 } 13466 13467 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13468 SourceLocation StartLoc, 13469 SourceLocation LParenLoc, 13470 SourceLocation EndLoc) { 13471 if (VarList.empty()) 13472 return nullptr; 13473 13474 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13475 } 13476 13477 OMPClause * 13478 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13479 SourceLocation DepLoc, SourceLocation ColonLoc, 13480 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13481 SourceLocation LParenLoc, SourceLocation EndLoc) { 13482 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13483 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13484 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13485 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13486 return nullptr; 13487 } 13488 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13489 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13490 DepKind == OMPC_DEPEND_sink)) { 13491 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13492 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13493 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13494 /*Last=*/OMPC_DEPEND_unknown, Except) 13495 << getOpenMPClauseName(OMPC_depend); 13496 return nullptr; 13497 } 13498 SmallVector<Expr *, 8> Vars; 13499 DSAStackTy::OperatorOffsetTy OpsOffs; 13500 llvm::APSInt DepCounter(/*BitWidth=*/32); 13501 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13502 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13503 if (const Expr *OrderedCountExpr = 13504 DSAStack->getParentOrderedRegionParam().first) { 13505 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13506 TotalDepCount.setIsUnsigned(/*Val=*/true); 13507 } 13508 } 13509 for (Expr *RefExpr : VarList) { 13510 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13511 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13512 // It will be analyzed later. 13513 Vars.push_back(RefExpr); 13514 continue; 13515 } 13516 13517 SourceLocation ELoc = RefExpr->getExprLoc(); 13518 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13519 if (DepKind == OMPC_DEPEND_sink) { 13520 if (DSAStack->getParentOrderedRegionParam().first && 13521 DepCounter >= TotalDepCount) { 13522 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13523 continue; 13524 } 13525 ++DepCounter; 13526 // OpenMP [2.13.9, Summary] 13527 // depend(dependence-type : vec), where dependence-type is: 13528 // 'sink' and where vec is the iteration vector, which has the form: 13529 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13530 // where n is the value specified by the ordered clause in the loop 13531 // directive, xi denotes the loop iteration variable of the i-th nested 13532 // loop associated with the loop directive, and di is a constant 13533 // non-negative integer. 13534 if (CurContext->isDependentContext()) { 13535 // It will be analyzed later. 13536 Vars.push_back(RefExpr); 13537 continue; 13538 } 13539 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13540 OverloadedOperatorKind OOK = OO_None; 13541 SourceLocation OOLoc; 13542 Expr *LHS = SimpleExpr; 13543 Expr *RHS = nullptr; 13544 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13545 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13546 OOLoc = BO->getOperatorLoc(); 13547 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13548 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13549 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13550 OOK = OCE->getOperator(); 13551 OOLoc = OCE->getOperatorLoc(); 13552 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13553 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13554 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13555 OOK = MCE->getMethodDecl() 13556 ->getNameInfo() 13557 .getName() 13558 .getCXXOverloadedOperator(); 13559 OOLoc = MCE->getCallee()->getExprLoc(); 13560 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13561 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13562 } 13563 SourceLocation ELoc; 13564 SourceRange ERange; 13565 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13566 if (Res.second) { 13567 // It will be analyzed later. 13568 Vars.push_back(RefExpr); 13569 } 13570 ValueDecl *D = Res.first; 13571 if (!D) 13572 continue; 13573 13574 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13575 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13576 continue; 13577 } 13578 if (RHS) { 13579 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13580 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13581 if (RHSRes.isInvalid()) 13582 continue; 13583 } 13584 if (!CurContext->isDependentContext() && 13585 DSAStack->getParentOrderedRegionParam().first && 13586 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13587 const ValueDecl *VD = 13588 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13589 if (VD) 13590 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13591 << 1 << VD; 13592 else 13593 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13594 continue; 13595 } 13596 OpsOffs.emplace_back(RHS, OOK); 13597 } else { 13598 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13599 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13600 (ASE && 13601 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13602 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13603 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13604 << RefExpr->getSourceRange(); 13605 continue; 13606 } 13607 13608 ExprResult Res; 13609 { 13610 Sema::TentativeAnalysisScope Trap(*this); 13611 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 13612 RefExpr->IgnoreParenImpCasts()); 13613 } 13614 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13615 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13616 << RefExpr->getSourceRange(); 13617 continue; 13618 } 13619 } 13620 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13621 } 13622 13623 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13624 TotalDepCount > VarList.size() && 13625 DSAStack->getParentOrderedRegionParam().first && 13626 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13627 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13628 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13629 } 13630 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13631 Vars.empty()) 13632 return nullptr; 13633 13634 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13635 DepKind, DepLoc, ColonLoc, Vars, 13636 TotalDepCount.getZExtValue()); 13637 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13638 DSAStack->isParentOrderedRegion()) 13639 DSAStack->addDoacrossDependClause(C, OpsOffs); 13640 return C; 13641 } 13642 13643 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13644 SourceLocation LParenLoc, 13645 SourceLocation EndLoc) { 13646 Expr *ValExpr = Device; 13647 Stmt *HelperValStmt = nullptr; 13648 13649 // OpenMP [2.9.1, Restrictions] 13650 // The device expression must evaluate to a non-negative integer value. 13651 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13652 /*StrictlyPositive=*/false)) 13653 return nullptr; 13654 13655 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13656 OpenMPDirectiveKind CaptureRegion = 13657 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13658 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13659 ValExpr = MakeFullExpr(ValExpr).get(); 13660 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13661 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13662 HelperValStmt = buildPreInits(Context, Captures); 13663 } 13664 13665 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13666 StartLoc, LParenLoc, EndLoc); 13667 } 13668 13669 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13670 DSAStackTy *Stack, QualType QTy, 13671 bool FullCheck = true) { 13672 NamedDecl *ND; 13673 if (QTy->isIncompleteType(&ND)) { 13674 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13675 return false; 13676 } 13677 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13678 !QTy.isTrivialType(SemaRef.Context)) 13679 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13680 return true; 13681 } 13682 13683 /// Return true if it can be proven that the provided array expression 13684 /// (array section or array subscript) does NOT specify the whole size of the 13685 /// array whose base type is \a BaseQTy. 13686 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13687 const Expr *E, 13688 QualType BaseQTy) { 13689 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13690 13691 // If this is an array subscript, it refers to the whole size if the size of 13692 // the dimension is constant and equals 1. Also, an array section assumes the 13693 // format of an array subscript if no colon is used. 13694 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13695 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13696 return ATy->getSize().getSExtValue() != 1; 13697 // Size can't be evaluated statically. 13698 return false; 13699 } 13700 13701 assert(OASE && "Expecting array section if not an array subscript."); 13702 const Expr *LowerBound = OASE->getLowerBound(); 13703 const Expr *Length = OASE->getLength(); 13704 13705 // If there is a lower bound that does not evaluates to zero, we are not 13706 // covering the whole dimension. 13707 if (LowerBound) { 13708 Expr::EvalResult Result; 13709 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13710 return false; // Can't get the integer value as a constant. 13711 13712 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13713 if (ConstLowerBound.getSExtValue()) 13714 return true; 13715 } 13716 13717 // If we don't have a length we covering the whole dimension. 13718 if (!Length) 13719 return false; 13720 13721 // If the base is a pointer, we don't have a way to get the size of the 13722 // pointee. 13723 if (BaseQTy->isPointerType()) 13724 return false; 13725 13726 // We can only check if the length is the same as the size of the dimension 13727 // if we have a constant array. 13728 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13729 if (!CATy) 13730 return false; 13731 13732 Expr::EvalResult Result; 13733 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13734 return false; // Can't get the integer value as a constant. 13735 13736 llvm::APSInt ConstLength = Result.Val.getInt(); 13737 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13738 } 13739 13740 // Return true if it can be proven that the provided array expression (array 13741 // section or array subscript) does NOT specify a single element of the array 13742 // whose base type is \a BaseQTy. 13743 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13744 const Expr *E, 13745 QualType BaseQTy) { 13746 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13747 13748 // An array subscript always refer to a single element. Also, an array section 13749 // assumes the format of an array subscript if no colon is used. 13750 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13751 return false; 13752 13753 assert(OASE && "Expecting array section if not an array subscript."); 13754 const Expr *Length = OASE->getLength(); 13755 13756 // If we don't have a length we have to check if the array has unitary size 13757 // for this dimension. Also, we should always expect a length if the base type 13758 // is pointer. 13759 if (!Length) { 13760 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13761 return ATy->getSize().getSExtValue() != 1; 13762 // We cannot assume anything. 13763 return false; 13764 } 13765 13766 // Check if the length evaluates to 1. 13767 Expr::EvalResult Result; 13768 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13769 return false; // Can't get the integer value as a constant. 13770 13771 llvm::APSInt ConstLength = Result.Val.getInt(); 13772 return ConstLength.getSExtValue() != 1; 13773 } 13774 13775 // Return the expression of the base of the mappable expression or null if it 13776 // cannot be determined and do all the necessary checks to see if the expression 13777 // is valid as a standalone mappable expression. In the process, record all the 13778 // components of the expression. 13779 static const Expr *checkMapClauseExpressionBase( 13780 Sema &SemaRef, Expr *E, 13781 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13782 OpenMPClauseKind CKind, bool NoDiagnose) { 13783 SourceLocation ELoc = E->getExprLoc(); 13784 SourceRange ERange = E->getSourceRange(); 13785 13786 // The base of elements of list in a map clause have to be either: 13787 // - a reference to variable or field. 13788 // - a member expression. 13789 // - an array expression. 13790 // 13791 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 13792 // reference to 'r'. 13793 // 13794 // If we have: 13795 // 13796 // struct SS { 13797 // Bla S; 13798 // foo() { 13799 // #pragma omp target map (S.Arr[:12]); 13800 // } 13801 // } 13802 // 13803 // We want to retrieve the member expression 'this->S'; 13804 13805 const Expr *RelevantExpr = nullptr; 13806 13807 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 13808 // If a list item is an array section, it must specify contiguous storage. 13809 // 13810 // For this restriction it is sufficient that we make sure only references 13811 // to variables or fields and array expressions, and that no array sections 13812 // exist except in the rightmost expression (unless they cover the whole 13813 // dimension of the array). E.g. these would be invalid: 13814 // 13815 // r.ArrS[3:5].Arr[6:7] 13816 // 13817 // r.ArrS[3:5].x 13818 // 13819 // but these would be valid: 13820 // r.ArrS[3].Arr[6:7] 13821 // 13822 // r.ArrS[3].x 13823 13824 bool AllowUnitySizeArraySection = true; 13825 bool AllowWholeSizeArraySection = true; 13826 13827 while (!RelevantExpr) { 13828 E = E->IgnoreParenImpCasts(); 13829 13830 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 13831 if (!isa<VarDecl>(CurE->getDecl())) 13832 return nullptr; 13833 13834 RelevantExpr = CurE; 13835 13836 // If we got a reference to a declaration, we should not expect any array 13837 // section before that. 13838 AllowUnitySizeArraySection = false; 13839 AllowWholeSizeArraySection = false; 13840 13841 // Record the component. 13842 CurComponents.emplace_back(CurE, CurE->getDecl()); 13843 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 13844 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 13845 13846 if (isa<CXXThisExpr>(BaseE)) 13847 // We found a base expression: this->Val. 13848 RelevantExpr = CurE; 13849 else 13850 E = BaseE; 13851 13852 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 13853 if (!NoDiagnose) { 13854 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 13855 << CurE->getSourceRange(); 13856 return nullptr; 13857 } 13858 if (RelevantExpr) 13859 return nullptr; 13860 continue; 13861 } 13862 13863 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 13864 13865 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 13866 // A bit-field cannot appear in a map clause. 13867 // 13868 if (FD->isBitField()) { 13869 if (!NoDiagnose) { 13870 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 13871 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 13872 return nullptr; 13873 } 13874 if (RelevantExpr) 13875 return nullptr; 13876 continue; 13877 } 13878 13879 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13880 // If the type of a list item is a reference to a type T then the type 13881 // will be considered to be T for all purposes of this clause. 13882 QualType CurType = BaseE->getType().getNonReferenceType(); 13883 13884 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 13885 // A list item cannot be a variable that is a member of a structure with 13886 // a union type. 13887 // 13888 if (CurType->isUnionType()) { 13889 if (!NoDiagnose) { 13890 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 13891 << CurE->getSourceRange(); 13892 return nullptr; 13893 } 13894 continue; 13895 } 13896 13897 // If we got a member expression, we should not expect any array section 13898 // before that: 13899 // 13900 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 13901 // If a list item is an element of a structure, only the rightmost symbol 13902 // of the variable reference can be an array section. 13903 // 13904 AllowUnitySizeArraySection = false; 13905 AllowWholeSizeArraySection = false; 13906 13907 // Record the component. 13908 CurComponents.emplace_back(CurE, FD); 13909 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 13910 E = CurE->getBase()->IgnoreParenImpCasts(); 13911 13912 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 13913 if (!NoDiagnose) { 13914 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13915 << 0 << CurE->getSourceRange(); 13916 return nullptr; 13917 } 13918 continue; 13919 } 13920 13921 // If we got an array subscript that express the whole dimension we 13922 // can have any array expressions before. If it only expressing part of 13923 // the dimension, we can only have unitary-size array expressions. 13924 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 13925 E->getType())) 13926 AllowWholeSizeArraySection = false; 13927 13928 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13929 Expr::EvalResult Result; 13930 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13931 if (!Result.Val.getInt().isNullValue()) { 13932 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13933 diag::err_omp_invalid_map_this_expr); 13934 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13935 diag::note_omp_invalid_subscript_on_this_ptr_map); 13936 } 13937 } 13938 RelevantExpr = TE; 13939 } 13940 13941 // Record the component - we don't have any declaration associated. 13942 CurComponents.emplace_back(CurE, nullptr); 13943 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13944 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13945 E = CurE->getBase()->IgnoreParenImpCasts(); 13946 13947 QualType CurType = 13948 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13949 13950 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13951 // If the type of a list item is a reference to a type T then the type 13952 // will be considered to be T for all purposes of this clause. 13953 if (CurType->isReferenceType()) 13954 CurType = CurType->getPointeeType(); 13955 13956 bool IsPointer = CurType->isAnyPointerType(); 13957 13958 if (!IsPointer && !CurType->isArrayType()) { 13959 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13960 << 0 << CurE->getSourceRange(); 13961 return nullptr; 13962 } 13963 13964 bool NotWhole = 13965 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13966 bool NotUnity = 13967 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13968 13969 if (AllowWholeSizeArraySection) { 13970 // Any array section is currently allowed. Allowing a whole size array 13971 // section implies allowing a unity array section as well. 13972 // 13973 // If this array section refers to the whole dimension we can still 13974 // accept other array sections before this one, except if the base is a 13975 // pointer. Otherwise, only unitary sections are accepted. 13976 if (NotWhole || IsPointer) 13977 AllowWholeSizeArraySection = false; 13978 } else if (AllowUnitySizeArraySection && NotUnity) { 13979 // A unity or whole array section is not allowed and that is not 13980 // compatible with the properties of the current array section. 13981 SemaRef.Diag( 13982 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13983 << CurE->getSourceRange(); 13984 return nullptr; 13985 } 13986 13987 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13988 Expr::EvalResult ResultR; 13989 Expr::EvalResult ResultL; 13990 if (CurE->getLength()->EvaluateAsInt(ResultR, 13991 SemaRef.getASTContext())) { 13992 if (!ResultR.Val.getInt().isOneValue()) { 13993 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13994 diag::err_omp_invalid_map_this_expr); 13995 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13996 diag::note_omp_invalid_length_on_this_ptr_mapping); 13997 } 13998 } 13999 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14000 ResultL, SemaRef.getASTContext())) { 14001 if (!ResultL.Val.getInt().isNullValue()) { 14002 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14003 diag::err_omp_invalid_map_this_expr); 14004 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14005 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14006 } 14007 } 14008 RelevantExpr = TE; 14009 } 14010 14011 // Record the component - we don't have any declaration associated. 14012 CurComponents.emplace_back(CurE, nullptr); 14013 } else { 14014 if (!NoDiagnose) { 14015 // If nothing else worked, this is not a valid map clause expression. 14016 SemaRef.Diag( 14017 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14018 << ERange; 14019 } 14020 return nullptr; 14021 } 14022 } 14023 14024 return RelevantExpr; 14025 } 14026 14027 // Return true if expression E associated with value VD has conflicts with other 14028 // map information. 14029 static bool checkMapConflicts( 14030 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14031 bool CurrentRegionOnly, 14032 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14033 OpenMPClauseKind CKind) { 14034 assert(VD && E); 14035 SourceLocation ELoc = E->getExprLoc(); 14036 SourceRange ERange = E->getSourceRange(); 14037 14038 // In order to easily check the conflicts we need to match each component of 14039 // the expression under test with the components of the expressions that are 14040 // already in the stack. 14041 14042 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14043 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14044 "Map clause expression with unexpected base!"); 14045 14046 // Variables to help detecting enclosing problems in data environment nests. 14047 bool IsEnclosedByDataEnvironmentExpr = false; 14048 const Expr *EnclosingExpr = nullptr; 14049 14050 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14051 VD, CurrentRegionOnly, 14052 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14053 ERange, CKind, &EnclosingExpr, 14054 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14055 StackComponents, 14056 OpenMPClauseKind) { 14057 assert(!StackComponents.empty() && 14058 "Map clause expression with no components!"); 14059 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14060 "Map clause expression with unexpected base!"); 14061 (void)VD; 14062 14063 // The whole expression in the stack. 14064 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14065 14066 // Expressions must start from the same base. Here we detect at which 14067 // point both expressions diverge from each other and see if we can 14068 // detect if the memory referred to both expressions is contiguous and 14069 // do not overlap. 14070 auto CI = CurComponents.rbegin(); 14071 auto CE = CurComponents.rend(); 14072 auto SI = StackComponents.rbegin(); 14073 auto SE = StackComponents.rend(); 14074 for (; CI != CE && SI != SE; ++CI, ++SI) { 14075 14076 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14077 // At most one list item can be an array item derived from a given 14078 // variable in map clauses of the same construct. 14079 if (CurrentRegionOnly && 14080 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14081 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14082 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14083 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14084 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14085 diag::err_omp_multiple_array_items_in_map_clause) 14086 << CI->getAssociatedExpression()->getSourceRange(); 14087 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14088 diag::note_used_here) 14089 << SI->getAssociatedExpression()->getSourceRange(); 14090 return true; 14091 } 14092 14093 // Do both expressions have the same kind? 14094 if (CI->getAssociatedExpression()->getStmtClass() != 14095 SI->getAssociatedExpression()->getStmtClass()) 14096 break; 14097 14098 // Are we dealing with different variables/fields? 14099 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14100 break; 14101 } 14102 // Check if the extra components of the expressions in the enclosing 14103 // data environment are redundant for the current base declaration. 14104 // If they are, the maps completely overlap, which is legal. 14105 for (; SI != SE; ++SI) { 14106 QualType Type; 14107 if (const auto *ASE = 14108 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14109 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14110 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14111 SI->getAssociatedExpression())) { 14112 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14113 Type = 14114 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14115 } 14116 if (Type.isNull() || Type->isAnyPointerType() || 14117 checkArrayExpressionDoesNotReferToWholeSize( 14118 SemaRef, SI->getAssociatedExpression(), Type)) 14119 break; 14120 } 14121 14122 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14123 // List items of map clauses in the same construct must not share 14124 // original storage. 14125 // 14126 // If the expressions are exactly the same or one is a subset of the 14127 // other, it means they are sharing storage. 14128 if (CI == CE && SI == SE) { 14129 if (CurrentRegionOnly) { 14130 if (CKind == OMPC_map) { 14131 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14132 } else { 14133 assert(CKind == OMPC_to || CKind == OMPC_from); 14134 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14135 << ERange; 14136 } 14137 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14138 << RE->getSourceRange(); 14139 return true; 14140 } 14141 // If we find the same expression in the enclosing data environment, 14142 // that is legal. 14143 IsEnclosedByDataEnvironmentExpr = true; 14144 return false; 14145 } 14146 14147 QualType DerivedType = 14148 std::prev(CI)->getAssociatedDeclaration()->getType(); 14149 SourceLocation DerivedLoc = 14150 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14151 14152 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14153 // If the type of a list item is a reference to a type T then the type 14154 // will be considered to be T for all purposes of this clause. 14155 DerivedType = DerivedType.getNonReferenceType(); 14156 14157 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14158 // A variable for which the type is pointer and an array section 14159 // derived from that variable must not appear as list items of map 14160 // clauses of the same construct. 14161 // 14162 // Also, cover one of the cases in: 14163 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14164 // If any part of the original storage of a list item has corresponding 14165 // storage in the device data environment, all of the original storage 14166 // must have corresponding storage in the device data environment. 14167 // 14168 if (DerivedType->isAnyPointerType()) { 14169 if (CI == CE || SI == SE) { 14170 SemaRef.Diag( 14171 DerivedLoc, 14172 diag::err_omp_pointer_mapped_along_with_derived_section) 14173 << DerivedLoc; 14174 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14175 << RE->getSourceRange(); 14176 return true; 14177 } 14178 if (CI->getAssociatedExpression()->getStmtClass() != 14179 SI->getAssociatedExpression()->getStmtClass() || 14180 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14181 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14182 assert(CI != CE && SI != SE); 14183 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14184 << DerivedLoc; 14185 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14186 << RE->getSourceRange(); 14187 return true; 14188 } 14189 } 14190 14191 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14192 // List items of map clauses in the same construct must not share 14193 // original storage. 14194 // 14195 // An expression is a subset of the other. 14196 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14197 if (CKind == OMPC_map) { 14198 if (CI != CE || SI != SE) { 14199 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14200 // a pointer. 14201 auto Begin = 14202 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14203 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14204 auto It = Begin; 14205 while (It != End && !It->getAssociatedDeclaration()) 14206 std::advance(It, 1); 14207 assert(It != End && 14208 "Expected at least one component with the declaration."); 14209 if (It != Begin && It->getAssociatedDeclaration() 14210 ->getType() 14211 .getCanonicalType() 14212 ->isAnyPointerType()) { 14213 IsEnclosedByDataEnvironmentExpr = false; 14214 EnclosingExpr = nullptr; 14215 return false; 14216 } 14217 } 14218 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14219 } else { 14220 assert(CKind == OMPC_to || CKind == OMPC_from); 14221 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14222 << ERange; 14223 } 14224 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14225 << RE->getSourceRange(); 14226 return true; 14227 } 14228 14229 // The current expression uses the same base as other expression in the 14230 // data environment but does not contain it completely. 14231 if (!CurrentRegionOnly && SI != SE) 14232 EnclosingExpr = RE; 14233 14234 // The current expression is a subset of the expression in the data 14235 // environment. 14236 IsEnclosedByDataEnvironmentExpr |= 14237 (!CurrentRegionOnly && CI != CE && SI == SE); 14238 14239 return false; 14240 }); 14241 14242 if (CurrentRegionOnly) 14243 return FoundError; 14244 14245 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14246 // If any part of the original storage of a list item has corresponding 14247 // storage in the device data environment, all of the original storage must 14248 // have corresponding storage in the device data environment. 14249 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 14250 // If a list item is an element of a structure, and a different element of 14251 // the structure has a corresponding list item in the device data environment 14252 // prior to a task encountering the construct associated with the map clause, 14253 // then the list item must also have a corresponding list item in the device 14254 // data environment prior to the task encountering the construct. 14255 // 14256 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 14257 SemaRef.Diag(ELoc, 14258 diag::err_omp_original_storage_is_shared_and_does_not_contain) 14259 << ERange; 14260 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 14261 << EnclosingExpr->getSourceRange(); 14262 return true; 14263 } 14264 14265 return FoundError; 14266 } 14267 14268 // Look up the user-defined mapper given the mapper name and mapped type, and 14269 // build a reference to it. 14270 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 14271 CXXScopeSpec &MapperIdScopeSpec, 14272 const DeclarationNameInfo &MapperId, 14273 QualType Type, 14274 Expr *UnresolvedMapper) { 14275 if (MapperIdScopeSpec.isInvalid()) 14276 return ExprError(); 14277 // Find all user-defined mappers with the given MapperId. 14278 SmallVector<UnresolvedSet<8>, 4> Lookups; 14279 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 14280 Lookup.suppressDiagnostics(); 14281 if (S) { 14282 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 14283 NamedDecl *D = Lookup.getRepresentativeDecl(); 14284 while (S && !S->isDeclScope(D)) 14285 S = S->getParent(); 14286 if (S) 14287 S = S->getParent(); 14288 Lookups.emplace_back(); 14289 Lookups.back().append(Lookup.begin(), Lookup.end()); 14290 Lookup.clear(); 14291 } 14292 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 14293 // Extract the user-defined mappers with the given MapperId. 14294 Lookups.push_back(UnresolvedSet<8>()); 14295 for (NamedDecl *D : ULE->decls()) { 14296 auto *DMD = cast<OMPDeclareMapperDecl>(D); 14297 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 14298 Lookups.back().addDecl(DMD); 14299 } 14300 } 14301 // Defer the lookup for dependent types. The results will be passed through 14302 // UnresolvedMapper on instantiation. 14303 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 14304 Type->isInstantiationDependentType() || 14305 Type->containsUnexpandedParameterPack() || 14306 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14307 return !D->isInvalidDecl() && 14308 (D->getType()->isDependentType() || 14309 D->getType()->isInstantiationDependentType() || 14310 D->getType()->containsUnexpandedParameterPack()); 14311 })) { 14312 UnresolvedSet<8> URS; 14313 for (const UnresolvedSet<8> &Set : Lookups) { 14314 if (Set.empty()) 14315 continue; 14316 URS.append(Set.begin(), Set.end()); 14317 } 14318 return UnresolvedLookupExpr::Create( 14319 SemaRef.Context, /*NamingClass=*/nullptr, 14320 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 14321 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 14322 } 14323 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14324 // The type must be of struct, union or class type in C and C++ 14325 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 14326 return ExprEmpty(); 14327 SourceLocation Loc = MapperId.getLoc(); 14328 // Perform argument dependent lookup. 14329 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 14330 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 14331 // Return the first user-defined mapper with the desired type. 14332 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14333 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 14334 if (!D->isInvalidDecl() && 14335 SemaRef.Context.hasSameType(D->getType(), Type)) 14336 return D; 14337 return nullptr; 14338 })) 14339 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14340 // Find the first user-defined mapper with a type derived from the desired 14341 // type. 14342 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14343 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 14344 if (!D->isInvalidDecl() && 14345 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 14346 !Type.isMoreQualifiedThan(D->getType())) 14347 return D; 14348 return nullptr; 14349 })) { 14350 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14351 /*DetectVirtual=*/false); 14352 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 14353 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14354 VD->getType().getUnqualifiedType()))) { 14355 if (SemaRef.CheckBaseClassAccess( 14356 Loc, VD->getType(), Type, Paths.front(), 14357 /*DiagID=*/0) != Sema::AR_inaccessible) { 14358 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14359 } 14360 } 14361 } 14362 } 14363 // Report error if a mapper is specified, but cannot be found. 14364 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 14365 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 14366 << Type << MapperId.getName(); 14367 return ExprError(); 14368 } 14369 return ExprEmpty(); 14370 } 14371 14372 namespace { 14373 // Utility struct that gathers all the related lists associated with a mappable 14374 // expression. 14375 struct MappableVarListInfo { 14376 // The list of expressions. 14377 ArrayRef<Expr *> VarList; 14378 // The list of processed expressions. 14379 SmallVector<Expr *, 16> ProcessedVarList; 14380 // The mappble components for each expression. 14381 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14382 // The base declaration of the variable. 14383 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14384 // The reference to the user-defined mapper associated with every expression. 14385 SmallVector<Expr *, 16> UDMapperList; 14386 14387 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14388 // We have a list of components and base declarations for each entry in the 14389 // variable list. 14390 VarComponents.reserve(VarList.size()); 14391 VarBaseDeclarations.reserve(VarList.size()); 14392 } 14393 }; 14394 } 14395 14396 // Check the validity of the provided variable list for the provided clause kind 14397 // \a CKind. In the check process the valid expressions, mappable expression 14398 // components, variables, and user-defined mappers are extracted and used to 14399 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14400 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14401 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14402 static void checkMappableExpressionList( 14403 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14404 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14405 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14406 ArrayRef<Expr *> UnresolvedMappers, 14407 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14408 bool IsMapTypeImplicit = false) { 14409 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14410 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14411 "Unexpected clause kind with mappable expressions!"); 14412 14413 // If the identifier of user-defined mapper is not specified, it is "default". 14414 // We do not change the actual name in this clause to distinguish whether a 14415 // mapper is specified explicitly, i.e., it is not explicitly specified when 14416 // MapperId.getName() is empty. 14417 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14418 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14419 MapperId.setName(DeclNames.getIdentifier( 14420 &SemaRef.getASTContext().Idents.get("default"))); 14421 } 14422 14423 // Iterators to find the current unresolved mapper expression. 14424 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14425 bool UpdateUMIt = false; 14426 Expr *UnresolvedMapper = nullptr; 14427 14428 // Keep track of the mappable components and base declarations in this clause. 14429 // Each entry in the list is going to have a list of components associated. We 14430 // record each set of the components so that we can build the clause later on. 14431 // In the end we should have the same amount of declarations and component 14432 // lists. 14433 14434 for (Expr *RE : MVLI.VarList) { 14435 assert(RE && "Null expr in omp to/from/map clause"); 14436 SourceLocation ELoc = RE->getExprLoc(); 14437 14438 // Find the current unresolved mapper expression. 14439 if (UpdateUMIt && UMIt != UMEnd) { 14440 UMIt++; 14441 assert( 14442 UMIt != UMEnd && 14443 "Expect the size of UnresolvedMappers to match with that of VarList"); 14444 } 14445 UpdateUMIt = true; 14446 if (UMIt != UMEnd) 14447 UnresolvedMapper = *UMIt; 14448 14449 const Expr *VE = RE->IgnoreParenLValueCasts(); 14450 14451 if (VE->isValueDependent() || VE->isTypeDependent() || 14452 VE->isInstantiationDependent() || 14453 VE->containsUnexpandedParameterPack()) { 14454 // Try to find the associated user-defined mapper. 14455 ExprResult ER = buildUserDefinedMapperRef( 14456 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14457 VE->getType().getCanonicalType(), UnresolvedMapper); 14458 if (ER.isInvalid()) 14459 continue; 14460 MVLI.UDMapperList.push_back(ER.get()); 14461 // We can only analyze this information once the missing information is 14462 // resolved. 14463 MVLI.ProcessedVarList.push_back(RE); 14464 continue; 14465 } 14466 14467 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14468 14469 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14470 SemaRef.Diag(ELoc, 14471 diag::err_omp_expected_named_var_member_or_array_expression) 14472 << RE->getSourceRange(); 14473 continue; 14474 } 14475 14476 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14477 ValueDecl *CurDeclaration = nullptr; 14478 14479 // Obtain the array or member expression bases if required. Also, fill the 14480 // components array with all the components identified in the process. 14481 const Expr *BE = checkMapClauseExpressionBase( 14482 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14483 if (!BE) 14484 continue; 14485 14486 assert(!CurComponents.empty() && 14487 "Invalid mappable expression information."); 14488 14489 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14490 // Add store "this" pointer to class in DSAStackTy for future checking 14491 DSAS->addMappedClassesQualTypes(TE->getType()); 14492 // Try to find the associated user-defined mapper. 14493 ExprResult ER = buildUserDefinedMapperRef( 14494 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14495 VE->getType().getCanonicalType(), UnresolvedMapper); 14496 if (ER.isInvalid()) 14497 continue; 14498 MVLI.UDMapperList.push_back(ER.get()); 14499 // Skip restriction checking for variable or field declarations 14500 MVLI.ProcessedVarList.push_back(RE); 14501 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14502 MVLI.VarComponents.back().append(CurComponents.begin(), 14503 CurComponents.end()); 14504 MVLI.VarBaseDeclarations.push_back(nullptr); 14505 continue; 14506 } 14507 14508 // For the following checks, we rely on the base declaration which is 14509 // expected to be associated with the last component. The declaration is 14510 // expected to be a variable or a field (if 'this' is being mapped). 14511 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14512 assert(CurDeclaration && "Null decl on map clause."); 14513 assert( 14514 CurDeclaration->isCanonicalDecl() && 14515 "Expecting components to have associated only canonical declarations."); 14516 14517 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14518 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14519 14520 assert((VD || FD) && "Only variables or fields are expected here!"); 14521 (void)FD; 14522 14523 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14524 // threadprivate variables cannot appear in a map clause. 14525 // OpenMP 4.5 [2.10.5, target update Construct] 14526 // threadprivate variables cannot appear in a from clause. 14527 if (VD && DSAS->isThreadPrivate(VD)) { 14528 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14529 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14530 << getOpenMPClauseName(CKind); 14531 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14532 continue; 14533 } 14534 14535 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14536 // A list item cannot appear in both a map clause and a data-sharing 14537 // attribute clause on the same construct. 14538 14539 // Check conflicts with other map clause expressions. We check the conflicts 14540 // with the current construct separately from the enclosing data 14541 // environment, because the restrictions are different. We only have to 14542 // check conflicts across regions for the map clauses. 14543 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14544 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14545 break; 14546 if (CKind == OMPC_map && 14547 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14548 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14549 break; 14550 14551 // OpenMP 4.5 [2.10.5, target update Construct] 14552 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14553 // If the type of a list item is a reference to a type T then the type will 14554 // be considered to be T for all purposes of this clause. 14555 auto I = llvm::find_if( 14556 CurComponents, 14557 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14558 return MC.getAssociatedDeclaration(); 14559 }); 14560 assert(I != CurComponents.end() && "Null decl on map clause."); 14561 QualType Type = 14562 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14563 14564 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14565 // A list item in a to or from clause must have a mappable type. 14566 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14567 // A list item must have a mappable type. 14568 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14569 DSAS, Type)) 14570 continue; 14571 14572 if (CKind == OMPC_map) { 14573 // target enter data 14574 // OpenMP [2.10.2, Restrictions, p. 99] 14575 // A map-type must be specified in all map clauses and must be either 14576 // to or alloc. 14577 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14578 if (DKind == OMPD_target_enter_data && 14579 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14580 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14581 << (IsMapTypeImplicit ? 1 : 0) 14582 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14583 << getOpenMPDirectiveName(DKind); 14584 continue; 14585 } 14586 14587 // target exit_data 14588 // OpenMP [2.10.3, Restrictions, p. 102] 14589 // A map-type must be specified in all map clauses and must be either 14590 // from, release, or delete. 14591 if (DKind == OMPD_target_exit_data && 14592 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14593 MapType == OMPC_MAP_delete)) { 14594 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14595 << (IsMapTypeImplicit ? 1 : 0) 14596 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14597 << getOpenMPDirectiveName(DKind); 14598 continue; 14599 } 14600 14601 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14602 // A list item cannot appear in both a map clause and a data-sharing 14603 // attribute clause on the same construct 14604 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 14605 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14606 if (isOpenMPPrivate(DVar.CKind)) { 14607 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14608 << getOpenMPClauseName(DVar.CKind) 14609 << getOpenMPClauseName(OMPC_map) 14610 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14611 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14612 continue; 14613 } 14614 } 14615 } 14616 14617 // Try to find the associated user-defined mapper. 14618 ExprResult ER = buildUserDefinedMapperRef( 14619 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14620 Type.getCanonicalType(), UnresolvedMapper); 14621 if (ER.isInvalid()) 14622 continue; 14623 MVLI.UDMapperList.push_back(ER.get()); 14624 14625 // Save the current expression. 14626 MVLI.ProcessedVarList.push_back(RE); 14627 14628 // Store the components in the stack so that they can be used to check 14629 // against other clauses later on. 14630 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14631 /*WhereFoundClauseKind=*/OMPC_map); 14632 14633 // Save the components and declaration to create the clause. For purposes of 14634 // the clause creation, any component list that has has base 'this' uses 14635 // null as base declaration. 14636 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14637 MVLI.VarComponents.back().append(CurComponents.begin(), 14638 CurComponents.end()); 14639 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14640 : CurDeclaration); 14641 } 14642 } 14643 14644 OMPClause *Sema::ActOnOpenMPMapClause( 14645 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14646 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14647 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14648 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14649 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14650 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14651 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14652 OMPC_MAP_MODIFIER_unknown, 14653 OMPC_MAP_MODIFIER_unknown}; 14654 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14655 14656 // Process map-type-modifiers, flag errors for duplicate modifiers. 14657 unsigned Count = 0; 14658 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14659 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14660 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14661 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14662 continue; 14663 } 14664 assert(Count < OMPMapClause::NumberOfModifiers && 14665 "Modifiers exceed the allowed number of map type modifiers"); 14666 Modifiers[Count] = MapTypeModifiers[I]; 14667 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14668 ++Count; 14669 } 14670 14671 MappableVarListInfo MVLI(VarList); 14672 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14673 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14674 MapType, IsMapTypeImplicit); 14675 14676 // We need to produce a map clause even if we don't have variables so that 14677 // other diagnostics related with non-existing map clauses are accurate. 14678 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14679 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14680 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14681 MapperIdScopeSpec.getWithLocInContext(Context), 14682 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14683 } 14684 14685 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14686 TypeResult ParsedType) { 14687 assert(ParsedType.isUsable()); 14688 14689 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14690 if (ReductionType.isNull()) 14691 return QualType(); 14692 14693 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14694 // A type name in a declare reduction directive cannot be a function type, an 14695 // array type, a reference type, or a type qualified with const, volatile or 14696 // restrict. 14697 if (ReductionType.hasQualifiers()) { 14698 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14699 return QualType(); 14700 } 14701 14702 if (ReductionType->isFunctionType()) { 14703 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14704 return QualType(); 14705 } 14706 if (ReductionType->isReferenceType()) { 14707 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14708 return QualType(); 14709 } 14710 if (ReductionType->isArrayType()) { 14711 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14712 return QualType(); 14713 } 14714 return ReductionType; 14715 } 14716 14717 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14718 Scope *S, DeclContext *DC, DeclarationName Name, 14719 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14720 AccessSpecifier AS, Decl *PrevDeclInScope) { 14721 SmallVector<Decl *, 8> Decls; 14722 Decls.reserve(ReductionTypes.size()); 14723 14724 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14725 forRedeclarationInCurContext()); 14726 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14727 // A reduction-identifier may not be re-declared in the current scope for the 14728 // same type or for a type that is compatible according to the base language 14729 // rules. 14730 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14731 OMPDeclareReductionDecl *PrevDRD = nullptr; 14732 bool InCompoundScope = true; 14733 if (S != nullptr) { 14734 // Find previous declaration with the same name not referenced in other 14735 // declarations. 14736 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14737 InCompoundScope = 14738 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14739 LookupName(Lookup, S); 14740 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14741 /*AllowInlineNamespace=*/false); 14742 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14743 LookupResult::Filter Filter = Lookup.makeFilter(); 14744 while (Filter.hasNext()) { 14745 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14746 if (InCompoundScope) { 14747 auto I = UsedAsPrevious.find(PrevDecl); 14748 if (I == UsedAsPrevious.end()) 14749 UsedAsPrevious[PrevDecl] = false; 14750 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14751 UsedAsPrevious[D] = true; 14752 } 14753 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14754 PrevDecl->getLocation(); 14755 } 14756 Filter.done(); 14757 if (InCompoundScope) { 14758 for (const auto &PrevData : UsedAsPrevious) { 14759 if (!PrevData.second) { 14760 PrevDRD = PrevData.first; 14761 break; 14762 } 14763 } 14764 } 14765 } else if (PrevDeclInScope != nullptr) { 14766 auto *PrevDRDInScope = PrevDRD = 14767 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14768 do { 14769 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14770 PrevDRDInScope->getLocation(); 14771 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14772 } while (PrevDRDInScope != nullptr); 14773 } 14774 for (const auto &TyData : ReductionTypes) { 14775 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14776 bool Invalid = false; 14777 if (I != PreviousRedeclTypes.end()) { 14778 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14779 << TyData.first; 14780 Diag(I->second, diag::note_previous_definition); 14781 Invalid = true; 14782 } 14783 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 14784 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 14785 Name, TyData.first, PrevDRD); 14786 DC->addDecl(DRD); 14787 DRD->setAccess(AS); 14788 Decls.push_back(DRD); 14789 if (Invalid) 14790 DRD->setInvalidDecl(); 14791 else 14792 PrevDRD = DRD; 14793 } 14794 14795 return DeclGroupPtrTy::make( 14796 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 14797 } 14798 14799 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 14800 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14801 14802 // Enter new function scope. 14803 PushFunctionScope(); 14804 setFunctionHasBranchProtectedScope(); 14805 getCurFunction()->setHasOMPDeclareReductionCombiner(); 14806 14807 if (S != nullptr) 14808 PushDeclContext(S, DRD); 14809 else 14810 CurContext = DRD; 14811 14812 PushExpressionEvaluationContext( 14813 ExpressionEvaluationContext::PotentiallyEvaluated); 14814 14815 QualType ReductionType = DRD->getType(); 14816 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 14817 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 14818 // uses semantics of argument handles by value, but it should be passed by 14819 // reference. C lang does not support references, so pass all parameters as 14820 // pointers. 14821 // Create 'T omp_in;' variable. 14822 VarDecl *OmpInParm = 14823 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 14824 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 14825 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 14826 // uses semantics of argument handles by value, but it should be passed by 14827 // reference. C lang does not support references, so pass all parameters as 14828 // pointers. 14829 // Create 'T omp_out;' variable. 14830 VarDecl *OmpOutParm = 14831 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 14832 if (S != nullptr) { 14833 PushOnScopeChains(OmpInParm, S); 14834 PushOnScopeChains(OmpOutParm, S); 14835 } else { 14836 DRD->addDecl(OmpInParm); 14837 DRD->addDecl(OmpOutParm); 14838 } 14839 Expr *InE = 14840 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 14841 Expr *OutE = 14842 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 14843 DRD->setCombinerData(InE, OutE); 14844 } 14845 14846 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 14847 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14848 DiscardCleanupsInEvaluationContext(); 14849 PopExpressionEvaluationContext(); 14850 14851 PopDeclContext(); 14852 PopFunctionScopeInfo(); 14853 14854 if (Combiner != nullptr) 14855 DRD->setCombiner(Combiner); 14856 else 14857 DRD->setInvalidDecl(); 14858 } 14859 14860 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 14861 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14862 14863 // Enter new function scope. 14864 PushFunctionScope(); 14865 setFunctionHasBranchProtectedScope(); 14866 14867 if (S != nullptr) 14868 PushDeclContext(S, DRD); 14869 else 14870 CurContext = DRD; 14871 14872 PushExpressionEvaluationContext( 14873 ExpressionEvaluationContext::PotentiallyEvaluated); 14874 14875 QualType ReductionType = DRD->getType(); 14876 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 14877 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 14878 // uses semantics of argument handles by value, but it should be passed by 14879 // reference. C lang does not support references, so pass all parameters as 14880 // pointers. 14881 // Create 'T omp_priv;' variable. 14882 VarDecl *OmpPrivParm = 14883 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 14884 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 14885 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 14886 // uses semantics of argument handles by value, but it should be passed by 14887 // reference. C lang does not support references, so pass all parameters as 14888 // pointers. 14889 // Create 'T omp_orig;' variable. 14890 VarDecl *OmpOrigParm = 14891 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 14892 if (S != nullptr) { 14893 PushOnScopeChains(OmpPrivParm, S); 14894 PushOnScopeChains(OmpOrigParm, S); 14895 } else { 14896 DRD->addDecl(OmpPrivParm); 14897 DRD->addDecl(OmpOrigParm); 14898 } 14899 Expr *OrigE = 14900 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 14901 Expr *PrivE = 14902 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 14903 DRD->setInitializerData(OrigE, PrivE); 14904 return OmpPrivParm; 14905 } 14906 14907 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 14908 VarDecl *OmpPrivParm) { 14909 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14910 DiscardCleanupsInEvaluationContext(); 14911 PopExpressionEvaluationContext(); 14912 14913 PopDeclContext(); 14914 PopFunctionScopeInfo(); 14915 14916 if (Initializer != nullptr) { 14917 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 14918 } else if (OmpPrivParm->hasInit()) { 14919 DRD->setInitializer(OmpPrivParm->getInit(), 14920 OmpPrivParm->isDirectInit() 14921 ? OMPDeclareReductionDecl::DirectInit 14922 : OMPDeclareReductionDecl::CopyInit); 14923 } else { 14924 DRD->setInvalidDecl(); 14925 } 14926 } 14927 14928 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14929 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14930 for (Decl *D : DeclReductions.get()) { 14931 if (IsValid) { 14932 if (S) 14933 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14934 /*AddToContext=*/false); 14935 } else { 14936 D->setInvalidDecl(); 14937 } 14938 } 14939 return DeclReductions; 14940 } 14941 14942 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14943 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14944 QualType T = TInfo->getType(); 14945 if (D.isInvalidType()) 14946 return true; 14947 14948 if (getLangOpts().CPlusPlus) { 14949 // Check that there are no default arguments (C++ only). 14950 CheckExtraCXXDefaultArguments(D); 14951 } 14952 14953 return CreateParsedType(T, TInfo); 14954 } 14955 14956 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14957 TypeResult ParsedType) { 14958 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14959 14960 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14961 assert(!MapperType.isNull() && "Expect valid mapper type"); 14962 14963 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14964 // The type must be of struct, union or class type in C and C++ 14965 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14966 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14967 return QualType(); 14968 } 14969 return MapperType; 14970 } 14971 14972 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14973 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14974 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14975 Decl *PrevDeclInScope) { 14976 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14977 forRedeclarationInCurContext()); 14978 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14979 // A mapper-identifier may not be redeclared in the current scope for the 14980 // same type or for a type that is compatible according to the base language 14981 // rules. 14982 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14983 OMPDeclareMapperDecl *PrevDMD = nullptr; 14984 bool InCompoundScope = true; 14985 if (S != nullptr) { 14986 // Find previous declaration with the same name not referenced in other 14987 // declarations. 14988 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14989 InCompoundScope = 14990 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14991 LookupName(Lookup, S); 14992 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14993 /*AllowInlineNamespace=*/false); 14994 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14995 LookupResult::Filter Filter = Lookup.makeFilter(); 14996 while (Filter.hasNext()) { 14997 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14998 if (InCompoundScope) { 14999 auto I = UsedAsPrevious.find(PrevDecl); 15000 if (I == UsedAsPrevious.end()) 15001 UsedAsPrevious[PrevDecl] = false; 15002 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15003 UsedAsPrevious[D] = true; 15004 } 15005 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15006 PrevDecl->getLocation(); 15007 } 15008 Filter.done(); 15009 if (InCompoundScope) { 15010 for (const auto &PrevData : UsedAsPrevious) { 15011 if (!PrevData.second) { 15012 PrevDMD = PrevData.first; 15013 break; 15014 } 15015 } 15016 } 15017 } else if (PrevDeclInScope) { 15018 auto *PrevDMDInScope = PrevDMD = 15019 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15020 do { 15021 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15022 PrevDMDInScope->getLocation(); 15023 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15024 } while (PrevDMDInScope != nullptr); 15025 } 15026 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15027 bool Invalid = false; 15028 if (I != PreviousRedeclTypes.end()) { 15029 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15030 << MapperType << Name; 15031 Diag(I->second, diag::note_previous_definition); 15032 Invalid = true; 15033 } 15034 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15035 MapperType, VN, PrevDMD); 15036 DC->addDecl(DMD); 15037 DMD->setAccess(AS); 15038 if (Invalid) 15039 DMD->setInvalidDecl(); 15040 15041 // Enter new function scope. 15042 PushFunctionScope(); 15043 setFunctionHasBranchProtectedScope(); 15044 15045 CurContext = DMD; 15046 15047 return DMD; 15048 } 15049 15050 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15051 Scope *S, 15052 QualType MapperType, 15053 SourceLocation StartLoc, 15054 DeclarationName VN) { 15055 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15056 if (S) 15057 PushOnScopeChains(VD, S); 15058 else 15059 DMD->addDecl(VD); 15060 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15061 DMD->setMapperVarRef(MapperVarRefExpr); 15062 } 15063 15064 Sema::DeclGroupPtrTy 15065 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15066 ArrayRef<OMPClause *> ClauseList) { 15067 PopDeclContext(); 15068 PopFunctionScopeInfo(); 15069 15070 if (D) { 15071 if (S) 15072 PushOnScopeChains(D, S, /*AddToContext=*/false); 15073 D->CreateClauses(Context, ClauseList); 15074 } 15075 15076 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15077 } 15078 15079 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15080 SourceLocation StartLoc, 15081 SourceLocation LParenLoc, 15082 SourceLocation EndLoc) { 15083 Expr *ValExpr = NumTeams; 15084 Stmt *HelperValStmt = nullptr; 15085 15086 // OpenMP [teams Constrcut, Restrictions] 15087 // The num_teams expression must evaluate to a positive integer value. 15088 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15089 /*StrictlyPositive=*/true)) 15090 return nullptr; 15091 15092 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15093 OpenMPDirectiveKind CaptureRegion = 15094 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15095 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15096 ValExpr = MakeFullExpr(ValExpr).get(); 15097 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15098 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15099 HelperValStmt = buildPreInits(Context, Captures); 15100 } 15101 15102 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15103 StartLoc, LParenLoc, EndLoc); 15104 } 15105 15106 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15107 SourceLocation StartLoc, 15108 SourceLocation LParenLoc, 15109 SourceLocation EndLoc) { 15110 Expr *ValExpr = ThreadLimit; 15111 Stmt *HelperValStmt = nullptr; 15112 15113 // OpenMP [teams Constrcut, Restrictions] 15114 // The thread_limit expression must evaluate to a positive integer value. 15115 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15116 /*StrictlyPositive=*/true)) 15117 return nullptr; 15118 15119 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15120 OpenMPDirectiveKind CaptureRegion = 15121 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15122 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15123 ValExpr = MakeFullExpr(ValExpr).get(); 15124 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15125 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15126 HelperValStmt = buildPreInits(Context, Captures); 15127 } 15128 15129 return new (Context) OMPThreadLimitClause( 15130 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15131 } 15132 15133 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15134 SourceLocation StartLoc, 15135 SourceLocation LParenLoc, 15136 SourceLocation EndLoc) { 15137 Expr *ValExpr = Priority; 15138 15139 // OpenMP [2.9.1, task Constrcut] 15140 // The priority-value is a non-negative numerical scalar expression. 15141 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15142 /*StrictlyPositive=*/false)) 15143 return nullptr; 15144 15145 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15146 } 15147 15148 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15149 SourceLocation StartLoc, 15150 SourceLocation LParenLoc, 15151 SourceLocation EndLoc) { 15152 Expr *ValExpr = Grainsize; 15153 15154 // OpenMP [2.9.2, taskloop Constrcut] 15155 // The parameter of the grainsize clause must be a positive integer 15156 // expression. 15157 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 15158 /*StrictlyPositive=*/true)) 15159 return nullptr; 15160 15161 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15162 } 15163 15164 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15165 SourceLocation StartLoc, 15166 SourceLocation LParenLoc, 15167 SourceLocation EndLoc) { 15168 Expr *ValExpr = NumTasks; 15169 15170 // OpenMP [2.9.2, taskloop Constrcut] 15171 // The parameter of the num_tasks clause must be a positive integer 15172 // expression. 15173 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 15174 /*StrictlyPositive=*/true)) 15175 return nullptr; 15176 15177 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15178 } 15179 15180 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15181 SourceLocation LParenLoc, 15182 SourceLocation EndLoc) { 15183 // OpenMP [2.13.2, critical construct, Description] 15184 // ... where hint-expression is an integer constant expression that evaluates 15185 // to a valid lock hint. 15186 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15187 if (HintExpr.isInvalid()) 15188 return nullptr; 15189 return new (Context) 15190 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 15191 } 15192 15193 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 15194 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 15195 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 15196 SourceLocation EndLoc) { 15197 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 15198 std::string Values; 15199 Values += "'"; 15200 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 15201 Values += "'"; 15202 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 15203 << Values << getOpenMPClauseName(OMPC_dist_schedule); 15204 return nullptr; 15205 } 15206 Expr *ValExpr = ChunkSize; 15207 Stmt *HelperValStmt = nullptr; 15208 if (ChunkSize) { 15209 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 15210 !ChunkSize->isInstantiationDependent() && 15211 !ChunkSize->containsUnexpandedParameterPack()) { 15212 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 15213 ExprResult Val = 15214 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 15215 if (Val.isInvalid()) 15216 return nullptr; 15217 15218 ValExpr = Val.get(); 15219 15220 // OpenMP [2.7.1, Restrictions] 15221 // chunk_size must be a loop invariant integer expression with a positive 15222 // value. 15223 llvm::APSInt Result; 15224 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 15225 if (Result.isSigned() && !Result.isStrictlyPositive()) { 15226 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 15227 << "dist_schedule" << ChunkSize->getSourceRange(); 15228 return nullptr; 15229 } 15230 } else if (getOpenMPCaptureRegionForClause( 15231 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 15232 OMPD_unknown && 15233 !CurContext->isDependentContext()) { 15234 ValExpr = MakeFullExpr(ValExpr).get(); 15235 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15236 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15237 HelperValStmt = buildPreInits(Context, Captures); 15238 } 15239 } 15240 } 15241 15242 return new (Context) 15243 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 15244 Kind, ValExpr, HelperValStmt); 15245 } 15246 15247 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 15248 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 15249 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 15250 SourceLocation KindLoc, SourceLocation EndLoc) { 15251 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 15252 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 15253 std::string Value; 15254 SourceLocation Loc; 15255 Value += "'"; 15256 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 15257 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15258 OMPC_DEFAULTMAP_MODIFIER_tofrom); 15259 Loc = MLoc; 15260 } else { 15261 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15262 OMPC_DEFAULTMAP_scalar); 15263 Loc = KindLoc; 15264 } 15265 Value += "'"; 15266 Diag(Loc, diag::err_omp_unexpected_clause_value) 15267 << Value << getOpenMPClauseName(OMPC_defaultmap); 15268 return nullptr; 15269 } 15270 DSAStack->setDefaultDMAToFromScalar(StartLoc); 15271 15272 return new (Context) 15273 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 15274 } 15275 15276 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 15277 DeclContext *CurLexicalContext = getCurLexicalContext(); 15278 if (!CurLexicalContext->isFileContext() && 15279 !CurLexicalContext->isExternCContext() && 15280 !CurLexicalContext->isExternCXXContext() && 15281 !isa<CXXRecordDecl>(CurLexicalContext) && 15282 !isa<ClassTemplateDecl>(CurLexicalContext) && 15283 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 15284 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 15285 Diag(Loc, diag::err_omp_region_not_file_context); 15286 return false; 15287 } 15288 ++DeclareTargetNestingLevel; 15289 return true; 15290 } 15291 15292 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 15293 assert(DeclareTargetNestingLevel > 0 && 15294 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 15295 --DeclareTargetNestingLevel; 15296 } 15297 15298 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 15299 CXXScopeSpec &ScopeSpec, 15300 const DeclarationNameInfo &Id, 15301 OMPDeclareTargetDeclAttr::MapTypeTy MT, 15302 NamedDeclSetType &SameDirectiveDecls) { 15303 LookupResult Lookup(*this, Id, LookupOrdinaryName); 15304 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 15305 15306 if (Lookup.isAmbiguous()) 15307 return; 15308 Lookup.suppressDiagnostics(); 15309 15310 if (!Lookup.isSingleResult()) { 15311 VarOrFuncDeclFilterCCC CCC(*this); 15312 if (TypoCorrection Corrected = 15313 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 15314 CTK_ErrorRecovery)) { 15315 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 15316 << Id.getName()); 15317 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 15318 return; 15319 } 15320 15321 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 15322 return; 15323 } 15324 15325 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 15326 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 15327 isa<FunctionTemplateDecl>(ND)) { 15328 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 15329 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 15330 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15331 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 15332 cast<ValueDecl>(ND)); 15333 if (!Res) { 15334 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 15335 ND->addAttr(A); 15336 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15337 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 15338 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 15339 } else if (*Res != MT) { 15340 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 15341 << Id.getName(); 15342 } 15343 } else { 15344 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 15345 } 15346 } 15347 15348 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 15349 Sema &SemaRef, Decl *D) { 15350 if (!D || !isa<VarDecl>(D)) 15351 return; 15352 auto *VD = cast<VarDecl>(D); 15353 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15354 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15355 if (SemaRef.LangOpts.OpenMP >= 50 && 15356 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 15357 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 15358 VD->hasGlobalStorage()) { 15359 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15360 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15361 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 15362 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 15363 // If a lambda declaration and definition appears between a 15364 // declare target directive and the matching end declare target 15365 // directive, all variables that are captured by the lambda 15366 // expression must also appear in a to clause. 15367 SemaRef.Diag(VD->getLocation(), 15368 diag::omp_lambda_capture_in_declare_target_not_to); 15369 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 15370 << VD << 0 << SR; 15371 return; 15372 } 15373 } 15374 if (MapTy.hasValue()) 15375 return; 15376 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 15377 SemaRef.Diag(SL, diag::note_used_here) << SR; 15378 } 15379 15380 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 15381 Sema &SemaRef, DSAStackTy *Stack, 15382 ValueDecl *VD) { 15383 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 15384 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 15385 /*FullCheck=*/false); 15386 } 15387 15388 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 15389 SourceLocation IdLoc) { 15390 if (!D || D->isInvalidDecl()) 15391 return; 15392 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 15393 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15394 if (auto *VD = dyn_cast<VarDecl>(D)) { 15395 // Only global variables can be marked as declare target. 15396 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15397 !VD->isStaticDataMember()) 15398 return; 15399 // 2.10.6: threadprivate variable cannot appear in a declare target 15400 // directive. 15401 if (DSAStack->isThreadPrivate(VD)) { 15402 Diag(SL, diag::err_omp_threadprivate_in_target); 15403 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15404 return; 15405 } 15406 } 15407 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 15408 D = FTD->getTemplatedDecl(); 15409 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 15410 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15411 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 15412 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 15413 assert(IdLoc.isValid() && "Source location is expected"); 15414 Diag(IdLoc, diag::err_omp_function_in_link_clause); 15415 Diag(FD->getLocation(), diag::note_defined_here) << FD; 15416 return; 15417 } 15418 } 15419 if (auto *VD = dyn_cast<ValueDecl>(D)) { 15420 // Problem if any with var declared with incomplete type will be reported 15421 // as normal, so no need to check it here. 15422 if ((E || !VD->getType()->isIncompleteType()) && 15423 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 15424 return; 15425 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 15426 // Checking declaration inside declare target region. 15427 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 15428 isa<FunctionTemplateDecl>(D)) { 15429 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 15430 Context, OMPDeclareTargetDeclAttr::MT_To); 15431 D->addAttr(A); 15432 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15433 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 15434 } 15435 return; 15436 } 15437 } 15438 if (!E) 15439 return; 15440 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 15441 } 15442 15443 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15444 CXXScopeSpec &MapperIdScopeSpec, 15445 DeclarationNameInfo &MapperId, 15446 const OMPVarListLocTy &Locs, 15447 ArrayRef<Expr *> UnresolvedMappers) { 15448 MappableVarListInfo MVLI(VarList); 15449 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15450 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15451 if (MVLI.ProcessedVarList.empty()) 15452 return nullptr; 15453 15454 return OMPToClause::Create( 15455 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15456 MVLI.VarComponents, MVLI.UDMapperList, 15457 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15458 } 15459 15460 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15461 CXXScopeSpec &MapperIdScopeSpec, 15462 DeclarationNameInfo &MapperId, 15463 const OMPVarListLocTy &Locs, 15464 ArrayRef<Expr *> UnresolvedMappers) { 15465 MappableVarListInfo MVLI(VarList); 15466 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15467 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15468 if (MVLI.ProcessedVarList.empty()) 15469 return nullptr; 15470 15471 return OMPFromClause::Create( 15472 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15473 MVLI.VarComponents, MVLI.UDMapperList, 15474 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15475 } 15476 15477 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15478 const OMPVarListLocTy &Locs) { 15479 MappableVarListInfo MVLI(VarList); 15480 SmallVector<Expr *, 8> PrivateCopies; 15481 SmallVector<Expr *, 8> Inits; 15482 15483 for (Expr *RefExpr : VarList) { 15484 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15485 SourceLocation ELoc; 15486 SourceRange ERange; 15487 Expr *SimpleRefExpr = RefExpr; 15488 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15489 if (Res.second) { 15490 // It will be analyzed later. 15491 MVLI.ProcessedVarList.push_back(RefExpr); 15492 PrivateCopies.push_back(nullptr); 15493 Inits.push_back(nullptr); 15494 } 15495 ValueDecl *D = Res.first; 15496 if (!D) 15497 continue; 15498 15499 QualType Type = D->getType(); 15500 Type = Type.getNonReferenceType().getUnqualifiedType(); 15501 15502 auto *VD = dyn_cast<VarDecl>(D); 15503 15504 // Item should be a pointer or reference to pointer. 15505 if (!Type->isPointerType()) { 15506 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15507 << 0 << RefExpr->getSourceRange(); 15508 continue; 15509 } 15510 15511 // Build the private variable and the expression that refers to it. 15512 auto VDPrivate = 15513 buildVarDecl(*this, ELoc, Type, D->getName(), 15514 D->hasAttrs() ? &D->getAttrs() : nullptr, 15515 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15516 if (VDPrivate->isInvalidDecl()) 15517 continue; 15518 15519 CurContext->addDecl(VDPrivate); 15520 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15521 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15522 15523 // Add temporary variable to initialize the private copy of the pointer. 15524 VarDecl *VDInit = 15525 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15526 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15527 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15528 AddInitializerToDecl(VDPrivate, 15529 DefaultLvalueConversion(VDInitRefExpr).get(), 15530 /*DirectInit=*/false); 15531 15532 // If required, build a capture to implement the privatization initialized 15533 // with the current list item value. 15534 DeclRefExpr *Ref = nullptr; 15535 if (!VD) 15536 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15537 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15538 PrivateCopies.push_back(VDPrivateRefExpr); 15539 Inits.push_back(VDInitRefExpr); 15540 15541 // We need to add a data sharing attribute for this variable to make sure it 15542 // is correctly captured. A variable that shows up in a use_device_ptr has 15543 // similar properties of a first private variable. 15544 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15545 15546 // Create a mappable component for the list item. List items in this clause 15547 // only need a component. 15548 MVLI.VarBaseDeclarations.push_back(D); 15549 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15550 MVLI.VarComponents.back().push_back( 15551 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15552 } 15553 15554 if (MVLI.ProcessedVarList.empty()) 15555 return nullptr; 15556 15557 return OMPUseDevicePtrClause::Create( 15558 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15559 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15560 } 15561 15562 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15563 const OMPVarListLocTy &Locs) { 15564 MappableVarListInfo MVLI(VarList); 15565 for (Expr *RefExpr : VarList) { 15566 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15567 SourceLocation ELoc; 15568 SourceRange ERange; 15569 Expr *SimpleRefExpr = RefExpr; 15570 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15571 if (Res.second) { 15572 // It will be analyzed later. 15573 MVLI.ProcessedVarList.push_back(RefExpr); 15574 } 15575 ValueDecl *D = Res.first; 15576 if (!D) 15577 continue; 15578 15579 QualType Type = D->getType(); 15580 // item should be a pointer or array or reference to pointer or array 15581 if (!Type.getNonReferenceType()->isPointerType() && 15582 !Type.getNonReferenceType()->isArrayType()) { 15583 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15584 << 0 << RefExpr->getSourceRange(); 15585 continue; 15586 } 15587 15588 // Check if the declaration in the clause does not show up in any data 15589 // sharing attribute. 15590 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15591 if (isOpenMPPrivate(DVar.CKind)) { 15592 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15593 << getOpenMPClauseName(DVar.CKind) 15594 << getOpenMPClauseName(OMPC_is_device_ptr) 15595 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15596 reportOriginalDsa(*this, DSAStack, D, DVar); 15597 continue; 15598 } 15599 15600 const Expr *ConflictExpr; 15601 if (DSAStack->checkMappableExprComponentListsForDecl( 15602 D, /*CurrentRegionOnly=*/true, 15603 [&ConflictExpr]( 15604 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15605 OpenMPClauseKind) -> bool { 15606 ConflictExpr = R.front().getAssociatedExpression(); 15607 return true; 15608 })) { 15609 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15610 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15611 << ConflictExpr->getSourceRange(); 15612 continue; 15613 } 15614 15615 // Store the components in the stack so that they can be used to check 15616 // against other clauses later on. 15617 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15618 DSAStack->addMappableExpressionComponents( 15619 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15620 15621 // Record the expression we've just processed. 15622 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15623 15624 // Create a mappable component for the list item. List items in this clause 15625 // only need a component. We use a null declaration to signal fields in 15626 // 'this'. 15627 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15628 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15629 "Unexpected device pointer expression!"); 15630 MVLI.VarBaseDeclarations.push_back( 15631 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15632 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15633 MVLI.VarComponents.back().push_back(MC); 15634 } 15635 15636 if (MVLI.ProcessedVarList.empty()) 15637 return nullptr; 15638 15639 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15640 MVLI.VarBaseDeclarations, 15641 MVLI.VarComponents); 15642 } 15643 15644 OMPClause *Sema::ActOnOpenMPAllocateClause( 15645 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15646 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15647 if (Allocator) { 15648 // OpenMP [2.11.4 allocate Clause, Description] 15649 // allocator is an expression of omp_allocator_handle_t type. 15650 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15651 return nullptr; 15652 15653 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15654 if (AllocatorRes.isInvalid()) 15655 return nullptr; 15656 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15657 DSAStack->getOMPAllocatorHandleT(), 15658 Sema::AA_Initializing, 15659 /*AllowExplicit=*/true); 15660 if (AllocatorRes.isInvalid()) 15661 return nullptr; 15662 Allocator = AllocatorRes.get(); 15663 } else { 15664 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15665 // allocate clauses that appear on a target construct or on constructs in a 15666 // target region must specify an allocator expression unless a requires 15667 // directive with the dynamic_allocators clause is present in the same 15668 // compilation unit. 15669 if (LangOpts.OpenMPIsDevice && 15670 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15671 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15672 } 15673 // Analyze and build list of variables. 15674 SmallVector<Expr *, 8> Vars; 15675 for (Expr *RefExpr : VarList) { 15676 assert(RefExpr && "NULL expr in OpenMP private clause."); 15677 SourceLocation ELoc; 15678 SourceRange ERange; 15679 Expr *SimpleRefExpr = RefExpr; 15680 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15681 if (Res.second) { 15682 // It will be analyzed later. 15683 Vars.push_back(RefExpr); 15684 } 15685 ValueDecl *D = Res.first; 15686 if (!D) 15687 continue; 15688 15689 auto *VD = dyn_cast<VarDecl>(D); 15690 DeclRefExpr *Ref = nullptr; 15691 if (!VD && !CurContext->isDependentContext()) 15692 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15693 Vars.push_back((VD || CurContext->isDependentContext()) 15694 ? RefExpr->IgnoreParens() 15695 : Ref); 15696 } 15697 15698 if (Vars.empty()) 15699 return nullptr; 15700 15701 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15702 ColonLoc, EndLoc, Vars); 15703 } 15704