1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 const Decl *PossiblyLoopCounter = nullptr; 143 bool NowaitRegion = false; 144 bool CancelRegion = false; 145 bool LoopStart = false; 146 bool BodyComplete = false; 147 SourceLocation InnerTeamsRegionLoc; 148 /// Reference to the taskgroup task_reduction reference expression. 149 Expr *TaskgroupReductionRef = nullptr; 150 llvm::DenseSet<QualType> MappedClassesQualTypes; 151 /// List of globals marked as declare target link in this target region 152 /// (isOpenMPTargetExecutionDirective(Directive) == true). 153 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 154 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 155 Scope *CurScope, SourceLocation Loc) 156 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 157 ConstructLoc(Loc) {} 158 SharingMapTy() = default; 159 }; 160 161 using StackTy = SmallVector<SharingMapTy, 4>; 162 163 /// Stack of used declaration and their data-sharing attributes. 164 DeclSAMapTy Threadprivates; 165 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 166 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 167 /// true, if check for DSA must be from parent directive, false, if 168 /// from current directive. 169 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 170 Sema &SemaRef; 171 bool ForceCapturing = false; 172 /// true if all the vaiables in the target executable directives must be 173 /// captured by reference. 174 bool ForceCaptureByReferenceInTargetExecutable = false; 175 CriticalsWithHintsTy Criticals; 176 unsigned IgnoredStackElements = 0; 177 178 /// Iterators over the stack iterate in order from innermost to outermost 179 /// directive. 180 using const_iterator = StackTy::const_reverse_iterator; 181 const_iterator begin() const { 182 return Stack.empty() ? const_iterator() 183 : Stack.back().first.rbegin() + IgnoredStackElements; 184 } 185 const_iterator end() const { 186 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 187 } 188 using iterator = StackTy::reverse_iterator; 189 iterator begin() { 190 return Stack.empty() ? iterator() 191 : Stack.back().first.rbegin() + IgnoredStackElements; 192 } 193 iterator end() { 194 return Stack.empty() ? iterator() : Stack.back().first.rend(); 195 } 196 197 // Convenience operations to get at the elements of the stack. 198 199 bool isStackEmpty() const { 200 return Stack.empty() || 201 Stack.back().second != CurrentNonCapturingFunctionScope || 202 Stack.back().first.size() <= IgnoredStackElements; 203 } 204 size_t getStackSize() const { 205 return isStackEmpty() ? 0 206 : Stack.back().first.size() - IgnoredStackElements; 207 } 208 209 SharingMapTy *getTopOfStackOrNull() { 210 size_t Size = getStackSize(); 211 if (Size == 0) 212 return nullptr; 213 return &Stack.back().first[Size - 1]; 214 } 215 const SharingMapTy *getTopOfStackOrNull() const { 216 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 217 } 218 SharingMapTy &getTopOfStack() { 219 assert(!isStackEmpty() && "no current directive"); 220 return *getTopOfStackOrNull(); 221 } 222 const SharingMapTy &getTopOfStack() const { 223 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 224 } 225 226 SharingMapTy *getSecondOnStackOrNull() { 227 size_t Size = getStackSize(); 228 if (Size <= 1) 229 return nullptr; 230 return &Stack.back().first[Size - 2]; 231 } 232 const SharingMapTy *getSecondOnStackOrNull() const { 233 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 234 } 235 236 /// Get the stack element at a certain level (previously returned by 237 /// \c getNestingLevel). 238 /// 239 /// Note that nesting levels count from outermost to innermost, and this is 240 /// the reverse of our iteration order where new inner levels are pushed at 241 /// the front of the stack. 242 SharingMapTy &getStackElemAtLevel(unsigned Level) { 243 assert(Level < getStackSize() && "no such stack element"); 244 return Stack.back().first[Level]; 245 } 246 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 247 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 248 } 249 250 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 251 252 /// Checks if the variable is a local for OpenMP region. 253 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 254 255 /// Vector of previously declared requires directives 256 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 257 /// omp_allocator_handle_t type. 258 QualType OMPAllocatorHandleT; 259 /// Expression for the predefined allocators. 260 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 261 nullptr}; 262 /// Vector of previously encountered target directives 263 SmallVector<SourceLocation, 2> TargetLocations; 264 265 public: 266 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 267 268 /// Sets omp_allocator_handle_t type. 269 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 270 /// Gets omp_allocator_handle_t type. 271 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 272 /// Sets the given default allocator. 273 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 274 Expr *Allocator) { 275 OMPPredefinedAllocators[AllocatorKind] = Allocator; 276 } 277 /// Returns the specified default allocator. 278 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 279 return OMPPredefinedAllocators[AllocatorKind]; 280 } 281 282 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 283 OpenMPClauseKind getClauseParsingMode() const { 284 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 285 return ClauseKindMode; 286 } 287 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 288 289 bool isBodyComplete() const { 290 const SharingMapTy *Top = getTopOfStackOrNull(); 291 return Top && Top->BodyComplete; 292 } 293 void setBodyComplete() { 294 getTopOfStack().BodyComplete = true; 295 } 296 297 bool isForceVarCapturing() const { return ForceCapturing; } 298 void setForceVarCapturing(bool V) { ForceCapturing = V; } 299 300 void setForceCaptureByReferenceInTargetExecutable(bool V) { 301 ForceCaptureByReferenceInTargetExecutable = V; 302 } 303 bool isForceCaptureByReferenceInTargetExecutable() const { 304 return ForceCaptureByReferenceInTargetExecutable; 305 } 306 307 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 308 Scope *CurScope, SourceLocation Loc) { 309 assert(!IgnoredStackElements && 310 "cannot change stack while ignoring elements"); 311 if (Stack.empty() || 312 Stack.back().second != CurrentNonCapturingFunctionScope) 313 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 314 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 315 Stack.back().first.back().DefaultAttrLoc = Loc; 316 } 317 318 void pop() { 319 assert(!IgnoredStackElements && 320 "cannot change stack while ignoring elements"); 321 assert(!Stack.back().first.empty() && 322 "Data-sharing attributes stack is empty!"); 323 Stack.back().first.pop_back(); 324 } 325 326 /// RAII object to temporarily leave the scope of a directive when we want to 327 /// logically operate in its parent. 328 class ParentDirectiveScope { 329 DSAStackTy &Self; 330 bool Active; 331 public: 332 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 333 : Self(Self), Active(false) { 334 if (Activate) 335 enable(); 336 } 337 ~ParentDirectiveScope() { disable(); } 338 void disable() { 339 if (Active) { 340 --Self.IgnoredStackElements; 341 Active = false; 342 } 343 } 344 void enable() { 345 if (!Active) { 346 ++Self.IgnoredStackElements; 347 Active = true; 348 } 349 } 350 }; 351 352 /// Marks that we're started loop parsing. 353 void loopInit() { 354 assert(isOpenMPLoopDirective(getCurrentDirective()) && 355 "Expected loop-based directive."); 356 getTopOfStack().LoopStart = true; 357 } 358 /// Start capturing of the variables in the loop context. 359 void loopStart() { 360 assert(isOpenMPLoopDirective(getCurrentDirective()) && 361 "Expected loop-based directive."); 362 getTopOfStack().LoopStart = false; 363 } 364 /// true, if variables are captured, false otherwise. 365 bool isLoopStarted() const { 366 assert(isOpenMPLoopDirective(getCurrentDirective()) && 367 "Expected loop-based directive."); 368 return !getTopOfStack().LoopStart; 369 } 370 /// Marks (or clears) declaration as possibly loop counter. 371 void resetPossibleLoopCounter(const Decl *D = nullptr) { 372 getTopOfStack().PossiblyLoopCounter = 373 D ? D->getCanonicalDecl() : D; 374 } 375 /// Gets the possible loop counter decl. 376 const Decl *getPossiblyLoopCunter() const { 377 return getTopOfStack().PossiblyLoopCounter; 378 } 379 /// Start new OpenMP region stack in new non-capturing function. 380 void pushFunction() { 381 assert(!IgnoredStackElements && 382 "cannot change stack while ignoring elements"); 383 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 384 assert(!isa<CapturingScopeInfo>(CurFnScope)); 385 CurrentNonCapturingFunctionScope = CurFnScope; 386 } 387 /// Pop region stack for non-capturing function. 388 void popFunction(const FunctionScopeInfo *OldFSI) { 389 assert(!IgnoredStackElements && 390 "cannot change stack while ignoring elements"); 391 if (!Stack.empty() && Stack.back().second == OldFSI) { 392 assert(Stack.back().first.empty()); 393 Stack.pop_back(); 394 } 395 CurrentNonCapturingFunctionScope = nullptr; 396 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 397 if (!isa<CapturingScopeInfo>(FSI)) { 398 CurrentNonCapturingFunctionScope = FSI; 399 break; 400 } 401 } 402 } 403 404 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 405 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 406 } 407 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 408 getCriticalWithHint(const DeclarationNameInfo &Name) const { 409 auto I = Criticals.find(Name.getAsString()); 410 if (I != Criticals.end()) 411 return I->second; 412 return std::make_pair(nullptr, llvm::APSInt()); 413 } 414 /// If 'aligned' declaration for given variable \a D was not seen yet, 415 /// add it and return NULL; otherwise return previous occurrence's expression 416 /// for diagnostics. 417 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 418 419 /// Register specified variable as loop control variable. 420 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 421 /// Check if the specified variable is a loop control variable for 422 /// current region. 423 /// \return The index of the loop control variable in the list of associated 424 /// for-loops (from outer to inner). 425 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 426 /// Check if the specified variable is a loop control variable for 427 /// parent region. 428 /// \return The index of the loop control variable in the list of associated 429 /// for-loops (from outer to inner). 430 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 431 /// Get the loop control variable for the I-th loop (or nullptr) in 432 /// parent directive. 433 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 434 435 /// Adds explicit data sharing attribute to the specified declaration. 436 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 437 DeclRefExpr *PrivateCopy = nullptr); 438 439 /// Adds additional information for the reduction items with the reduction id 440 /// represented as an operator. 441 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 442 BinaryOperatorKind BOK); 443 /// Adds additional information for the reduction items with the reduction id 444 /// represented as reduction identifier. 445 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 446 const Expr *ReductionRef); 447 /// Returns the location and reduction operation from the innermost parent 448 /// region for the given \p D. 449 const DSAVarData 450 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 451 BinaryOperatorKind &BOK, 452 Expr *&TaskgroupDescriptor) const; 453 /// Returns the location and reduction operation from the innermost parent 454 /// region for the given \p D. 455 const DSAVarData 456 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 457 const Expr *&ReductionRef, 458 Expr *&TaskgroupDescriptor) const; 459 /// Return reduction reference expression for the current taskgroup. 460 Expr *getTaskgroupReductionRef() const { 461 assert(getTopOfStack().Directive == OMPD_taskgroup && 462 "taskgroup reference expression requested for non taskgroup " 463 "directive."); 464 return getTopOfStack().TaskgroupReductionRef; 465 } 466 /// Checks if the given \p VD declaration is actually a taskgroup reduction 467 /// descriptor variable at the \p Level of OpenMP regions. 468 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 469 return getStackElemAtLevel(Level).TaskgroupReductionRef && 470 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 471 ->getDecl() == VD; 472 } 473 474 /// Returns data sharing attributes from top of the stack for the 475 /// specified declaration. 476 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 477 /// Returns data-sharing attributes for the specified declaration. 478 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 479 /// Checks if the specified variables has data-sharing attributes which 480 /// match specified \a CPred predicate in any directive which matches \a DPred 481 /// predicate. 482 const DSAVarData 483 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 484 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 485 bool FromParent) const; 486 /// Checks if the specified variables has data-sharing attributes which 487 /// match specified \a CPred predicate in any innermost directive which 488 /// matches \a DPred predicate. 489 const DSAVarData 490 hasInnermostDSA(ValueDecl *D, 491 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 492 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 493 bool FromParent) const; 494 /// Checks if the specified variables has explicit data-sharing 495 /// attributes which match specified \a CPred predicate at the specified 496 /// OpenMP region. 497 bool hasExplicitDSA(const ValueDecl *D, 498 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 499 unsigned Level, bool NotLastprivate = false) const; 500 501 /// Returns true if the directive at level \Level matches in the 502 /// specified \a DPred predicate. 503 bool hasExplicitDirective( 504 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 505 unsigned Level) const; 506 507 /// Finds a directive which matches specified \a DPred predicate. 508 bool hasDirective( 509 const llvm::function_ref<bool( 510 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 511 DPred, 512 bool FromParent) const; 513 514 /// Returns currently analyzed directive. 515 OpenMPDirectiveKind getCurrentDirective() const { 516 const SharingMapTy *Top = getTopOfStackOrNull(); 517 return Top ? Top->Directive : OMPD_unknown; 518 } 519 /// Returns directive kind at specified level. 520 OpenMPDirectiveKind getDirective(unsigned Level) const { 521 assert(!isStackEmpty() && "No directive at specified level."); 522 return getStackElemAtLevel(Level).Directive; 523 } 524 /// Returns parent directive. 525 OpenMPDirectiveKind getParentDirective() const { 526 const SharingMapTy *Parent = getSecondOnStackOrNull(); 527 return Parent ? Parent->Directive : OMPD_unknown; 528 } 529 530 /// Add requires decl to internal vector 531 void addRequiresDecl(OMPRequiresDecl *RD) { 532 RequiresDecls.push_back(RD); 533 } 534 535 /// Checks if the defined 'requires' directive has specified type of clause. 536 template <typename ClauseType> 537 bool hasRequiresDeclWithClause() { 538 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 539 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 540 return isa<ClauseType>(C); 541 }); 542 }); 543 } 544 545 /// Checks for a duplicate clause amongst previously declared requires 546 /// directives 547 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 548 bool IsDuplicate = false; 549 for (OMPClause *CNew : ClauseList) { 550 for (const OMPRequiresDecl *D : RequiresDecls) { 551 for (const OMPClause *CPrev : D->clauselists()) { 552 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 553 SemaRef.Diag(CNew->getBeginLoc(), 554 diag::err_omp_requires_clause_redeclaration) 555 << getOpenMPClauseName(CNew->getClauseKind()); 556 SemaRef.Diag(CPrev->getBeginLoc(), 557 diag::note_omp_requires_previous_clause) 558 << getOpenMPClauseName(CPrev->getClauseKind()); 559 IsDuplicate = true; 560 } 561 } 562 } 563 } 564 return IsDuplicate; 565 } 566 567 /// Add location of previously encountered target to internal vector 568 void addTargetDirLocation(SourceLocation LocStart) { 569 TargetLocations.push_back(LocStart); 570 } 571 572 // Return previously encountered target region locations. 573 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 574 return TargetLocations; 575 } 576 577 /// Set default data sharing attribute to none. 578 void setDefaultDSANone(SourceLocation Loc) { 579 getTopOfStack().DefaultAttr = DSA_none; 580 getTopOfStack().DefaultAttrLoc = Loc; 581 } 582 /// Set default data sharing attribute to shared. 583 void setDefaultDSAShared(SourceLocation Loc) { 584 getTopOfStack().DefaultAttr = DSA_shared; 585 getTopOfStack().DefaultAttrLoc = Loc; 586 } 587 /// Set default data mapping attribute to 'tofrom:scalar'. 588 void setDefaultDMAToFromScalar(SourceLocation Loc) { 589 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 590 getTopOfStack().DefaultMapAttrLoc = Loc; 591 } 592 593 DefaultDataSharingAttributes getDefaultDSA() const { 594 return isStackEmpty() ? DSA_unspecified 595 : getTopOfStack().DefaultAttr; 596 } 597 SourceLocation getDefaultDSALocation() const { 598 return isStackEmpty() ? SourceLocation() 599 : getTopOfStack().DefaultAttrLoc; 600 } 601 DefaultMapAttributes getDefaultDMA() const { 602 return isStackEmpty() ? DMA_unspecified 603 : getTopOfStack().DefaultMapAttr; 604 } 605 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 606 return getStackElemAtLevel(Level).DefaultMapAttr; 607 } 608 SourceLocation getDefaultDMALocation() const { 609 return isStackEmpty() ? SourceLocation() 610 : getTopOfStack().DefaultMapAttrLoc; 611 } 612 613 /// Checks if the specified variable is a threadprivate. 614 bool isThreadPrivate(VarDecl *D) { 615 const DSAVarData DVar = getTopDSA(D, false); 616 return isOpenMPThreadPrivate(DVar.CKind); 617 } 618 619 /// Marks current region as ordered (it has an 'ordered' clause). 620 void setOrderedRegion(bool IsOrdered, const Expr *Param, 621 OMPOrderedClause *Clause) { 622 if (IsOrdered) 623 getTopOfStack().OrderedRegion.emplace(Param, Clause); 624 else 625 getTopOfStack().OrderedRegion.reset(); 626 } 627 /// Returns true, if region is ordered (has associated 'ordered' clause), 628 /// false - otherwise. 629 bool isOrderedRegion() const { 630 if (const SharingMapTy *Top = getTopOfStackOrNull()) 631 return Top->OrderedRegion.hasValue(); 632 return false; 633 } 634 /// Returns optional parameter for the ordered region. 635 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 636 if (const SharingMapTy *Top = getTopOfStackOrNull()) 637 if (Top->OrderedRegion.hasValue()) 638 return Top->OrderedRegion.getValue(); 639 return std::make_pair(nullptr, nullptr); 640 } 641 /// Returns true, if parent region is ordered (has associated 642 /// 'ordered' clause), false - otherwise. 643 bool isParentOrderedRegion() const { 644 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 645 return Parent->OrderedRegion.hasValue(); 646 return false; 647 } 648 /// Returns optional parameter for the ordered region. 649 std::pair<const Expr *, OMPOrderedClause *> 650 getParentOrderedRegionParam() const { 651 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 652 if (Parent->OrderedRegion.hasValue()) 653 return Parent->OrderedRegion.getValue(); 654 return std::make_pair(nullptr, nullptr); 655 } 656 /// Marks current region as nowait (it has a 'nowait' clause). 657 void setNowaitRegion(bool IsNowait = true) { 658 getTopOfStack().NowaitRegion = IsNowait; 659 } 660 /// Returns true, if parent region is nowait (has associated 661 /// 'nowait' clause), false - otherwise. 662 bool isParentNowaitRegion() const { 663 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 664 return Parent->NowaitRegion; 665 return false; 666 } 667 /// Marks parent region as cancel region. 668 void setParentCancelRegion(bool Cancel = true) { 669 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 670 Parent->CancelRegion |= Cancel; 671 } 672 /// Return true if current region has inner cancel construct. 673 bool isCancelRegion() const { 674 const SharingMapTy *Top = getTopOfStackOrNull(); 675 return Top ? Top->CancelRegion : false; 676 } 677 678 /// Set collapse value for the region. 679 void setAssociatedLoops(unsigned Val) { 680 getTopOfStack().AssociatedLoops = Val; 681 } 682 /// Return collapse value for region. 683 unsigned getAssociatedLoops() const { 684 const SharingMapTy *Top = getTopOfStackOrNull(); 685 return Top ? Top->AssociatedLoops : 0; 686 } 687 688 /// Marks current target region as one with closely nested teams 689 /// region. 690 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 691 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 692 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 693 } 694 /// Returns true, if current region has closely nested teams region. 695 bool hasInnerTeamsRegion() const { 696 return getInnerTeamsRegionLoc().isValid(); 697 } 698 /// Returns location of the nested teams region (if any). 699 SourceLocation getInnerTeamsRegionLoc() const { 700 const SharingMapTy *Top = getTopOfStackOrNull(); 701 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 702 } 703 704 Scope *getCurScope() const { 705 const SharingMapTy *Top = getTopOfStackOrNull(); 706 return Top ? Top->CurScope : nullptr; 707 } 708 SourceLocation getConstructLoc() const { 709 const SharingMapTy *Top = getTopOfStackOrNull(); 710 return Top ? Top->ConstructLoc : SourceLocation(); 711 } 712 713 /// Do the check specified in \a Check to all component lists and return true 714 /// if any issue is found. 715 bool checkMappableExprComponentListsForDecl( 716 const ValueDecl *VD, bool CurrentRegionOnly, 717 const llvm::function_ref< 718 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 719 OpenMPClauseKind)> 720 Check) const { 721 if (isStackEmpty()) 722 return false; 723 auto SI = begin(); 724 auto SE = end(); 725 726 if (SI == SE) 727 return false; 728 729 if (CurrentRegionOnly) 730 SE = std::next(SI); 731 else 732 std::advance(SI, 1); 733 734 for (; SI != SE; ++SI) { 735 auto MI = SI->MappedExprComponents.find(VD); 736 if (MI != SI->MappedExprComponents.end()) 737 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 738 MI->second.Components) 739 if (Check(L, MI->second.Kind)) 740 return true; 741 } 742 return false; 743 } 744 745 /// Do the check specified in \a Check to all component lists at a given level 746 /// and return true if any issue is found. 747 bool checkMappableExprComponentListsForDeclAtLevel( 748 const ValueDecl *VD, unsigned Level, 749 const llvm::function_ref< 750 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 751 OpenMPClauseKind)> 752 Check) const { 753 if (getStackSize() <= Level) 754 return false; 755 756 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 757 auto MI = StackElem.MappedExprComponents.find(VD); 758 if (MI != StackElem.MappedExprComponents.end()) 759 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 760 MI->second.Components) 761 if (Check(L, MI->second.Kind)) 762 return true; 763 return false; 764 } 765 766 /// Create a new mappable expression component list associated with a given 767 /// declaration and initialize it with the provided list of components. 768 void addMappableExpressionComponents( 769 const ValueDecl *VD, 770 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 771 OpenMPClauseKind WhereFoundClauseKind) { 772 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 773 // Create new entry and append the new components there. 774 MEC.Components.resize(MEC.Components.size() + 1); 775 MEC.Components.back().append(Components.begin(), Components.end()); 776 MEC.Kind = WhereFoundClauseKind; 777 } 778 779 unsigned getNestingLevel() const { 780 assert(!isStackEmpty()); 781 return getStackSize() - 1; 782 } 783 void addDoacrossDependClause(OMPDependClause *C, 784 const OperatorOffsetTy &OpsOffs) { 785 SharingMapTy *Parent = getSecondOnStackOrNull(); 786 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 787 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 788 } 789 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 790 getDoacrossDependClauses() const { 791 const SharingMapTy &StackElem = getTopOfStack(); 792 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 793 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 794 return llvm::make_range(Ref.begin(), Ref.end()); 795 } 796 return llvm::make_range(StackElem.DoacrossDepends.end(), 797 StackElem.DoacrossDepends.end()); 798 } 799 800 // Store types of classes which have been explicitly mapped 801 void addMappedClassesQualTypes(QualType QT) { 802 SharingMapTy &StackElem = getTopOfStack(); 803 StackElem.MappedClassesQualTypes.insert(QT); 804 } 805 806 // Return set of mapped classes types 807 bool isClassPreviouslyMapped(QualType QT) const { 808 const SharingMapTy &StackElem = getTopOfStack(); 809 return StackElem.MappedClassesQualTypes.count(QT) != 0; 810 } 811 812 /// Adds global declare target to the parent target region. 813 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 814 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 815 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 816 "Expected declare target link global."); 817 for (auto &Elem : *this) { 818 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 819 Elem.DeclareTargetLinkVarDecls.push_back(E); 820 return; 821 } 822 } 823 } 824 825 /// Returns the list of globals with declare target link if current directive 826 /// is target. 827 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 828 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 829 "Expected target executable directive."); 830 return getTopOfStack().DeclareTargetLinkVarDecls; 831 } 832 }; 833 834 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 835 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 836 } 837 838 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 839 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 840 DKind == OMPD_unknown; 841 } 842 843 } // namespace 844 845 static const Expr *getExprAsWritten(const Expr *E) { 846 if (const auto *FE = dyn_cast<FullExpr>(E)) 847 E = FE->getSubExpr(); 848 849 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 850 E = MTE->GetTemporaryExpr(); 851 852 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 853 E = Binder->getSubExpr(); 854 855 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 856 E = ICE->getSubExprAsWritten(); 857 return E->IgnoreParens(); 858 } 859 860 static Expr *getExprAsWritten(Expr *E) { 861 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 862 } 863 864 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 865 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 866 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 867 D = ME->getMemberDecl(); 868 const auto *VD = dyn_cast<VarDecl>(D); 869 const auto *FD = dyn_cast<FieldDecl>(D); 870 if (VD != nullptr) { 871 VD = VD->getCanonicalDecl(); 872 D = VD; 873 } else { 874 assert(FD); 875 FD = FD->getCanonicalDecl(); 876 D = FD; 877 } 878 return D; 879 } 880 881 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 882 return const_cast<ValueDecl *>( 883 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 884 } 885 886 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 887 ValueDecl *D) const { 888 D = getCanonicalDecl(D); 889 auto *VD = dyn_cast<VarDecl>(D); 890 const auto *FD = dyn_cast<FieldDecl>(D); 891 DSAVarData DVar; 892 if (Iter == end()) { 893 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 894 // in a region but not in construct] 895 // File-scope or namespace-scope variables referenced in called routines 896 // in the region are shared unless they appear in a threadprivate 897 // directive. 898 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 899 DVar.CKind = OMPC_shared; 900 901 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 902 // in a region but not in construct] 903 // Variables with static storage duration that are declared in called 904 // routines in the region are shared. 905 if (VD && VD->hasGlobalStorage()) 906 DVar.CKind = OMPC_shared; 907 908 // Non-static data members are shared by default. 909 if (FD) 910 DVar.CKind = OMPC_shared; 911 912 return DVar; 913 } 914 915 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 916 // in a Construct, C/C++, predetermined, p.1] 917 // Variables with automatic storage duration that are declared in a scope 918 // inside the construct are private. 919 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 920 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 921 DVar.CKind = OMPC_private; 922 return DVar; 923 } 924 925 DVar.DKind = Iter->Directive; 926 // Explicitly specified attributes and local variables with predetermined 927 // attributes. 928 if (Iter->SharingMap.count(D)) { 929 const DSAInfo &Data = Iter->SharingMap.lookup(D); 930 DVar.RefExpr = Data.RefExpr.getPointer(); 931 DVar.PrivateCopy = Data.PrivateCopy; 932 DVar.CKind = Data.Attributes; 933 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 934 return DVar; 935 } 936 937 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 938 // in a Construct, C/C++, implicitly determined, p.1] 939 // In a parallel or task construct, the data-sharing attributes of these 940 // variables are determined by the default clause, if present. 941 switch (Iter->DefaultAttr) { 942 case DSA_shared: 943 DVar.CKind = OMPC_shared; 944 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 945 return DVar; 946 case DSA_none: 947 return DVar; 948 case DSA_unspecified: 949 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 950 // in a Construct, implicitly determined, p.2] 951 // In a parallel construct, if no default clause is present, these 952 // variables are shared. 953 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 954 if (isOpenMPParallelDirective(DVar.DKind) || 955 isOpenMPTeamsDirective(DVar.DKind)) { 956 DVar.CKind = OMPC_shared; 957 return DVar; 958 } 959 960 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 961 // in a Construct, implicitly determined, p.4] 962 // In a task construct, if no default clause is present, a variable that in 963 // the enclosing context is determined to be shared by all implicit tasks 964 // bound to the current team is shared. 965 if (isOpenMPTaskingDirective(DVar.DKind)) { 966 DSAVarData DVarTemp; 967 const_iterator I = Iter, E = end(); 968 do { 969 ++I; 970 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 971 // Referenced in a Construct, implicitly determined, p.6] 972 // In a task construct, if no default clause is present, a variable 973 // whose data-sharing attribute is not determined by the rules above is 974 // firstprivate. 975 DVarTemp = getDSA(I, D); 976 if (DVarTemp.CKind != OMPC_shared) { 977 DVar.RefExpr = nullptr; 978 DVar.CKind = OMPC_firstprivate; 979 return DVar; 980 } 981 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 982 DVar.CKind = 983 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 984 return DVar; 985 } 986 } 987 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 988 // in a Construct, implicitly determined, p.3] 989 // For constructs other than task, if no default clause is present, these 990 // variables inherit their data-sharing attributes from the enclosing 991 // context. 992 return getDSA(++Iter, D); 993 } 994 995 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 996 const Expr *NewDE) { 997 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 998 D = getCanonicalDecl(D); 999 SharingMapTy &StackElem = getTopOfStack(); 1000 auto It = StackElem.AlignedMap.find(D); 1001 if (It == StackElem.AlignedMap.end()) { 1002 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1003 StackElem.AlignedMap[D] = NewDE; 1004 return nullptr; 1005 } 1006 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1007 return It->second; 1008 } 1009 1010 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1011 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1012 D = getCanonicalDecl(D); 1013 SharingMapTy &StackElem = getTopOfStack(); 1014 StackElem.LCVMap.try_emplace( 1015 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1016 } 1017 1018 const DSAStackTy::LCDeclInfo 1019 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1020 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1021 D = getCanonicalDecl(D); 1022 const SharingMapTy &StackElem = getTopOfStack(); 1023 auto It = StackElem.LCVMap.find(D); 1024 if (It != StackElem.LCVMap.end()) 1025 return It->second; 1026 return {0, nullptr}; 1027 } 1028 1029 const DSAStackTy::LCDeclInfo 1030 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1031 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1032 assert(Parent && "Data-sharing attributes stack is empty"); 1033 D = getCanonicalDecl(D); 1034 auto It = Parent->LCVMap.find(D); 1035 if (It != Parent->LCVMap.end()) 1036 return It->second; 1037 return {0, nullptr}; 1038 } 1039 1040 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1041 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1042 assert(Parent && "Data-sharing attributes stack is empty"); 1043 if (Parent->LCVMap.size() < I) 1044 return nullptr; 1045 for (const auto &Pair : Parent->LCVMap) 1046 if (Pair.second.first == I) 1047 return Pair.first; 1048 return nullptr; 1049 } 1050 1051 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1052 DeclRefExpr *PrivateCopy) { 1053 D = getCanonicalDecl(D); 1054 if (A == OMPC_threadprivate) { 1055 DSAInfo &Data = Threadprivates[D]; 1056 Data.Attributes = A; 1057 Data.RefExpr.setPointer(E); 1058 Data.PrivateCopy = nullptr; 1059 } else { 1060 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1061 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1062 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1063 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1064 (isLoopControlVariable(D).first && A == OMPC_private)); 1065 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1066 Data.RefExpr.setInt(/*IntVal=*/true); 1067 return; 1068 } 1069 const bool IsLastprivate = 1070 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1071 Data.Attributes = A; 1072 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1073 Data.PrivateCopy = PrivateCopy; 1074 if (PrivateCopy) { 1075 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1076 Data.Attributes = A; 1077 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1078 Data.PrivateCopy = nullptr; 1079 } 1080 } 1081 } 1082 1083 /// Build a variable declaration for OpenMP loop iteration variable. 1084 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1085 StringRef Name, const AttrVec *Attrs = nullptr, 1086 DeclRefExpr *OrigRef = nullptr) { 1087 DeclContext *DC = SemaRef.CurContext; 1088 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1089 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1090 auto *Decl = 1091 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1092 if (Attrs) { 1093 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1094 I != E; ++I) 1095 Decl->addAttr(*I); 1096 } 1097 Decl->setImplicit(); 1098 if (OrigRef) { 1099 Decl->addAttr( 1100 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1101 } 1102 return Decl; 1103 } 1104 1105 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1106 SourceLocation Loc, 1107 bool RefersToCapture = false) { 1108 D->setReferenced(); 1109 D->markUsed(S.Context); 1110 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1111 SourceLocation(), D, RefersToCapture, Loc, Ty, 1112 VK_LValue); 1113 } 1114 1115 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1116 BinaryOperatorKind BOK) { 1117 D = getCanonicalDecl(D); 1118 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1119 assert( 1120 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1121 "Additional reduction info may be specified only for reduction items."); 1122 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1123 assert(ReductionData.ReductionRange.isInvalid() && 1124 getTopOfStack().Directive == OMPD_taskgroup && 1125 "Additional reduction info may be specified only once for reduction " 1126 "items."); 1127 ReductionData.set(BOK, SR); 1128 Expr *&TaskgroupReductionRef = 1129 getTopOfStack().TaskgroupReductionRef; 1130 if (!TaskgroupReductionRef) { 1131 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1132 SemaRef.Context.VoidPtrTy, ".task_red."); 1133 TaskgroupReductionRef = 1134 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1135 } 1136 } 1137 1138 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1139 const Expr *ReductionRef) { 1140 D = getCanonicalDecl(D); 1141 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1142 assert( 1143 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1144 "Additional reduction info may be specified only for reduction items."); 1145 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1146 assert(ReductionData.ReductionRange.isInvalid() && 1147 getTopOfStack().Directive == OMPD_taskgroup && 1148 "Additional reduction info may be specified only once for reduction " 1149 "items."); 1150 ReductionData.set(ReductionRef, SR); 1151 Expr *&TaskgroupReductionRef = 1152 getTopOfStack().TaskgroupReductionRef; 1153 if (!TaskgroupReductionRef) { 1154 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1155 SemaRef.Context.VoidPtrTy, ".task_red."); 1156 TaskgroupReductionRef = 1157 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1158 } 1159 } 1160 1161 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1162 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1163 Expr *&TaskgroupDescriptor) const { 1164 D = getCanonicalDecl(D); 1165 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1166 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1167 const DSAInfo &Data = I->SharingMap.lookup(D); 1168 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1169 continue; 1170 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1171 if (!ReductionData.ReductionOp || 1172 ReductionData.ReductionOp.is<const Expr *>()) 1173 return DSAVarData(); 1174 SR = ReductionData.ReductionRange; 1175 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1176 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1177 "expression for the descriptor is not " 1178 "set."); 1179 TaskgroupDescriptor = I->TaskgroupReductionRef; 1180 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1181 Data.PrivateCopy, I->DefaultAttrLoc); 1182 } 1183 return DSAVarData(); 1184 } 1185 1186 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1187 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1188 Expr *&TaskgroupDescriptor) const { 1189 D = getCanonicalDecl(D); 1190 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1191 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1192 const DSAInfo &Data = I->SharingMap.lookup(D); 1193 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1194 continue; 1195 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1196 if (!ReductionData.ReductionOp || 1197 !ReductionData.ReductionOp.is<const Expr *>()) 1198 return DSAVarData(); 1199 SR = ReductionData.ReductionRange; 1200 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1201 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1202 "expression for the descriptor is not " 1203 "set."); 1204 TaskgroupDescriptor = I->TaskgroupReductionRef; 1205 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1206 Data.PrivateCopy, I->DefaultAttrLoc); 1207 } 1208 return DSAVarData(); 1209 } 1210 1211 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1212 D = D->getCanonicalDecl(); 1213 for (const_iterator E = end(); I != E; ++I) { 1214 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1215 isOpenMPTargetExecutionDirective(I->Directive)) { 1216 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1217 Scope *CurScope = getCurScope(); 1218 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1219 CurScope = CurScope->getParent(); 1220 return CurScope != TopScope; 1221 } 1222 } 1223 return false; 1224 } 1225 1226 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1227 bool AcceptIfMutable = true, 1228 bool *IsClassType = nullptr) { 1229 ASTContext &Context = SemaRef.getASTContext(); 1230 Type = Type.getNonReferenceType().getCanonicalType(); 1231 bool IsConstant = Type.isConstant(Context); 1232 Type = Context.getBaseElementType(Type); 1233 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1234 ? Type->getAsCXXRecordDecl() 1235 : nullptr; 1236 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1237 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1238 RD = CTD->getTemplatedDecl(); 1239 if (IsClassType) 1240 *IsClassType = RD; 1241 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1242 RD->hasDefinition() && RD->hasMutableFields()); 1243 } 1244 1245 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1246 QualType Type, OpenMPClauseKind CKind, 1247 SourceLocation ELoc, 1248 bool AcceptIfMutable = true, 1249 bool ListItemNotVar = false) { 1250 ASTContext &Context = SemaRef.getASTContext(); 1251 bool IsClassType; 1252 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1253 unsigned Diag = ListItemNotVar 1254 ? diag::err_omp_const_list_item 1255 : IsClassType ? diag::err_omp_const_not_mutable_variable 1256 : diag::err_omp_const_variable; 1257 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1258 if (!ListItemNotVar && D) { 1259 const VarDecl *VD = dyn_cast<VarDecl>(D); 1260 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1261 VarDecl::DeclarationOnly; 1262 SemaRef.Diag(D->getLocation(), 1263 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1264 << D; 1265 } 1266 return true; 1267 } 1268 return false; 1269 } 1270 1271 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1272 bool FromParent) { 1273 D = getCanonicalDecl(D); 1274 DSAVarData DVar; 1275 1276 auto *VD = dyn_cast<VarDecl>(D); 1277 auto TI = Threadprivates.find(D); 1278 if (TI != Threadprivates.end()) { 1279 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1280 DVar.CKind = OMPC_threadprivate; 1281 return DVar; 1282 } 1283 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1284 DVar.RefExpr = buildDeclRefExpr( 1285 SemaRef, VD, D->getType().getNonReferenceType(), 1286 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1287 DVar.CKind = OMPC_threadprivate; 1288 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1289 return DVar; 1290 } 1291 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1292 // in a Construct, C/C++, predetermined, p.1] 1293 // Variables appearing in threadprivate directives are threadprivate. 1294 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1295 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1296 SemaRef.getLangOpts().OpenMPUseTLS && 1297 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1298 (VD && VD->getStorageClass() == SC_Register && 1299 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1300 DVar.RefExpr = buildDeclRefExpr( 1301 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1302 DVar.CKind = OMPC_threadprivate; 1303 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1304 return DVar; 1305 } 1306 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1307 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1308 !isLoopControlVariable(D).first) { 1309 const_iterator IterTarget = 1310 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1311 return isOpenMPTargetExecutionDirective(Data.Directive); 1312 }); 1313 if (IterTarget != end()) { 1314 const_iterator ParentIterTarget = IterTarget + 1; 1315 for (const_iterator Iter = begin(); 1316 Iter != ParentIterTarget; ++Iter) { 1317 if (isOpenMPLocal(VD, Iter)) { 1318 DVar.RefExpr = 1319 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1320 D->getLocation()); 1321 DVar.CKind = OMPC_threadprivate; 1322 return DVar; 1323 } 1324 } 1325 if (!isClauseParsingMode() || IterTarget != begin()) { 1326 auto DSAIter = IterTarget->SharingMap.find(D); 1327 if (DSAIter != IterTarget->SharingMap.end() && 1328 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1329 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1330 DVar.CKind = OMPC_threadprivate; 1331 return DVar; 1332 } 1333 const_iterator End = end(); 1334 if (!SemaRef.isOpenMPCapturedByRef( 1335 D, std::distance(ParentIterTarget, End))) { 1336 DVar.RefExpr = 1337 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1338 IterTarget->ConstructLoc); 1339 DVar.CKind = OMPC_threadprivate; 1340 return DVar; 1341 } 1342 } 1343 } 1344 } 1345 1346 if (isStackEmpty()) 1347 // Not in OpenMP execution region and top scope was already checked. 1348 return DVar; 1349 1350 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1351 // in a Construct, C/C++, predetermined, p.4] 1352 // Static data members are shared. 1353 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1354 // in a Construct, C/C++, predetermined, p.7] 1355 // Variables with static storage duration that are declared in a scope 1356 // inside the construct are shared. 1357 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1358 if (VD && VD->isStaticDataMember()) { 1359 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1360 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1361 return DVar; 1362 1363 DVar.CKind = OMPC_shared; 1364 return DVar; 1365 } 1366 1367 // The predetermined shared attribute for const-qualified types having no 1368 // mutable members was removed after OpenMP 3.1. 1369 if (SemaRef.LangOpts.OpenMP <= 31) { 1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1371 // in a Construct, C/C++, predetermined, p.6] 1372 // Variables with const qualified type having no mutable member are 1373 // shared. 1374 if (isConstNotMutableType(SemaRef, D->getType())) { 1375 // Variables with const-qualified type having no mutable member may be 1376 // listed in a firstprivate clause, even if they are static data members. 1377 DSAVarData DVarTemp = hasInnermostDSA( 1378 D, 1379 [](OpenMPClauseKind C) { 1380 return C == OMPC_firstprivate || C == OMPC_shared; 1381 }, 1382 MatchesAlways, FromParent); 1383 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1384 return DVarTemp; 1385 1386 DVar.CKind = OMPC_shared; 1387 return DVar; 1388 } 1389 } 1390 1391 // Explicitly specified attributes and local variables with predetermined 1392 // attributes. 1393 const_iterator I = begin(); 1394 const_iterator EndI = end(); 1395 if (FromParent && I != EndI) 1396 ++I; 1397 auto It = I->SharingMap.find(D); 1398 if (It != I->SharingMap.end()) { 1399 const DSAInfo &Data = It->getSecond(); 1400 DVar.RefExpr = Data.RefExpr.getPointer(); 1401 DVar.PrivateCopy = Data.PrivateCopy; 1402 DVar.CKind = Data.Attributes; 1403 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1404 DVar.DKind = I->Directive; 1405 } 1406 1407 return DVar; 1408 } 1409 1410 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1411 bool FromParent) const { 1412 if (isStackEmpty()) { 1413 const_iterator I; 1414 return getDSA(I, D); 1415 } 1416 D = getCanonicalDecl(D); 1417 const_iterator StartI = begin(); 1418 const_iterator EndI = end(); 1419 if (FromParent && StartI != EndI) 1420 ++StartI; 1421 return getDSA(StartI, D); 1422 } 1423 1424 const DSAStackTy::DSAVarData 1425 DSAStackTy::hasDSA(ValueDecl *D, 1426 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1427 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1428 bool FromParent) const { 1429 if (isStackEmpty()) 1430 return {}; 1431 D = getCanonicalDecl(D); 1432 const_iterator I = begin(); 1433 const_iterator EndI = end(); 1434 if (FromParent && I != EndI) 1435 ++I; 1436 for (; I != EndI; ++I) { 1437 if (!DPred(I->Directive) && 1438 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1439 continue; 1440 const_iterator NewI = I; 1441 DSAVarData DVar = getDSA(NewI, D); 1442 if (I == NewI && CPred(DVar.CKind)) 1443 return DVar; 1444 } 1445 return {}; 1446 } 1447 1448 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1449 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1450 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1451 bool FromParent) const { 1452 if (isStackEmpty()) 1453 return {}; 1454 D = getCanonicalDecl(D); 1455 const_iterator StartI = begin(); 1456 const_iterator EndI = end(); 1457 if (FromParent && StartI != EndI) 1458 ++StartI; 1459 if (StartI == EndI || !DPred(StartI->Directive)) 1460 return {}; 1461 const_iterator NewI = StartI; 1462 DSAVarData DVar = getDSA(NewI, D); 1463 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1464 } 1465 1466 bool DSAStackTy::hasExplicitDSA( 1467 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1468 unsigned Level, bool NotLastprivate) const { 1469 if (getStackSize() <= Level) 1470 return false; 1471 D = getCanonicalDecl(D); 1472 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1473 auto I = StackElem.SharingMap.find(D); 1474 if (I != StackElem.SharingMap.end() && 1475 I->getSecond().RefExpr.getPointer() && 1476 CPred(I->getSecond().Attributes) && 1477 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1478 return true; 1479 // Check predetermined rules for the loop control variables. 1480 auto LI = StackElem.LCVMap.find(D); 1481 if (LI != StackElem.LCVMap.end()) 1482 return CPred(OMPC_private); 1483 return false; 1484 } 1485 1486 bool DSAStackTy::hasExplicitDirective( 1487 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1488 unsigned Level) const { 1489 if (getStackSize() <= Level) 1490 return false; 1491 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1492 return DPred(StackElem.Directive); 1493 } 1494 1495 bool DSAStackTy::hasDirective( 1496 const llvm::function_ref<bool(OpenMPDirectiveKind, 1497 const DeclarationNameInfo &, SourceLocation)> 1498 DPred, 1499 bool FromParent) const { 1500 // We look only in the enclosing region. 1501 size_t Skip = FromParent ? 2 : 1; 1502 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1503 I != E; ++I) { 1504 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1505 return true; 1506 } 1507 return false; 1508 } 1509 1510 void Sema::InitDataSharingAttributesStack() { 1511 VarDataSharingAttributesStack = new DSAStackTy(*this); 1512 } 1513 1514 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1515 1516 void Sema::pushOpenMPFunctionRegion() { 1517 DSAStack->pushFunction(); 1518 } 1519 1520 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1521 DSAStack->popFunction(OldFSI); 1522 } 1523 1524 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1525 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1526 "Expected OpenMP device compilation."); 1527 return !S.isInOpenMPTargetExecutionDirective() && 1528 !S.isInOpenMPDeclareTargetContext(); 1529 } 1530 1531 /// Do we know that we will eventually codegen the given function? 1532 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1533 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1534 "Expected OpenMP device compilation."); 1535 // Templates are emitted when they're instantiated. 1536 if (FD->isDependentContext()) 1537 return false; 1538 1539 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1540 FD->getCanonicalDecl())) 1541 return true; 1542 1543 // Otherwise, the function is known-emitted if it's in our set of 1544 // known-emitted functions. 1545 return S.DeviceKnownEmittedFns.count(FD) > 0; 1546 } 1547 1548 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1549 unsigned DiagID) { 1550 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1551 "Expected OpenMP device compilation."); 1552 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1553 !isKnownEmitted(*this, getCurFunctionDecl())) 1554 ? DeviceDiagBuilder::K_Deferred 1555 : DeviceDiagBuilder::K_Immediate, 1556 Loc, DiagID, getCurFunctionDecl(), *this); 1557 } 1558 1559 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1560 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1561 "Expected OpenMP device compilation."); 1562 assert(Callee && "Callee may not be null."); 1563 FunctionDecl *Caller = getCurFunctionDecl(); 1564 1565 // If the caller is known-emitted, mark the callee as known-emitted. 1566 // Otherwise, mark the call in our call graph so we can traverse it later. 1567 if (!isOpenMPDeviceDelayedContext(*this) || 1568 (Caller && isKnownEmitted(*this, Caller))) 1569 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1570 else if (Caller) 1571 DeviceCallGraph[Caller].insert({Callee, Loc}); 1572 } 1573 1574 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1575 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1576 "OpenMP device compilation mode is expected."); 1577 QualType Ty = E->getType(); 1578 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1579 (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) || 1580 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1581 !Context.getTargetInfo().hasInt128Type())) 1582 targetDiag(E->getExprLoc(), diag::err_type_unsupported) 1583 << Ty << E->getSourceRange(); 1584 } 1585 1586 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1587 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1588 1589 ASTContext &Ctx = getASTContext(); 1590 bool IsByRef = true; 1591 1592 // Find the directive that is associated with the provided scope. 1593 D = cast<ValueDecl>(D->getCanonicalDecl()); 1594 QualType Ty = D->getType(); 1595 1596 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1597 // This table summarizes how a given variable should be passed to the device 1598 // given its type and the clauses where it appears. This table is based on 1599 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1600 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1601 // 1602 // ========================================================================= 1603 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1604 // | |(tofrom:scalar)| | pvt | | | | 1605 // ========================================================================= 1606 // | scl | | | | - | | bycopy| 1607 // | scl | | - | x | - | - | bycopy| 1608 // | scl | | x | - | - | - | null | 1609 // | scl | x | | | - | | byref | 1610 // | scl | x | - | x | - | - | bycopy| 1611 // | scl | x | x | - | - | - | null | 1612 // | scl | | - | - | - | x | byref | 1613 // | scl | x | - | - | - | x | byref | 1614 // 1615 // | agg | n.a. | | | - | | byref | 1616 // | agg | n.a. | - | x | - | - | byref | 1617 // | agg | n.a. | x | - | - | - | null | 1618 // | agg | n.a. | - | - | - | x | byref | 1619 // | agg | n.a. | - | - | - | x[] | byref | 1620 // 1621 // | ptr | n.a. | | | - | | bycopy| 1622 // | ptr | n.a. | - | x | - | - | bycopy| 1623 // | ptr | n.a. | x | - | - | - | null | 1624 // | ptr | n.a. | - | - | - | x | byref | 1625 // | ptr | n.a. | - | - | - | x[] | bycopy| 1626 // | ptr | n.a. | - | - | x | | bycopy| 1627 // | ptr | n.a. | - | - | x | x | bycopy| 1628 // | ptr | n.a. | - | - | x | x[] | bycopy| 1629 // ========================================================================= 1630 // Legend: 1631 // scl - scalar 1632 // ptr - pointer 1633 // agg - aggregate 1634 // x - applies 1635 // - - invalid in this combination 1636 // [] - mapped with an array section 1637 // byref - should be mapped by reference 1638 // byval - should be mapped by value 1639 // null - initialize a local variable to null on the device 1640 // 1641 // Observations: 1642 // - All scalar declarations that show up in a map clause have to be passed 1643 // by reference, because they may have been mapped in the enclosing data 1644 // environment. 1645 // - If the scalar value does not fit the size of uintptr, it has to be 1646 // passed by reference, regardless the result in the table above. 1647 // - For pointers mapped by value that have either an implicit map or an 1648 // array section, the runtime library may pass the NULL value to the 1649 // device instead of the value passed to it by the compiler. 1650 1651 if (Ty->isReferenceType()) 1652 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1653 1654 // Locate map clauses and see if the variable being captured is referred to 1655 // in any of those clauses. Here we only care about variables, not fields, 1656 // because fields are part of aggregates. 1657 bool IsVariableUsedInMapClause = false; 1658 bool IsVariableAssociatedWithSection = false; 1659 1660 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1661 D, Level, 1662 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1663 OMPClauseMappableExprCommon::MappableExprComponentListRef 1664 MapExprComponents, 1665 OpenMPClauseKind WhereFoundClauseKind) { 1666 // Only the map clause information influences how a variable is 1667 // captured. E.g. is_device_ptr does not require changing the default 1668 // behavior. 1669 if (WhereFoundClauseKind != OMPC_map) 1670 return false; 1671 1672 auto EI = MapExprComponents.rbegin(); 1673 auto EE = MapExprComponents.rend(); 1674 1675 assert(EI != EE && "Invalid map expression!"); 1676 1677 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1678 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1679 1680 ++EI; 1681 if (EI == EE) 1682 return false; 1683 1684 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1685 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1686 isa<MemberExpr>(EI->getAssociatedExpression())) { 1687 IsVariableAssociatedWithSection = true; 1688 // There is nothing more we need to know about this variable. 1689 return true; 1690 } 1691 1692 // Keep looking for more map info. 1693 return false; 1694 }); 1695 1696 if (IsVariableUsedInMapClause) { 1697 // If variable is identified in a map clause it is always captured by 1698 // reference except if it is a pointer that is dereferenced somehow. 1699 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1700 } else { 1701 // By default, all the data that has a scalar type is mapped by copy 1702 // (except for reduction variables). 1703 IsByRef = 1704 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1705 !Ty->isAnyPointerType()) || 1706 !Ty->isScalarType() || 1707 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1708 DSAStack->hasExplicitDSA( 1709 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1710 } 1711 } 1712 1713 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1714 IsByRef = 1715 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1716 !Ty->isAnyPointerType()) || 1717 !DSAStack->hasExplicitDSA( 1718 D, 1719 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1720 Level, /*NotLastprivate=*/true)) && 1721 // If the variable is artificial and must be captured by value - try to 1722 // capture by value. 1723 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1724 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1725 } 1726 1727 // When passing data by copy, we need to make sure it fits the uintptr size 1728 // and alignment, because the runtime library only deals with uintptr types. 1729 // If it does not fit the uintptr size, we need to pass the data by reference 1730 // instead. 1731 if (!IsByRef && 1732 (Ctx.getTypeSizeInChars(Ty) > 1733 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1734 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1735 IsByRef = true; 1736 } 1737 1738 return IsByRef; 1739 } 1740 1741 unsigned Sema::getOpenMPNestingLevel() const { 1742 assert(getLangOpts().OpenMP); 1743 return DSAStack->getNestingLevel(); 1744 } 1745 1746 bool Sema::isInOpenMPTargetExecutionDirective() const { 1747 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1748 !DSAStack->isClauseParsingMode()) || 1749 DSAStack->hasDirective( 1750 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1751 SourceLocation) -> bool { 1752 return isOpenMPTargetExecutionDirective(K); 1753 }, 1754 false); 1755 } 1756 1757 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1758 unsigned StopAt) { 1759 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1760 D = getCanonicalDecl(D); 1761 1762 // If we want to determine whether the variable should be captured from the 1763 // perspective of the current capturing scope, and we've already left all the 1764 // capturing scopes of the top directive on the stack, check from the 1765 // perspective of its parent directive (if any) instead. 1766 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1767 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1768 1769 // If we are attempting to capture a global variable in a directive with 1770 // 'target' we return true so that this global is also mapped to the device. 1771 // 1772 auto *VD = dyn_cast<VarDecl>(D); 1773 if (VD && !VD->hasLocalStorage() && 1774 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1775 if (isInOpenMPDeclareTargetContext()) { 1776 // Try to mark variable as declare target if it is used in capturing 1777 // regions. 1778 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1779 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1780 return nullptr; 1781 } else if (isInOpenMPTargetExecutionDirective()) { 1782 // If the declaration is enclosed in a 'declare target' directive, 1783 // then it should not be captured. 1784 // 1785 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1786 return nullptr; 1787 return VD; 1788 } 1789 } 1790 // Capture variables captured by reference in lambdas for target-based 1791 // directives. 1792 // FIXME: Triggering capture from here is completely inappropriate. 1793 if (VD && !DSAStack->isClauseParsingMode()) { 1794 if (const auto *RD = VD->getType() 1795 .getCanonicalType() 1796 .getNonReferenceType() 1797 ->getAsCXXRecordDecl()) { 1798 bool SavedForceCaptureByReferenceInTargetExecutable = 1799 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1800 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1801 InParentDirectiveRAII.disable(); 1802 if (RD->isLambda()) { 1803 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1804 FieldDecl *ThisCapture; 1805 RD->getCaptureFields(Captures, ThisCapture); 1806 for (const LambdaCapture &LC : RD->captures()) { 1807 if (LC.getCaptureKind() == LCK_ByRef) { 1808 VarDecl *VD = LC.getCapturedVar(); 1809 DeclContext *VDC = VD->getDeclContext(); 1810 if (!VDC->Encloses(CurContext)) 1811 continue; 1812 DSAStackTy::DSAVarData DVarPrivate = 1813 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1814 // Do not capture already captured variables. 1815 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1816 DVarPrivate.CKind == OMPC_unknown && 1817 !DSAStack->checkMappableExprComponentListsForDecl( 1818 D, /*CurrentRegionOnly=*/true, 1819 [](OMPClauseMappableExprCommon:: 1820 MappableExprComponentListRef, 1821 OpenMPClauseKind) { return true; })) 1822 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1823 } else if (LC.getCaptureKind() == LCK_This) { 1824 QualType ThisTy = getCurrentThisType(); 1825 if (!ThisTy.isNull() && 1826 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1827 CheckCXXThisCapture(LC.getLocation()); 1828 } 1829 } 1830 } 1831 if (CheckScopeInfo && DSAStack->isBodyComplete()) 1832 InParentDirectiveRAII.enable(); 1833 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1834 SavedForceCaptureByReferenceInTargetExecutable); 1835 } 1836 } 1837 1838 if (CheckScopeInfo) { 1839 bool OpenMPFound = false; 1840 for (unsigned I = StopAt + 1; I > 0; --I) { 1841 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1842 if(!isa<CapturingScopeInfo>(FSI)) 1843 return nullptr; 1844 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1845 if (RSI->CapRegionKind == CR_OpenMP) { 1846 OpenMPFound = true; 1847 break; 1848 } 1849 } 1850 if (!OpenMPFound) 1851 return nullptr; 1852 } 1853 1854 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1855 (!DSAStack->isClauseParsingMode() || 1856 DSAStack->getParentDirective() != OMPD_unknown)) { 1857 auto &&Info = DSAStack->isLoopControlVariable(D); 1858 if (Info.first || 1859 (VD && VD->hasLocalStorage() && 1860 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1861 (VD && DSAStack->isForceVarCapturing())) 1862 return VD ? VD : Info.second; 1863 DSAStackTy::DSAVarData DVarPrivate = 1864 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1865 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1866 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1867 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1868 [](OpenMPDirectiveKind) { return true; }, 1869 DSAStack->isClauseParsingMode()); 1870 // The variable is not private or it is the variable in the directive with 1871 // default(none) clause and not used in any clause. 1872 if (DVarPrivate.CKind != OMPC_unknown || 1873 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1874 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1875 } 1876 return nullptr; 1877 } 1878 1879 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1880 unsigned Level) const { 1881 SmallVector<OpenMPDirectiveKind, 4> Regions; 1882 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1883 FunctionScopesIndex -= Regions.size(); 1884 } 1885 1886 void Sema::startOpenMPLoop() { 1887 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1888 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1889 DSAStack->loopInit(); 1890 } 1891 1892 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1893 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1894 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1895 if (DSAStack->getAssociatedLoops() > 0 && 1896 !DSAStack->isLoopStarted()) { 1897 DSAStack->resetPossibleLoopCounter(D); 1898 DSAStack->loopStart(); 1899 return true; 1900 } 1901 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1902 DSAStack->isLoopControlVariable(D).first) && 1903 !DSAStack->hasExplicitDSA( 1904 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1905 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1906 return true; 1907 } 1908 return DSAStack->hasExplicitDSA( 1909 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1910 (DSAStack->isClauseParsingMode() && 1911 DSAStack->getClauseParsingMode() == OMPC_private) || 1912 // Consider taskgroup reduction descriptor variable a private to avoid 1913 // possible capture in the region. 1914 (DSAStack->hasExplicitDirective( 1915 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1916 Level) && 1917 DSAStack->isTaskgroupReductionRef(D, Level)); 1918 } 1919 1920 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1921 unsigned Level) { 1922 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1923 D = getCanonicalDecl(D); 1924 OpenMPClauseKind OMPC = OMPC_unknown; 1925 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1926 const unsigned NewLevel = I - 1; 1927 if (DSAStack->hasExplicitDSA(D, 1928 [&OMPC](const OpenMPClauseKind K) { 1929 if (isOpenMPPrivate(K)) { 1930 OMPC = K; 1931 return true; 1932 } 1933 return false; 1934 }, 1935 NewLevel)) 1936 break; 1937 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1938 D, NewLevel, 1939 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1940 OpenMPClauseKind) { return true; })) { 1941 OMPC = OMPC_map; 1942 break; 1943 } 1944 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1945 NewLevel)) { 1946 OMPC = OMPC_map; 1947 if (D->getType()->isScalarType() && 1948 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1949 DefaultMapAttributes::DMA_tofrom_scalar) 1950 OMPC = OMPC_firstprivate; 1951 break; 1952 } 1953 } 1954 if (OMPC != OMPC_unknown) 1955 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1956 } 1957 1958 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1959 unsigned Level) const { 1960 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1961 // Return true if the current level is no longer enclosed in a target region. 1962 1963 const auto *VD = dyn_cast<VarDecl>(D); 1964 return VD && !VD->hasLocalStorage() && 1965 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1966 Level); 1967 } 1968 1969 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1970 1971 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1972 const DeclarationNameInfo &DirName, 1973 Scope *CurScope, SourceLocation Loc) { 1974 DSAStack->push(DKind, DirName, CurScope, Loc); 1975 PushExpressionEvaluationContext( 1976 ExpressionEvaluationContext::PotentiallyEvaluated); 1977 } 1978 1979 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1980 DSAStack->setClauseParsingMode(K); 1981 } 1982 1983 void Sema::EndOpenMPClause() { 1984 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1985 } 1986 1987 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 1988 ArrayRef<OMPClause *> Clauses); 1989 1990 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1991 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1992 // A variable of class type (or array thereof) that appears in a lastprivate 1993 // clause requires an accessible, unambiguous default constructor for the 1994 // class type, unless the list item is also specified in a firstprivate 1995 // clause. 1996 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1997 for (OMPClause *C : D->clauses()) { 1998 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1999 SmallVector<Expr *, 8> PrivateCopies; 2000 for (Expr *DE : Clause->varlists()) { 2001 if (DE->isValueDependent() || DE->isTypeDependent()) { 2002 PrivateCopies.push_back(nullptr); 2003 continue; 2004 } 2005 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2006 auto *VD = cast<VarDecl>(DRE->getDecl()); 2007 QualType Type = VD->getType().getNonReferenceType(); 2008 const DSAStackTy::DSAVarData DVar = 2009 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2010 if (DVar.CKind == OMPC_lastprivate) { 2011 // Generate helper private variable and initialize it with the 2012 // default value. The address of the original variable is replaced 2013 // by the address of the new private variable in CodeGen. This new 2014 // variable is not added to IdResolver, so the code in the OpenMP 2015 // region uses original variable for proper diagnostics. 2016 VarDecl *VDPrivate = buildVarDecl( 2017 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2018 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2019 ActOnUninitializedDecl(VDPrivate); 2020 if (VDPrivate->isInvalidDecl()) { 2021 PrivateCopies.push_back(nullptr); 2022 continue; 2023 } 2024 PrivateCopies.push_back(buildDeclRefExpr( 2025 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2026 } else { 2027 // The variable is also a firstprivate, so initialization sequence 2028 // for private copy is generated already. 2029 PrivateCopies.push_back(nullptr); 2030 } 2031 } 2032 Clause->setPrivateCopies(PrivateCopies); 2033 } 2034 } 2035 // Check allocate clauses. 2036 if (!CurContext->isDependentContext()) 2037 checkAllocateClauses(*this, DSAStack, D->clauses()); 2038 } 2039 2040 DSAStack->pop(); 2041 DiscardCleanupsInEvaluationContext(); 2042 PopExpressionEvaluationContext(); 2043 } 2044 2045 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2046 Expr *NumIterations, Sema &SemaRef, 2047 Scope *S, DSAStackTy *Stack); 2048 2049 namespace { 2050 2051 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2052 private: 2053 Sema &SemaRef; 2054 2055 public: 2056 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2057 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2058 NamedDecl *ND = Candidate.getCorrectionDecl(); 2059 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2060 return VD->hasGlobalStorage() && 2061 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2062 SemaRef.getCurScope()); 2063 } 2064 return false; 2065 } 2066 2067 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2068 return llvm::make_unique<VarDeclFilterCCC>(*this); 2069 } 2070 2071 }; 2072 2073 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2074 private: 2075 Sema &SemaRef; 2076 2077 public: 2078 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2079 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2080 NamedDecl *ND = Candidate.getCorrectionDecl(); 2081 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2082 isa<FunctionDecl>(ND))) { 2083 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2084 SemaRef.getCurScope()); 2085 } 2086 return false; 2087 } 2088 2089 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2090 return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this); 2091 } 2092 }; 2093 2094 } // namespace 2095 2096 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2097 CXXScopeSpec &ScopeSpec, 2098 const DeclarationNameInfo &Id, 2099 OpenMPDirectiveKind Kind) { 2100 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2101 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2102 2103 if (Lookup.isAmbiguous()) 2104 return ExprError(); 2105 2106 VarDecl *VD; 2107 if (!Lookup.isSingleResult()) { 2108 VarDeclFilterCCC CCC(*this); 2109 if (TypoCorrection Corrected = 2110 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2111 CTK_ErrorRecovery)) { 2112 diagnoseTypo(Corrected, 2113 PDiag(Lookup.empty() 2114 ? diag::err_undeclared_var_use_suggest 2115 : diag::err_omp_expected_var_arg_suggest) 2116 << Id.getName()); 2117 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2118 } else { 2119 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2120 : diag::err_omp_expected_var_arg) 2121 << Id.getName(); 2122 return ExprError(); 2123 } 2124 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2125 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2126 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2127 return ExprError(); 2128 } 2129 Lookup.suppressDiagnostics(); 2130 2131 // OpenMP [2.9.2, Syntax, C/C++] 2132 // Variables must be file-scope, namespace-scope, or static block-scope. 2133 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2134 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2135 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2136 bool IsDecl = 2137 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2138 Diag(VD->getLocation(), 2139 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2140 << VD; 2141 return ExprError(); 2142 } 2143 2144 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2145 NamedDecl *ND = CanonicalVD; 2146 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2147 // A threadprivate directive for file-scope variables must appear outside 2148 // any definition or declaration. 2149 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2150 !getCurLexicalContext()->isTranslationUnit()) { 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.3] 2161 // A threadprivate directive for static class member variables must appear 2162 // in the class definition, in the same scope in which the member 2163 // variables are declared. 2164 if (CanonicalVD->isStaticDataMember() && 2165 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2166 Diag(Id.getLoc(), diag::err_omp_var_scope) 2167 << getOpenMPDirectiveName(Kind) << VD; 2168 bool IsDecl = 2169 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2170 Diag(VD->getLocation(), 2171 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2172 << VD; 2173 return ExprError(); 2174 } 2175 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2176 // A threadprivate directive for namespace-scope variables must appear 2177 // outside any definition or declaration other than the namespace 2178 // definition itself. 2179 if (CanonicalVD->getDeclContext()->isNamespace() && 2180 (!getCurLexicalContext()->isFileContext() || 2181 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2182 Diag(Id.getLoc(), diag::err_omp_var_scope) 2183 << getOpenMPDirectiveName(Kind) << VD; 2184 bool IsDecl = 2185 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2186 Diag(VD->getLocation(), 2187 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2188 << VD; 2189 return ExprError(); 2190 } 2191 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2192 // A threadprivate directive for static block-scope variables must appear 2193 // in the scope of the variable and not in a nested scope. 2194 if (CanonicalVD->isLocalVarDecl() && CurScope && 2195 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2196 Diag(Id.getLoc(), diag::err_omp_var_scope) 2197 << getOpenMPDirectiveName(Kind) << VD; 2198 bool IsDecl = 2199 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2200 Diag(VD->getLocation(), 2201 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2202 << VD; 2203 return ExprError(); 2204 } 2205 2206 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2207 // A threadprivate directive must lexically precede all references to any 2208 // of the variables in its list. 2209 if (Kind == OMPD_threadprivate && VD->isUsed() && 2210 !DSAStack->isThreadPrivate(VD)) { 2211 Diag(Id.getLoc(), diag::err_omp_var_used) 2212 << getOpenMPDirectiveName(Kind) << VD; 2213 return ExprError(); 2214 } 2215 2216 QualType ExprType = VD->getType().getNonReferenceType(); 2217 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2218 SourceLocation(), VD, 2219 /*RefersToEnclosingVariableOrCapture=*/false, 2220 Id.getLoc(), ExprType, VK_LValue); 2221 } 2222 2223 Sema::DeclGroupPtrTy 2224 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2225 ArrayRef<Expr *> VarList) { 2226 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2227 CurContext->addDecl(D); 2228 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2229 } 2230 return nullptr; 2231 } 2232 2233 namespace { 2234 class LocalVarRefChecker final 2235 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2236 Sema &SemaRef; 2237 2238 public: 2239 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2240 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2241 if (VD->hasLocalStorage()) { 2242 SemaRef.Diag(E->getBeginLoc(), 2243 diag::err_omp_local_var_in_threadprivate_init) 2244 << E->getSourceRange(); 2245 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2246 << VD << VD->getSourceRange(); 2247 return true; 2248 } 2249 } 2250 return false; 2251 } 2252 bool VisitStmt(const Stmt *S) { 2253 for (const Stmt *Child : S->children()) { 2254 if (Child && Visit(Child)) 2255 return true; 2256 } 2257 return false; 2258 } 2259 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2260 }; 2261 } // namespace 2262 2263 OMPThreadPrivateDecl * 2264 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2265 SmallVector<Expr *, 8> Vars; 2266 for (Expr *RefExpr : VarList) { 2267 auto *DE = cast<DeclRefExpr>(RefExpr); 2268 auto *VD = cast<VarDecl>(DE->getDecl()); 2269 SourceLocation ILoc = DE->getExprLoc(); 2270 2271 // Mark variable as used. 2272 VD->setReferenced(); 2273 VD->markUsed(Context); 2274 2275 QualType QType = VD->getType(); 2276 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2277 // It will be analyzed later. 2278 Vars.push_back(DE); 2279 continue; 2280 } 2281 2282 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2283 // A threadprivate variable must not have an incomplete type. 2284 if (RequireCompleteType(ILoc, VD->getType(), 2285 diag::err_omp_threadprivate_incomplete_type)) { 2286 continue; 2287 } 2288 2289 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2290 // A threadprivate variable must not have a reference type. 2291 if (VD->getType()->isReferenceType()) { 2292 Diag(ILoc, diag::err_omp_ref_type_arg) 2293 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2294 bool IsDecl = 2295 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2296 Diag(VD->getLocation(), 2297 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2298 << VD; 2299 continue; 2300 } 2301 2302 // Check if this is a TLS variable. If TLS is not being supported, produce 2303 // the corresponding diagnostic. 2304 if ((VD->getTLSKind() != VarDecl::TLS_None && 2305 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2306 getLangOpts().OpenMPUseTLS && 2307 getASTContext().getTargetInfo().isTLSSupported())) || 2308 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2309 !VD->isLocalVarDecl())) { 2310 Diag(ILoc, diag::err_omp_var_thread_local) 2311 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2312 bool IsDecl = 2313 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2314 Diag(VD->getLocation(), 2315 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2316 << VD; 2317 continue; 2318 } 2319 2320 // Check if initial value of threadprivate variable reference variable with 2321 // local storage (it is not supported by runtime). 2322 if (const Expr *Init = VD->getAnyInitializer()) { 2323 LocalVarRefChecker Checker(*this); 2324 if (Checker.Visit(Init)) 2325 continue; 2326 } 2327 2328 Vars.push_back(RefExpr); 2329 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2330 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2331 Context, SourceRange(Loc, Loc))); 2332 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2333 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2334 } 2335 OMPThreadPrivateDecl *D = nullptr; 2336 if (!Vars.empty()) { 2337 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2338 Vars); 2339 D->setAccess(AS_public); 2340 } 2341 return D; 2342 } 2343 2344 static OMPAllocateDeclAttr::AllocatorTypeTy 2345 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2346 if (!Allocator) 2347 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2348 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2349 Allocator->isInstantiationDependent() || 2350 Allocator->containsUnexpandedParameterPack()) 2351 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2352 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2353 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2354 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2355 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2356 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2357 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2358 llvm::FoldingSetNodeID AEId, DAEId; 2359 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2360 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2361 if (AEId == DAEId) { 2362 AllocatorKindRes = AllocatorKind; 2363 break; 2364 } 2365 } 2366 return AllocatorKindRes; 2367 } 2368 2369 static bool checkPreviousOMPAllocateAttribute( 2370 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2371 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2372 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2373 return false; 2374 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2375 Expr *PrevAllocator = A->getAllocator(); 2376 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2377 getAllocatorKind(S, Stack, PrevAllocator); 2378 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2379 if (AllocatorsMatch && 2380 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2381 Allocator && PrevAllocator) { 2382 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2383 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2384 llvm::FoldingSetNodeID AEId, PAEId; 2385 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2386 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2387 AllocatorsMatch = AEId == PAEId; 2388 } 2389 if (!AllocatorsMatch) { 2390 SmallString<256> AllocatorBuffer; 2391 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2392 if (Allocator) 2393 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2394 SmallString<256> PrevAllocatorBuffer; 2395 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2396 if (PrevAllocator) 2397 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2398 S.getPrintingPolicy()); 2399 2400 SourceLocation AllocatorLoc = 2401 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2402 SourceRange AllocatorRange = 2403 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2404 SourceLocation PrevAllocatorLoc = 2405 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2406 SourceRange PrevAllocatorRange = 2407 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2408 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2409 << (Allocator ? 1 : 0) << AllocatorStream.str() 2410 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2411 << AllocatorRange; 2412 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2413 << PrevAllocatorRange; 2414 return true; 2415 } 2416 return false; 2417 } 2418 2419 static void 2420 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2421 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2422 Expr *Allocator, SourceRange SR) { 2423 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2424 return; 2425 if (Allocator && 2426 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2427 Allocator->isInstantiationDependent() || 2428 Allocator->containsUnexpandedParameterPack())) 2429 return; 2430 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2431 Allocator, SR); 2432 VD->addAttr(A); 2433 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2434 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2435 } 2436 2437 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2438 SourceLocation Loc, ArrayRef<Expr *> VarList, 2439 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2440 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2441 Expr *Allocator = nullptr; 2442 if (Clauses.empty()) { 2443 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2444 // allocate directives that appear in a target region must specify an 2445 // allocator clause unless a requires directive with the dynamic_allocators 2446 // clause is present in the same compilation unit. 2447 if (LangOpts.OpenMPIsDevice && 2448 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2449 targetDiag(Loc, diag::err_expected_allocator_clause); 2450 } else { 2451 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2452 } 2453 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2454 getAllocatorKind(*this, DSAStack, Allocator); 2455 SmallVector<Expr *, 8> Vars; 2456 for (Expr *RefExpr : VarList) { 2457 auto *DE = cast<DeclRefExpr>(RefExpr); 2458 auto *VD = cast<VarDecl>(DE->getDecl()); 2459 2460 // Check if this is a TLS variable or global register. 2461 if (VD->getTLSKind() != VarDecl::TLS_None || 2462 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2463 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2464 !VD->isLocalVarDecl())) 2465 continue; 2466 2467 // If the used several times in the allocate directive, the same allocator 2468 // must be used. 2469 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2470 AllocatorKind, Allocator)) 2471 continue; 2472 2473 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2474 // If a list item has a static storage type, the allocator expression in the 2475 // allocator clause must be a constant expression that evaluates to one of 2476 // the predefined memory allocator values. 2477 if (Allocator && VD->hasGlobalStorage()) { 2478 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2479 Diag(Allocator->getExprLoc(), 2480 diag::err_omp_expected_predefined_allocator) 2481 << Allocator->getSourceRange(); 2482 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2483 VarDecl::DeclarationOnly; 2484 Diag(VD->getLocation(), 2485 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2486 << VD; 2487 continue; 2488 } 2489 } 2490 2491 Vars.push_back(RefExpr); 2492 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2493 DE->getSourceRange()); 2494 } 2495 if (Vars.empty()) 2496 return nullptr; 2497 if (!Owner) 2498 Owner = getCurLexicalContext(); 2499 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2500 D->setAccess(AS_public); 2501 Owner->addDecl(D); 2502 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2503 } 2504 2505 Sema::DeclGroupPtrTy 2506 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2507 ArrayRef<OMPClause *> ClauseList) { 2508 OMPRequiresDecl *D = nullptr; 2509 if (!CurContext->isFileContext()) { 2510 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2511 } else { 2512 D = CheckOMPRequiresDecl(Loc, ClauseList); 2513 if (D) { 2514 CurContext->addDecl(D); 2515 DSAStack->addRequiresDecl(D); 2516 } 2517 } 2518 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2519 } 2520 2521 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2522 ArrayRef<OMPClause *> ClauseList) { 2523 /// For target specific clauses, the requires directive cannot be 2524 /// specified after the handling of any of the target regions in the 2525 /// current compilation unit. 2526 ArrayRef<SourceLocation> TargetLocations = 2527 DSAStack->getEncounteredTargetLocs(); 2528 if (!TargetLocations.empty()) { 2529 for (const OMPClause *CNew : ClauseList) { 2530 // Check if any of the requires clauses affect target regions. 2531 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2532 isa<OMPUnifiedAddressClause>(CNew) || 2533 isa<OMPReverseOffloadClause>(CNew) || 2534 isa<OMPDynamicAllocatorsClause>(CNew)) { 2535 Diag(Loc, diag::err_omp_target_before_requires) 2536 << getOpenMPClauseName(CNew->getClauseKind()); 2537 for (SourceLocation TargetLoc : TargetLocations) { 2538 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2539 } 2540 } 2541 } 2542 } 2543 2544 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2545 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2546 ClauseList); 2547 return nullptr; 2548 } 2549 2550 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2551 const ValueDecl *D, 2552 const DSAStackTy::DSAVarData &DVar, 2553 bool IsLoopIterVar = false) { 2554 if (DVar.RefExpr) { 2555 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2556 << getOpenMPClauseName(DVar.CKind); 2557 return; 2558 } 2559 enum { 2560 PDSA_StaticMemberShared, 2561 PDSA_StaticLocalVarShared, 2562 PDSA_LoopIterVarPrivate, 2563 PDSA_LoopIterVarLinear, 2564 PDSA_LoopIterVarLastprivate, 2565 PDSA_ConstVarShared, 2566 PDSA_GlobalVarShared, 2567 PDSA_TaskVarFirstprivate, 2568 PDSA_LocalVarPrivate, 2569 PDSA_Implicit 2570 } Reason = PDSA_Implicit; 2571 bool ReportHint = false; 2572 auto ReportLoc = D->getLocation(); 2573 auto *VD = dyn_cast<VarDecl>(D); 2574 if (IsLoopIterVar) { 2575 if (DVar.CKind == OMPC_private) 2576 Reason = PDSA_LoopIterVarPrivate; 2577 else if (DVar.CKind == OMPC_lastprivate) 2578 Reason = PDSA_LoopIterVarLastprivate; 2579 else 2580 Reason = PDSA_LoopIterVarLinear; 2581 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2582 DVar.CKind == OMPC_firstprivate) { 2583 Reason = PDSA_TaskVarFirstprivate; 2584 ReportLoc = DVar.ImplicitDSALoc; 2585 } else if (VD && VD->isStaticLocal()) 2586 Reason = PDSA_StaticLocalVarShared; 2587 else if (VD && VD->isStaticDataMember()) 2588 Reason = PDSA_StaticMemberShared; 2589 else if (VD && VD->isFileVarDecl()) 2590 Reason = PDSA_GlobalVarShared; 2591 else if (D->getType().isConstant(SemaRef.getASTContext())) 2592 Reason = PDSA_ConstVarShared; 2593 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2594 ReportHint = true; 2595 Reason = PDSA_LocalVarPrivate; 2596 } 2597 if (Reason != PDSA_Implicit) { 2598 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2599 << Reason << ReportHint 2600 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2601 } else if (DVar.ImplicitDSALoc.isValid()) { 2602 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2603 << getOpenMPClauseName(DVar.CKind); 2604 } 2605 } 2606 2607 namespace { 2608 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2609 DSAStackTy *Stack; 2610 Sema &SemaRef; 2611 bool ErrorFound = false; 2612 CapturedStmt *CS = nullptr; 2613 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2614 llvm::SmallVector<Expr *, 4> ImplicitMap; 2615 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2616 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2617 2618 void VisitSubCaptures(OMPExecutableDirective *S) { 2619 // Check implicitly captured variables. 2620 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2621 return; 2622 for (const CapturedStmt::Capture &Cap : 2623 S->getInnermostCapturedStmt()->captures()) { 2624 if (!Cap.capturesVariable()) 2625 continue; 2626 VarDecl *VD = Cap.getCapturedVar(); 2627 // Do not try to map the variable if it or its sub-component was mapped 2628 // already. 2629 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2630 Stack->checkMappableExprComponentListsForDecl( 2631 VD, /*CurrentRegionOnly=*/true, 2632 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2633 OpenMPClauseKind) { return true; })) 2634 continue; 2635 DeclRefExpr *DRE = buildDeclRefExpr( 2636 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2637 Cap.getLocation(), /*RefersToCapture=*/true); 2638 Visit(DRE); 2639 } 2640 } 2641 2642 public: 2643 void VisitDeclRefExpr(DeclRefExpr *E) { 2644 if (E->isTypeDependent() || E->isValueDependent() || 2645 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2646 return; 2647 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2648 // Check the datasharing rules for the expressions in the clauses. 2649 if (!CS) { 2650 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2651 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2652 Visit(CED->getInit()); 2653 return; 2654 } 2655 } 2656 VD = VD->getCanonicalDecl(); 2657 // Skip internally declared variables. 2658 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2659 return; 2660 2661 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2662 // Check if the variable has explicit DSA set and stop analysis if it so. 2663 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2664 return; 2665 2666 // Skip internally declared static variables. 2667 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2668 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2669 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2670 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2671 return; 2672 2673 SourceLocation ELoc = E->getExprLoc(); 2674 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2675 // The default(none) clause requires that each variable that is referenced 2676 // in the construct, and does not have a predetermined data-sharing 2677 // attribute, must have its data-sharing attribute explicitly determined 2678 // by being listed in a data-sharing attribute clause. 2679 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2680 isImplicitOrExplicitTaskingRegion(DKind) && 2681 VarsWithInheritedDSA.count(VD) == 0) { 2682 VarsWithInheritedDSA[VD] = E; 2683 return; 2684 } 2685 2686 if (isOpenMPTargetExecutionDirective(DKind) && 2687 !Stack->isLoopControlVariable(VD).first) { 2688 if (!Stack->checkMappableExprComponentListsForDecl( 2689 VD, /*CurrentRegionOnly=*/true, 2690 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2691 StackComponents, 2692 OpenMPClauseKind) { 2693 // Variable is used if it has been marked as an array, array 2694 // section or the variable iself. 2695 return StackComponents.size() == 1 || 2696 std::all_of( 2697 std::next(StackComponents.rbegin()), 2698 StackComponents.rend(), 2699 [](const OMPClauseMappableExprCommon:: 2700 MappableComponent &MC) { 2701 return MC.getAssociatedDeclaration() == 2702 nullptr && 2703 (isa<OMPArraySectionExpr>( 2704 MC.getAssociatedExpression()) || 2705 isa<ArraySubscriptExpr>( 2706 MC.getAssociatedExpression())); 2707 }); 2708 })) { 2709 bool IsFirstprivate = false; 2710 // By default lambdas are captured as firstprivates. 2711 if (const auto *RD = 2712 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2713 IsFirstprivate = RD->isLambda(); 2714 IsFirstprivate = 2715 IsFirstprivate || 2716 (VD->getType().getNonReferenceType()->isScalarType() && 2717 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2718 if (IsFirstprivate) 2719 ImplicitFirstprivate.emplace_back(E); 2720 else 2721 ImplicitMap.emplace_back(E); 2722 return; 2723 } 2724 } 2725 2726 // OpenMP [2.9.3.6, Restrictions, p.2] 2727 // A list item that appears in a reduction clause of the innermost 2728 // enclosing worksharing or parallel construct may not be accessed in an 2729 // explicit task. 2730 DVar = Stack->hasInnermostDSA( 2731 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2732 [](OpenMPDirectiveKind K) { 2733 return isOpenMPParallelDirective(K) || 2734 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2735 }, 2736 /*FromParent=*/true); 2737 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2738 ErrorFound = true; 2739 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2740 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2741 return; 2742 } 2743 2744 // Define implicit data-sharing attributes for task. 2745 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2746 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2747 !Stack->isLoopControlVariable(VD).first) { 2748 ImplicitFirstprivate.push_back(E); 2749 return; 2750 } 2751 2752 // Store implicitly used globals with declare target link for parent 2753 // target. 2754 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2755 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2756 Stack->addToParentTargetRegionLinkGlobals(E); 2757 return; 2758 } 2759 } 2760 } 2761 void VisitMemberExpr(MemberExpr *E) { 2762 if (E->isTypeDependent() || E->isValueDependent() || 2763 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2764 return; 2765 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2766 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2767 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2768 if (!FD) 2769 return; 2770 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2771 // Check if the variable has explicit DSA set and stop analysis if it 2772 // so. 2773 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2774 return; 2775 2776 if (isOpenMPTargetExecutionDirective(DKind) && 2777 !Stack->isLoopControlVariable(FD).first && 2778 !Stack->checkMappableExprComponentListsForDecl( 2779 FD, /*CurrentRegionOnly=*/true, 2780 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2781 StackComponents, 2782 OpenMPClauseKind) { 2783 return isa<CXXThisExpr>( 2784 cast<MemberExpr>( 2785 StackComponents.back().getAssociatedExpression()) 2786 ->getBase() 2787 ->IgnoreParens()); 2788 })) { 2789 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2790 // A bit-field cannot appear in a map clause. 2791 // 2792 if (FD->isBitField()) 2793 return; 2794 2795 // Check to see if the member expression is referencing a class that 2796 // has already been explicitly mapped 2797 if (Stack->isClassPreviouslyMapped(TE->getType())) 2798 return; 2799 2800 ImplicitMap.emplace_back(E); 2801 return; 2802 } 2803 2804 SourceLocation ELoc = E->getExprLoc(); 2805 // OpenMP [2.9.3.6, Restrictions, p.2] 2806 // A list item that appears in a reduction clause of the innermost 2807 // enclosing worksharing or parallel construct may not be accessed in 2808 // an explicit task. 2809 DVar = Stack->hasInnermostDSA( 2810 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2811 [](OpenMPDirectiveKind K) { 2812 return isOpenMPParallelDirective(K) || 2813 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2814 }, 2815 /*FromParent=*/true); 2816 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2817 ErrorFound = true; 2818 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2819 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2820 return; 2821 } 2822 2823 // Define implicit data-sharing attributes for task. 2824 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2825 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2826 !Stack->isLoopControlVariable(FD).first) { 2827 // Check if there is a captured expression for the current field in the 2828 // region. Do not mark it as firstprivate unless there is no captured 2829 // expression. 2830 // TODO: try to make it firstprivate. 2831 if (DVar.CKind != OMPC_unknown) 2832 ImplicitFirstprivate.push_back(E); 2833 } 2834 return; 2835 } 2836 if (isOpenMPTargetExecutionDirective(DKind)) { 2837 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2838 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2839 /*NoDiagnose=*/true)) 2840 return; 2841 const auto *VD = cast<ValueDecl>( 2842 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2843 if (!Stack->checkMappableExprComponentListsForDecl( 2844 VD, /*CurrentRegionOnly=*/true, 2845 [&CurComponents]( 2846 OMPClauseMappableExprCommon::MappableExprComponentListRef 2847 StackComponents, 2848 OpenMPClauseKind) { 2849 auto CCI = CurComponents.rbegin(); 2850 auto CCE = CurComponents.rend(); 2851 for (const auto &SC : llvm::reverse(StackComponents)) { 2852 // Do both expressions have the same kind? 2853 if (CCI->getAssociatedExpression()->getStmtClass() != 2854 SC.getAssociatedExpression()->getStmtClass()) 2855 if (!(isa<OMPArraySectionExpr>( 2856 SC.getAssociatedExpression()) && 2857 isa<ArraySubscriptExpr>( 2858 CCI->getAssociatedExpression()))) 2859 return false; 2860 2861 const Decl *CCD = CCI->getAssociatedDeclaration(); 2862 const Decl *SCD = SC.getAssociatedDeclaration(); 2863 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2864 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2865 if (SCD != CCD) 2866 return false; 2867 std::advance(CCI, 1); 2868 if (CCI == CCE) 2869 break; 2870 } 2871 return true; 2872 })) { 2873 Visit(E->getBase()); 2874 } 2875 } else { 2876 Visit(E->getBase()); 2877 } 2878 } 2879 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2880 for (OMPClause *C : S->clauses()) { 2881 // Skip analysis of arguments of implicitly defined firstprivate clause 2882 // for task|target directives. 2883 // Skip analysis of arguments of implicitly defined map clause for target 2884 // directives. 2885 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2886 C->isImplicit())) { 2887 for (Stmt *CC : C->children()) { 2888 if (CC) 2889 Visit(CC); 2890 } 2891 } 2892 } 2893 // Check implicitly captured variables. 2894 VisitSubCaptures(S); 2895 } 2896 void VisitStmt(Stmt *S) { 2897 for (Stmt *C : S->children()) { 2898 if (C) { 2899 // Check implicitly captured variables in the task-based directives to 2900 // check if they must be firstprivatized. 2901 Visit(C); 2902 } 2903 } 2904 } 2905 2906 bool isErrorFound() const { return ErrorFound; } 2907 ArrayRef<Expr *> getImplicitFirstprivate() const { 2908 return ImplicitFirstprivate; 2909 } 2910 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2911 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2912 return VarsWithInheritedDSA; 2913 } 2914 2915 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2916 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2917 // Process declare target link variables for the target directives. 2918 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2919 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2920 Visit(E); 2921 } 2922 } 2923 }; 2924 } // namespace 2925 2926 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2927 switch (DKind) { 2928 case OMPD_parallel: 2929 case OMPD_parallel_for: 2930 case OMPD_parallel_for_simd: 2931 case OMPD_parallel_sections: 2932 case OMPD_teams: 2933 case OMPD_teams_distribute: 2934 case OMPD_teams_distribute_simd: { 2935 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2936 QualType KmpInt32PtrTy = 2937 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2938 Sema::CapturedParamNameType Params[] = { 2939 std::make_pair(".global_tid.", KmpInt32PtrTy), 2940 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2941 std::make_pair(StringRef(), QualType()) // __context with shared vars 2942 }; 2943 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2944 Params); 2945 break; 2946 } 2947 case OMPD_target_teams: 2948 case OMPD_target_parallel: 2949 case OMPD_target_parallel_for: 2950 case OMPD_target_parallel_for_simd: 2951 case OMPD_target_teams_distribute: 2952 case OMPD_target_teams_distribute_simd: { 2953 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2954 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2955 QualType KmpInt32PtrTy = 2956 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2957 QualType Args[] = {VoidPtrTy}; 2958 FunctionProtoType::ExtProtoInfo EPI; 2959 EPI.Variadic = true; 2960 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2961 Sema::CapturedParamNameType Params[] = { 2962 std::make_pair(".global_tid.", KmpInt32Ty), 2963 std::make_pair(".part_id.", KmpInt32PtrTy), 2964 std::make_pair(".privates.", VoidPtrTy), 2965 std::make_pair( 2966 ".copy_fn.", 2967 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2968 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2969 std::make_pair(StringRef(), QualType()) // __context with shared vars 2970 }; 2971 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2972 Params); 2973 // Mark this captured region as inlined, because we don't use outlined 2974 // function directly. 2975 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2976 AlwaysInlineAttr::CreateImplicit( 2977 Context, AlwaysInlineAttr::Keyword_forceinline)); 2978 Sema::CapturedParamNameType ParamsTarget[] = { 2979 std::make_pair(StringRef(), QualType()) // __context with shared vars 2980 }; 2981 // Start a captured region for 'target' with no implicit parameters. 2982 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2983 ParamsTarget); 2984 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2985 std::make_pair(".global_tid.", KmpInt32PtrTy), 2986 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2987 std::make_pair(StringRef(), QualType()) // __context with shared vars 2988 }; 2989 // Start a captured region for 'teams' or 'parallel'. Both regions have 2990 // the same implicit parameters. 2991 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2992 ParamsTeamsOrParallel); 2993 break; 2994 } 2995 case OMPD_target: 2996 case OMPD_target_simd: { 2997 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2998 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2999 QualType KmpInt32PtrTy = 3000 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3001 QualType Args[] = {VoidPtrTy}; 3002 FunctionProtoType::ExtProtoInfo EPI; 3003 EPI.Variadic = true; 3004 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3005 Sema::CapturedParamNameType Params[] = { 3006 std::make_pair(".global_tid.", KmpInt32Ty), 3007 std::make_pair(".part_id.", KmpInt32PtrTy), 3008 std::make_pair(".privates.", VoidPtrTy), 3009 std::make_pair( 3010 ".copy_fn.", 3011 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3012 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3013 std::make_pair(StringRef(), QualType()) // __context with shared vars 3014 }; 3015 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3016 Params); 3017 // Mark this captured region as inlined, because we don't use outlined 3018 // function directly. 3019 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3020 AlwaysInlineAttr::CreateImplicit( 3021 Context, AlwaysInlineAttr::Keyword_forceinline)); 3022 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3023 std::make_pair(StringRef(), QualType())); 3024 break; 3025 } 3026 case OMPD_simd: 3027 case OMPD_for: 3028 case OMPD_for_simd: 3029 case OMPD_sections: 3030 case OMPD_section: 3031 case OMPD_single: 3032 case OMPD_master: 3033 case OMPD_critical: 3034 case OMPD_taskgroup: 3035 case OMPD_distribute: 3036 case OMPD_distribute_simd: 3037 case OMPD_ordered: 3038 case OMPD_atomic: 3039 case OMPD_target_data: { 3040 Sema::CapturedParamNameType Params[] = { 3041 std::make_pair(StringRef(), QualType()) // __context with shared vars 3042 }; 3043 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3044 Params); 3045 break; 3046 } 3047 case OMPD_task: { 3048 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3049 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3050 QualType KmpInt32PtrTy = 3051 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3052 QualType Args[] = {VoidPtrTy}; 3053 FunctionProtoType::ExtProtoInfo EPI; 3054 EPI.Variadic = true; 3055 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3056 Sema::CapturedParamNameType Params[] = { 3057 std::make_pair(".global_tid.", KmpInt32Ty), 3058 std::make_pair(".part_id.", KmpInt32PtrTy), 3059 std::make_pair(".privates.", VoidPtrTy), 3060 std::make_pair( 3061 ".copy_fn.", 3062 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3063 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3064 std::make_pair(StringRef(), QualType()) // __context with shared vars 3065 }; 3066 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3067 Params); 3068 // Mark this captured region as inlined, because we don't use outlined 3069 // function directly. 3070 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3071 AlwaysInlineAttr::CreateImplicit( 3072 Context, AlwaysInlineAttr::Keyword_forceinline)); 3073 break; 3074 } 3075 case OMPD_taskloop: 3076 case OMPD_taskloop_simd: { 3077 QualType KmpInt32Ty = 3078 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3079 .withConst(); 3080 QualType KmpUInt64Ty = 3081 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3082 .withConst(); 3083 QualType KmpInt64Ty = 3084 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3085 .withConst(); 3086 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3087 QualType KmpInt32PtrTy = 3088 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3089 QualType Args[] = {VoidPtrTy}; 3090 FunctionProtoType::ExtProtoInfo EPI; 3091 EPI.Variadic = true; 3092 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3093 Sema::CapturedParamNameType Params[] = { 3094 std::make_pair(".global_tid.", KmpInt32Ty), 3095 std::make_pair(".part_id.", KmpInt32PtrTy), 3096 std::make_pair(".privates.", VoidPtrTy), 3097 std::make_pair( 3098 ".copy_fn.", 3099 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3100 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3101 std::make_pair(".lb.", KmpUInt64Ty), 3102 std::make_pair(".ub.", KmpUInt64Ty), 3103 std::make_pair(".st.", KmpInt64Ty), 3104 std::make_pair(".liter.", KmpInt32Ty), 3105 std::make_pair(".reductions.", VoidPtrTy), 3106 std::make_pair(StringRef(), QualType()) // __context with shared vars 3107 }; 3108 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3109 Params); 3110 // Mark this captured region as inlined, because we don't use outlined 3111 // function directly. 3112 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3113 AlwaysInlineAttr::CreateImplicit( 3114 Context, AlwaysInlineAttr::Keyword_forceinline)); 3115 break; 3116 } 3117 case OMPD_distribute_parallel_for_simd: 3118 case OMPD_distribute_parallel_for: { 3119 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3120 QualType KmpInt32PtrTy = 3121 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3122 Sema::CapturedParamNameType Params[] = { 3123 std::make_pair(".global_tid.", KmpInt32PtrTy), 3124 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3125 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3126 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3127 std::make_pair(StringRef(), QualType()) // __context with shared vars 3128 }; 3129 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3130 Params); 3131 break; 3132 } 3133 case OMPD_target_teams_distribute_parallel_for: 3134 case OMPD_target_teams_distribute_parallel_for_simd: { 3135 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3136 QualType KmpInt32PtrTy = 3137 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3138 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3139 3140 QualType Args[] = {VoidPtrTy}; 3141 FunctionProtoType::ExtProtoInfo EPI; 3142 EPI.Variadic = true; 3143 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3144 Sema::CapturedParamNameType Params[] = { 3145 std::make_pair(".global_tid.", KmpInt32Ty), 3146 std::make_pair(".part_id.", KmpInt32PtrTy), 3147 std::make_pair(".privates.", VoidPtrTy), 3148 std::make_pair( 3149 ".copy_fn.", 3150 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3151 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3152 std::make_pair(StringRef(), QualType()) // __context with shared vars 3153 }; 3154 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3155 Params); 3156 // Mark this captured region as inlined, because we don't use outlined 3157 // function directly. 3158 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3159 AlwaysInlineAttr::CreateImplicit( 3160 Context, AlwaysInlineAttr::Keyword_forceinline)); 3161 Sema::CapturedParamNameType ParamsTarget[] = { 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 ParamsTarget); 3167 3168 Sema::CapturedParamNameType ParamsTeams[] = { 3169 std::make_pair(".global_tid.", KmpInt32PtrTy), 3170 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3171 std::make_pair(StringRef(), QualType()) // __context with shared vars 3172 }; 3173 // Start a captured region for 'target' with no implicit parameters. 3174 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3175 ParamsTeams); 3176 3177 Sema::CapturedParamNameType ParamsParallel[] = { 3178 std::make_pair(".global_tid.", KmpInt32PtrTy), 3179 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3180 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3181 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3182 std::make_pair(StringRef(), QualType()) // __context with shared vars 3183 }; 3184 // Start a captured region for 'teams' or 'parallel'. Both regions have 3185 // the same implicit parameters. 3186 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3187 ParamsParallel); 3188 break; 3189 } 3190 3191 case OMPD_teams_distribute_parallel_for: 3192 case OMPD_teams_distribute_parallel_for_simd: { 3193 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3194 QualType KmpInt32PtrTy = 3195 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3196 3197 Sema::CapturedParamNameType ParamsTeams[] = { 3198 std::make_pair(".global_tid.", KmpInt32PtrTy), 3199 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3200 std::make_pair(StringRef(), QualType()) // __context with shared vars 3201 }; 3202 // Start a captured region for 'target' with no implicit parameters. 3203 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3204 ParamsTeams); 3205 3206 Sema::CapturedParamNameType ParamsParallel[] = { 3207 std::make_pair(".global_tid.", KmpInt32PtrTy), 3208 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3209 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3210 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3211 std::make_pair(StringRef(), QualType()) // __context with shared vars 3212 }; 3213 // Start a captured region for 'teams' or 'parallel'. Both regions have 3214 // the same implicit parameters. 3215 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3216 ParamsParallel); 3217 break; 3218 } 3219 case OMPD_target_update: 3220 case OMPD_target_enter_data: 3221 case OMPD_target_exit_data: { 3222 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3223 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3224 QualType KmpInt32PtrTy = 3225 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3226 QualType Args[] = {VoidPtrTy}; 3227 FunctionProtoType::ExtProtoInfo EPI; 3228 EPI.Variadic = true; 3229 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3230 Sema::CapturedParamNameType Params[] = { 3231 std::make_pair(".global_tid.", KmpInt32Ty), 3232 std::make_pair(".part_id.", KmpInt32PtrTy), 3233 std::make_pair(".privates.", VoidPtrTy), 3234 std::make_pair( 3235 ".copy_fn.", 3236 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3237 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3238 std::make_pair(StringRef(), QualType()) // __context with shared vars 3239 }; 3240 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3241 Params); 3242 // Mark this captured region as inlined, because we don't use outlined 3243 // function directly. 3244 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3245 AlwaysInlineAttr::CreateImplicit( 3246 Context, AlwaysInlineAttr::Keyword_forceinline)); 3247 break; 3248 } 3249 case OMPD_threadprivate: 3250 case OMPD_allocate: 3251 case OMPD_taskyield: 3252 case OMPD_barrier: 3253 case OMPD_taskwait: 3254 case OMPD_cancellation_point: 3255 case OMPD_cancel: 3256 case OMPD_flush: 3257 case OMPD_declare_reduction: 3258 case OMPD_declare_mapper: 3259 case OMPD_declare_simd: 3260 case OMPD_declare_target: 3261 case OMPD_end_declare_target: 3262 case OMPD_requires: 3263 llvm_unreachable("OpenMP Directive is not allowed"); 3264 case OMPD_unknown: 3265 llvm_unreachable("Unknown OpenMP directive"); 3266 } 3267 } 3268 3269 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3270 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3271 getOpenMPCaptureRegions(CaptureRegions, DKind); 3272 return CaptureRegions.size(); 3273 } 3274 3275 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3276 Expr *CaptureExpr, bool WithInit, 3277 bool AsExpression) { 3278 assert(CaptureExpr); 3279 ASTContext &C = S.getASTContext(); 3280 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3281 QualType Ty = Init->getType(); 3282 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3283 if (S.getLangOpts().CPlusPlus) { 3284 Ty = C.getLValueReferenceType(Ty); 3285 } else { 3286 Ty = C.getPointerType(Ty); 3287 ExprResult Res = 3288 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3289 if (!Res.isUsable()) 3290 return nullptr; 3291 Init = Res.get(); 3292 } 3293 WithInit = true; 3294 } 3295 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3296 CaptureExpr->getBeginLoc()); 3297 if (!WithInit) 3298 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3299 S.CurContext->addHiddenDecl(CED); 3300 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3301 return CED; 3302 } 3303 3304 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3305 bool WithInit) { 3306 OMPCapturedExprDecl *CD; 3307 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3308 CD = cast<OMPCapturedExprDecl>(VD); 3309 else 3310 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3311 /*AsExpression=*/false); 3312 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3313 CaptureExpr->getExprLoc()); 3314 } 3315 3316 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3317 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3318 if (!Ref) { 3319 OMPCapturedExprDecl *CD = buildCaptureDecl( 3320 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3321 /*WithInit=*/true, /*AsExpression=*/true); 3322 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3323 CaptureExpr->getExprLoc()); 3324 } 3325 ExprResult Res = Ref; 3326 if (!S.getLangOpts().CPlusPlus && 3327 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3328 Ref->getType()->isPointerType()) { 3329 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3330 if (!Res.isUsable()) 3331 return ExprError(); 3332 } 3333 return S.DefaultLvalueConversion(Res.get()); 3334 } 3335 3336 namespace { 3337 // OpenMP directives parsed in this section are represented as a 3338 // CapturedStatement with an associated statement. If a syntax error 3339 // is detected during the parsing of the associated statement, the 3340 // compiler must abort processing and close the CapturedStatement. 3341 // 3342 // Combined directives such as 'target parallel' have more than one 3343 // nested CapturedStatements. This RAII ensures that we unwind out 3344 // of all the nested CapturedStatements when an error is found. 3345 class CaptureRegionUnwinderRAII { 3346 private: 3347 Sema &S; 3348 bool &ErrorFound; 3349 OpenMPDirectiveKind DKind = OMPD_unknown; 3350 3351 public: 3352 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3353 OpenMPDirectiveKind DKind) 3354 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3355 ~CaptureRegionUnwinderRAII() { 3356 if (ErrorFound) { 3357 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3358 while (--ThisCaptureLevel >= 0) 3359 S.ActOnCapturedRegionError(); 3360 } 3361 } 3362 }; 3363 } // namespace 3364 3365 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3366 ArrayRef<OMPClause *> Clauses) { 3367 bool ErrorFound = false; 3368 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3369 *this, ErrorFound, DSAStack->getCurrentDirective()); 3370 if (!S.isUsable()) { 3371 ErrorFound = true; 3372 return StmtError(); 3373 } 3374 3375 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3376 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3377 OMPOrderedClause *OC = nullptr; 3378 OMPScheduleClause *SC = nullptr; 3379 SmallVector<const OMPLinearClause *, 4> LCs; 3380 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3381 // This is required for proper codegen. 3382 for (OMPClause *Clause : Clauses) { 3383 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3384 Clause->getClauseKind() == OMPC_in_reduction) { 3385 // Capture taskgroup task_reduction descriptors inside the tasking regions 3386 // with the corresponding in_reduction items. 3387 auto *IRC = cast<OMPInReductionClause>(Clause); 3388 for (Expr *E : IRC->taskgroup_descriptors()) 3389 if (E) 3390 MarkDeclarationsReferencedInExpr(E); 3391 } 3392 if (isOpenMPPrivate(Clause->getClauseKind()) || 3393 Clause->getClauseKind() == OMPC_copyprivate || 3394 (getLangOpts().OpenMPUseTLS && 3395 getASTContext().getTargetInfo().isTLSSupported() && 3396 Clause->getClauseKind() == OMPC_copyin)) { 3397 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3398 // Mark all variables in private list clauses as used in inner region. 3399 for (Stmt *VarRef : Clause->children()) { 3400 if (auto *E = cast_or_null<Expr>(VarRef)) { 3401 MarkDeclarationsReferencedInExpr(E); 3402 } 3403 } 3404 DSAStack->setForceVarCapturing(/*V=*/false); 3405 } else if (CaptureRegions.size() > 1 || 3406 CaptureRegions.back() != OMPD_unknown) { 3407 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3408 PICs.push_back(C); 3409 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3410 if (Expr *E = C->getPostUpdateExpr()) 3411 MarkDeclarationsReferencedInExpr(E); 3412 } 3413 } 3414 if (Clause->getClauseKind() == OMPC_schedule) 3415 SC = cast<OMPScheduleClause>(Clause); 3416 else if (Clause->getClauseKind() == OMPC_ordered) 3417 OC = cast<OMPOrderedClause>(Clause); 3418 else if (Clause->getClauseKind() == OMPC_linear) 3419 LCs.push_back(cast<OMPLinearClause>(Clause)); 3420 } 3421 // OpenMP, 2.7.1 Loop Construct, Restrictions 3422 // The nonmonotonic modifier cannot be specified if an ordered clause is 3423 // specified. 3424 if (SC && 3425 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3426 SC->getSecondScheduleModifier() == 3427 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3428 OC) { 3429 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3430 ? SC->getFirstScheduleModifierLoc() 3431 : SC->getSecondScheduleModifierLoc(), 3432 diag::err_omp_schedule_nonmonotonic_ordered) 3433 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3434 ErrorFound = true; 3435 } 3436 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3437 for (const OMPLinearClause *C : LCs) { 3438 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3439 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3440 } 3441 ErrorFound = true; 3442 } 3443 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3444 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3445 OC->getNumForLoops()) { 3446 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3447 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3448 ErrorFound = true; 3449 } 3450 if (ErrorFound) { 3451 return StmtError(); 3452 } 3453 StmtResult SR = S; 3454 unsigned CompletedRegions = 0; 3455 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3456 // Mark all variables in private list clauses as used in inner region. 3457 // Required for proper codegen of combined directives. 3458 // TODO: add processing for other clauses. 3459 if (ThisCaptureRegion != OMPD_unknown) { 3460 for (const clang::OMPClauseWithPreInit *C : PICs) { 3461 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3462 // Find the particular capture region for the clause if the 3463 // directive is a combined one with multiple capture regions. 3464 // If the directive is not a combined one, the capture region 3465 // associated with the clause is OMPD_unknown and is generated 3466 // only once. 3467 if (CaptureRegion == ThisCaptureRegion || 3468 CaptureRegion == OMPD_unknown) { 3469 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3470 for (Decl *D : DS->decls()) 3471 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3472 } 3473 } 3474 } 3475 } 3476 if (++CompletedRegions == CaptureRegions.size()) 3477 DSAStack->setBodyComplete(); 3478 SR = ActOnCapturedRegionEnd(SR.get()); 3479 } 3480 return SR; 3481 } 3482 3483 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3484 OpenMPDirectiveKind CancelRegion, 3485 SourceLocation StartLoc) { 3486 // CancelRegion is only needed for cancel and cancellation_point. 3487 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3488 return false; 3489 3490 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3491 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3492 return false; 3493 3494 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3495 << getOpenMPDirectiveName(CancelRegion); 3496 return true; 3497 } 3498 3499 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3500 OpenMPDirectiveKind CurrentRegion, 3501 const DeclarationNameInfo &CurrentName, 3502 OpenMPDirectiveKind CancelRegion, 3503 SourceLocation StartLoc) { 3504 if (Stack->getCurScope()) { 3505 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3506 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3507 bool NestingProhibited = false; 3508 bool CloseNesting = true; 3509 bool OrphanSeen = false; 3510 enum { 3511 NoRecommend, 3512 ShouldBeInParallelRegion, 3513 ShouldBeInOrderedRegion, 3514 ShouldBeInTargetRegion, 3515 ShouldBeInTeamsRegion 3516 } Recommend = NoRecommend; 3517 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3518 // OpenMP [2.16, Nesting of Regions] 3519 // OpenMP constructs may not be nested inside a simd region. 3520 // OpenMP [2.8.1,simd Construct, Restrictions] 3521 // An ordered construct with the simd clause is the only OpenMP 3522 // construct that can appear in the simd region. 3523 // Allowing a SIMD construct nested in another SIMD construct is an 3524 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3525 // message. 3526 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3527 ? diag::err_omp_prohibited_region_simd 3528 : diag::warn_omp_nesting_simd); 3529 return CurrentRegion != OMPD_simd; 3530 } 3531 if (ParentRegion == OMPD_atomic) { 3532 // OpenMP [2.16, Nesting of Regions] 3533 // OpenMP constructs may not be nested inside an atomic region. 3534 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3535 return true; 3536 } 3537 if (CurrentRegion == OMPD_section) { 3538 // OpenMP [2.7.2, sections Construct, Restrictions] 3539 // Orphaned section directives are prohibited. That is, the section 3540 // directives must appear within the sections construct and must not be 3541 // encountered elsewhere in the sections region. 3542 if (ParentRegion != OMPD_sections && 3543 ParentRegion != OMPD_parallel_sections) { 3544 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3545 << (ParentRegion != OMPD_unknown) 3546 << getOpenMPDirectiveName(ParentRegion); 3547 return true; 3548 } 3549 return false; 3550 } 3551 // Allow some constructs (except teams and cancellation constructs) to be 3552 // orphaned (they could be used in functions, called from OpenMP regions 3553 // with the required preconditions). 3554 if (ParentRegion == OMPD_unknown && 3555 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3556 CurrentRegion != OMPD_cancellation_point && 3557 CurrentRegion != OMPD_cancel) 3558 return false; 3559 if (CurrentRegion == OMPD_cancellation_point || 3560 CurrentRegion == OMPD_cancel) { 3561 // OpenMP [2.16, Nesting of Regions] 3562 // A cancellation point construct for which construct-type-clause is 3563 // taskgroup must be nested inside a task construct. A cancellation 3564 // point construct for which construct-type-clause is not taskgroup must 3565 // be closely nested inside an OpenMP construct that matches the type 3566 // specified in construct-type-clause. 3567 // A cancel construct for which construct-type-clause is taskgroup must be 3568 // nested inside a task construct. A cancel construct for which 3569 // construct-type-clause is not taskgroup must be closely nested inside an 3570 // OpenMP construct that matches the type specified in 3571 // construct-type-clause. 3572 NestingProhibited = 3573 !((CancelRegion == OMPD_parallel && 3574 (ParentRegion == OMPD_parallel || 3575 ParentRegion == OMPD_target_parallel)) || 3576 (CancelRegion == OMPD_for && 3577 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3578 ParentRegion == OMPD_target_parallel_for || 3579 ParentRegion == OMPD_distribute_parallel_for || 3580 ParentRegion == OMPD_teams_distribute_parallel_for || 3581 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3582 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3583 (CancelRegion == OMPD_sections && 3584 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3585 ParentRegion == OMPD_parallel_sections))); 3586 OrphanSeen = ParentRegion == OMPD_unknown; 3587 } else if (CurrentRegion == OMPD_master) { 3588 // OpenMP [2.16, Nesting of Regions] 3589 // A master region may not be closely nested inside a worksharing, 3590 // atomic, or explicit task region. 3591 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3592 isOpenMPTaskingDirective(ParentRegion); 3593 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3594 // OpenMP [2.16, Nesting of Regions] 3595 // A critical region may not be nested (closely or otherwise) inside a 3596 // critical region with the same name. Note that this restriction is not 3597 // sufficient to prevent deadlock. 3598 SourceLocation PreviousCriticalLoc; 3599 bool DeadLock = Stack->hasDirective( 3600 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3601 const DeclarationNameInfo &DNI, 3602 SourceLocation Loc) { 3603 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3604 PreviousCriticalLoc = Loc; 3605 return true; 3606 } 3607 return false; 3608 }, 3609 false /* skip top directive */); 3610 if (DeadLock) { 3611 SemaRef.Diag(StartLoc, 3612 diag::err_omp_prohibited_region_critical_same_name) 3613 << CurrentName.getName(); 3614 if (PreviousCriticalLoc.isValid()) 3615 SemaRef.Diag(PreviousCriticalLoc, 3616 diag::note_omp_previous_critical_region); 3617 return true; 3618 } 3619 } else if (CurrentRegion == OMPD_barrier) { 3620 // OpenMP [2.16, Nesting of Regions] 3621 // A barrier region may not be closely nested inside a worksharing, 3622 // explicit task, critical, ordered, atomic, or master region. 3623 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3624 isOpenMPTaskingDirective(ParentRegion) || 3625 ParentRegion == OMPD_master || 3626 ParentRegion == OMPD_critical || 3627 ParentRegion == OMPD_ordered; 3628 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3629 !isOpenMPParallelDirective(CurrentRegion) && 3630 !isOpenMPTeamsDirective(CurrentRegion)) { 3631 // OpenMP [2.16, Nesting of Regions] 3632 // A worksharing region may not be closely nested inside a worksharing, 3633 // explicit task, critical, ordered, atomic, or master region. 3634 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3635 isOpenMPTaskingDirective(ParentRegion) || 3636 ParentRegion == OMPD_master || 3637 ParentRegion == OMPD_critical || 3638 ParentRegion == OMPD_ordered; 3639 Recommend = ShouldBeInParallelRegion; 3640 } else if (CurrentRegion == OMPD_ordered) { 3641 // OpenMP [2.16, Nesting of Regions] 3642 // An ordered region may not be closely nested inside a critical, 3643 // atomic, or explicit task region. 3644 // An ordered region must be closely nested inside a loop region (or 3645 // parallel loop region) with an ordered clause. 3646 // OpenMP [2.8.1,simd Construct, Restrictions] 3647 // An ordered construct with the simd clause is the only OpenMP construct 3648 // that can appear in the simd region. 3649 NestingProhibited = ParentRegion == OMPD_critical || 3650 isOpenMPTaskingDirective(ParentRegion) || 3651 !(isOpenMPSimdDirective(ParentRegion) || 3652 Stack->isParentOrderedRegion()); 3653 Recommend = ShouldBeInOrderedRegion; 3654 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3655 // OpenMP [2.16, Nesting of Regions] 3656 // If specified, a teams construct must be contained within a target 3657 // construct. 3658 NestingProhibited = ParentRegion != OMPD_target; 3659 OrphanSeen = ParentRegion == OMPD_unknown; 3660 Recommend = ShouldBeInTargetRegion; 3661 } 3662 if (!NestingProhibited && 3663 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3664 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3665 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3666 // OpenMP [2.16, Nesting of Regions] 3667 // distribute, parallel, parallel sections, parallel workshare, and the 3668 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3669 // constructs that can be closely nested in the teams region. 3670 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3671 !isOpenMPDistributeDirective(CurrentRegion); 3672 Recommend = ShouldBeInParallelRegion; 3673 } 3674 if (!NestingProhibited && 3675 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3676 // OpenMP 4.5 [2.17 Nesting of Regions] 3677 // The region associated with the distribute construct must be strictly 3678 // nested inside a teams region 3679 NestingProhibited = 3680 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3681 Recommend = ShouldBeInTeamsRegion; 3682 } 3683 if (!NestingProhibited && 3684 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3685 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3686 // OpenMP 4.5 [2.17 Nesting of Regions] 3687 // If a target, target update, target data, target enter data, or 3688 // target exit data construct is encountered during execution of a 3689 // target region, the behavior is unspecified. 3690 NestingProhibited = Stack->hasDirective( 3691 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3692 SourceLocation) { 3693 if (isOpenMPTargetExecutionDirective(K)) { 3694 OffendingRegion = K; 3695 return true; 3696 } 3697 return false; 3698 }, 3699 false /* don't skip top directive */); 3700 CloseNesting = false; 3701 } 3702 if (NestingProhibited) { 3703 if (OrphanSeen) { 3704 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3705 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3706 } else { 3707 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3708 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3709 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3710 } 3711 return true; 3712 } 3713 } 3714 return false; 3715 } 3716 3717 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3718 ArrayRef<OMPClause *> Clauses, 3719 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3720 bool ErrorFound = false; 3721 unsigned NamedModifiersNumber = 0; 3722 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3723 OMPD_unknown + 1); 3724 SmallVector<SourceLocation, 4> NameModifierLoc; 3725 for (const OMPClause *C : Clauses) { 3726 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3727 // At most one if clause without a directive-name-modifier can appear on 3728 // the directive. 3729 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3730 if (FoundNameModifiers[CurNM]) { 3731 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3732 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3733 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3734 ErrorFound = true; 3735 } else if (CurNM != OMPD_unknown) { 3736 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3737 ++NamedModifiersNumber; 3738 } 3739 FoundNameModifiers[CurNM] = IC; 3740 if (CurNM == OMPD_unknown) 3741 continue; 3742 // Check if the specified name modifier is allowed for the current 3743 // directive. 3744 // At most one if clause with the particular directive-name-modifier can 3745 // appear on the directive. 3746 bool MatchFound = false; 3747 for (auto NM : AllowedNameModifiers) { 3748 if (CurNM == NM) { 3749 MatchFound = true; 3750 break; 3751 } 3752 } 3753 if (!MatchFound) { 3754 S.Diag(IC->getNameModifierLoc(), 3755 diag::err_omp_wrong_if_directive_name_modifier) 3756 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3757 ErrorFound = true; 3758 } 3759 } 3760 } 3761 // If any if clause on the directive includes a directive-name-modifier then 3762 // all if clauses on the directive must include a directive-name-modifier. 3763 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3764 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3765 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3766 diag::err_omp_no_more_if_clause); 3767 } else { 3768 std::string Values; 3769 std::string Sep(", "); 3770 unsigned AllowedCnt = 0; 3771 unsigned TotalAllowedNum = 3772 AllowedNameModifiers.size() - NamedModifiersNumber; 3773 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3774 ++Cnt) { 3775 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3776 if (!FoundNameModifiers[NM]) { 3777 Values += "'"; 3778 Values += getOpenMPDirectiveName(NM); 3779 Values += "'"; 3780 if (AllowedCnt + 2 == TotalAllowedNum) 3781 Values += " or "; 3782 else if (AllowedCnt + 1 != TotalAllowedNum) 3783 Values += Sep; 3784 ++AllowedCnt; 3785 } 3786 } 3787 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3788 diag::err_omp_unnamed_if_clause) 3789 << (TotalAllowedNum > 1) << Values; 3790 } 3791 for (SourceLocation Loc : NameModifierLoc) { 3792 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3793 } 3794 ErrorFound = true; 3795 } 3796 return ErrorFound; 3797 } 3798 3799 static std::pair<ValueDecl *, bool> 3800 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 3801 SourceRange &ERange, bool AllowArraySection = false) { 3802 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 3803 RefExpr->containsUnexpandedParameterPack()) 3804 return std::make_pair(nullptr, true); 3805 3806 // OpenMP [3.1, C/C++] 3807 // A list item is a variable name. 3808 // OpenMP [2.9.3.3, Restrictions, p.1] 3809 // A variable that is part of another variable (as an array or 3810 // structure element) cannot appear in a private clause. 3811 RefExpr = RefExpr->IgnoreParens(); 3812 enum { 3813 NoArrayExpr = -1, 3814 ArraySubscript = 0, 3815 OMPArraySection = 1 3816 } IsArrayExpr = NoArrayExpr; 3817 if (AllowArraySection) { 3818 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 3819 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 3820 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3821 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3822 RefExpr = Base; 3823 IsArrayExpr = ArraySubscript; 3824 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 3825 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 3826 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 3827 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 3828 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3829 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3830 RefExpr = Base; 3831 IsArrayExpr = OMPArraySection; 3832 } 3833 } 3834 ELoc = RefExpr->getExprLoc(); 3835 ERange = RefExpr->getSourceRange(); 3836 RefExpr = RefExpr->IgnoreParenImpCasts(); 3837 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 3838 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 3839 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 3840 (S.getCurrentThisType().isNull() || !ME || 3841 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 3842 !isa<FieldDecl>(ME->getMemberDecl()))) { 3843 if (IsArrayExpr != NoArrayExpr) { 3844 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 3845 << ERange; 3846 } else { 3847 S.Diag(ELoc, 3848 AllowArraySection 3849 ? diag::err_omp_expected_var_name_member_expr_or_array_item 3850 : diag::err_omp_expected_var_name_member_expr) 3851 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 3852 } 3853 return std::make_pair(nullptr, false); 3854 } 3855 return std::make_pair( 3856 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 3857 } 3858 3859 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 3860 ArrayRef<OMPClause *> Clauses) { 3861 assert(!S.CurContext->isDependentContext() && 3862 "Expected non-dependent context."); 3863 auto AllocateRange = 3864 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 3865 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 3866 DeclToCopy; 3867 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 3868 return isOpenMPPrivate(C->getClauseKind()); 3869 }); 3870 for (OMPClause *Cl : PrivateRange) { 3871 MutableArrayRef<Expr *>::iterator I, It, Et; 3872 if (Cl->getClauseKind() == OMPC_private) { 3873 auto *PC = cast<OMPPrivateClause>(Cl); 3874 I = PC->private_copies().begin(); 3875 It = PC->varlist_begin(); 3876 Et = PC->varlist_end(); 3877 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 3878 auto *PC = cast<OMPFirstprivateClause>(Cl); 3879 I = PC->private_copies().begin(); 3880 It = PC->varlist_begin(); 3881 Et = PC->varlist_end(); 3882 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 3883 auto *PC = cast<OMPLastprivateClause>(Cl); 3884 I = PC->private_copies().begin(); 3885 It = PC->varlist_begin(); 3886 Et = PC->varlist_end(); 3887 } else if (Cl->getClauseKind() == OMPC_linear) { 3888 auto *PC = cast<OMPLinearClause>(Cl); 3889 I = PC->privates().begin(); 3890 It = PC->varlist_begin(); 3891 Et = PC->varlist_end(); 3892 } else if (Cl->getClauseKind() == OMPC_reduction) { 3893 auto *PC = cast<OMPReductionClause>(Cl); 3894 I = PC->privates().begin(); 3895 It = PC->varlist_begin(); 3896 Et = PC->varlist_end(); 3897 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 3898 auto *PC = cast<OMPTaskReductionClause>(Cl); 3899 I = PC->privates().begin(); 3900 It = PC->varlist_begin(); 3901 Et = PC->varlist_end(); 3902 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 3903 auto *PC = cast<OMPInReductionClause>(Cl); 3904 I = PC->privates().begin(); 3905 It = PC->varlist_begin(); 3906 Et = PC->varlist_end(); 3907 } else { 3908 llvm_unreachable("Expected private clause."); 3909 } 3910 for (Expr *E : llvm::make_range(It, Et)) { 3911 if (!*I) { 3912 ++I; 3913 continue; 3914 } 3915 SourceLocation ELoc; 3916 SourceRange ERange; 3917 Expr *SimpleRefExpr = E; 3918 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 3919 /*AllowArraySection=*/true); 3920 DeclToCopy.try_emplace(Res.first, 3921 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 3922 ++I; 3923 } 3924 } 3925 for (OMPClause *C : AllocateRange) { 3926 auto *AC = cast<OMPAllocateClause>(C); 3927 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3928 getAllocatorKind(S, Stack, AC->getAllocator()); 3929 // OpenMP, 2.11.4 allocate Clause, Restrictions. 3930 // For task, taskloop or target directives, allocation requests to memory 3931 // allocators with the trait access set to thread result in unspecified 3932 // behavior. 3933 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 3934 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 3935 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 3936 S.Diag(AC->getAllocator()->getExprLoc(), 3937 diag::warn_omp_allocate_thread_on_task_target_directive) 3938 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3939 } 3940 for (Expr *E : AC->varlists()) { 3941 SourceLocation ELoc; 3942 SourceRange ERange; 3943 Expr *SimpleRefExpr = E; 3944 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 3945 ValueDecl *VD = Res.first; 3946 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 3947 if (!isOpenMPPrivate(Data.CKind)) { 3948 S.Diag(E->getExprLoc(), 3949 diag::err_omp_expected_private_copy_for_allocate); 3950 continue; 3951 } 3952 VarDecl *PrivateVD = DeclToCopy[VD]; 3953 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 3954 AllocatorKind, AC->getAllocator())) 3955 continue; 3956 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 3957 E->getSourceRange()); 3958 } 3959 } 3960 } 3961 3962 StmtResult Sema::ActOnOpenMPExecutableDirective( 3963 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3964 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3965 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3966 StmtResult Res = StmtError(); 3967 // First check CancelRegion which is then used in checkNestingOfRegions. 3968 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3969 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3970 StartLoc)) 3971 return StmtError(); 3972 3973 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3974 VarsWithInheritedDSAType VarsWithInheritedDSA; 3975 bool ErrorFound = false; 3976 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3977 if (AStmt && !CurContext->isDependentContext()) { 3978 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3979 3980 // Check default data sharing attributes for referenced variables. 3981 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3982 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3983 Stmt *S = AStmt; 3984 while (--ThisCaptureLevel >= 0) 3985 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3986 DSAChecker.Visit(S); 3987 if (DSAChecker.isErrorFound()) 3988 return StmtError(); 3989 // Generate list of implicitly defined firstprivate variables. 3990 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3991 3992 SmallVector<Expr *, 4> ImplicitFirstprivates( 3993 DSAChecker.getImplicitFirstprivate().begin(), 3994 DSAChecker.getImplicitFirstprivate().end()); 3995 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3996 DSAChecker.getImplicitMap().end()); 3997 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3998 for (OMPClause *C : Clauses) { 3999 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4000 for (Expr *E : IRC->taskgroup_descriptors()) 4001 if (E) 4002 ImplicitFirstprivates.emplace_back(E); 4003 } 4004 } 4005 if (!ImplicitFirstprivates.empty()) { 4006 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4007 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4008 SourceLocation())) { 4009 ClausesWithImplicit.push_back(Implicit); 4010 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4011 ImplicitFirstprivates.size(); 4012 } else { 4013 ErrorFound = true; 4014 } 4015 } 4016 if (!ImplicitMaps.empty()) { 4017 CXXScopeSpec MapperIdScopeSpec; 4018 DeclarationNameInfo MapperId; 4019 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4020 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4021 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4022 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4023 ClausesWithImplicit.emplace_back(Implicit); 4024 ErrorFound |= 4025 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4026 } else { 4027 ErrorFound = true; 4028 } 4029 } 4030 } 4031 4032 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4033 switch (Kind) { 4034 case OMPD_parallel: 4035 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4036 EndLoc); 4037 AllowedNameModifiers.push_back(OMPD_parallel); 4038 break; 4039 case OMPD_simd: 4040 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4041 VarsWithInheritedDSA); 4042 break; 4043 case OMPD_for: 4044 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4045 VarsWithInheritedDSA); 4046 break; 4047 case OMPD_for_simd: 4048 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4049 EndLoc, VarsWithInheritedDSA); 4050 break; 4051 case OMPD_sections: 4052 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4053 EndLoc); 4054 break; 4055 case OMPD_section: 4056 assert(ClausesWithImplicit.empty() && 4057 "No clauses are allowed for 'omp section' directive"); 4058 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4059 break; 4060 case OMPD_single: 4061 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4062 EndLoc); 4063 break; 4064 case OMPD_master: 4065 assert(ClausesWithImplicit.empty() && 4066 "No clauses are allowed for 'omp master' directive"); 4067 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4068 break; 4069 case OMPD_critical: 4070 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4071 StartLoc, EndLoc); 4072 break; 4073 case OMPD_parallel_for: 4074 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4075 EndLoc, VarsWithInheritedDSA); 4076 AllowedNameModifiers.push_back(OMPD_parallel); 4077 break; 4078 case OMPD_parallel_for_simd: 4079 Res = ActOnOpenMPParallelForSimdDirective( 4080 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4081 AllowedNameModifiers.push_back(OMPD_parallel); 4082 break; 4083 case OMPD_parallel_sections: 4084 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4085 StartLoc, EndLoc); 4086 AllowedNameModifiers.push_back(OMPD_parallel); 4087 break; 4088 case OMPD_task: 4089 Res = 4090 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4091 AllowedNameModifiers.push_back(OMPD_task); 4092 break; 4093 case OMPD_taskyield: 4094 assert(ClausesWithImplicit.empty() && 4095 "No clauses are allowed for 'omp taskyield' directive"); 4096 assert(AStmt == nullptr && 4097 "No associated statement allowed for 'omp taskyield' directive"); 4098 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4099 break; 4100 case OMPD_barrier: 4101 assert(ClausesWithImplicit.empty() && 4102 "No clauses are allowed for 'omp barrier' directive"); 4103 assert(AStmt == nullptr && 4104 "No associated statement allowed for 'omp barrier' directive"); 4105 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4106 break; 4107 case OMPD_taskwait: 4108 assert(ClausesWithImplicit.empty() && 4109 "No clauses are allowed for 'omp taskwait' directive"); 4110 assert(AStmt == nullptr && 4111 "No associated statement allowed for 'omp taskwait' directive"); 4112 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4113 break; 4114 case OMPD_taskgroup: 4115 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4116 EndLoc); 4117 break; 4118 case OMPD_flush: 4119 assert(AStmt == nullptr && 4120 "No associated statement allowed for 'omp flush' directive"); 4121 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4122 break; 4123 case OMPD_ordered: 4124 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4125 EndLoc); 4126 break; 4127 case OMPD_atomic: 4128 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4129 EndLoc); 4130 break; 4131 case OMPD_teams: 4132 Res = 4133 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4134 break; 4135 case OMPD_target: 4136 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4137 EndLoc); 4138 AllowedNameModifiers.push_back(OMPD_target); 4139 break; 4140 case OMPD_target_parallel: 4141 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4142 StartLoc, EndLoc); 4143 AllowedNameModifiers.push_back(OMPD_target); 4144 AllowedNameModifiers.push_back(OMPD_parallel); 4145 break; 4146 case OMPD_target_parallel_for: 4147 Res = ActOnOpenMPTargetParallelForDirective( 4148 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4149 AllowedNameModifiers.push_back(OMPD_target); 4150 AllowedNameModifiers.push_back(OMPD_parallel); 4151 break; 4152 case OMPD_cancellation_point: 4153 assert(ClausesWithImplicit.empty() && 4154 "No clauses are allowed for 'omp cancellation point' directive"); 4155 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4156 "cancellation point' directive"); 4157 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4158 break; 4159 case OMPD_cancel: 4160 assert(AStmt == nullptr && 4161 "No associated statement allowed for 'omp cancel' directive"); 4162 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4163 CancelRegion); 4164 AllowedNameModifiers.push_back(OMPD_cancel); 4165 break; 4166 case OMPD_target_data: 4167 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4168 EndLoc); 4169 AllowedNameModifiers.push_back(OMPD_target_data); 4170 break; 4171 case OMPD_target_enter_data: 4172 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4173 EndLoc, AStmt); 4174 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4175 break; 4176 case OMPD_target_exit_data: 4177 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4178 EndLoc, AStmt); 4179 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4180 break; 4181 case OMPD_taskloop: 4182 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4183 EndLoc, VarsWithInheritedDSA); 4184 AllowedNameModifiers.push_back(OMPD_taskloop); 4185 break; 4186 case OMPD_taskloop_simd: 4187 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4188 EndLoc, VarsWithInheritedDSA); 4189 AllowedNameModifiers.push_back(OMPD_taskloop); 4190 break; 4191 case OMPD_distribute: 4192 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4193 EndLoc, VarsWithInheritedDSA); 4194 break; 4195 case OMPD_target_update: 4196 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4197 EndLoc, AStmt); 4198 AllowedNameModifiers.push_back(OMPD_target_update); 4199 break; 4200 case OMPD_distribute_parallel_for: 4201 Res = ActOnOpenMPDistributeParallelForDirective( 4202 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4203 AllowedNameModifiers.push_back(OMPD_parallel); 4204 break; 4205 case OMPD_distribute_parallel_for_simd: 4206 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4207 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4208 AllowedNameModifiers.push_back(OMPD_parallel); 4209 break; 4210 case OMPD_distribute_simd: 4211 Res = ActOnOpenMPDistributeSimdDirective( 4212 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4213 break; 4214 case OMPD_target_parallel_for_simd: 4215 Res = ActOnOpenMPTargetParallelForSimdDirective( 4216 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4217 AllowedNameModifiers.push_back(OMPD_target); 4218 AllowedNameModifiers.push_back(OMPD_parallel); 4219 break; 4220 case OMPD_target_simd: 4221 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4222 EndLoc, VarsWithInheritedDSA); 4223 AllowedNameModifiers.push_back(OMPD_target); 4224 break; 4225 case OMPD_teams_distribute: 4226 Res = ActOnOpenMPTeamsDistributeDirective( 4227 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4228 break; 4229 case OMPD_teams_distribute_simd: 4230 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4231 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4232 break; 4233 case OMPD_teams_distribute_parallel_for_simd: 4234 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4235 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4236 AllowedNameModifiers.push_back(OMPD_parallel); 4237 break; 4238 case OMPD_teams_distribute_parallel_for: 4239 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4240 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4241 AllowedNameModifiers.push_back(OMPD_parallel); 4242 break; 4243 case OMPD_target_teams: 4244 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4245 EndLoc); 4246 AllowedNameModifiers.push_back(OMPD_target); 4247 break; 4248 case OMPD_target_teams_distribute: 4249 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4250 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4251 AllowedNameModifiers.push_back(OMPD_target); 4252 break; 4253 case OMPD_target_teams_distribute_parallel_for: 4254 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4255 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4256 AllowedNameModifiers.push_back(OMPD_target); 4257 AllowedNameModifiers.push_back(OMPD_parallel); 4258 break; 4259 case OMPD_target_teams_distribute_parallel_for_simd: 4260 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4261 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4262 AllowedNameModifiers.push_back(OMPD_target); 4263 AllowedNameModifiers.push_back(OMPD_parallel); 4264 break; 4265 case OMPD_target_teams_distribute_simd: 4266 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4267 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4268 AllowedNameModifiers.push_back(OMPD_target); 4269 break; 4270 case OMPD_declare_target: 4271 case OMPD_end_declare_target: 4272 case OMPD_threadprivate: 4273 case OMPD_allocate: 4274 case OMPD_declare_reduction: 4275 case OMPD_declare_mapper: 4276 case OMPD_declare_simd: 4277 case OMPD_requires: 4278 llvm_unreachable("OpenMP Directive is not allowed"); 4279 case OMPD_unknown: 4280 llvm_unreachable("Unknown OpenMP directive"); 4281 } 4282 4283 ErrorFound = Res.isInvalid() || ErrorFound; 4284 4285 // Check variables in the clauses if default(none) was specified. 4286 if (DSAStack->getDefaultDSA() == DSA_none) { 4287 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4288 for (OMPClause *C : Clauses) { 4289 switch (C->getClauseKind()) { 4290 case OMPC_num_threads: 4291 case OMPC_dist_schedule: 4292 // Do not analyse if no parent teams directive. 4293 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4294 break; 4295 continue; 4296 case OMPC_if: 4297 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4298 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4299 break; 4300 continue; 4301 case OMPC_schedule: 4302 break; 4303 case OMPC_ordered: 4304 case OMPC_device: 4305 case OMPC_num_teams: 4306 case OMPC_thread_limit: 4307 case OMPC_priority: 4308 case OMPC_grainsize: 4309 case OMPC_num_tasks: 4310 case OMPC_hint: 4311 case OMPC_collapse: 4312 case OMPC_safelen: 4313 case OMPC_simdlen: 4314 case OMPC_final: 4315 case OMPC_default: 4316 case OMPC_proc_bind: 4317 case OMPC_private: 4318 case OMPC_firstprivate: 4319 case OMPC_lastprivate: 4320 case OMPC_shared: 4321 case OMPC_reduction: 4322 case OMPC_task_reduction: 4323 case OMPC_in_reduction: 4324 case OMPC_linear: 4325 case OMPC_aligned: 4326 case OMPC_copyin: 4327 case OMPC_copyprivate: 4328 case OMPC_nowait: 4329 case OMPC_untied: 4330 case OMPC_mergeable: 4331 case OMPC_allocate: 4332 case OMPC_read: 4333 case OMPC_write: 4334 case OMPC_update: 4335 case OMPC_capture: 4336 case OMPC_seq_cst: 4337 case OMPC_depend: 4338 case OMPC_threads: 4339 case OMPC_simd: 4340 case OMPC_map: 4341 case OMPC_nogroup: 4342 case OMPC_defaultmap: 4343 case OMPC_to: 4344 case OMPC_from: 4345 case OMPC_use_device_ptr: 4346 case OMPC_is_device_ptr: 4347 continue; 4348 case OMPC_allocator: 4349 case OMPC_flush: 4350 case OMPC_threadprivate: 4351 case OMPC_uniform: 4352 case OMPC_unknown: 4353 case OMPC_unified_address: 4354 case OMPC_unified_shared_memory: 4355 case OMPC_reverse_offload: 4356 case OMPC_dynamic_allocators: 4357 case OMPC_atomic_default_mem_order: 4358 llvm_unreachable("Unexpected clause"); 4359 } 4360 for (Stmt *CC : C->children()) { 4361 if (CC) 4362 DSAChecker.Visit(CC); 4363 } 4364 } 4365 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4366 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4367 } 4368 for (const auto &P : VarsWithInheritedDSA) { 4369 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4370 << P.first << P.second->getSourceRange(); 4371 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4372 } 4373 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 4374 4375 if (!AllowedNameModifiers.empty()) 4376 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4377 ErrorFound; 4378 4379 if (ErrorFound) 4380 return StmtError(); 4381 4382 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4383 Res.getAs<OMPExecutableDirective>() 4384 ->getStructuredBlock() 4385 ->setIsOMPStructuredBlock(true); 4386 } 4387 4388 if (!CurContext->isDependentContext() && 4389 isOpenMPTargetExecutionDirective(Kind) && 4390 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4391 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4392 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4393 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4394 // Register target to DSA Stack. 4395 DSAStack->addTargetDirLocation(StartLoc); 4396 } 4397 4398 return Res; 4399 } 4400 4401 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4402 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4403 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4404 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4405 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4406 assert(Aligneds.size() == Alignments.size()); 4407 assert(Linears.size() == LinModifiers.size()); 4408 assert(Linears.size() == Steps.size()); 4409 if (!DG || DG.get().isNull()) 4410 return DeclGroupPtrTy(); 4411 4412 if (!DG.get().isSingleDecl()) { 4413 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4414 return DG; 4415 } 4416 Decl *ADecl = DG.get().getSingleDecl(); 4417 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4418 ADecl = FTD->getTemplatedDecl(); 4419 4420 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4421 if (!FD) { 4422 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4423 return DeclGroupPtrTy(); 4424 } 4425 4426 // OpenMP [2.8.2, declare simd construct, Description] 4427 // The parameter of the simdlen clause must be a constant positive integer 4428 // expression. 4429 ExprResult SL; 4430 if (Simdlen) 4431 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4432 // OpenMP [2.8.2, declare simd construct, Description] 4433 // The special this pointer can be used as if was one of the arguments to the 4434 // function in any of the linear, aligned, or uniform clauses. 4435 // The uniform clause declares one or more arguments to have an invariant 4436 // value for all concurrent invocations of the function in the execution of a 4437 // single SIMD loop. 4438 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4439 const Expr *UniformedLinearThis = nullptr; 4440 for (const Expr *E : Uniforms) { 4441 E = E->IgnoreParenImpCasts(); 4442 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4443 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4444 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4445 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4446 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4447 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4448 continue; 4449 } 4450 if (isa<CXXThisExpr>(E)) { 4451 UniformedLinearThis = E; 4452 continue; 4453 } 4454 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4455 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4456 } 4457 // OpenMP [2.8.2, declare simd construct, Description] 4458 // The aligned clause declares that the object to which each list item points 4459 // is aligned to the number of bytes expressed in the optional parameter of 4460 // the aligned clause. 4461 // The special this pointer can be used as if was one of the arguments to the 4462 // function in any of the linear, aligned, or uniform clauses. 4463 // The type of list items appearing in the aligned clause must be array, 4464 // pointer, reference to array, or reference to pointer. 4465 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4466 const Expr *AlignedThis = nullptr; 4467 for (const Expr *E : Aligneds) { 4468 E = E->IgnoreParenImpCasts(); 4469 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4470 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4471 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4472 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4473 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4474 ->getCanonicalDecl() == CanonPVD) { 4475 // OpenMP [2.8.1, simd construct, Restrictions] 4476 // A list-item cannot appear in more than one aligned clause. 4477 if (AlignedArgs.count(CanonPVD) > 0) { 4478 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4479 << 1 << E->getSourceRange(); 4480 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4481 diag::note_omp_explicit_dsa) 4482 << getOpenMPClauseName(OMPC_aligned); 4483 continue; 4484 } 4485 AlignedArgs[CanonPVD] = E; 4486 QualType QTy = PVD->getType() 4487 .getNonReferenceType() 4488 .getUnqualifiedType() 4489 .getCanonicalType(); 4490 const Type *Ty = QTy.getTypePtrOrNull(); 4491 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4492 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4493 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4494 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4495 } 4496 continue; 4497 } 4498 } 4499 if (isa<CXXThisExpr>(E)) { 4500 if (AlignedThis) { 4501 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4502 << 2 << E->getSourceRange(); 4503 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4504 << getOpenMPClauseName(OMPC_aligned); 4505 } 4506 AlignedThis = E; 4507 continue; 4508 } 4509 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4510 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4511 } 4512 // The optional parameter of the aligned clause, alignment, must be a constant 4513 // positive integer expression. If no optional parameter is specified, 4514 // implementation-defined default alignments for SIMD instructions on the 4515 // target platforms are assumed. 4516 SmallVector<const Expr *, 4> NewAligns; 4517 for (Expr *E : Alignments) { 4518 ExprResult Align; 4519 if (E) 4520 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4521 NewAligns.push_back(Align.get()); 4522 } 4523 // OpenMP [2.8.2, declare simd construct, Description] 4524 // The linear clause declares one or more list items to be private to a SIMD 4525 // lane and to have a linear relationship with respect to the iteration space 4526 // of a loop. 4527 // The special this pointer can be used as if was one of the arguments to the 4528 // function in any of the linear, aligned, or uniform clauses. 4529 // When a linear-step expression is specified in a linear clause it must be 4530 // either a constant integer expression or an integer-typed parameter that is 4531 // specified in a uniform clause on the directive. 4532 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4533 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4534 auto MI = LinModifiers.begin(); 4535 for (const Expr *E : Linears) { 4536 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4537 ++MI; 4538 E = E->IgnoreParenImpCasts(); 4539 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4540 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4541 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4542 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4543 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4544 ->getCanonicalDecl() == CanonPVD) { 4545 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4546 // A list-item cannot appear in more than one linear clause. 4547 if (LinearArgs.count(CanonPVD) > 0) { 4548 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4549 << getOpenMPClauseName(OMPC_linear) 4550 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4551 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4552 diag::note_omp_explicit_dsa) 4553 << getOpenMPClauseName(OMPC_linear); 4554 continue; 4555 } 4556 // Each argument can appear in at most one uniform or linear clause. 4557 if (UniformedArgs.count(CanonPVD) > 0) { 4558 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4559 << getOpenMPClauseName(OMPC_linear) 4560 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4561 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4562 diag::note_omp_explicit_dsa) 4563 << getOpenMPClauseName(OMPC_uniform); 4564 continue; 4565 } 4566 LinearArgs[CanonPVD] = E; 4567 if (E->isValueDependent() || E->isTypeDependent() || 4568 E->isInstantiationDependent() || 4569 E->containsUnexpandedParameterPack()) 4570 continue; 4571 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4572 PVD->getOriginalType()); 4573 continue; 4574 } 4575 } 4576 if (isa<CXXThisExpr>(E)) { 4577 if (UniformedLinearThis) { 4578 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4579 << getOpenMPClauseName(OMPC_linear) 4580 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4581 << E->getSourceRange(); 4582 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4583 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4584 : OMPC_linear); 4585 continue; 4586 } 4587 UniformedLinearThis = E; 4588 if (E->isValueDependent() || E->isTypeDependent() || 4589 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4590 continue; 4591 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4592 E->getType()); 4593 continue; 4594 } 4595 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4596 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4597 } 4598 Expr *Step = nullptr; 4599 Expr *NewStep = nullptr; 4600 SmallVector<Expr *, 4> NewSteps; 4601 for (Expr *E : Steps) { 4602 // Skip the same step expression, it was checked already. 4603 if (Step == E || !E) { 4604 NewSteps.push_back(E ? NewStep : nullptr); 4605 continue; 4606 } 4607 Step = E; 4608 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4609 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4610 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4611 if (UniformedArgs.count(CanonPVD) == 0) { 4612 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4613 << Step->getSourceRange(); 4614 } else if (E->isValueDependent() || E->isTypeDependent() || 4615 E->isInstantiationDependent() || 4616 E->containsUnexpandedParameterPack() || 4617 CanonPVD->getType()->hasIntegerRepresentation()) { 4618 NewSteps.push_back(Step); 4619 } else { 4620 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4621 << Step->getSourceRange(); 4622 } 4623 continue; 4624 } 4625 NewStep = Step; 4626 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4627 !Step->isInstantiationDependent() && 4628 !Step->containsUnexpandedParameterPack()) { 4629 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4630 .get(); 4631 if (NewStep) 4632 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4633 } 4634 NewSteps.push_back(NewStep); 4635 } 4636 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4637 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4638 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4639 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4640 const_cast<Expr **>(Linears.data()), Linears.size(), 4641 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4642 NewSteps.data(), NewSteps.size(), SR); 4643 ADecl->addAttr(NewAttr); 4644 return ConvertDeclToDeclGroup(ADecl); 4645 } 4646 4647 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4648 Stmt *AStmt, 4649 SourceLocation StartLoc, 4650 SourceLocation EndLoc) { 4651 if (!AStmt) 4652 return StmtError(); 4653 4654 auto *CS = cast<CapturedStmt>(AStmt); 4655 // 1.2.2 OpenMP Language Terminology 4656 // Structured block - An executable statement with a single entry at the 4657 // top and a single exit at the bottom. 4658 // The point of exit cannot be a branch out of the structured block. 4659 // longjmp() and throw() must not violate the entry/exit criteria. 4660 CS->getCapturedDecl()->setNothrow(); 4661 4662 setFunctionHasBranchProtectedScope(); 4663 4664 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4665 DSAStack->isCancelRegion()); 4666 } 4667 4668 namespace { 4669 /// Helper class for checking canonical form of the OpenMP loops and 4670 /// extracting iteration space of each loop in the loop nest, that will be used 4671 /// for IR generation. 4672 class OpenMPIterationSpaceChecker { 4673 /// Reference to Sema. 4674 Sema &SemaRef; 4675 /// Data-sharing stack. 4676 DSAStackTy &Stack; 4677 /// A location for diagnostics (when there is no some better location). 4678 SourceLocation DefaultLoc; 4679 /// A location for diagnostics (when increment is not compatible). 4680 SourceLocation ConditionLoc; 4681 /// A source location for referring to loop init later. 4682 SourceRange InitSrcRange; 4683 /// A source location for referring to condition later. 4684 SourceRange ConditionSrcRange; 4685 /// A source location for referring to increment later. 4686 SourceRange IncrementSrcRange; 4687 /// Loop variable. 4688 ValueDecl *LCDecl = nullptr; 4689 /// Reference to loop variable. 4690 Expr *LCRef = nullptr; 4691 /// Lower bound (initializer for the var). 4692 Expr *LB = nullptr; 4693 /// Upper bound. 4694 Expr *UB = nullptr; 4695 /// Loop step (increment). 4696 Expr *Step = nullptr; 4697 /// This flag is true when condition is one of: 4698 /// Var < UB 4699 /// Var <= UB 4700 /// UB > Var 4701 /// UB >= Var 4702 /// This will have no value when the condition is != 4703 llvm::Optional<bool> TestIsLessOp; 4704 /// This flag is true when condition is strict ( < or > ). 4705 bool TestIsStrictOp = false; 4706 /// This flag is true when step is subtracted on each iteration. 4707 bool SubtractStep = false; 4708 /// The outer loop counter this loop depends on (if any). 4709 const ValueDecl *DepDecl = nullptr; 4710 /// Contains number of loop (starts from 1) on which loop counter init 4711 /// expression of this loop depends on. 4712 Optional<unsigned> InitDependOnLC; 4713 /// Contains number of loop (starts from 1) on which loop counter condition 4714 /// expression of this loop depends on. 4715 Optional<unsigned> CondDependOnLC; 4716 /// Checks if the provide statement depends on the loop counter. 4717 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 4718 4719 public: 4720 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 4721 SourceLocation DefaultLoc) 4722 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 4723 ConditionLoc(DefaultLoc) {} 4724 /// Check init-expr for canonical loop form and save loop counter 4725 /// variable - #Var and its initialization value - #LB. 4726 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4727 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4728 /// for less/greater and for strict/non-strict comparison. 4729 bool checkAndSetCond(Expr *S); 4730 /// Check incr-expr for canonical loop form and return true if it 4731 /// does not conform, otherwise save loop step (#Step). 4732 bool checkAndSetInc(Expr *S); 4733 /// Return the loop counter variable. 4734 ValueDecl *getLoopDecl() const { return LCDecl; } 4735 /// Return the reference expression to loop counter variable. 4736 Expr *getLoopDeclRefExpr() const { return LCRef; } 4737 /// Source range of the loop init. 4738 SourceRange getInitSrcRange() const { return InitSrcRange; } 4739 /// Source range of the loop condition. 4740 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4741 /// Source range of the loop increment. 4742 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4743 /// True if the step should be subtracted. 4744 bool shouldSubtractStep() const { return SubtractStep; } 4745 /// True, if the compare operator is strict (<, > or !=). 4746 bool isStrictTestOp() const { return TestIsStrictOp; } 4747 /// Build the expression to calculate the number of iterations. 4748 Expr *buildNumIterations( 4749 Scope *S, const bool LimitedType, 4750 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4751 /// Build the precondition expression for the loops. 4752 Expr * 4753 buildPreCond(Scope *S, Expr *Cond, 4754 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4755 /// Build reference expression to the counter be used for codegen. 4756 DeclRefExpr * 4757 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4758 DSAStackTy &DSA) const; 4759 /// Build reference expression to the private counter be used for 4760 /// codegen. 4761 Expr *buildPrivateCounterVar() const; 4762 /// Build initialization of the counter be used for codegen. 4763 Expr *buildCounterInit() const; 4764 /// Build step of the counter be used for codegen. 4765 Expr *buildCounterStep() const; 4766 /// Build loop data with counter value for depend clauses in ordered 4767 /// directives. 4768 Expr * 4769 buildOrderedLoopData(Scope *S, Expr *Counter, 4770 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4771 SourceLocation Loc, Expr *Inc = nullptr, 4772 OverloadedOperatorKind OOK = OO_Amp); 4773 /// Return true if any expression is dependent. 4774 bool dependent() const; 4775 4776 private: 4777 /// Check the right-hand side of an assignment in the increment 4778 /// expression. 4779 bool checkAndSetIncRHS(Expr *RHS); 4780 /// Helper to set loop counter variable and its initializer. 4781 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 4782 bool EmitDiags); 4783 /// Helper to set upper bound. 4784 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4785 SourceRange SR, SourceLocation SL); 4786 /// Helper to set loop increment. 4787 bool setStep(Expr *NewStep, bool Subtract); 4788 }; 4789 4790 bool OpenMPIterationSpaceChecker::dependent() const { 4791 if (!LCDecl) { 4792 assert(!LB && !UB && !Step); 4793 return false; 4794 } 4795 return LCDecl->getType()->isDependentType() || 4796 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4797 (Step && Step->isValueDependent()); 4798 } 4799 4800 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4801 Expr *NewLCRefExpr, 4802 Expr *NewLB, bool EmitDiags) { 4803 // State consistency checking to ensure correct usage. 4804 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4805 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4806 if (!NewLCDecl || !NewLB) 4807 return true; 4808 LCDecl = getCanonicalDecl(NewLCDecl); 4809 LCRef = NewLCRefExpr; 4810 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4811 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4812 if ((Ctor->isCopyOrMoveConstructor() || 4813 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4814 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4815 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4816 LB = NewLB; 4817 if (EmitDiags) 4818 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 4819 return false; 4820 } 4821 4822 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4823 llvm::Optional<bool> LessOp, 4824 bool StrictOp, SourceRange SR, 4825 SourceLocation SL) { 4826 // State consistency checking to ensure correct usage. 4827 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4828 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4829 if (!NewUB) 4830 return true; 4831 UB = NewUB; 4832 if (LessOp) 4833 TestIsLessOp = LessOp; 4834 TestIsStrictOp = StrictOp; 4835 ConditionSrcRange = SR; 4836 ConditionLoc = SL; 4837 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 4838 return false; 4839 } 4840 4841 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4842 // State consistency checking to ensure correct usage. 4843 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4844 if (!NewStep) 4845 return true; 4846 if (!NewStep->isValueDependent()) { 4847 // Check that the step is integer expression. 4848 SourceLocation StepLoc = NewStep->getBeginLoc(); 4849 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4850 StepLoc, getExprAsWritten(NewStep)); 4851 if (Val.isInvalid()) 4852 return true; 4853 NewStep = Val.get(); 4854 4855 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4856 // If test-expr is of form var relational-op b and relational-op is < or 4857 // <= then incr-expr must cause var to increase on each iteration of the 4858 // loop. If test-expr is of form var relational-op b and relational-op is 4859 // > or >= then incr-expr must cause var to decrease on each iteration of 4860 // the loop. 4861 // If test-expr is of form b relational-op var and relational-op is < or 4862 // <= then incr-expr must cause var to decrease on each iteration of the 4863 // loop. If test-expr is of form b relational-op var and relational-op is 4864 // > or >= then incr-expr must cause var to increase on each iteration of 4865 // the loop. 4866 llvm::APSInt Result; 4867 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4868 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4869 bool IsConstNeg = 4870 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4871 bool IsConstPos = 4872 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4873 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4874 4875 // != with increment is treated as <; != with decrement is treated as > 4876 if (!TestIsLessOp.hasValue()) 4877 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4878 if (UB && (IsConstZero || 4879 (TestIsLessOp.getValue() ? 4880 (IsConstNeg || (IsUnsigned && Subtract)) : 4881 (IsConstPos || (IsUnsigned && !Subtract))))) { 4882 SemaRef.Diag(NewStep->getExprLoc(), 4883 diag::err_omp_loop_incr_not_compatible) 4884 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4885 SemaRef.Diag(ConditionLoc, 4886 diag::note_omp_loop_cond_requres_compatible_incr) 4887 << TestIsLessOp.getValue() << ConditionSrcRange; 4888 return true; 4889 } 4890 if (TestIsLessOp.getValue() == Subtract) { 4891 NewStep = 4892 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4893 .get(); 4894 Subtract = !Subtract; 4895 } 4896 } 4897 4898 Step = NewStep; 4899 SubtractStep = Subtract; 4900 return false; 4901 } 4902 4903 namespace { 4904 /// Checker for the non-rectangular loops. Checks if the initializer or 4905 /// condition expression references loop counter variable. 4906 class LoopCounterRefChecker final 4907 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 4908 Sema &SemaRef; 4909 DSAStackTy &Stack; 4910 const ValueDecl *CurLCDecl = nullptr; 4911 const ValueDecl *DepDecl = nullptr; 4912 const ValueDecl *PrevDepDecl = nullptr; 4913 bool IsInitializer = true; 4914 unsigned BaseLoopId = 0; 4915 bool checkDecl(const Expr *E, const ValueDecl *VD) { 4916 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 4917 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 4918 << (IsInitializer ? 0 : 1); 4919 return false; 4920 } 4921 const auto &&Data = Stack.isLoopControlVariable(VD); 4922 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 4923 // The type of the loop iterator on which we depend may not have a random 4924 // access iterator type. 4925 if (Data.first && VD->getType()->isRecordType()) { 4926 SmallString<128> Name; 4927 llvm::raw_svector_ostream OS(Name); 4928 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4929 /*Qualified=*/true); 4930 SemaRef.Diag(E->getExprLoc(), 4931 diag::err_omp_wrong_dependency_iterator_type) 4932 << OS.str(); 4933 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 4934 return false; 4935 } 4936 if (Data.first && 4937 (DepDecl || (PrevDepDecl && 4938 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 4939 if (!DepDecl && PrevDepDecl) 4940 DepDecl = PrevDepDecl; 4941 SmallString<128> Name; 4942 llvm::raw_svector_ostream OS(Name); 4943 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4944 /*Qualified=*/true); 4945 SemaRef.Diag(E->getExprLoc(), 4946 diag::err_omp_invariant_or_linear_dependency) 4947 << OS.str(); 4948 return false; 4949 } 4950 if (Data.first) { 4951 DepDecl = VD; 4952 BaseLoopId = Data.first; 4953 } 4954 return Data.first; 4955 } 4956 4957 public: 4958 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4959 const ValueDecl *VD = E->getDecl(); 4960 if (isa<VarDecl>(VD)) 4961 return checkDecl(E, VD); 4962 return false; 4963 } 4964 bool VisitMemberExpr(const MemberExpr *E) { 4965 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 4966 const ValueDecl *VD = E->getMemberDecl(); 4967 return checkDecl(E, VD); 4968 } 4969 return false; 4970 } 4971 bool VisitStmt(const Stmt *S) { 4972 bool Res = true; 4973 for (const Stmt *Child : S->children()) 4974 Res = Child && Visit(Child) && Res; 4975 return Res; 4976 } 4977 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 4978 const ValueDecl *CurLCDecl, bool IsInitializer, 4979 const ValueDecl *PrevDepDecl = nullptr) 4980 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 4981 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 4982 unsigned getBaseLoopId() const { 4983 assert(CurLCDecl && "Expected loop dependency."); 4984 return BaseLoopId; 4985 } 4986 const ValueDecl *getDepDecl() const { 4987 assert(CurLCDecl && "Expected loop dependency."); 4988 return DepDecl; 4989 } 4990 }; 4991 } // namespace 4992 4993 Optional<unsigned> 4994 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 4995 bool IsInitializer) { 4996 // Check for the non-rectangular loops. 4997 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 4998 DepDecl); 4999 if (LoopStmtChecker.Visit(S)) { 5000 DepDecl = LoopStmtChecker.getDepDecl(); 5001 return LoopStmtChecker.getBaseLoopId(); 5002 } 5003 return llvm::None; 5004 } 5005 5006 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5007 // Check init-expr for canonical loop form and save loop counter 5008 // variable - #Var and its initialization value - #LB. 5009 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5010 // var = lb 5011 // integer-type var = lb 5012 // random-access-iterator-type var = lb 5013 // pointer-type var = lb 5014 // 5015 if (!S) { 5016 if (EmitDiags) { 5017 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5018 } 5019 return true; 5020 } 5021 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5022 if (!ExprTemp->cleanupsHaveSideEffects()) 5023 S = ExprTemp->getSubExpr(); 5024 5025 InitSrcRange = S->getSourceRange(); 5026 if (Expr *E = dyn_cast<Expr>(S)) 5027 S = E->IgnoreParens(); 5028 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5029 if (BO->getOpcode() == BO_Assign) { 5030 Expr *LHS = BO->getLHS()->IgnoreParens(); 5031 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5032 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5033 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5034 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5035 EmitDiags); 5036 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5037 } 5038 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5039 if (ME->isArrow() && 5040 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5041 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5042 EmitDiags); 5043 } 5044 } 5045 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5046 if (DS->isSingleDecl()) { 5047 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5048 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5049 // Accept non-canonical init form here but emit ext. warning. 5050 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5051 SemaRef.Diag(S->getBeginLoc(), 5052 diag::ext_omp_loop_not_canonical_init) 5053 << S->getSourceRange(); 5054 return setLCDeclAndLB( 5055 Var, 5056 buildDeclRefExpr(SemaRef, Var, 5057 Var->getType().getNonReferenceType(), 5058 DS->getBeginLoc()), 5059 Var->getInit(), EmitDiags); 5060 } 5061 } 5062 } 5063 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5064 if (CE->getOperator() == OO_Equal) { 5065 Expr *LHS = CE->getArg(0); 5066 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5067 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5068 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5069 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5070 EmitDiags); 5071 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5072 } 5073 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5074 if (ME->isArrow() && 5075 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5076 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5077 EmitDiags); 5078 } 5079 } 5080 } 5081 5082 if (dependent() || SemaRef.CurContext->isDependentContext()) 5083 return false; 5084 if (EmitDiags) { 5085 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5086 << S->getSourceRange(); 5087 } 5088 return true; 5089 } 5090 5091 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5092 /// variable (which may be the loop variable) if possible. 5093 static const ValueDecl *getInitLCDecl(const Expr *E) { 5094 if (!E) 5095 return nullptr; 5096 E = getExprAsWritten(E); 5097 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5098 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5099 if ((Ctor->isCopyOrMoveConstructor() || 5100 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5101 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5102 E = CE->getArg(0)->IgnoreParenImpCasts(); 5103 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5104 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5105 return getCanonicalDecl(VD); 5106 } 5107 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5108 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5109 return getCanonicalDecl(ME->getMemberDecl()); 5110 return nullptr; 5111 } 5112 5113 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5114 // Check test-expr for canonical form, save upper-bound UB, flags for 5115 // less/greater and for strict/non-strict comparison. 5116 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5117 // var relational-op b 5118 // b relational-op var 5119 // 5120 if (!S) { 5121 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 5122 return true; 5123 } 5124 S = getExprAsWritten(S); 5125 SourceLocation CondLoc = S->getBeginLoc(); 5126 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5127 if (BO->isRelationalOp()) { 5128 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5129 return setUB(BO->getRHS(), 5130 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5131 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5132 BO->getSourceRange(), BO->getOperatorLoc()); 5133 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5134 return setUB(BO->getLHS(), 5135 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5136 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5137 BO->getSourceRange(), BO->getOperatorLoc()); 5138 } else if (BO->getOpcode() == BO_NE) 5139 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 5140 BO->getRHS() : BO->getLHS(), 5141 /*LessOp=*/llvm::None, 5142 /*StrictOp=*/true, 5143 BO->getSourceRange(), BO->getOperatorLoc()); 5144 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5145 if (CE->getNumArgs() == 2) { 5146 auto Op = CE->getOperator(); 5147 switch (Op) { 5148 case OO_Greater: 5149 case OO_GreaterEqual: 5150 case OO_Less: 5151 case OO_LessEqual: 5152 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5153 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5154 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5155 CE->getOperatorLoc()); 5156 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5157 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5158 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5159 CE->getOperatorLoc()); 5160 break; 5161 case OO_ExclaimEqual: 5162 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 5163 CE->getArg(1) : CE->getArg(0), 5164 /*LessOp=*/llvm::None, 5165 /*StrictOp=*/true, 5166 CE->getSourceRange(), 5167 CE->getOperatorLoc()); 5168 break; 5169 default: 5170 break; 5171 } 5172 } 5173 } 5174 if (dependent() || SemaRef.CurContext->isDependentContext()) 5175 return false; 5176 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5177 << S->getSourceRange() << LCDecl; 5178 return true; 5179 } 5180 5181 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5182 // RHS of canonical loop form increment can be: 5183 // var + incr 5184 // incr + var 5185 // var - incr 5186 // 5187 RHS = RHS->IgnoreParenImpCasts(); 5188 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5189 if (BO->isAdditiveOp()) { 5190 bool IsAdd = BO->getOpcode() == BO_Add; 5191 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5192 return setStep(BO->getRHS(), !IsAdd); 5193 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5194 return setStep(BO->getLHS(), /*Subtract=*/false); 5195 } 5196 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5197 bool IsAdd = CE->getOperator() == OO_Plus; 5198 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5199 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5200 return setStep(CE->getArg(1), !IsAdd); 5201 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5202 return setStep(CE->getArg(0), /*Subtract=*/false); 5203 } 5204 } 5205 if (dependent() || SemaRef.CurContext->isDependentContext()) 5206 return false; 5207 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5208 << RHS->getSourceRange() << LCDecl; 5209 return true; 5210 } 5211 5212 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5213 // Check incr-expr for canonical loop form and return true if it 5214 // does not conform. 5215 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5216 // ++var 5217 // var++ 5218 // --var 5219 // var-- 5220 // var += incr 5221 // var -= incr 5222 // var = var + incr 5223 // var = incr + var 5224 // var = var - incr 5225 // 5226 if (!S) { 5227 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5228 return true; 5229 } 5230 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5231 if (!ExprTemp->cleanupsHaveSideEffects()) 5232 S = ExprTemp->getSubExpr(); 5233 5234 IncrementSrcRange = S->getSourceRange(); 5235 S = S->IgnoreParens(); 5236 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5237 if (UO->isIncrementDecrementOp() && 5238 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5239 return setStep(SemaRef 5240 .ActOnIntegerConstant(UO->getBeginLoc(), 5241 (UO->isDecrementOp() ? -1 : 1)) 5242 .get(), 5243 /*Subtract=*/false); 5244 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5245 switch (BO->getOpcode()) { 5246 case BO_AddAssign: 5247 case BO_SubAssign: 5248 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5249 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5250 break; 5251 case BO_Assign: 5252 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5253 return checkAndSetIncRHS(BO->getRHS()); 5254 break; 5255 default: 5256 break; 5257 } 5258 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5259 switch (CE->getOperator()) { 5260 case OO_PlusPlus: 5261 case OO_MinusMinus: 5262 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5263 return setStep(SemaRef 5264 .ActOnIntegerConstant( 5265 CE->getBeginLoc(), 5266 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5267 .get(), 5268 /*Subtract=*/false); 5269 break; 5270 case OO_PlusEqual: 5271 case OO_MinusEqual: 5272 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5273 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5274 break; 5275 case OO_Equal: 5276 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5277 return checkAndSetIncRHS(CE->getArg(1)); 5278 break; 5279 default: 5280 break; 5281 } 5282 } 5283 if (dependent() || SemaRef.CurContext->isDependentContext()) 5284 return false; 5285 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5286 << S->getSourceRange() << LCDecl; 5287 return true; 5288 } 5289 5290 static ExprResult 5291 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5292 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5293 if (SemaRef.CurContext->isDependentContext()) 5294 return ExprResult(Capture); 5295 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5296 return SemaRef.PerformImplicitConversion( 5297 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5298 /*AllowExplicit=*/true); 5299 auto I = Captures.find(Capture); 5300 if (I != Captures.end()) 5301 return buildCapture(SemaRef, Capture, I->second); 5302 DeclRefExpr *Ref = nullptr; 5303 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5304 Captures[Capture] = Ref; 5305 return Res; 5306 } 5307 5308 /// Build the expression to calculate the number of iterations. 5309 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5310 Scope *S, const bool LimitedType, 5311 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5312 ExprResult Diff; 5313 QualType VarType = LCDecl->getType().getNonReferenceType(); 5314 if (VarType->isIntegerType() || VarType->isPointerType() || 5315 SemaRef.getLangOpts().CPlusPlus) { 5316 // Upper - Lower 5317 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5318 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5319 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5320 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5321 if (!Upper || !Lower) 5322 return nullptr; 5323 5324 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5325 5326 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5327 // BuildBinOp already emitted error, this one is to point user to upper 5328 // and lower bound, and to tell what is passed to 'operator-'. 5329 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5330 << Upper->getSourceRange() << Lower->getSourceRange(); 5331 return nullptr; 5332 } 5333 } 5334 5335 if (!Diff.isUsable()) 5336 return nullptr; 5337 5338 // Upper - Lower [- 1] 5339 if (TestIsStrictOp) 5340 Diff = SemaRef.BuildBinOp( 5341 S, DefaultLoc, BO_Sub, Diff.get(), 5342 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5343 if (!Diff.isUsable()) 5344 return nullptr; 5345 5346 // Upper - Lower [- 1] + Step 5347 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5348 if (!NewStep.isUsable()) 5349 return nullptr; 5350 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5351 if (!Diff.isUsable()) 5352 return nullptr; 5353 5354 // Parentheses (for dumping/debugging purposes only). 5355 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5356 if (!Diff.isUsable()) 5357 return nullptr; 5358 5359 // (Upper - Lower [- 1] + Step) / Step 5360 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5361 if (!Diff.isUsable()) 5362 return nullptr; 5363 5364 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5365 QualType Type = Diff.get()->getType(); 5366 ASTContext &C = SemaRef.Context; 5367 bool UseVarType = VarType->hasIntegerRepresentation() && 5368 C.getTypeSize(Type) > C.getTypeSize(VarType); 5369 if (!Type->isIntegerType() || UseVarType) { 5370 unsigned NewSize = 5371 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5372 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5373 : Type->hasSignedIntegerRepresentation(); 5374 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5375 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5376 Diff = SemaRef.PerformImplicitConversion( 5377 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5378 if (!Diff.isUsable()) 5379 return nullptr; 5380 } 5381 } 5382 if (LimitedType) { 5383 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5384 if (NewSize != C.getTypeSize(Type)) { 5385 if (NewSize < C.getTypeSize(Type)) { 5386 assert(NewSize == 64 && "incorrect loop var size"); 5387 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5388 << InitSrcRange << ConditionSrcRange; 5389 } 5390 QualType NewType = C.getIntTypeForBitwidth( 5391 NewSize, Type->hasSignedIntegerRepresentation() || 5392 C.getTypeSize(Type) < NewSize); 5393 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5394 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5395 Sema::AA_Converting, true); 5396 if (!Diff.isUsable()) 5397 return nullptr; 5398 } 5399 } 5400 } 5401 5402 return Diff.get(); 5403 } 5404 5405 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5406 Scope *S, Expr *Cond, 5407 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5408 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5409 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5410 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5411 5412 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 5413 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 5414 if (!NewLB.isUsable() || !NewUB.isUsable()) 5415 return nullptr; 5416 5417 ExprResult CondExpr = 5418 SemaRef.BuildBinOp(S, DefaultLoc, 5419 TestIsLessOp.getValue() ? 5420 (TestIsStrictOp ? BO_LT : BO_LE) : 5421 (TestIsStrictOp ? BO_GT : BO_GE), 5422 NewLB.get(), NewUB.get()); 5423 if (CondExpr.isUsable()) { 5424 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 5425 SemaRef.Context.BoolTy)) 5426 CondExpr = SemaRef.PerformImplicitConversion( 5427 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 5428 /*AllowExplicit=*/true); 5429 } 5430 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5431 // Otherwise use original loop condition and evaluate it in runtime. 5432 return CondExpr.isUsable() ? CondExpr.get() : Cond; 5433 } 5434 5435 /// Build reference expression to the counter be used for codegen. 5436 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 5437 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5438 DSAStackTy &DSA) const { 5439 auto *VD = dyn_cast<VarDecl>(LCDecl); 5440 if (!VD) { 5441 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 5442 DeclRefExpr *Ref = buildDeclRefExpr( 5443 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 5444 const DSAStackTy::DSAVarData Data = 5445 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 5446 // If the loop control decl is explicitly marked as private, do not mark it 5447 // as captured again. 5448 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 5449 Captures.insert(std::make_pair(LCRef, Ref)); 5450 return Ref; 5451 } 5452 return cast<DeclRefExpr>(LCRef); 5453 } 5454 5455 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 5456 if (LCDecl && !LCDecl->isInvalidDecl()) { 5457 QualType Type = LCDecl->getType().getNonReferenceType(); 5458 VarDecl *PrivateVar = buildVarDecl( 5459 SemaRef, DefaultLoc, Type, LCDecl->getName(), 5460 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 5461 isa<VarDecl>(LCDecl) 5462 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 5463 : nullptr); 5464 if (PrivateVar->isInvalidDecl()) 5465 return nullptr; 5466 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 5467 } 5468 return nullptr; 5469 } 5470 5471 /// Build initialization of the counter to be used for codegen. 5472 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 5473 5474 /// Build step of the counter be used for codegen. 5475 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 5476 5477 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 5478 Scope *S, Expr *Counter, 5479 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 5480 Expr *Inc, OverloadedOperatorKind OOK) { 5481 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 5482 if (!Cnt) 5483 return nullptr; 5484 if (Inc) { 5485 assert((OOK == OO_Plus || OOK == OO_Minus) && 5486 "Expected only + or - operations for depend clauses."); 5487 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 5488 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 5489 if (!Cnt) 5490 return nullptr; 5491 } 5492 ExprResult Diff; 5493 QualType VarType = LCDecl->getType().getNonReferenceType(); 5494 if (VarType->isIntegerType() || VarType->isPointerType() || 5495 SemaRef.getLangOpts().CPlusPlus) { 5496 // Upper - Lower 5497 Expr *Upper = TestIsLessOp.getValue() 5498 ? Cnt 5499 : tryBuildCapture(SemaRef, UB, Captures).get(); 5500 Expr *Lower = TestIsLessOp.getValue() 5501 ? tryBuildCapture(SemaRef, LB, Captures).get() 5502 : Cnt; 5503 if (!Upper || !Lower) 5504 return nullptr; 5505 5506 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5507 5508 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5509 // BuildBinOp already emitted error, this one is to point user to upper 5510 // and lower bound, and to tell what is passed to 'operator-'. 5511 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5512 << Upper->getSourceRange() << Lower->getSourceRange(); 5513 return nullptr; 5514 } 5515 } 5516 5517 if (!Diff.isUsable()) 5518 return nullptr; 5519 5520 // Parentheses (for dumping/debugging purposes only). 5521 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5522 if (!Diff.isUsable()) 5523 return nullptr; 5524 5525 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5526 if (!NewStep.isUsable()) 5527 return nullptr; 5528 // (Upper - Lower) / Step 5529 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5530 if (!Diff.isUsable()) 5531 return nullptr; 5532 5533 return Diff.get(); 5534 } 5535 5536 /// Iteration space of a single for loop. 5537 struct LoopIterationSpace final { 5538 /// True if the condition operator is the strict compare operator (<, > or 5539 /// !=). 5540 bool IsStrictCompare = false; 5541 /// Condition of the loop. 5542 Expr *PreCond = nullptr; 5543 /// This expression calculates the number of iterations in the loop. 5544 /// It is always possible to calculate it before starting the loop. 5545 Expr *NumIterations = nullptr; 5546 /// The loop counter variable. 5547 Expr *CounterVar = nullptr; 5548 /// Private loop counter variable. 5549 Expr *PrivateCounterVar = nullptr; 5550 /// This is initializer for the initial value of #CounterVar. 5551 Expr *CounterInit = nullptr; 5552 /// This is step for the #CounterVar used to generate its update: 5553 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5554 Expr *CounterStep = nullptr; 5555 /// Should step be subtracted? 5556 bool Subtract = false; 5557 /// Source range of the loop init. 5558 SourceRange InitSrcRange; 5559 /// Source range of the loop condition. 5560 SourceRange CondSrcRange; 5561 /// Source range of the loop increment. 5562 SourceRange IncSrcRange; 5563 }; 5564 5565 } // namespace 5566 5567 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5568 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5569 assert(Init && "Expected loop in canonical form."); 5570 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5571 if (AssociatedLoops > 0 && 5572 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5573 DSAStack->loopStart(); 5574 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 5575 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5576 if (ValueDecl *D = ISC.getLoopDecl()) { 5577 auto *VD = dyn_cast<VarDecl>(D); 5578 if (!VD) { 5579 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5580 VD = Private; 5581 } else { 5582 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5583 /*WithInit=*/false); 5584 VD = cast<VarDecl>(Ref->getDecl()); 5585 } 5586 } 5587 DSAStack->addLoopControlVariable(D, VD); 5588 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5589 if (LD != D->getCanonicalDecl()) { 5590 DSAStack->resetPossibleLoopCounter(); 5591 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5592 MarkDeclarationsReferencedInExpr( 5593 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5594 Var->getType().getNonLValueExprType(Context), 5595 ForLoc, /*RefersToCapture=*/true)); 5596 } 5597 } 5598 } 5599 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 5600 } 5601 } 5602 5603 /// Called on a for stmt to check and extract its iteration space 5604 /// for further processing (such as collapsing). 5605 static bool checkOpenMPIterationSpace( 5606 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 5607 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 5608 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 5609 Expr *OrderedLoopCountExpr, 5610 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5611 LoopIterationSpace &ResultIterSpace, 5612 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5613 // OpenMP [2.6, Canonical Loop Form] 5614 // for (init-expr; test-expr; incr-expr) structured-block 5615 auto *For = dyn_cast_or_null<ForStmt>(S); 5616 if (!For) { 5617 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 5618 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 5619 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 5620 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 5621 if (TotalNestedLoopCount > 1) { 5622 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 5623 SemaRef.Diag(DSA.getConstructLoc(), 5624 diag::note_omp_collapse_ordered_expr) 5625 << 2 << CollapseLoopCountExpr->getSourceRange() 5626 << OrderedLoopCountExpr->getSourceRange(); 5627 else if (CollapseLoopCountExpr) 5628 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5629 diag::note_omp_collapse_ordered_expr) 5630 << 0 << CollapseLoopCountExpr->getSourceRange(); 5631 else 5632 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5633 diag::note_omp_collapse_ordered_expr) 5634 << 1 << OrderedLoopCountExpr->getSourceRange(); 5635 } 5636 return true; 5637 } 5638 assert(For->getBody()); 5639 5640 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 5641 5642 // Check init. 5643 Stmt *Init = For->getInit(); 5644 if (ISC.checkAndSetInit(Init)) 5645 return true; 5646 5647 bool HasErrors = false; 5648 5649 // Check loop variable's type. 5650 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 5651 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5652 5653 // OpenMP [2.6, Canonical Loop Form] 5654 // Var is one of the following: 5655 // A variable of signed or unsigned integer type. 5656 // For C++, a variable of a random access iterator type. 5657 // For C, a variable of a pointer type. 5658 QualType VarType = LCDecl->getType().getNonReferenceType(); 5659 if (!VarType->isDependentType() && !VarType->isIntegerType() && 5660 !VarType->isPointerType() && 5661 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 5662 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 5663 << SemaRef.getLangOpts().CPlusPlus; 5664 HasErrors = true; 5665 } 5666 5667 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 5668 // a Construct 5669 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5670 // parallel for construct is (are) private. 5671 // The loop iteration variable in the associated for-loop of a simd 5672 // construct with just one associated for-loop is linear with a 5673 // constant-linear-step that is the increment of the associated for-loop. 5674 // Exclude loop var from the list of variables with implicitly defined data 5675 // sharing attributes. 5676 VarsWithImplicitDSA.erase(LCDecl); 5677 5678 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5679 // in a Construct, C/C++]. 5680 // The loop iteration variable in the associated for-loop of a simd 5681 // construct with just one associated for-loop may be listed in a linear 5682 // clause with a constant-linear-step that is the increment of the 5683 // associated for-loop. 5684 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5685 // parallel for construct may be listed in a private or lastprivate clause. 5686 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 5687 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 5688 // declared in the loop and it is predetermined as a private. 5689 OpenMPClauseKind PredeterminedCKind = 5690 isOpenMPSimdDirective(DKind) 5691 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5692 : OMPC_private; 5693 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5694 DVar.CKind != PredeterminedCKind) || 5695 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5696 isOpenMPDistributeDirective(DKind)) && 5697 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5698 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5699 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5700 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5701 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5702 << getOpenMPClauseName(PredeterminedCKind); 5703 if (DVar.RefExpr == nullptr) 5704 DVar.CKind = PredeterminedCKind; 5705 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5706 HasErrors = true; 5707 } else if (LoopDeclRefExpr != nullptr) { 5708 // Make the loop iteration variable private (for worksharing constructs), 5709 // linear (for simd directives with the only one associated loop) or 5710 // lastprivate (for simd directives with several collapsed or ordered 5711 // loops). 5712 if (DVar.CKind == OMPC_unknown) 5713 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5714 } 5715 5716 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5717 5718 // Check test-expr. 5719 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5720 5721 // Check incr-expr. 5722 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5723 } 5724 5725 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5726 return HasErrors; 5727 5728 // Build the loop's iteration space representation. 5729 ResultIterSpace.PreCond = 5730 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5731 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5732 DSA.getCurScope(), 5733 (isOpenMPWorksharingDirective(DKind) || 5734 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5735 Captures); 5736 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5737 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5738 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5739 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5740 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5741 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5742 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5743 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5744 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5745 5746 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5747 ResultIterSpace.NumIterations == nullptr || 5748 ResultIterSpace.CounterVar == nullptr || 5749 ResultIterSpace.PrivateCounterVar == nullptr || 5750 ResultIterSpace.CounterInit == nullptr || 5751 ResultIterSpace.CounterStep == nullptr); 5752 if (!HasErrors && DSA.isOrderedRegion()) { 5753 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5754 if (CurrentNestedLoopCount < 5755 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5756 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5757 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5758 DSA.getOrderedRegionParam().second->setLoopCounter( 5759 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5760 } 5761 } 5762 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5763 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5764 // Erroneous case - clause has some problems. 5765 continue; 5766 } 5767 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5768 Pair.second.size() <= CurrentNestedLoopCount) { 5769 // Erroneous case - clause has some problems. 5770 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5771 continue; 5772 } 5773 Expr *CntValue; 5774 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5775 CntValue = ISC.buildOrderedLoopData( 5776 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5777 Pair.first->getDependencyLoc()); 5778 else 5779 CntValue = ISC.buildOrderedLoopData( 5780 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5781 Pair.first->getDependencyLoc(), 5782 Pair.second[CurrentNestedLoopCount].first, 5783 Pair.second[CurrentNestedLoopCount].second); 5784 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5785 } 5786 } 5787 5788 return HasErrors; 5789 } 5790 5791 /// Build 'VarRef = Start. 5792 static ExprResult 5793 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5794 ExprResult Start, 5795 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5796 // Build 'VarRef = Start. 5797 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5798 if (!NewStart.isUsable()) 5799 return ExprError(); 5800 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5801 VarRef.get()->getType())) { 5802 NewStart = SemaRef.PerformImplicitConversion( 5803 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5804 /*AllowExplicit=*/true); 5805 if (!NewStart.isUsable()) 5806 return ExprError(); 5807 } 5808 5809 ExprResult Init = 5810 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5811 return Init; 5812 } 5813 5814 /// Build 'VarRef = Start + Iter * Step'. 5815 static ExprResult buildCounterUpdate( 5816 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5817 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5818 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5819 // Add parentheses (for debugging purposes only). 5820 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5821 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5822 !Step.isUsable()) 5823 return ExprError(); 5824 5825 ExprResult NewStep = Step; 5826 if (Captures) 5827 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5828 if (NewStep.isInvalid()) 5829 return ExprError(); 5830 ExprResult Update = 5831 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5832 if (!Update.isUsable()) 5833 return ExprError(); 5834 5835 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5836 // 'VarRef = Start (+|-) Iter * Step'. 5837 ExprResult NewStart = Start; 5838 if (Captures) 5839 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5840 if (NewStart.isInvalid()) 5841 return ExprError(); 5842 5843 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5844 ExprResult SavedUpdate = Update; 5845 ExprResult UpdateVal; 5846 if (VarRef.get()->getType()->isOverloadableType() || 5847 NewStart.get()->getType()->isOverloadableType() || 5848 Update.get()->getType()->isOverloadableType()) { 5849 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5850 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5851 Update = 5852 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5853 if (Update.isUsable()) { 5854 UpdateVal = 5855 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5856 VarRef.get(), SavedUpdate.get()); 5857 if (UpdateVal.isUsable()) { 5858 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5859 UpdateVal.get()); 5860 } 5861 } 5862 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5863 } 5864 5865 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5866 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5867 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5868 NewStart.get(), SavedUpdate.get()); 5869 if (!Update.isUsable()) 5870 return ExprError(); 5871 5872 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5873 VarRef.get()->getType())) { 5874 Update = SemaRef.PerformImplicitConversion( 5875 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5876 if (!Update.isUsable()) 5877 return ExprError(); 5878 } 5879 5880 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5881 } 5882 return Update; 5883 } 5884 5885 /// Convert integer expression \a E to make it have at least \a Bits 5886 /// bits. 5887 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5888 if (E == nullptr) 5889 return ExprError(); 5890 ASTContext &C = SemaRef.Context; 5891 QualType OldType = E->getType(); 5892 unsigned HasBits = C.getTypeSize(OldType); 5893 if (HasBits >= Bits) 5894 return ExprResult(E); 5895 // OK to convert to signed, because new type has more bits than old. 5896 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5897 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5898 true); 5899 } 5900 5901 /// Check if the given expression \a E is a constant integer that fits 5902 /// into \a Bits bits. 5903 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5904 if (E == nullptr) 5905 return false; 5906 llvm::APSInt Result; 5907 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5908 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5909 return false; 5910 } 5911 5912 /// Build preinits statement for the given declarations. 5913 static Stmt *buildPreInits(ASTContext &Context, 5914 MutableArrayRef<Decl *> PreInits) { 5915 if (!PreInits.empty()) { 5916 return new (Context) DeclStmt( 5917 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5918 SourceLocation(), SourceLocation()); 5919 } 5920 return nullptr; 5921 } 5922 5923 /// Build preinits statement for the given declarations. 5924 static Stmt * 5925 buildPreInits(ASTContext &Context, 5926 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5927 if (!Captures.empty()) { 5928 SmallVector<Decl *, 16> PreInits; 5929 for (const auto &Pair : Captures) 5930 PreInits.push_back(Pair.second->getDecl()); 5931 return buildPreInits(Context, PreInits); 5932 } 5933 return nullptr; 5934 } 5935 5936 /// Build postupdate expression for the given list of postupdates expressions. 5937 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5938 Expr *PostUpdate = nullptr; 5939 if (!PostUpdates.empty()) { 5940 for (Expr *E : PostUpdates) { 5941 Expr *ConvE = S.BuildCStyleCastExpr( 5942 E->getExprLoc(), 5943 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5944 E->getExprLoc(), E) 5945 .get(); 5946 PostUpdate = PostUpdate 5947 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5948 PostUpdate, ConvE) 5949 .get() 5950 : ConvE; 5951 } 5952 } 5953 return PostUpdate; 5954 } 5955 5956 /// Called on a for stmt to check itself and nested loops (if any). 5957 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5958 /// number of collapsed loops otherwise. 5959 static unsigned 5960 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5961 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5962 DSAStackTy &DSA, 5963 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5964 OMPLoopDirective::HelperExprs &Built) { 5965 unsigned NestedLoopCount = 1; 5966 if (CollapseLoopCountExpr) { 5967 // Found 'collapse' clause - calculate collapse number. 5968 Expr::EvalResult Result; 5969 if (!CollapseLoopCountExpr->isValueDependent() && 5970 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 5971 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5972 } else { 5973 Built.clear(/*size=*/1); 5974 return 1; 5975 } 5976 } 5977 unsigned OrderedLoopCount = 1; 5978 if (OrderedLoopCountExpr) { 5979 // Found 'ordered' clause - calculate collapse number. 5980 Expr::EvalResult EVResult; 5981 if (!OrderedLoopCountExpr->isValueDependent() && 5982 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 5983 SemaRef.getASTContext())) { 5984 llvm::APSInt Result = EVResult.Val.getInt(); 5985 if (Result.getLimitedValue() < NestedLoopCount) { 5986 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5987 diag::err_omp_wrong_ordered_loop_count) 5988 << OrderedLoopCountExpr->getSourceRange(); 5989 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5990 diag::note_collapse_loop_count) 5991 << CollapseLoopCountExpr->getSourceRange(); 5992 } 5993 OrderedLoopCount = Result.getLimitedValue(); 5994 } else { 5995 Built.clear(/*size=*/1); 5996 return 1; 5997 } 5998 } 5999 // This is helper routine for loop directives (e.g., 'for', 'simd', 6000 // 'for simd', etc.). 6001 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6002 SmallVector<LoopIterationSpace, 4> IterSpaces( 6003 std::max(OrderedLoopCount, NestedLoopCount)); 6004 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6005 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6006 if (checkOpenMPIterationSpace( 6007 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6008 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6009 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 6010 Captures)) 6011 return 0; 6012 // Move on to the next nested for loop, or to the loop body. 6013 // OpenMP [2.8.1, simd construct, Restrictions] 6014 // All loops associated with the construct must be perfectly nested; that 6015 // is, there must be no intervening code nor any OpenMP directive between 6016 // any two loops. 6017 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6018 } 6019 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6020 if (checkOpenMPIterationSpace( 6021 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6022 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6023 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 6024 Captures)) 6025 return 0; 6026 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6027 // Handle initialization of captured loop iterator variables. 6028 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6029 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6030 Captures[DRE] = DRE; 6031 } 6032 } 6033 // Move on to the next nested for loop, or to the loop body. 6034 // OpenMP [2.8.1, simd construct, Restrictions] 6035 // All loops associated with the construct must be perfectly nested; that 6036 // is, there must be no intervening code nor any OpenMP directive between 6037 // any two loops. 6038 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6039 } 6040 6041 Built.clear(/* size */ NestedLoopCount); 6042 6043 if (SemaRef.CurContext->isDependentContext()) 6044 return NestedLoopCount; 6045 6046 // An example of what is generated for the following code: 6047 // 6048 // #pragma omp simd collapse(2) ordered(2) 6049 // for (i = 0; i < NI; ++i) 6050 // for (k = 0; k < NK; ++k) 6051 // for (j = J0; j < NJ; j+=2) { 6052 // <loop body> 6053 // } 6054 // 6055 // We generate the code below. 6056 // Note: the loop body may be outlined in CodeGen. 6057 // Note: some counters may be C++ classes, operator- is used to find number of 6058 // iterations and operator+= to calculate counter value. 6059 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6060 // or i64 is currently supported). 6061 // 6062 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6063 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6064 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6065 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6066 // // similar updates for vars in clauses (e.g. 'linear') 6067 // <loop body (using local i and j)> 6068 // } 6069 // i = NI; // assign final values of counters 6070 // j = NJ; 6071 // 6072 6073 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6074 // the iteration counts of the collapsed for loops. 6075 // Precondition tests if there is at least one iteration (all conditions are 6076 // true). 6077 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6078 Expr *N0 = IterSpaces[0].NumIterations; 6079 ExprResult LastIteration32 = 6080 widenIterationCount(/*Bits=*/32, 6081 SemaRef 6082 .PerformImplicitConversion( 6083 N0->IgnoreImpCasts(), N0->getType(), 6084 Sema::AA_Converting, /*AllowExplicit=*/true) 6085 .get(), 6086 SemaRef); 6087 ExprResult LastIteration64 = widenIterationCount( 6088 /*Bits=*/64, 6089 SemaRef 6090 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6091 Sema::AA_Converting, 6092 /*AllowExplicit=*/true) 6093 .get(), 6094 SemaRef); 6095 6096 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6097 return NestedLoopCount; 6098 6099 ASTContext &C = SemaRef.Context; 6100 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6101 6102 Scope *CurScope = DSA.getCurScope(); 6103 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6104 if (PreCond.isUsable()) { 6105 PreCond = 6106 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6107 PreCond.get(), IterSpaces[Cnt].PreCond); 6108 } 6109 Expr *N = IterSpaces[Cnt].NumIterations; 6110 SourceLocation Loc = N->getExprLoc(); 6111 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6112 if (LastIteration32.isUsable()) 6113 LastIteration32 = SemaRef.BuildBinOp( 6114 CurScope, Loc, BO_Mul, LastIteration32.get(), 6115 SemaRef 6116 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6117 Sema::AA_Converting, 6118 /*AllowExplicit=*/true) 6119 .get()); 6120 if (LastIteration64.isUsable()) 6121 LastIteration64 = SemaRef.BuildBinOp( 6122 CurScope, Loc, BO_Mul, LastIteration64.get(), 6123 SemaRef 6124 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6125 Sema::AA_Converting, 6126 /*AllowExplicit=*/true) 6127 .get()); 6128 } 6129 6130 // Choose either the 32-bit or 64-bit version. 6131 ExprResult LastIteration = LastIteration64; 6132 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6133 (LastIteration32.isUsable() && 6134 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6135 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6136 fitsInto( 6137 /*Bits=*/32, 6138 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6139 LastIteration64.get(), SemaRef)))) 6140 LastIteration = LastIteration32; 6141 QualType VType = LastIteration.get()->getType(); 6142 QualType RealVType = VType; 6143 QualType StrideVType = VType; 6144 if (isOpenMPTaskLoopDirective(DKind)) { 6145 VType = 6146 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6147 StrideVType = 6148 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6149 } 6150 6151 if (!LastIteration.isUsable()) 6152 return 0; 6153 6154 // Save the number of iterations. 6155 ExprResult NumIterations = LastIteration; 6156 { 6157 LastIteration = SemaRef.BuildBinOp( 6158 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6159 LastIteration.get(), 6160 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6161 if (!LastIteration.isUsable()) 6162 return 0; 6163 } 6164 6165 // Calculate the last iteration number beforehand instead of doing this on 6166 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6167 llvm::APSInt Result; 6168 bool IsConstant = 6169 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6170 ExprResult CalcLastIteration; 6171 if (!IsConstant) { 6172 ExprResult SaveRef = 6173 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6174 LastIteration = SaveRef; 6175 6176 // Prepare SaveRef + 1. 6177 NumIterations = SemaRef.BuildBinOp( 6178 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6179 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6180 if (!NumIterations.isUsable()) 6181 return 0; 6182 } 6183 6184 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6185 6186 // Build variables passed into runtime, necessary for worksharing directives. 6187 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6188 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6189 isOpenMPDistributeDirective(DKind)) { 6190 // Lower bound variable, initialized with zero. 6191 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6192 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6193 SemaRef.AddInitializerToDecl(LBDecl, 6194 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6195 /*DirectInit*/ false); 6196 6197 // Upper bound variable, initialized with last iteration number. 6198 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6199 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6200 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6201 /*DirectInit*/ false); 6202 6203 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6204 // This will be used to implement clause 'lastprivate'. 6205 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6206 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6207 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6208 SemaRef.AddInitializerToDecl(ILDecl, 6209 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6210 /*DirectInit*/ false); 6211 6212 // Stride variable returned by runtime (we initialize it to 1 by default). 6213 VarDecl *STDecl = 6214 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6215 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6216 SemaRef.AddInitializerToDecl(STDecl, 6217 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6218 /*DirectInit*/ false); 6219 6220 // Build expression: UB = min(UB, LastIteration) 6221 // It is necessary for CodeGen of directives with static scheduling. 6222 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6223 UB.get(), LastIteration.get()); 6224 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6225 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6226 LastIteration.get(), UB.get()); 6227 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6228 CondOp.get()); 6229 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6230 6231 // If we have a combined directive that combines 'distribute', 'for' or 6232 // 'simd' we need to be able to access the bounds of the schedule of the 6233 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6234 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6235 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6236 // Lower bound variable, initialized with zero. 6237 VarDecl *CombLBDecl = 6238 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6239 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6240 SemaRef.AddInitializerToDecl( 6241 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6242 /*DirectInit*/ false); 6243 6244 // Upper bound variable, initialized with last iteration number. 6245 VarDecl *CombUBDecl = 6246 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6247 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6248 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6249 /*DirectInit*/ false); 6250 6251 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6252 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6253 ExprResult CombCondOp = 6254 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6255 LastIteration.get(), CombUB.get()); 6256 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6257 CombCondOp.get()); 6258 CombEUB = 6259 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6260 6261 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6262 // We expect to have at least 2 more parameters than the 'parallel' 6263 // directive does - the lower and upper bounds of the previous schedule. 6264 assert(CD->getNumParams() >= 4 && 6265 "Unexpected number of parameters in loop combined directive"); 6266 6267 // Set the proper type for the bounds given what we learned from the 6268 // enclosed loops. 6269 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6270 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6271 6272 // Previous lower and upper bounds are obtained from the region 6273 // parameters. 6274 PrevLB = 6275 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6276 PrevUB = 6277 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6278 } 6279 } 6280 6281 // Build the iteration variable and its initialization before loop. 6282 ExprResult IV; 6283 ExprResult Init, CombInit; 6284 { 6285 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6286 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6287 Expr *RHS = 6288 (isOpenMPWorksharingDirective(DKind) || 6289 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6290 ? LB.get() 6291 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6292 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6293 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6294 6295 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6296 Expr *CombRHS = 6297 (isOpenMPWorksharingDirective(DKind) || 6298 isOpenMPTaskLoopDirective(DKind) || 6299 isOpenMPDistributeDirective(DKind)) 6300 ? CombLB.get() 6301 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6302 CombInit = 6303 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6304 CombInit = 6305 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6306 } 6307 } 6308 6309 bool UseStrictCompare = 6310 RealVType->hasUnsignedIntegerRepresentation() && 6311 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6312 return LIS.IsStrictCompare; 6313 }); 6314 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6315 // unsigned IV)) for worksharing loops. 6316 SourceLocation CondLoc = AStmt->getBeginLoc(); 6317 Expr *BoundUB = UB.get(); 6318 if (UseStrictCompare) { 6319 BoundUB = 6320 SemaRef 6321 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6322 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6323 .get(); 6324 BoundUB = 6325 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6326 } 6327 ExprResult Cond = 6328 (isOpenMPWorksharingDirective(DKind) || 6329 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6330 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6331 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6332 BoundUB) 6333 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6334 NumIterations.get()); 6335 ExprResult CombDistCond; 6336 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6337 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6338 NumIterations.get()); 6339 } 6340 6341 ExprResult CombCond; 6342 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6343 Expr *BoundCombUB = CombUB.get(); 6344 if (UseStrictCompare) { 6345 BoundCombUB = 6346 SemaRef 6347 .BuildBinOp( 6348 CurScope, CondLoc, BO_Add, BoundCombUB, 6349 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6350 .get(); 6351 BoundCombUB = 6352 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6353 .get(); 6354 } 6355 CombCond = 6356 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6357 IV.get(), BoundCombUB); 6358 } 6359 // Loop increment (IV = IV + 1) 6360 SourceLocation IncLoc = AStmt->getBeginLoc(); 6361 ExprResult Inc = 6362 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6363 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6364 if (!Inc.isUsable()) 6365 return 0; 6366 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6367 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6368 if (!Inc.isUsable()) 6369 return 0; 6370 6371 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6372 // Used for directives with static scheduling. 6373 // In combined construct, add combined version that use CombLB and CombUB 6374 // base variables for the update 6375 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6376 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6377 isOpenMPDistributeDirective(DKind)) { 6378 // LB + ST 6379 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6380 if (!NextLB.isUsable()) 6381 return 0; 6382 // LB = LB + ST 6383 NextLB = 6384 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6385 NextLB = 6386 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6387 if (!NextLB.isUsable()) 6388 return 0; 6389 // UB + ST 6390 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6391 if (!NextUB.isUsable()) 6392 return 0; 6393 // UB = UB + ST 6394 NextUB = 6395 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6396 NextUB = 6397 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6398 if (!NextUB.isUsable()) 6399 return 0; 6400 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6401 CombNextLB = 6402 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6403 if (!NextLB.isUsable()) 6404 return 0; 6405 // LB = LB + ST 6406 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6407 CombNextLB.get()); 6408 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6409 /*DiscardedValue*/ false); 6410 if (!CombNextLB.isUsable()) 6411 return 0; 6412 // UB + ST 6413 CombNextUB = 6414 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 6415 if (!CombNextUB.isUsable()) 6416 return 0; 6417 // UB = UB + ST 6418 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 6419 CombNextUB.get()); 6420 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 6421 /*DiscardedValue*/ false); 6422 if (!CombNextUB.isUsable()) 6423 return 0; 6424 } 6425 } 6426 6427 // Create increment expression for distribute loop when combined in a same 6428 // directive with for as IV = IV + ST; ensure upper bound expression based 6429 // on PrevUB instead of NumIterations - used to implement 'for' when found 6430 // in combination with 'distribute', like in 'distribute parallel for' 6431 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 6432 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 6433 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6434 DistCond = SemaRef.BuildBinOp( 6435 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 6436 assert(DistCond.isUsable() && "distribute cond expr was not built"); 6437 6438 DistInc = 6439 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 6440 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6441 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 6442 DistInc.get()); 6443 DistInc = 6444 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 6445 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6446 6447 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 6448 // construct 6449 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 6450 ExprResult IsUBGreater = 6451 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 6452 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6453 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 6454 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 6455 CondOp.get()); 6456 PrevEUB = 6457 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 6458 6459 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 6460 // parallel for is in combination with a distribute directive with 6461 // schedule(static, 1) 6462 Expr *BoundPrevUB = PrevUB.get(); 6463 if (UseStrictCompare) { 6464 BoundPrevUB = 6465 SemaRef 6466 .BuildBinOp( 6467 CurScope, CondLoc, BO_Add, BoundPrevUB, 6468 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6469 .get(); 6470 BoundPrevUB = 6471 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 6472 .get(); 6473 } 6474 ParForInDistCond = 6475 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6476 IV.get(), BoundPrevUB); 6477 } 6478 6479 // Build updates and final values of the loop counters. 6480 bool HasErrors = false; 6481 Built.Counters.resize(NestedLoopCount); 6482 Built.Inits.resize(NestedLoopCount); 6483 Built.Updates.resize(NestedLoopCount); 6484 Built.Finals.resize(NestedLoopCount); 6485 { 6486 // We implement the following algorithm for obtaining the 6487 // original loop iteration variable values based on the 6488 // value of the collapsed loop iteration variable IV. 6489 // 6490 // Let n+1 be the number of collapsed loops in the nest. 6491 // Iteration variables (I0, I1, .... In) 6492 // Iteration counts (N0, N1, ... Nn) 6493 // 6494 // Acc = IV; 6495 // 6496 // To compute Ik for loop k, 0 <= k <= n, generate: 6497 // Prod = N(k+1) * N(k+2) * ... * Nn; 6498 // Ik = Acc / Prod; 6499 // Acc -= Ik * Prod; 6500 // 6501 ExprResult Acc = IV; 6502 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6503 LoopIterationSpace &IS = IterSpaces[Cnt]; 6504 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 6505 ExprResult Iter; 6506 6507 // Compute prod 6508 ExprResult Prod = 6509 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6510 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 6511 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 6512 IterSpaces[K].NumIterations); 6513 6514 // Iter = Acc / Prod 6515 // If there is at least one more inner loop to avoid 6516 // multiplication by 1. 6517 if (Cnt + 1 < NestedLoopCount) 6518 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 6519 Acc.get(), Prod.get()); 6520 else 6521 Iter = Acc; 6522 if (!Iter.isUsable()) { 6523 HasErrors = true; 6524 break; 6525 } 6526 6527 // Update Acc: 6528 // Acc -= Iter * Prod 6529 // Check if there is at least one more inner loop to avoid 6530 // multiplication by 1. 6531 if (Cnt + 1 < NestedLoopCount) 6532 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 6533 Iter.get(), Prod.get()); 6534 else 6535 Prod = Iter; 6536 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 6537 Acc.get(), Prod.get()); 6538 6539 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 6540 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 6541 DeclRefExpr *CounterVar = buildDeclRefExpr( 6542 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 6543 /*RefersToCapture=*/true); 6544 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 6545 IS.CounterInit, Captures); 6546 if (!Init.isUsable()) { 6547 HasErrors = true; 6548 break; 6549 } 6550 ExprResult Update = buildCounterUpdate( 6551 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 6552 IS.CounterStep, IS.Subtract, &Captures); 6553 if (!Update.isUsable()) { 6554 HasErrors = true; 6555 break; 6556 } 6557 6558 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6559 ExprResult Final = buildCounterUpdate( 6560 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 6561 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 6562 if (!Final.isUsable()) { 6563 HasErrors = true; 6564 break; 6565 } 6566 6567 if (!Update.isUsable() || !Final.isUsable()) { 6568 HasErrors = true; 6569 break; 6570 } 6571 // Save results 6572 Built.Counters[Cnt] = IS.CounterVar; 6573 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6574 Built.Inits[Cnt] = Init.get(); 6575 Built.Updates[Cnt] = Update.get(); 6576 Built.Finals[Cnt] = Final.get(); 6577 } 6578 } 6579 6580 if (HasErrors) 6581 return 0; 6582 6583 // Save results 6584 Built.IterationVarRef = IV.get(); 6585 Built.LastIteration = LastIteration.get(); 6586 Built.NumIterations = NumIterations.get(); 6587 Built.CalcLastIteration = SemaRef 6588 .ActOnFinishFullExpr(CalcLastIteration.get(), 6589 /*DiscardedValue*/ false) 6590 .get(); 6591 Built.PreCond = PreCond.get(); 6592 Built.PreInits = buildPreInits(C, Captures); 6593 Built.Cond = Cond.get(); 6594 Built.Init = Init.get(); 6595 Built.Inc = Inc.get(); 6596 Built.LB = LB.get(); 6597 Built.UB = UB.get(); 6598 Built.IL = IL.get(); 6599 Built.ST = ST.get(); 6600 Built.EUB = EUB.get(); 6601 Built.NLB = NextLB.get(); 6602 Built.NUB = NextUB.get(); 6603 Built.PrevLB = PrevLB.get(); 6604 Built.PrevUB = PrevUB.get(); 6605 Built.DistInc = DistInc.get(); 6606 Built.PrevEUB = PrevEUB.get(); 6607 Built.DistCombinedFields.LB = CombLB.get(); 6608 Built.DistCombinedFields.UB = CombUB.get(); 6609 Built.DistCombinedFields.EUB = CombEUB.get(); 6610 Built.DistCombinedFields.Init = CombInit.get(); 6611 Built.DistCombinedFields.Cond = CombCond.get(); 6612 Built.DistCombinedFields.NLB = CombNextLB.get(); 6613 Built.DistCombinedFields.NUB = CombNextUB.get(); 6614 Built.DistCombinedFields.DistCond = CombDistCond.get(); 6615 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 6616 6617 return NestedLoopCount; 6618 } 6619 6620 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 6621 auto CollapseClauses = 6622 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 6623 if (CollapseClauses.begin() != CollapseClauses.end()) 6624 return (*CollapseClauses.begin())->getNumForLoops(); 6625 return nullptr; 6626 } 6627 6628 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 6629 auto OrderedClauses = 6630 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 6631 if (OrderedClauses.begin() != OrderedClauses.end()) 6632 return (*OrderedClauses.begin())->getNumForLoops(); 6633 return nullptr; 6634 } 6635 6636 static bool checkSimdlenSafelenSpecified(Sema &S, 6637 const ArrayRef<OMPClause *> Clauses) { 6638 const OMPSafelenClause *Safelen = nullptr; 6639 const OMPSimdlenClause *Simdlen = nullptr; 6640 6641 for (const OMPClause *Clause : Clauses) { 6642 if (Clause->getClauseKind() == OMPC_safelen) 6643 Safelen = cast<OMPSafelenClause>(Clause); 6644 else if (Clause->getClauseKind() == OMPC_simdlen) 6645 Simdlen = cast<OMPSimdlenClause>(Clause); 6646 if (Safelen && Simdlen) 6647 break; 6648 } 6649 6650 if (Simdlen && Safelen) { 6651 const Expr *SimdlenLength = Simdlen->getSimdlen(); 6652 const Expr *SafelenLength = Safelen->getSafelen(); 6653 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 6654 SimdlenLength->isInstantiationDependent() || 6655 SimdlenLength->containsUnexpandedParameterPack()) 6656 return false; 6657 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 6658 SafelenLength->isInstantiationDependent() || 6659 SafelenLength->containsUnexpandedParameterPack()) 6660 return false; 6661 Expr::EvalResult SimdlenResult, SafelenResult; 6662 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 6663 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 6664 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 6665 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 6666 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 6667 // If both simdlen and safelen clauses are specified, the value of the 6668 // simdlen parameter must be less than or equal to the value of the safelen 6669 // parameter. 6670 if (SimdlenRes > SafelenRes) { 6671 S.Diag(SimdlenLength->getExprLoc(), 6672 diag::err_omp_wrong_simdlen_safelen_values) 6673 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 6674 return true; 6675 } 6676 } 6677 return false; 6678 } 6679 6680 StmtResult 6681 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6682 SourceLocation StartLoc, SourceLocation EndLoc, 6683 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6684 if (!AStmt) 6685 return StmtError(); 6686 6687 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6688 OMPLoopDirective::HelperExprs B; 6689 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6690 // define the nested loops number. 6691 unsigned NestedLoopCount = checkOpenMPLoop( 6692 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6693 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6694 if (NestedLoopCount == 0) 6695 return StmtError(); 6696 6697 assert((CurContext->isDependentContext() || B.builtAll()) && 6698 "omp simd loop exprs were not built"); 6699 6700 if (!CurContext->isDependentContext()) { 6701 // Finalize the clauses that need pre-built expressions for CodeGen. 6702 for (OMPClause *C : Clauses) { 6703 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6704 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6705 B.NumIterations, *this, CurScope, 6706 DSAStack)) 6707 return StmtError(); 6708 } 6709 } 6710 6711 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6712 return StmtError(); 6713 6714 setFunctionHasBranchProtectedScope(); 6715 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6716 Clauses, AStmt, B); 6717 } 6718 6719 StmtResult 6720 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6721 SourceLocation StartLoc, SourceLocation EndLoc, 6722 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6723 if (!AStmt) 6724 return StmtError(); 6725 6726 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6727 OMPLoopDirective::HelperExprs B; 6728 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6729 // define the nested loops number. 6730 unsigned NestedLoopCount = checkOpenMPLoop( 6731 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6732 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6733 if (NestedLoopCount == 0) 6734 return StmtError(); 6735 6736 assert((CurContext->isDependentContext() || B.builtAll()) && 6737 "omp for loop exprs were not built"); 6738 6739 if (!CurContext->isDependentContext()) { 6740 // Finalize the clauses that need pre-built expressions for CodeGen. 6741 for (OMPClause *C : Clauses) { 6742 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6743 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6744 B.NumIterations, *this, CurScope, 6745 DSAStack)) 6746 return StmtError(); 6747 } 6748 } 6749 6750 setFunctionHasBranchProtectedScope(); 6751 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6752 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6753 } 6754 6755 StmtResult Sema::ActOnOpenMPForSimdDirective( 6756 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6757 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6758 if (!AStmt) 6759 return StmtError(); 6760 6761 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6762 OMPLoopDirective::HelperExprs B; 6763 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6764 // define the nested loops number. 6765 unsigned NestedLoopCount = 6766 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6767 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6768 VarsWithImplicitDSA, B); 6769 if (NestedLoopCount == 0) 6770 return StmtError(); 6771 6772 assert((CurContext->isDependentContext() || B.builtAll()) && 6773 "omp for simd loop exprs were not built"); 6774 6775 if (!CurContext->isDependentContext()) { 6776 // Finalize the clauses that need pre-built expressions for CodeGen. 6777 for (OMPClause *C : Clauses) { 6778 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6779 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6780 B.NumIterations, *this, CurScope, 6781 DSAStack)) 6782 return StmtError(); 6783 } 6784 } 6785 6786 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6787 return StmtError(); 6788 6789 setFunctionHasBranchProtectedScope(); 6790 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6791 Clauses, AStmt, B); 6792 } 6793 6794 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6795 Stmt *AStmt, 6796 SourceLocation StartLoc, 6797 SourceLocation EndLoc) { 6798 if (!AStmt) 6799 return StmtError(); 6800 6801 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6802 auto BaseStmt = AStmt; 6803 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6804 BaseStmt = CS->getCapturedStmt(); 6805 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6806 auto S = C->children(); 6807 if (S.begin() == S.end()) 6808 return StmtError(); 6809 // All associated statements must be '#pragma omp section' except for 6810 // the first one. 6811 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6812 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6813 if (SectionStmt) 6814 Diag(SectionStmt->getBeginLoc(), 6815 diag::err_omp_sections_substmt_not_section); 6816 return StmtError(); 6817 } 6818 cast<OMPSectionDirective>(SectionStmt) 6819 ->setHasCancel(DSAStack->isCancelRegion()); 6820 } 6821 } else { 6822 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6823 return StmtError(); 6824 } 6825 6826 setFunctionHasBranchProtectedScope(); 6827 6828 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6829 DSAStack->isCancelRegion()); 6830 } 6831 6832 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6833 SourceLocation StartLoc, 6834 SourceLocation EndLoc) { 6835 if (!AStmt) 6836 return StmtError(); 6837 6838 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6839 6840 setFunctionHasBranchProtectedScope(); 6841 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6842 6843 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6844 DSAStack->isCancelRegion()); 6845 } 6846 6847 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6848 Stmt *AStmt, 6849 SourceLocation StartLoc, 6850 SourceLocation EndLoc) { 6851 if (!AStmt) 6852 return StmtError(); 6853 6854 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6855 6856 setFunctionHasBranchProtectedScope(); 6857 6858 // OpenMP [2.7.3, single Construct, Restrictions] 6859 // The copyprivate clause must not be used with the nowait clause. 6860 const OMPClause *Nowait = nullptr; 6861 const OMPClause *Copyprivate = nullptr; 6862 for (const OMPClause *Clause : Clauses) { 6863 if (Clause->getClauseKind() == OMPC_nowait) 6864 Nowait = Clause; 6865 else if (Clause->getClauseKind() == OMPC_copyprivate) 6866 Copyprivate = Clause; 6867 if (Copyprivate && Nowait) { 6868 Diag(Copyprivate->getBeginLoc(), 6869 diag::err_omp_single_copyprivate_with_nowait); 6870 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6871 return StmtError(); 6872 } 6873 } 6874 6875 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6876 } 6877 6878 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6879 SourceLocation StartLoc, 6880 SourceLocation EndLoc) { 6881 if (!AStmt) 6882 return StmtError(); 6883 6884 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6885 6886 setFunctionHasBranchProtectedScope(); 6887 6888 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6889 } 6890 6891 StmtResult Sema::ActOnOpenMPCriticalDirective( 6892 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6893 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6894 if (!AStmt) 6895 return StmtError(); 6896 6897 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6898 6899 bool ErrorFound = false; 6900 llvm::APSInt Hint; 6901 SourceLocation HintLoc; 6902 bool DependentHint = false; 6903 for (const OMPClause *C : Clauses) { 6904 if (C->getClauseKind() == OMPC_hint) { 6905 if (!DirName.getName()) { 6906 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6907 ErrorFound = true; 6908 } 6909 Expr *E = cast<OMPHintClause>(C)->getHint(); 6910 if (E->isTypeDependent() || E->isValueDependent() || 6911 E->isInstantiationDependent()) { 6912 DependentHint = true; 6913 } else { 6914 Hint = E->EvaluateKnownConstInt(Context); 6915 HintLoc = C->getBeginLoc(); 6916 } 6917 } 6918 } 6919 if (ErrorFound) 6920 return StmtError(); 6921 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6922 if (Pair.first && DirName.getName() && !DependentHint) { 6923 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6924 Diag(StartLoc, diag::err_omp_critical_with_hint); 6925 if (HintLoc.isValid()) 6926 Diag(HintLoc, diag::note_omp_critical_hint_here) 6927 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6928 else 6929 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6930 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6931 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6932 << 1 6933 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6934 /*Radix=*/10, /*Signed=*/false); 6935 } else { 6936 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6937 } 6938 } 6939 } 6940 6941 setFunctionHasBranchProtectedScope(); 6942 6943 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6944 Clauses, AStmt); 6945 if (!Pair.first && DirName.getName() && !DependentHint) 6946 DSAStack->addCriticalWithHint(Dir, Hint); 6947 return Dir; 6948 } 6949 6950 StmtResult Sema::ActOnOpenMPParallelForDirective( 6951 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6952 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6953 if (!AStmt) 6954 return StmtError(); 6955 6956 auto *CS = cast<CapturedStmt>(AStmt); 6957 // 1.2.2 OpenMP Language Terminology 6958 // Structured block - An executable statement with a single entry at the 6959 // top and a single exit at the bottom. 6960 // The point of exit cannot be a branch out of the structured block. 6961 // longjmp() and throw() must not violate the entry/exit criteria. 6962 CS->getCapturedDecl()->setNothrow(); 6963 6964 OMPLoopDirective::HelperExprs B; 6965 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6966 // define the nested loops number. 6967 unsigned NestedLoopCount = 6968 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6969 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6970 VarsWithImplicitDSA, B); 6971 if (NestedLoopCount == 0) 6972 return StmtError(); 6973 6974 assert((CurContext->isDependentContext() || B.builtAll()) && 6975 "omp parallel for loop exprs were not built"); 6976 6977 if (!CurContext->isDependentContext()) { 6978 // Finalize the clauses that need pre-built expressions for CodeGen. 6979 for (OMPClause *C : Clauses) { 6980 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6981 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6982 B.NumIterations, *this, CurScope, 6983 DSAStack)) 6984 return StmtError(); 6985 } 6986 } 6987 6988 setFunctionHasBranchProtectedScope(); 6989 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6990 NestedLoopCount, Clauses, AStmt, B, 6991 DSAStack->isCancelRegion()); 6992 } 6993 6994 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6995 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6996 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6997 if (!AStmt) 6998 return StmtError(); 6999 7000 auto *CS = cast<CapturedStmt>(AStmt); 7001 // 1.2.2 OpenMP Language Terminology 7002 // Structured block - An executable statement with a single entry at the 7003 // top and a single exit at the bottom. 7004 // The point of exit cannot be a branch out of the structured block. 7005 // longjmp() and throw() must not violate the entry/exit criteria. 7006 CS->getCapturedDecl()->setNothrow(); 7007 7008 OMPLoopDirective::HelperExprs B; 7009 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7010 // define the nested loops number. 7011 unsigned NestedLoopCount = 7012 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7013 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7014 VarsWithImplicitDSA, B); 7015 if (NestedLoopCount == 0) 7016 return StmtError(); 7017 7018 if (!CurContext->isDependentContext()) { 7019 // Finalize the clauses that need pre-built expressions for CodeGen. 7020 for (OMPClause *C : Clauses) { 7021 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7022 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7023 B.NumIterations, *this, CurScope, 7024 DSAStack)) 7025 return StmtError(); 7026 } 7027 } 7028 7029 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7030 return StmtError(); 7031 7032 setFunctionHasBranchProtectedScope(); 7033 return OMPParallelForSimdDirective::Create( 7034 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7035 } 7036 7037 StmtResult 7038 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7039 Stmt *AStmt, SourceLocation StartLoc, 7040 SourceLocation EndLoc) { 7041 if (!AStmt) 7042 return StmtError(); 7043 7044 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7045 auto BaseStmt = AStmt; 7046 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7047 BaseStmt = CS->getCapturedStmt(); 7048 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7049 auto S = C->children(); 7050 if (S.begin() == S.end()) 7051 return StmtError(); 7052 // All associated statements must be '#pragma omp section' except for 7053 // the first one. 7054 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7055 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7056 if (SectionStmt) 7057 Diag(SectionStmt->getBeginLoc(), 7058 diag::err_omp_parallel_sections_substmt_not_section); 7059 return StmtError(); 7060 } 7061 cast<OMPSectionDirective>(SectionStmt) 7062 ->setHasCancel(DSAStack->isCancelRegion()); 7063 } 7064 } else { 7065 Diag(AStmt->getBeginLoc(), 7066 diag::err_omp_parallel_sections_not_compound_stmt); 7067 return StmtError(); 7068 } 7069 7070 setFunctionHasBranchProtectedScope(); 7071 7072 return OMPParallelSectionsDirective::Create( 7073 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7074 } 7075 7076 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7077 Stmt *AStmt, SourceLocation StartLoc, 7078 SourceLocation EndLoc) { 7079 if (!AStmt) 7080 return StmtError(); 7081 7082 auto *CS = cast<CapturedStmt>(AStmt); 7083 // 1.2.2 OpenMP Language Terminology 7084 // Structured block - An executable statement with a single entry at the 7085 // top and a single exit at the bottom. 7086 // The point of exit cannot be a branch out of the structured block. 7087 // longjmp() and throw() must not violate the entry/exit criteria. 7088 CS->getCapturedDecl()->setNothrow(); 7089 7090 setFunctionHasBranchProtectedScope(); 7091 7092 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7093 DSAStack->isCancelRegion()); 7094 } 7095 7096 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7097 SourceLocation EndLoc) { 7098 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7099 } 7100 7101 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7102 SourceLocation EndLoc) { 7103 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7104 } 7105 7106 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7107 SourceLocation EndLoc) { 7108 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7109 } 7110 7111 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7112 Stmt *AStmt, 7113 SourceLocation StartLoc, 7114 SourceLocation EndLoc) { 7115 if (!AStmt) 7116 return StmtError(); 7117 7118 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7119 7120 setFunctionHasBranchProtectedScope(); 7121 7122 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7123 AStmt, 7124 DSAStack->getTaskgroupReductionRef()); 7125 } 7126 7127 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7128 SourceLocation StartLoc, 7129 SourceLocation EndLoc) { 7130 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7131 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7132 } 7133 7134 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7135 Stmt *AStmt, 7136 SourceLocation StartLoc, 7137 SourceLocation EndLoc) { 7138 const OMPClause *DependFound = nullptr; 7139 const OMPClause *DependSourceClause = nullptr; 7140 const OMPClause *DependSinkClause = nullptr; 7141 bool ErrorFound = false; 7142 const OMPThreadsClause *TC = nullptr; 7143 const OMPSIMDClause *SC = nullptr; 7144 for (const OMPClause *C : Clauses) { 7145 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7146 DependFound = C; 7147 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7148 if (DependSourceClause) { 7149 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7150 << getOpenMPDirectiveName(OMPD_ordered) 7151 << getOpenMPClauseName(OMPC_depend) << 2; 7152 ErrorFound = true; 7153 } else { 7154 DependSourceClause = C; 7155 } 7156 if (DependSinkClause) { 7157 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7158 << 0; 7159 ErrorFound = true; 7160 } 7161 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7162 if (DependSourceClause) { 7163 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7164 << 1; 7165 ErrorFound = true; 7166 } 7167 DependSinkClause = C; 7168 } 7169 } else if (C->getClauseKind() == OMPC_threads) { 7170 TC = cast<OMPThreadsClause>(C); 7171 } else if (C->getClauseKind() == OMPC_simd) { 7172 SC = cast<OMPSIMDClause>(C); 7173 } 7174 } 7175 if (!ErrorFound && !SC && 7176 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7177 // OpenMP [2.8.1,simd Construct, Restrictions] 7178 // An ordered construct with the simd clause is the only OpenMP construct 7179 // that can appear in the simd region. 7180 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7181 ErrorFound = true; 7182 } else if (DependFound && (TC || SC)) { 7183 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7184 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7185 ErrorFound = true; 7186 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7187 Diag(DependFound->getBeginLoc(), 7188 diag::err_omp_ordered_directive_without_param); 7189 ErrorFound = true; 7190 } else if (TC || Clauses.empty()) { 7191 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7192 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7193 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7194 << (TC != nullptr); 7195 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7196 ErrorFound = true; 7197 } 7198 } 7199 if ((!AStmt && !DependFound) || ErrorFound) 7200 return StmtError(); 7201 7202 if (AStmt) { 7203 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7204 7205 setFunctionHasBranchProtectedScope(); 7206 } 7207 7208 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7209 } 7210 7211 namespace { 7212 /// Helper class for checking expression in 'omp atomic [update]' 7213 /// construct. 7214 class OpenMPAtomicUpdateChecker { 7215 /// Error results for atomic update expressions. 7216 enum ExprAnalysisErrorCode { 7217 /// A statement is not an expression statement. 7218 NotAnExpression, 7219 /// Expression is not builtin binary or unary operation. 7220 NotABinaryOrUnaryExpression, 7221 /// Unary operation is not post-/pre- increment/decrement operation. 7222 NotAnUnaryIncDecExpression, 7223 /// An expression is not of scalar type. 7224 NotAScalarType, 7225 /// A binary operation is not an assignment operation. 7226 NotAnAssignmentOp, 7227 /// RHS part of the binary operation is not a binary expression. 7228 NotABinaryExpression, 7229 /// RHS part is not additive/multiplicative/shift/biwise binary 7230 /// expression. 7231 NotABinaryOperator, 7232 /// RHS binary operation does not have reference to the updated LHS 7233 /// part. 7234 NotAnUpdateExpression, 7235 /// No errors is found. 7236 NoError 7237 }; 7238 /// Reference to Sema. 7239 Sema &SemaRef; 7240 /// A location for note diagnostics (when error is found). 7241 SourceLocation NoteLoc; 7242 /// 'x' lvalue part of the source atomic expression. 7243 Expr *X; 7244 /// 'expr' rvalue part of the source atomic expression. 7245 Expr *E; 7246 /// Helper expression of the form 7247 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7248 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7249 Expr *UpdateExpr; 7250 /// Is 'x' a LHS in a RHS part of full update expression. It is 7251 /// important for non-associative operations. 7252 bool IsXLHSInRHSPart; 7253 BinaryOperatorKind Op; 7254 SourceLocation OpLoc; 7255 /// true if the source expression is a postfix unary operation, false 7256 /// if it is a prefix unary operation. 7257 bool IsPostfixUpdate; 7258 7259 public: 7260 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7261 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7262 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7263 /// Check specified statement that it is suitable for 'atomic update' 7264 /// constructs and extract 'x', 'expr' and Operation from the original 7265 /// expression. If DiagId and NoteId == 0, then only check is performed 7266 /// without error notification. 7267 /// \param DiagId Diagnostic which should be emitted if error is found. 7268 /// \param NoteId Diagnostic note for the main error message. 7269 /// \return true if statement is not an update expression, false otherwise. 7270 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7271 /// Return the 'x' lvalue part of the source atomic expression. 7272 Expr *getX() const { return X; } 7273 /// Return the 'expr' rvalue part of the source atomic expression. 7274 Expr *getExpr() const { return E; } 7275 /// Return the update expression used in calculation of the updated 7276 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7277 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7278 Expr *getUpdateExpr() const { return UpdateExpr; } 7279 /// Return true if 'x' is LHS in RHS part of full update expression, 7280 /// false otherwise. 7281 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7282 7283 /// true if the source expression is a postfix unary operation, false 7284 /// if it is a prefix unary operation. 7285 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7286 7287 private: 7288 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7289 unsigned NoteId = 0); 7290 }; 7291 } // namespace 7292 7293 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7294 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7295 ExprAnalysisErrorCode ErrorFound = NoError; 7296 SourceLocation ErrorLoc, NoteLoc; 7297 SourceRange ErrorRange, NoteRange; 7298 // Allowed constructs are: 7299 // x = x binop expr; 7300 // x = expr binop x; 7301 if (AtomicBinOp->getOpcode() == BO_Assign) { 7302 X = AtomicBinOp->getLHS(); 7303 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7304 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7305 if (AtomicInnerBinOp->isMultiplicativeOp() || 7306 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7307 AtomicInnerBinOp->isBitwiseOp()) { 7308 Op = AtomicInnerBinOp->getOpcode(); 7309 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7310 Expr *LHS = AtomicInnerBinOp->getLHS(); 7311 Expr *RHS = AtomicInnerBinOp->getRHS(); 7312 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7313 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7314 /*Canonical=*/true); 7315 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7316 /*Canonical=*/true); 7317 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7318 /*Canonical=*/true); 7319 if (XId == LHSId) { 7320 E = RHS; 7321 IsXLHSInRHSPart = true; 7322 } else if (XId == RHSId) { 7323 E = LHS; 7324 IsXLHSInRHSPart = false; 7325 } else { 7326 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7327 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7328 NoteLoc = X->getExprLoc(); 7329 NoteRange = X->getSourceRange(); 7330 ErrorFound = NotAnUpdateExpression; 7331 } 7332 } else { 7333 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7334 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7335 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7336 NoteRange = SourceRange(NoteLoc, NoteLoc); 7337 ErrorFound = NotABinaryOperator; 7338 } 7339 } else { 7340 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7341 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7342 ErrorFound = NotABinaryExpression; 7343 } 7344 } else { 7345 ErrorLoc = AtomicBinOp->getExprLoc(); 7346 ErrorRange = AtomicBinOp->getSourceRange(); 7347 NoteLoc = AtomicBinOp->getOperatorLoc(); 7348 NoteRange = SourceRange(NoteLoc, NoteLoc); 7349 ErrorFound = NotAnAssignmentOp; 7350 } 7351 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7352 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7353 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7354 return true; 7355 } 7356 if (SemaRef.CurContext->isDependentContext()) 7357 E = X = UpdateExpr = nullptr; 7358 return ErrorFound != NoError; 7359 } 7360 7361 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7362 unsigned NoteId) { 7363 ExprAnalysisErrorCode ErrorFound = NoError; 7364 SourceLocation ErrorLoc, NoteLoc; 7365 SourceRange ErrorRange, NoteRange; 7366 // Allowed constructs are: 7367 // x++; 7368 // x--; 7369 // ++x; 7370 // --x; 7371 // x binop= expr; 7372 // x = x binop expr; 7373 // x = expr binop x; 7374 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7375 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7376 if (AtomicBody->getType()->isScalarType() || 7377 AtomicBody->isInstantiationDependent()) { 7378 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7379 AtomicBody->IgnoreParenImpCasts())) { 7380 // Check for Compound Assignment Operation 7381 Op = BinaryOperator::getOpForCompoundAssignment( 7382 AtomicCompAssignOp->getOpcode()); 7383 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7384 E = AtomicCompAssignOp->getRHS(); 7385 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7386 IsXLHSInRHSPart = true; 7387 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7388 AtomicBody->IgnoreParenImpCasts())) { 7389 // Check for Binary Operation 7390 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7391 return true; 7392 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7393 AtomicBody->IgnoreParenImpCasts())) { 7394 // Check for Unary Operation 7395 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7396 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7397 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7398 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7399 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 7400 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 7401 IsXLHSInRHSPart = true; 7402 } else { 7403 ErrorFound = NotAnUnaryIncDecExpression; 7404 ErrorLoc = AtomicUnaryOp->getExprLoc(); 7405 ErrorRange = AtomicUnaryOp->getSourceRange(); 7406 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 7407 NoteRange = SourceRange(NoteLoc, NoteLoc); 7408 } 7409 } else if (!AtomicBody->isInstantiationDependent()) { 7410 ErrorFound = NotABinaryOrUnaryExpression; 7411 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 7412 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 7413 } 7414 } else { 7415 ErrorFound = NotAScalarType; 7416 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 7417 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7418 } 7419 } else { 7420 ErrorFound = NotAnExpression; 7421 NoteLoc = ErrorLoc = S->getBeginLoc(); 7422 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7423 } 7424 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7425 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7426 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7427 return true; 7428 } 7429 if (SemaRef.CurContext->isDependentContext()) 7430 E = X = UpdateExpr = nullptr; 7431 if (ErrorFound == NoError && E && X) { 7432 // Build an update expression of form 'OpaqueValueExpr(x) binop 7433 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 7434 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 7435 auto *OVEX = new (SemaRef.getASTContext()) 7436 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 7437 auto *OVEExpr = new (SemaRef.getASTContext()) 7438 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 7439 ExprResult Update = 7440 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 7441 IsXLHSInRHSPart ? OVEExpr : OVEX); 7442 if (Update.isInvalid()) 7443 return true; 7444 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 7445 Sema::AA_Casting); 7446 if (Update.isInvalid()) 7447 return true; 7448 UpdateExpr = Update.get(); 7449 } 7450 return ErrorFound != NoError; 7451 } 7452 7453 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 7454 Stmt *AStmt, 7455 SourceLocation StartLoc, 7456 SourceLocation EndLoc) { 7457 if (!AStmt) 7458 return StmtError(); 7459 7460 auto *CS = cast<CapturedStmt>(AStmt); 7461 // 1.2.2 OpenMP Language Terminology 7462 // Structured block - An executable statement with a single entry at the 7463 // top and a single exit at the bottom. 7464 // The point of exit cannot be a branch out of the structured block. 7465 // longjmp() and throw() must not violate the entry/exit criteria. 7466 OpenMPClauseKind AtomicKind = OMPC_unknown; 7467 SourceLocation AtomicKindLoc; 7468 for (const OMPClause *C : Clauses) { 7469 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 7470 C->getClauseKind() == OMPC_update || 7471 C->getClauseKind() == OMPC_capture) { 7472 if (AtomicKind != OMPC_unknown) { 7473 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 7474 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 7475 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 7476 << getOpenMPClauseName(AtomicKind); 7477 } else { 7478 AtomicKind = C->getClauseKind(); 7479 AtomicKindLoc = C->getBeginLoc(); 7480 } 7481 } 7482 } 7483 7484 Stmt *Body = CS->getCapturedStmt(); 7485 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 7486 Body = EWC->getSubExpr(); 7487 7488 Expr *X = nullptr; 7489 Expr *V = nullptr; 7490 Expr *E = nullptr; 7491 Expr *UE = nullptr; 7492 bool IsXLHSInRHSPart = false; 7493 bool IsPostfixUpdate = false; 7494 // OpenMP [2.12.6, atomic Construct] 7495 // In the next expressions: 7496 // * x and v (as applicable) are both l-value expressions with scalar type. 7497 // * During the execution of an atomic region, multiple syntactic 7498 // occurrences of x must designate the same storage location. 7499 // * Neither of v and expr (as applicable) may access the storage location 7500 // designated by x. 7501 // * Neither of x and expr (as applicable) may access the storage location 7502 // designated by v. 7503 // * expr is an expression with scalar type. 7504 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 7505 // * binop, binop=, ++, and -- are not overloaded operators. 7506 // * The expression x binop expr must be numerically equivalent to x binop 7507 // (expr). This requirement is satisfied if the operators in expr have 7508 // precedence greater than binop, or by using parentheses around expr or 7509 // subexpressions of expr. 7510 // * The expression expr binop x must be numerically equivalent to (expr) 7511 // binop x. This requirement is satisfied if the operators in expr have 7512 // precedence equal to or greater than binop, or by using parentheses around 7513 // expr or subexpressions of expr. 7514 // * For forms that allow multiple occurrences of x, the number of times 7515 // that x is evaluated is unspecified. 7516 if (AtomicKind == OMPC_read) { 7517 enum { 7518 NotAnExpression, 7519 NotAnAssignmentOp, 7520 NotAScalarType, 7521 NotAnLValue, 7522 NoError 7523 } ErrorFound = NoError; 7524 SourceLocation ErrorLoc, NoteLoc; 7525 SourceRange ErrorRange, NoteRange; 7526 // If clause is read: 7527 // v = x; 7528 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7529 const auto *AtomicBinOp = 7530 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7531 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7532 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7533 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 7534 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7535 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 7536 if (!X->isLValue() || !V->isLValue()) { 7537 const Expr *NotLValueExpr = X->isLValue() ? V : X; 7538 ErrorFound = NotAnLValue; 7539 ErrorLoc = AtomicBinOp->getExprLoc(); 7540 ErrorRange = AtomicBinOp->getSourceRange(); 7541 NoteLoc = NotLValueExpr->getExprLoc(); 7542 NoteRange = NotLValueExpr->getSourceRange(); 7543 } 7544 } else if (!X->isInstantiationDependent() || 7545 !V->isInstantiationDependent()) { 7546 const Expr *NotScalarExpr = 7547 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7548 ? V 7549 : X; 7550 ErrorFound = NotAScalarType; 7551 ErrorLoc = AtomicBinOp->getExprLoc(); 7552 ErrorRange = AtomicBinOp->getSourceRange(); 7553 NoteLoc = NotScalarExpr->getExprLoc(); 7554 NoteRange = NotScalarExpr->getSourceRange(); 7555 } 7556 } else if (!AtomicBody->isInstantiationDependent()) { 7557 ErrorFound = NotAnAssignmentOp; 7558 ErrorLoc = AtomicBody->getExprLoc(); 7559 ErrorRange = AtomicBody->getSourceRange(); 7560 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7561 : AtomicBody->getExprLoc(); 7562 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7563 : AtomicBody->getSourceRange(); 7564 } 7565 } else { 7566 ErrorFound = NotAnExpression; 7567 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7568 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7569 } 7570 if (ErrorFound != NoError) { 7571 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7572 << ErrorRange; 7573 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7574 << NoteRange; 7575 return StmtError(); 7576 } 7577 if (CurContext->isDependentContext()) 7578 V = X = nullptr; 7579 } else if (AtomicKind == OMPC_write) { 7580 enum { 7581 NotAnExpression, 7582 NotAnAssignmentOp, 7583 NotAScalarType, 7584 NotAnLValue, 7585 NoError 7586 } ErrorFound = NoError; 7587 SourceLocation ErrorLoc, NoteLoc; 7588 SourceRange ErrorRange, NoteRange; 7589 // If clause is write: 7590 // x = expr; 7591 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7592 const auto *AtomicBinOp = 7593 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7594 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7595 X = AtomicBinOp->getLHS(); 7596 E = AtomicBinOp->getRHS(); 7597 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7598 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 7599 if (!X->isLValue()) { 7600 ErrorFound = NotAnLValue; 7601 ErrorLoc = AtomicBinOp->getExprLoc(); 7602 ErrorRange = AtomicBinOp->getSourceRange(); 7603 NoteLoc = X->getExprLoc(); 7604 NoteRange = X->getSourceRange(); 7605 } 7606 } else if (!X->isInstantiationDependent() || 7607 !E->isInstantiationDependent()) { 7608 const Expr *NotScalarExpr = 7609 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7610 ? E 7611 : X; 7612 ErrorFound = NotAScalarType; 7613 ErrorLoc = AtomicBinOp->getExprLoc(); 7614 ErrorRange = AtomicBinOp->getSourceRange(); 7615 NoteLoc = NotScalarExpr->getExprLoc(); 7616 NoteRange = NotScalarExpr->getSourceRange(); 7617 } 7618 } else if (!AtomicBody->isInstantiationDependent()) { 7619 ErrorFound = NotAnAssignmentOp; 7620 ErrorLoc = AtomicBody->getExprLoc(); 7621 ErrorRange = AtomicBody->getSourceRange(); 7622 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7623 : AtomicBody->getExprLoc(); 7624 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7625 : AtomicBody->getSourceRange(); 7626 } 7627 } else { 7628 ErrorFound = NotAnExpression; 7629 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7630 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7631 } 7632 if (ErrorFound != NoError) { 7633 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 7634 << ErrorRange; 7635 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7636 << NoteRange; 7637 return StmtError(); 7638 } 7639 if (CurContext->isDependentContext()) 7640 E = X = nullptr; 7641 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 7642 // If clause is update: 7643 // x++; 7644 // x--; 7645 // ++x; 7646 // --x; 7647 // x binop= expr; 7648 // x = x binop expr; 7649 // x = expr binop x; 7650 OpenMPAtomicUpdateChecker Checker(*this); 7651 if (Checker.checkStatement( 7652 Body, (AtomicKind == OMPC_update) 7653 ? diag::err_omp_atomic_update_not_expression_statement 7654 : diag::err_omp_atomic_not_expression_statement, 7655 diag::note_omp_atomic_update)) 7656 return StmtError(); 7657 if (!CurContext->isDependentContext()) { 7658 E = Checker.getExpr(); 7659 X = Checker.getX(); 7660 UE = Checker.getUpdateExpr(); 7661 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7662 } 7663 } else if (AtomicKind == OMPC_capture) { 7664 enum { 7665 NotAnAssignmentOp, 7666 NotACompoundStatement, 7667 NotTwoSubstatements, 7668 NotASpecificExpression, 7669 NoError 7670 } ErrorFound = NoError; 7671 SourceLocation ErrorLoc, NoteLoc; 7672 SourceRange ErrorRange, NoteRange; 7673 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7674 // If clause is a capture: 7675 // v = x++; 7676 // v = x--; 7677 // v = ++x; 7678 // v = --x; 7679 // v = x binop= expr; 7680 // v = x = x binop expr; 7681 // v = x = expr binop x; 7682 const auto *AtomicBinOp = 7683 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7684 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7685 V = AtomicBinOp->getLHS(); 7686 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7687 OpenMPAtomicUpdateChecker Checker(*this); 7688 if (Checker.checkStatement( 7689 Body, diag::err_omp_atomic_capture_not_expression_statement, 7690 diag::note_omp_atomic_update)) 7691 return StmtError(); 7692 E = Checker.getExpr(); 7693 X = Checker.getX(); 7694 UE = Checker.getUpdateExpr(); 7695 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7696 IsPostfixUpdate = Checker.isPostfixUpdate(); 7697 } else if (!AtomicBody->isInstantiationDependent()) { 7698 ErrorLoc = AtomicBody->getExprLoc(); 7699 ErrorRange = AtomicBody->getSourceRange(); 7700 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7701 : AtomicBody->getExprLoc(); 7702 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7703 : AtomicBody->getSourceRange(); 7704 ErrorFound = NotAnAssignmentOp; 7705 } 7706 if (ErrorFound != NoError) { 7707 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7708 << ErrorRange; 7709 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7710 return StmtError(); 7711 } 7712 if (CurContext->isDependentContext()) 7713 UE = V = E = X = nullptr; 7714 } else { 7715 // If clause is a capture: 7716 // { v = x; x = expr; } 7717 // { v = x; x++; } 7718 // { v = x; x--; } 7719 // { v = x; ++x; } 7720 // { v = x; --x; } 7721 // { v = x; x binop= expr; } 7722 // { v = x; x = x binop expr; } 7723 // { v = x; x = expr binop x; } 7724 // { x++; v = x; } 7725 // { x--; v = x; } 7726 // { ++x; v = x; } 7727 // { --x; v = x; } 7728 // { x binop= expr; v = x; } 7729 // { x = x binop expr; v = x; } 7730 // { x = expr binop x; v = x; } 7731 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7732 // Check that this is { expr1; expr2; } 7733 if (CS->size() == 2) { 7734 Stmt *First = CS->body_front(); 7735 Stmt *Second = CS->body_back(); 7736 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7737 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7738 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7739 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7740 // Need to find what subexpression is 'v' and what is 'x'. 7741 OpenMPAtomicUpdateChecker Checker(*this); 7742 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7743 BinaryOperator *BinOp = nullptr; 7744 if (IsUpdateExprFound) { 7745 BinOp = dyn_cast<BinaryOperator>(First); 7746 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7747 } 7748 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7749 // { v = x; x++; } 7750 // { v = x; x--; } 7751 // { v = x; ++x; } 7752 // { v = x; --x; } 7753 // { v = x; x binop= expr; } 7754 // { v = x; x = x binop expr; } 7755 // { v = x; x = expr binop x; } 7756 // Check that the first expression has form v = x. 7757 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7758 llvm::FoldingSetNodeID XId, PossibleXId; 7759 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7760 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7761 IsUpdateExprFound = XId == PossibleXId; 7762 if (IsUpdateExprFound) { 7763 V = BinOp->getLHS(); 7764 X = Checker.getX(); 7765 E = Checker.getExpr(); 7766 UE = Checker.getUpdateExpr(); 7767 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7768 IsPostfixUpdate = true; 7769 } 7770 } 7771 if (!IsUpdateExprFound) { 7772 IsUpdateExprFound = !Checker.checkStatement(First); 7773 BinOp = nullptr; 7774 if (IsUpdateExprFound) { 7775 BinOp = dyn_cast<BinaryOperator>(Second); 7776 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7777 } 7778 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7779 // { x++; v = x; } 7780 // { x--; v = x; } 7781 // { ++x; v = x; } 7782 // { --x; v = x; } 7783 // { x binop= expr; v = x; } 7784 // { x = x binop expr; v = x; } 7785 // { x = expr binop x; v = x; } 7786 // Check that the second expression has form v = x. 7787 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7788 llvm::FoldingSetNodeID XId, PossibleXId; 7789 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7790 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7791 IsUpdateExprFound = XId == PossibleXId; 7792 if (IsUpdateExprFound) { 7793 V = BinOp->getLHS(); 7794 X = Checker.getX(); 7795 E = Checker.getExpr(); 7796 UE = Checker.getUpdateExpr(); 7797 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7798 IsPostfixUpdate = false; 7799 } 7800 } 7801 } 7802 if (!IsUpdateExprFound) { 7803 // { v = x; x = expr; } 7804 auto *FirstExpr = dyn_cast<Expr>(First); 7805 auto *SecondExpr = dyn_cast<Expr>(Second); 7806 if (!FirstExpr || !SecondExpr || 7807 !(FirstExpr->isInstantiationDependent() || 7808 SecondExpr->isInstantiationDependent())) { 7809 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7810 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7811 ErrorFound = NotAnAssignmentOp; 7812 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7813 : First->getBeginLoc(); 7814 NoteRange = ErrorRange = FirstBinOp 7815 ? FirstBinOp->getSourceRange() 7816 : SourceRange(ErrorLoc, ErrorLoc); 7817 } else { 7818 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7819 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7820 ErrorFound = NotAnAssignmentOp; 7821 NoteLoc = ErrorLoc = SecondBinOp 7822 ? SecondBinOp->getOperatorLoc() 7823 : Second->getBeginLoc(); 7824 NoteRange = ErrorRange = 7825 SecondBinOp ? SecondBinOp->getSourceRange() 7826 : SourceRange(ErrorLoc, ErrorLoc); 7827 } else { 7828 Expr *PossibleXRHSInFirst = 7829 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7830 Expr *PossibleXLHSInSecond = 7831 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7832 llvm::FoldingSetNodeID X1Id, X2Id; 7833 PossibleXRHSInFirst->Profile(X1Id, Context, 7834 /*Canonical=*/true); 7835 PossibleXLHSInSecond->Profile(X2Id, Context, 7836 /*Canonical=*/true); 7837 IsUpdateExprFound = X1Id == X2Id; 7838 if (IsUpdateExprFound) { 7839 V = FirstBinOp->getLHS(); 7840 X = SecondBinOp->getLHS(); 7841 E = SecondBinOp->getRHS(); 7842 UE = nullptr; 7843 IsXLHSInRHSPart = false; 7844 IsPostfixUpdate = true; 7845 } else { 7846 ErrorFound = NotASpecificExpression; 7847 ErrorLoc = FirstBinOp->getExprLoc(); 7848 ErrorRange = FirstBinOp->getSourceRange(); 7849 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7850 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7851 } 7852 } 7853 } 7854 } 7855 } 7856 } else { 7857 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7858 NoteRange = ErrorRange = 7859 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7860 ErrorFound = NotTwoSubstatements; 7861 } 7862 } else { 7863 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7864 NoteRange = ErrorRange = 7865 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7866 ErrorFound = NotACompoundStatement; 7867 } 7868 if (ErrorFound != NoError) { 7869 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7870 << ErrorRange; 7871 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7872 return StmtError(); 7873 } 7874 if (CurContext->isDependentContext()) 7875 UE = V = E = X = nullptr; 7876 } 7877 } 7878 7879 setFunctionHasBranchProtectedScope(); 7880 7881 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7882 X, V, E, UE, IsXLHSInRHSPart, 7883 IsPostfixUpdate); 7884 } 7885 7886 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7887 Stmt *AStmt, 7888 SourceLocation StartLoc, 7889 SourceLocation EndLoc) { 7890 if (!AStmt) 7891 return StmtError(); 7892 7893 auto *CS = cast<CapturedStmt>(AStmt); 7894 // 1.2.2 OpenMP Language Terminology 7895 // Structured block - An executable statement with a single entry at the 7896 // top and a single exit at the bottom. 7897 // The point of exit cannot be a branch out of the structured block. 7898 // longjmp() and throw() must not violate the entry/exit criteria. 7899 CS->getCapturedDecl()->setNothrow(); 7900 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7901 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7902 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7903 // 1.2.2 OpenMP Language Terminology 7904 // Structured block - An executable statement with a single entry at the 7905 // top and a single exit at the bottom. 7906 // The point of exit cannot be a branch out of the structured block. 7907 // longjmp() and throw() must not violate the entry/exit criteria. 7908 CS->getCapturedDecl()->setNothrow(); 7909 } 7910 7911 // OpenMP [2.16, Nesting of Regions] 7912 // If specified, a teams construct must be contained within a target 7913 // construct. That target construct must contain no statements or directives 7914 // outside of the teams construct. 7915 if (DSAStack->hasInnerTeamsRegion()) { 7916 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7917 bool OMPTeamsFound = true; 7918 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7919 auto I = CS->body_begin(); 7920 while (I != CS->body_end()) { 7921 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7922 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7923 OMPTeamsFound) { 7924 7925 OMPTeamsFound = false; 7926 break; 7927 } 7928 ++I; 7929 } 7930 assert(I != CS->body_end() && "Not found statement"); 7931 S = *I; 7932 } else { 7933 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7934 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7935 } 7936 if (!OMPTeamsFound) { 7937 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7938 Diag(DSAStack->getInnerTeamsRegionLoc(), 7939 diag::note_omp_nested_teams_construct_here); 7940 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7941 << isa<OMPExecutableDirective>(S); 7942 return StmtError(); 7943 } 7944 } 7945 7946 setFunctionHasBranchProtectedScope(); 7947 7948 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7949 } 7950 7951 StmtResult 7952 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7953 Stmt *AStmt, SourceLocation StartLoc, 7954 SourceLocation EndLoc) { 7955 if (!AStmt) 7956 return StmtError(); 7957 7958 auto *CS = cast<CapturedStmt>(AStmt); 7959 // 1.2.2 OpenMP Language Terminology 7960 // Structured block - An executable statement with a single entry at the 7961 // top and a single exit at the bottom. 7962 // The point of exit cannot be a branch out of the structured block. 7963 // longjmp() and throw() must not violate the entry/exit criteria. 7964 CS->getCapturedDecl()->setNothrow(); 7965 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7966 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7967 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7968 // 1.2.2 OpenMP Language Terminology 7969 // Structured block - An executable statement with a single entry at the 7970 // top and a single exit at the bottom. 7971 // The point of exit cannot be a branch out of the structured block. 7972 // longjmp() and throw() must not violate the entry/exit criteria. 7973 CS->getCapturedDecl()->setNothrow(); 7974 } 7975 7976 setFunctionHasBranchProtectedScope(); 7977 7978 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7979 AStmt); 7980 } 7981 7982 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7983 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7984 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7985 if (!AStmt) 7986 return StmtError(); 7987 7988 auto *CS = cast<CapturedStmt>(AStmt); 7989 // 1.2.2 OpenMP Language Terminology 7990 // Structured block - An executable statement with a single entry at the 7991 // top and a single exit at the bottom. 7992 // The point of exit cannot be a branch out of the structured block. 7993 // longjmp() and throw() must not violate the entry/exit criteria. 7994 CS->getCapturedDecl()->setNothrow(); 7995 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7996 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7997 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7998 // 1.2.2 OpenMP Language Terminology 7999 // Structured block - An executable statement with a single entry at the 8000 // top and a single exit at the bottom. 8001 // The point of exit cannot be a branch out of the structured block. 8002 // longjmp() and throw() must not violate the entry/exit criteria. 8003 CS->getCapturedDecl()->setNothrow(); 8004 } 8005 8006 OMPLoopDirective::HelperExprs B; 8007 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8008 // define the nested loops number. 8009 unsigned NestedLoopCount = 8010 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8011 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8012 VarsWithImplicitDSA, B); 8013 if (NestedLoopCount == 0) 8014 return StmtError(); 8015 8016 assert((CurContext->isDependentContext() || B.builtAll()) && 8017 "omp target parallel for loop exprs were not built"); 8018 8019 if (!CurContext->isDependentContext()) { 8020 // Finalize the clauses that need pre-built expressions for CodeGen. 8021 for (OMPClause *C : Clauses) { 8022 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8023 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8024 B.NumIterations, *this, CurScope, 8025 DSAStack)) 8026 return StmtError(); 8027 } 8028 } 8029 8030 setFunctionHasBranchProtectedScope(); 8031 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8032 NestedLoopCount, Clauses, AStmt, 8033 B, DSAStack->isCancelRegion()); 8034 } 8035 8036 /// Check for existence of a map clause in the list of clauses. 8037 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8038 const OpenMPClauseKind K) { 8039 return llvm::any_of( 8040 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8041 } 8042 8043 template <typename... Params> 8044 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8045 const Params... ClauseTypes) { 8046 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8047 } 8048 8049 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8050 Stmt *AStmt, 8051 SourceLocation StartLoc, 8052 SourceLocation EndLoc) { 8053 if (!AStmt) 8054 return StmtError(); 8055 8056 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8057 8058 // OpenMP [2.10.1, Restrictions, p. 97] 8059 // At least one map clause must appear on the directive. 8060 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8061 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8062 << "'map' or 'use_device_ptr'" 8063 << getOpenMPDirectiveName(OMPD_target_data); 8064 return StmtError(); 8065 } 8066 8067 setFunctionHasBranchProtectedScope(); 8068 8069 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8070 AStmt); 8071 } 8072 8073 StmtResult 8074 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8075 SourceLocation StartLoc, 8076 SourceLocation EndLoc, Stmt *AStmt) { 8077 if (!AStmt) 8078 return StmtError(); 8079 8080 auto *CS = cast<CapturedStmt>(AStmt); 8081 // 1.2.2 OpenMP Language Terminology 8082 // Structured block - An executable statement with a single entry at the 8083 // top and a single exit at the bottom. 8084 // The point of exit cannot be a branch out of the structured block. 8085 // longjmp() and throw() must not violate the entry/exit criteria. 8086 CS->getCapturedDecl()->setNothrow(); 8087 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8088 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8089 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8090 // 1.2.2 OpenMP Language Terminology 8091 // Structured block - An executable statement with a single entry at the 8092 // top and a single exit at the bottom. 8093 // The point of exit cannot be a branch out of the structured block. 8094 // longjmp() and throw() must not violate the entry/exit criteria. 8095 CS->getCapturedDecl()->setNothrow(); 8096 } 8097 8098 // OpenMP [2.10.2, Restrictions, p. 99] 8099 // At least one map clause must appear on the directive. 8100 if (!hasClauses(Clauses, OMPC_map)) { 8101 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8102 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8103 return StmtError(); 8104 } 8105 8106 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8107 AStmt); 8108 } 8109 8110 StmtResult 8111 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8112 SourceLocation StartLoc, 8113 SourceLocation EndLoc, Stmt *AStmt) { 8114 if (!AStmt) 8115 return StmtError(); 8116 8117 auto *CS = cast<CapturedStmt>(AStmt); 8118 // 1.2.2 OpenMP Language Terminology 8119 // Structured block - An executable statement with a single entry at the 8120 // top and a single exit at the bottom. 8121 // The point of exit cannot be a branch out of the structured block. 8122 // longjmp() and throw() must not violate the entry/exit criteria. 8123 CS->getCapturedDecl()->setNothrow(); 8124 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8125 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8126 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8127 // 1.2.2 OpenMP Language Terminology 8128 // Structured block - An executable statement with a single entry at the 8129 // top and a single exit at the bottom. 8130 // The point of exit cannot be a branch out of the structured block. 8131 // longjmp() and throw() must not violate the entry/exit criteria. 8132 CS->getCapturedDecl()->setNothrow(); 8133 } 8134 8135 // OpenMP [2.10.3, Restrictions, p. 102] 8136 // At least one map clause must appear on the directive. 8137 if (!hasClauses(Clauses, OMPC_map)) { 8138 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8139 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8140 return StmtError(); 8141 } 8142 8143 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8144 AStmt); 8145 } 8146 8147 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8148 SourceLocation StartLoc, 8149 SourceLocation EndLoc, 8150 Stmt *AStmt) { 8151 if (!AStmt) 8152 return StmtError(); 8153 8154 auto *CS = cast<CapturedStmt>(AStmt); 8155 // 1.2.2 OpenMP Language Terminology 8156 // Structured block - An executable statement with a single entry at the 8157 // top and a single exit at the bottom. 8158 // The point of exit cannot be a branch out of the structured block. 8159 // longjmp() and throw() must not violate the entry/exit criteria. 8160 CS->getCapturedDecl()->setNothrow(); 8161 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8162 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8163 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8164 // 1.2.2 OpenMP Language Terminology 8165 // Structured block - An executable statement with a single entry at the 8166 // top and a single exit at the bottom. 8167 // The point of exit cannot be a branch out of the structured block. 8168 // longjmp() and throw() must not violate the entry/exit criteria. 8169 CS->getCapturedDecl()->setNothrow(); 8170 } 8171 8172 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8173 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8174 return StmtError(); 8175 } 8176 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8177 AStmt); 8178 } 8179 8180 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8181 Stmt *AStmt, SourceLocation StartLoc, 8182 SourceLocation EndLoc) { 8183 if (!AStmt) 8184 return StmtError(); 8185 8186 auto *CS = cast<CapturedStmt>(AStmt); 8187 // 1.2.2 OpenMP Language Terminology 8188 // Structured block - An executable statement with a single entry at the 8189 // top and a single exit at the bottom. 8190 // The point of exit cannot be a branch out of the structured block. 8191 // longjmp() and throw() must not violate the entry/exit criteria. 8192 CS->getCapturedDecl()->setNothrow(); 8193 8194 setFunctionHasBranchProtectedScope(); 8195 8196 DSAStack->setParentTeamsRegionLoc(StartLoc); 8197 8198 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8199 } 8200 8201 StmtResult 8202 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8203 SourceLocation EndLoc, 8204 OpenMPDirectiveKind CancelRegion) { 8205 if (DSAStack->isParentNowaitRegion()) { 8206 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8207 return StmtError(); 8208 } 8209 if (DSAStack->isParentOrderedRegion()) { 8210 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8211 return StmtError(); 8212 } 8213 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8214 CancelRegion); 8215 } 8216 8217 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8218 SourceLocation StartLoc, 8219 SourceLocation EndLoc, 8220 OpenMPDirectiveKind CancelRegion) { 8221 if (DSAStack->isParentNowaitRegion()) { 8222 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8223 return StmtError(); 8224 } 8225 if (DSAStack->isParentOrderedRegion()) { 8226 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8227 return StmtError(); 8228 } 8229 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8230 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8231 CancelRegion); 8232 } 8233 8234 static bool checkGrainsizeNumTasksClauses(Sema &S, 8235 ArrayRef<OMPClause *> Clauses) { 8236 const OMPClause *PrevClause = nullptr; 8237 bool ErrorFound = false; 8238 for (const OMPClause *C : Clauses) { 8239 if (C->getClauseKind() == OMPC_grainsize || 8240 C->getClauseKind() == OMPC_num_tasks) { 8241 if (!PrevClause) 8242 PrevClause = C; 8243 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8244 S.Diag(C->getBeginLoc(), 8245 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8246 << getOpenMPClauseName(C->getClauseKind()) 8247 << getOpenMPClauseName(PrevClause->getClauseKind()); 8248 S.Diag(PrevClause->getBeginLoc(), 8249 diag::note_omp_previous_grainsize_num_tasks) 8250 << getOpenMPClauseName(PrevClause->getClauseKind()); 8251 ErrorFound = true; 8252 } 8253 } 8254 } 8255 return ErrorFound; 8256 } 8257 8258 static bool checkReductionClauseWithNogroup(Sema &S, 8259 ArrayRef<OMPClause *> Clauses) { 8260 const OMPClause *ReductionClause = nullptr; 8261 const OMPClause *NogroupClause = nullptr; 8262 for (const OMPClause *C : Clauses) { 8263 if (C->getClauseKind() == OMPC_reduction) { 8264 ReductionClause = C; 8265 if (NogroupClause) 8266 break; 8267 continue; 8268 } 8269 if (C->getClauseKind() == OMPC_nogroup) { 8270 NogroupClause = C; 8271 if (ReductionClause) 8272 break; 8273 continue; 8274 } 8275 } 8276 if (ReductionClause && NogroupClause) { 8277 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8278 << SourceRange(NogroupClause->getBeginLoc(), 8279 NogroupClause->getEndLoc()); 8280 return true; 8281 } 8282 return false; 8283 } 8284 8285 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8286 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8287 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8288 if (!AStmt) 8289 return StmtError(); 8290 8291 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8292 OMPLoopDirective::HelperExprs B; 8293 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8294 // define the nested loops number. 8295 unsigned NestedLoopCount = 8296 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8297 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8298 VarsWithImplicitDSA, B); 8299 if (NestedLoopCount == 0) 8300 return StmtError(); 8301 8302 assert((CurContext->isDependentContext() || B.builtAll()) && 8303 "omp for loop exprs were not built"); 8304 8305 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8306 // The grainsize clause and num_tasks clause are mutually exclusive and may 8307 // not appear on the same taskloop directive. 8308 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8309 return StmtError(); 8310 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8311 // If a reduction clause is present on the taskloop directive, the nogroup 8312 // clause must not be specified. 8313 if (checkReductionClauseWithNogroup(*this, Clauses)) 8314 return StmtError(); 8315 8316 setFunctionHasBranchProtectedScope(); 8317 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8318 NestedLoopCount, Clauses, AStmt, B); 8319 } 8320 8321 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8322 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8323 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8324 if (!AStmt) 8325 return StmtError(); 8326 8327 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8328 OMPLoopDirective::HelperExprs B; 8329 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8330 // define the nested loops number. 8331 unsigned NestedLoopCount = 8332 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8333 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8334 VarsWithImplicitDSA, B); 8335 if (NestedLoopCount == 0) 8336 return StmtError(); 8337 8338 assert((CurContext->isDependentContext() || B.builtAll()) && 8339 "omp for loop exprs were not built"); 8340 8341 if (!CurContext->isDependentContext()) { 8342 // Finalize the clauses that need pre-built expressions for CodeGen. 8343 for (OMPClause *C : Clauses) { 8344 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8345 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8346 B.NumIterations, *this, CurScope, 8347 DSAStack)) 8348 return StmtError(); 8349 } 8350 } 8351 8352 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8353 // The grainsize clause and num_tasks clause are mutually exclusive and may 8354 // not appear on the same taskloop directive. 8355 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8356 return StmtError(); 8357 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8358 // If a reduction clause is present on the taskloop directive, the nogroup 8359 // clause must not be specified. 8360 if (checkReductionClauseWithNogroup(*this, Clauses)) 8361 return StmtError(); 8362 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8363 return StmtError(); 8364 8365 setFunctionHasBranchProtectedScope(); 8366 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8367 NestedLoopCount, Clauses, AStmt, B); 8368 } 8369 8370 StmtResult Sema::ActOnOpenMPDistributeDirective( 8371 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8372 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8373 if (!AStmt) 8374 return StmtError(); 8375 8376 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8377 OMPLoopDirective::HelperExprs B; 8378 // In presence of clause 'collapse' with number of loops, it will 8379 // define the nested loops number. 8380 unsigned NestedLoopCount = 8381 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8382 nullptr /*ordered not a clause on distribute*/, AStmt, 8383 *this, *DSAStack, VarsWithImplicitDSA, B); 8384 if (NestedLoopCount == 0) 8385 return StmtError(); 8386 8387 assert((CurContext->isDependentContext() || B.builtAll()) && 8388 "omp for loop exprs were not built"); 8389 8390 setFunctionHasBranchProtectedScope(); 8391 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8392 NestedLoopCount, Clauses, AStmt, B); 8393 } 8394 8395 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8396 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8397 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8398 if (!AStmt) 8399 return StmtError(); 8400 8401 auto *CS = cast<CapturedStmt>(AStmt); 8402 // 1.2.2 OpenMP Language Terminology 8403 // Structured block - An executable statement with a single entry at the 8404 // top and a single exit at the bottom. 8405 // The point of exit cannot be a branch out of the structured block. 8406 // longjmp() and throw() must not violate the entry/exit criteria. 8407 CS->getCapturedDecl()->setNothrow(); 8408 for (int ThisCaptureLevel = 8409 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 8410 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8411 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8412 // 1.2.2 OpenMP Language Terminology 8413 // Structured block - An executable statement with a single entry at the 8414 // top and a single exit at the bottom. 8415 // The point of exit cannot be a branch out of the structured block. 8416 // longjmp() and throw() must not violate the entry/exit criteria. 8417 CS->getCapturedDecl()->setNothrow(); 8418 } 8419 8420 OMPLoopDirective::HelperExprs B; 8421 // In presence of clause 'collapse' with number of loops, it will 8422 // define the nested loops number. 8423 unsigned NestedLoopCount = checkOpenMPLoop( 8424 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8425 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8426 VarsWithImplicitDSA, B); 8427 if (NestedLoopCount == 0) 8428 return StmtError(); 8429 8430 assert((CurContext->isDependentContext() || B.builtAll()) && 8431 "omp for loop exprs were not built"); 8432 8433 setFunctionHasBranchProtectedScope(); 8434 return OMPDistributeParallelForDirective::Create( 8435 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8436 DSAStack->isCancelRegion()); 8437 } 8438 8439 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 8440 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8441 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8442 if (!AStmt) 8443 return StmtError(); 8444 8445 auto *CS = cast<CapturedStmt>(AStmt); 8446 // 1.2.2 OpenMP Language Terminology 8447 // Structured block - An executable statement with a single entry at the 8448 // top and a single exit at the bottom. 8449 // The point of exit cannot be a branch out of the structured block. 8450 // longjmp() and throw() must not violate the entry/exit criteria. 8451 CS->getCapturedDecl()->setNothrow(); 8452 for (int ThisCaptureLevel = 8453 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 8454 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8455 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8456 // 1.2.2 OpenMP Language Terminology 8457 // Structured block - An executable statement with a single entry at the 8458 // top and a single exit at the bottom. 8459 // The point of exit cannot be a branch out of the structured block. 8460 // longjmp() and throw() must not violate the entry/exit criteria. 8461 CS->getCapturedDecl()->setNothrow(); 8462 } 8463 8464 OMPLoopDirective::HelperExprs B; 8465 // In presence of clause 'collapse' with number of loops, it will 8466 // define the nested loops number. 8467 unsigned NestedLoopCount = checkOpenMPLoop( 8468 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8469 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8470 VarsWithImplicitDSA, B); 8471 if (NestedLoopCount == 0) 8472 return StmtError(); 8473 8474 assert((CurContext->isDependentContext() || B.builtAll()) && 8475 "omp for loop exprs were not built"); 8476 8477 if (!CurContext->isDependentContext()) { 8478 // Finalize the clauses that need pre-built expressions for CodeGen. 8479 for (OMPClause *C : Clauses) { 8480 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8481 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8482 B.NumIterations, *this, CurScope, 8483 DSAStack)) 8484 return StmtError(); 8485 } 8486 } 8487 8488 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8489 return StmtError(); 8490 8491 setFunctionHasBranchProtectedScope(); 8492 return OMPDistributeParallelForSimdDirective::Create( 8493 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8494 } 8495 8496 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 8497 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8498 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8499 if (!AStmt) 8500 return StmtError(); 8501 8502 auto *CS = cast<CapturedStmt>(AStmt); 8503 // 1.2.2 OpenMP Language Terminology 8504 // Structured block - An executable statement with a single entry at the 8505 // top and a single exit at the bottom. 8506 // The point of exit cannot be a branch out of the structured block. 8507 // longjmp() and throw() must not violate the entry/exit criteria. 8508 CS->getCapturedDecl()->setNothrow(); 8509 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 8510 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8511 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8512 // 1.2.2 OpenMP Language Terminology 8513 // Structured block - An executable statement with a single entry at the 8514 // top and a single exit at the bottom. 8515 // The point of exit cannot be a branch out of the structured block. 8516 // longjmp() and throw() must not violate the entry/exit criteria. 8517 CS->getCapturedDecl()->setNothrow(); 8518 } 8519 8520 OMPLoopDirective::HelperExprs B; 8521 // In presence of clause 'collapse' with number of loops, it will 8522 // define the nested loops number. 8523 unsigned NestedLoopCount = 8524 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 8525 nullptr /*ordered not a clause on distribute*/, CS, *this, 8526 *DSAStack, VarsWithImplicitDSA, B); 8527 if (NestedLoopCount == 0) 8528 return StmtError(); 8529 8530 assert((CurContext->isDependentContext() || B.builtAll()) && 8531 "omp for loop exprs were not built"); 8532 8533 if (!CurContext->isDependentContext()) { 8534 // Finalize the clauses that need pre-built expressions for CodeGen. 8535 for (OMPClause *C : Clauses) { 8536 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8537 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8538 B.NumIterations, *this, CurScope, 8539 DSAStack)) 8540 return StmtError(); 8541 } 8542 } 8543 8544 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8545 return StmtError(); 8546 8547 setFunctionHasBranchProtectedScope(); 8548 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 8549 NestedLoopCount, Clauses, AStmt, B); 8550 } 8551 8552 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 8553 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8554 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8555 if (!AStmt) 8556 return StmtError(); 8557 8558 auto *CS = cast<CapturedStmt>(AStmt); 8559 // 1.2.2 OpenMP Language Terminology 8560 // Structured block - An executable statement with a single entry at the 8561 // top and a single exit at the bottom. 8562 // The point of exit cannot be a branch out of the structured block. 8563 // longjmp() and throw() must not violate the entry/exit criteria. 8564 CS->getCapturedDecl()->setNothrow(); 8565 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8566 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8567 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8568 // 1.2.2 OpenMP Language Terminology 8569 // Structured block - An executable statement with a single entry at the 8570 // top and a single exit at the bottom. 8571 // The point of exit cannot be a branch out of the structured block. 8572 // longjmp() and throw() must not violate the entry/exit criteria. 8573 CS->getCapturedDecl()->setNothrow(); 8574 } 8575 8576 OMPLoopDirective::HelperExprs B; 8577 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8578 // define the nested loops number. 8579 unsigned NestedLoopCount = checkOpenMPLoop( 8580 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8581 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8582 VarsWithImplicitDSA, B); 8583 if (NestedLoopCount == 0) 8584 return StmtError(); 8585 8586 assert((CurContext->isDependentContext() || B.builtAll()) && 8587 "omp target parallel for simd loop exprs were not built"); 8588 8589 if (!CurContext->isDependentContext()) { 8590 // Finalize the clauses that need pre-built expressions for CodeGen. 8591 for (OMPClause *C : Clauses) { 8592 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8593 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8594 B.NumIterations, *this, CurScope, 8595 DSAStack)) 8596 return StmtError(); 8597 } 8598 } 8599 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8600 return StmtError(); 8601 8602 setFunctionHasBranchProtectedScope(); 8603 return OMPTargetParallelForSimdDirective::Create( 8604 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8605 } 8606 8607 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 8608 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8609 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8610 if (!AStmt) 8611 return StmtError(); 8612 8613 auto *CS = cast<CapturedStmt>(AStmt); 8614 // 1.2.2 OpenMP Language Terminology 8615 // Structured block - An executable statement with a single entry at the 8616 // top and a single exit at the bottom. 8617 // The point of exit cannot be a branch out of the structured block. 8618 // longjmp() and throw() must not violate the entry/exit criteria. 8619 CS->getCapturedDecl()->setNothrow(); 8620 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 8621 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8622 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8623 // 1.2.2 OpenMP Language Terminology 8624 // Structured block - An executable statement with a single entry at the 8625 // top and a single exit at the bottom. 8626 // The point of exit cannot be a branch out of the structured block. 8627 // longjmp() and throw() must not violate the entry/exit criteria. 8628 CS->getCapturedDecl()->setNothrow(); 8629 } 8630 8631 OMPLoopDirective::HelperExprs B; 8632 // In presence of clause 'collapse' with number of loops, it will define the 8633 // nested loops number. 8634 unsigned NestedLoopCount = 8635 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 8636 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8637 VarsWithImplicitDSA, B); 8638 if (NestedLoopCount == 0) 8639 return StmtError(); 8640 8641 assert((CurContext->isDependentContext() || B.builtAll()) && 8642 "omp target simd loop exprs were not built"); 8643 8644 if (!CurContext->isDependentContext()) { 8645 // Finalize the clauses that need pre-built expressions for CodeGen. 8646 for (OMPClause *C : Clauses) { 8647 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8648 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8649 B.NumIterations, *this, CurScope, 8650 DSAStack)) 8651 return StmtError(); 8652 } 8653 } 8654 8655 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8656 return StmtError(); 8657 8658 setFunctionHasBranchProtectedScope(); 8659 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 8660 NestedLoopCount, Clauses, AStmt, B); 8661 } 8662 8663 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 8664 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8665 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8666 if (!AStmt) 8667 return StmtError(); 8668 8669 auto *CS = cast<CapturedStmt>(AStmt); 8670 // 1.2.2 OpenMP Language Terminology 8671 // Structured block - An executable statement with a single entry at the 8672 // top and a single exit at the bottom. 8673 // The point of exit cannot be a branch out of the structured block. 8674 // longjmp() and throw() must not violate the entry/exit criteria. 8675 CS->getCapturedDecl()->setNothrow(); 8676 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 8677 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8678 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8679 // 1.2.2 OpenMP Language Terminology 8680 // Structured block - An executable statement with a single entry at the 8681 // top and a single exit at the bottom. 8682 // The point of exit cannot be a branch out of the structured block. 8683 // longjmp() and throw() must not violate the entry/exit criteria. 8684 CS->getCapturedDecl()->setNothrow(); 8685 } 8686 8687 OMPLoopDirective::HelperExprs B; 8688 // In presence of clause 'collapse' with number of loops, it will 8689 // define the nested loops number. 8690 unsigned NestedLoopCount = 8691 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 8692 nullptr /*ordered not a clause on distribute*/, CS, *this, 8693 *DSAStack, VarsWithImplicitDSA, B); 8694 if (NestedLoopCount == 0) 8695 return StmtError(); 8696 8697 assert((CurContext->isDependentContext() || B.builtAll()) && 8698 "omp teams distribute loop exprs were not built"); 8699 8700 setFunctionHasBranchProtectedScope(); 8701 8702 DSAStack->setParentTeamsRegionLoc(StartLoc); 8703 8704 return OMPTeamsDistributeDirective::Create( 8705 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8706 } 8707 8708 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 8709 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8710 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8711 if (!AStmt) 8712 return StmtError(); 8713 8714 auto *CS = cast<CapturedStmt>(AStmt); 8715 // 1.2.2 OpenMP Language Terminology 8716 // Structured block - An executable statement with a single entry at the 8717 // top and a single exit at the bottom. 8718 // The point of exit cannot be a branch out of the structured block. 8719 // longjmp() and throw() must not violate the entry/exit criteria. 8720 CS->getCapturedDecl()->setNothrow(); 8721 for (int ThisCaptureLevel = 8722 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8723 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8724 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8725 // 1.2.2 OpenMP Language Terminology 8726 // Structured block - An executable statement with a single entry at the 8727 // top and a single exit at the bottom. 8728 // The point of exit cannot be a branch out of the structured block. 8729 // longjmp() and throw() must not violate the entry/exit criteria. 8730 CS->getCapturedDecl()->setNothrow(); 8731 } 8732 8733 8734 OMPLoopDirective::HelperExprs B; 8735 // In presence of clause 'collapse' with number of loops, it will 8736 // define the nested loops number. 8737 unsigned NestedLoopCount = checkOpenMPLoop( 8738 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8739 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8740 VarsWithImplicitDSA, B); 8741 8742 if (NestedLoopCount == 0) 8743 return StmtError(); 8744 8745 assert((CurContext->isDependentContext() || B.builtAll()) && 8746 "omp teams distribute simd loop exprs were not built"); 8747 8748 if (!CurContext->isDependentContext()) { 8749 // Finalize the clauses that need pre-built expressions for CodeGen. 8750 for (OMPClause *C : Clauses) { 8751 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8752 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8753 B.NumIterations, *this, CurScope, 8754 DSAStack)) 8755 return StmtError(); 8756 } 8757 } 8758 8759 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8760 return StmtError(); 8761 8762 setFunctionHasBranchProtectedScope(); 8763 8764 DSAStack->setParentTeamsRegionLoc(StartLoc); 8765 8766 return OMPTeamsDistributeSimdDirective::Create( 8767 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8768 } 8769 8770 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8771 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8772 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8773 if (!AStmt) 8774 return StmtError(); 8775 8776 auto *CS = cast<CapturedStmt>(AStmt); 8777 // 1.2.2 OpenMP Language Terminology 8778 // Structured block - An executable statement with a single entry at the 8779 // top and a single exit at the bottom. 8780 // The point of exit cannot be a branch out of the structured block. 8781 // longjmp() and throw() must not violate the entry/exit criteria. 8782 CS->getCapturedDecl()->setNothrow(); 8783 8784 for (int ThisCaptureLevel = 8785 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8786 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8787 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8788 // 1.2.2 OpenMP Language Terminology 8789 // Structured block - An executable statement with a single entry at the 8790 // top and a single exit at the bottom. 8791 // The point of exit cannot be a branch out of the structured block. 8792 // longjmp() and throw() must not violate the entry/exit criteria. 8793 CS->getCapturedDecl()->setNothrow(); 8794 } 8795 8796 OMPLoopDirective::HelperExprs B; 8797 // In presence of clause 'collapse' with number of loops, it will 8798 // define the nested loops number. 8799 unsigned NestedLoopCount = checkOpenMPLoop( 8800 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8801 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8802 VarsWithImplicitDSA, B); 8803 8804 if (NestedLoopCount == 0) 8805 return StmtError(); 8806 8807 assert((CurContext->isDependentContext() || B.builtAll()) && 8808 "omp for loop exprs were not built"); 8809 8810 if (!CurContext->isDependentContext()) { 8811 // Finalize the clauses that need pre-built expressions for CodeGen. 8812 for (OMPClause *C : Clauses) { 8813 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8814 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8815 B.NumIterations, *this, CurScope, 8816 DSAStack)) 8817 return StmtError(); 8818 } 8819 } 8820 8821 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8822 return StmtError(); 8823 8824 setFunctionHasBranchProtectedScope(); 8825 8826 DSAStack->setParentTeamsRegionLoc(StartLoc); 8827 8828 return OMPTeamsDistributeParallelForSimdDirective::Create( 8829 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8830 } 8831 8832 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 8833 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8834 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8835 if (!AStmt) 8836 return StmtError(); 8837 8838 auto *CS = cast<CapturedStmt>(AStmt); 8839 // 1.2.2 OpenMP Language Terminology 8840 // Structured block - An executable statement with a single entry at the 8841 // top and a single exit at the bottom. 8842 // The point of exit cannot be a branch out of the structured block. 8843 // longjmp() and throw() must not violate the entry/exit criteria. 8844 CS->getCapturedDecl()->setNothrow(); 8845 8846 for (int ThisCaptureLevel = 8847 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8848 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8849 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8850 // 1.2.2 OpenMP Language Terminology 8851 // Structured block - An executable statement with a single entry at the 8852 // top and a single exit at the bottom. 8853 // The point of exit cannot be a branch out of the structured block. 8854 // longjmp() and throw() must not violate the entry/exit criteria. 8855 CS->getCapturedDecl()->setNothrow(); 8856 } 8857 8858 OMPLoopDirective::HelperExprs B; 8859 // In presence of clause 'collapse' with number of loops, it will 8860 // define the nested loops number. 8861 unsigned NestedLoopCount = checkOpenMPLoop( 8862 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8863 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8864 VarsWithImplicitDSA, B); 8865 8866 if (NestedLoopCount == 0) 8867 return StmtError(); 8868 8869 assert((CurContext->isDependentContext() || B.builtAll()) && 8870 "omp for loop exprs were not built"); 8871 8872 setFunctionHasBranchProtectedScope(); 8873 8874 DSAStack->setParentTeamsRegionLoc(StartLoc); 8875 8876 return OMPTeamsDistributeParallelForDirective::Create( 8877 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8878 DSAStack->isCancelRegion()); 8879 } 8880 8881 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8882 Stmt *AStmt, 8883 SourceLocation StartLoc, 8884 SourceLocation EndLoc) { 8885 if (!AStmt) 8886 return StmtError(); 8887 8888 auto *CS = cast<CapturedStmt>(AStmt); 8889 // 1.2.2 OpenMP Language Terminology 8890 // Structured block - An executable statement with a single entry at the 8891 // top and a single exit at the bottom. 8892 // The point of exit cannot be a branch out of the structured block. 8893 // longjmp() and throw() must not violate the entry/exit criteria. 8894 CS->getCapturedDecl()->setNothrow(); 8895 8896 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8897 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8898 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8899 // 1.2.2 OpenMP Language Terminology 8900 // Structured block - An executable statement with a single entry at the 8901 // top and a single exit at the bottom. 8902 // The point of exit cannot be a branch out of the structured block. 8903 // longjmp() and throw() must not violate the entry/exit criteria. 8904 CS->getCapturedDecl()->setNothrow(); 8905 } 8906 setFunctionHasBranchProtectedScope(); 8907 8908 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8909 AStmt); 8910 } 8911 8912 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8913 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8914 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8915 if (!AStmt) 8916 return StmtError(); 8917 8918 auto *CS = cast<CapturedStmt>(AStmt); 8919 // 1.2.2 OpenMP Language Terminology 8920 // Structured block - An executable statement with a single entry at the 8921 // top and a single exit at the bottom. 8922 // The point of exit cannot be a branch out of the structured block. 8923 // longjmp() and throw() must not violate the entry/exit criteria. 8924 CS->getCapturedDecl()->setNothrow(); 8925 for (int ThisCaptureLevel = 8926 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8927 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8928 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8929 // 1.2.2 OpenMP Language Terminology 8930 // Structured block - An executable statement with a single entry at the 8931 // top and a single exit at the bottom. 8932 // The point of exit cannot be a branch out of the structured block. 8933 // longjmp() and throw() must not violate the entry/exit criteria. 8934 CS->getCapturedDecl()->setNothrow(); 8935 } 8936 8937 OMPLoopDirective::HelperExprs B; 8938 // In presence of clause 'collapse' with number of loops, it will 8939 // define the nested loops number. 8940 unsigned NestedLoopCount = checkOpenMPLoop( 8941 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8942 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8943 VarsWithImplicitDSA, B); 8944 if (NestedLoopCount == 0) 8945 return StmtError(); 8946 8947 assert((CurContext->isDependentContext() || B.builtAll()) && 8948 "omp target teams distribute loop exprs were not built"); 8949 8950 setFunctionHasBranchProtectedScope(); 8951 return OMPTargetTeamsDistributeDirective::Create( 8952 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8953 } 8954 8955 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8956 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8957 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8958 if (!AStmt) 8959 return StmtError(); 8960 8961 auto *CS = cast<CapturedStmt>(AStmt); 8962 // 1.2.2 OpenMP Language Terminology 8963 // Structured block - An executable statement with a single entry at the 8964 // top and a single exit at the bottom. 8965 // The point of exit cannot be a branch out of the structured block. 8966 // longjmp() and throw() must not violate the entry/exit criteria. 8967 CS->getCapturedDecl()->setNothrow(); 8968 for (int ThisCaptureLevel = 8969 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 8970 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8971 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8972 // 1.2.2 OpenMP Language Terminology 8973 // Structured block - An executable statement with a single entry at the 8974 // top and a single exit at the bottom. 8975 // The point of exit cannot be a branch out of the structured block. 8976 // longjmp() and throw() must not violate the entry/exit criteria. 8977 CS->getCapturedDecl()->setNothrow(); 8978 } 8979 8980 OMPLoopDirective::HelperExprs B; 8981 // In presence of clause 'collapse' with number of loops, it will 8982 // define the nested loops number. 8983 unsigned NestedLoopCount = checkOpenMPLoop( 8984 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8985 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8986 VarsWithImplicitDSA, B); 8987 if (NestedLoopCount == 0) 8988 return StmtError(); 8989 8990 assert((CurContext->isDependentContext() || B.builtAll()) && 8991 "omp target teams distribute parallel for loop exprs were not built"); 8992 8993 if (!CurContext->isDependentContext()) { 8994 // Finalize the clauses that need pre-built expressions for CodeGen. 8995 for (OMPClause *C : Clauses) { 8996 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8997 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8998 B.NumIterations, *this, CurScope, 8999 DSAStack)) 9000 return StmtError(); 9001 } 9002 } 9003 9004 setFunctionHasBranchProtectedScope(); 9005 return OMPTargetTeamsDistributeParallelForDirective::Create( 9006 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9007 DSAStack->isCancelRegion()); 9008 } 9009 9010 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9011 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9012 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9013 if (!AStmt) 9014 return StmtError(); 9015 9016 auto *CS = cast<CapturedStmt>(AStmt); 9017 // 1.2.2 OpenMP Language Terminology 9018 // Structured block - An executable statement with a single entry at the 9019 // top and a single exit at the bottom. 9020 // The point of exit cannot be a branch out of the structured block. 9021 // longjmp() and throw() must not violate the entry/exit criteria. 9022 CS->getCapturedDecl()->setNothrow(); 9023 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9024 OMPD_target_teams_distribute_parallel_for_simd); 9025 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9026 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9027 // 1.2.2 OpenMP Language Terminology 9028 // Structured block - An executable statement with a single entry at the 9029 // top and a single exit at the bottom. 9030 // The point of exit cannot be a branch out of the structured block. 9031 // longjmp() and throw() must not violate the entry/exit criteria. 9032 CS->getCapturedDecl()->setNothrow(); 9033 } 9034 9035 OMPLoopDirective::HelperExprs B; 9036 // In presence of clause 'collapse' with number of loops, it will 9037 // define the nested loops number. 9038 unsigned NestedLoopCount = 9039 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9040 getCollapseNumberExpr(Clauses), 9041 nullptr /*ordered not a clause on distribute*/, CS, *this, 9042 *DSAStack, VarsWithImplicitDSA, B); 9043 if (NestedLoopCount == 0) 9044 return StmtError(); 9045 9046 assert((CurContext->isDependentContext() || B.builtAll()) && 9047 "omp target teams distribute parallel for simd loop exprs were not " 9048 "built"); 9049 9050 if (!CurContext->isDependentContext()) { 9051 // Finalize the clauses that need pre-built expressions for CodeGen. 9052 for (OMPClause *C : Clauses) { 9053 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9054 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9055 B.NumIterations, *this, CurScope, 9056 DSAStack)) 9057 return StmtError(); 9058 } 9059 } 9060 9061 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9062 return StmtError(); 9063 9064 setFunctionHasBranchProtectedScope(); 9065 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9066 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9067 } 9068 9069 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9070 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9071 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9072 if (!AStmt) 9073 return StmtError(); 9074 9075 auto *CS = cast<CapturedStmt>(AStmt); 9076 // 1.2.2 OpenMP Language Terminology 9077 // Structured block - An executable statement with a single entry at the 9078 // top and a single exit at the bottom. 9079 // The point of exit cannot be a branch out of the structured block. 9080 // longjmp() and throw() must not violate the entry/exit criteria. 9081 CS->getCapturedDecl()->setNothrow(); 9082 for (int ThisCaptureLevel = 9083 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9084 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9085 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9086 // 1.2.2 OpenMP Language Terminology 9087 // Structured block - An executable statement with a single entry at the 9088 // top and a single exit at the bottom. 9089 // The point of exit cannot be a branch out of the structured block. 9090 // longjmp() and throw() must not violate the entry/exit criteria. 9091 CS->getCapturedDecl()->setNothrow(); 9092 } 9093 9094 OMPLoopDirective::HelperExprs B; 9095 // In presence of clause 'collapse' with number of loops, it will 9096 // define the nested loops number. 9097 unsigned NestedLoopCount = checkOpenMPLoop( 9098 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9099 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9100 VarsWithImplicitDSA, B); 9101 if (NestedLoopCount == 0) 9102 return StmtError(); 9103 9104 assert((CurContext->isDependentContext() || B.builtAll()) && 9105 "omp target teams distribute simd loop exprs were not built"); 9106 9107 if (!CurContext->isDependentContext()) { 9108 // Finalize the clauses that need pre-built expressions for CodeGen. 9109 for (OMPClause *C : Clauses) { 9110 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9111 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9112 B.NumIterations, *this, CurScope, 9113 DSAStack)) 9114 return StmtError(); 9115 } 9116 } 9117 9118 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9119 return StmtError(); 9120 9121 setFunctionHasBranchProtectedScope(); 9122 return OMPTargetTeamsDistributeSimdDirective::Create( 9123 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9124 } 9125 9126 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9127 SourceLocation StartLoc, 9128 SourceLocation LParenLoc, 9129 SourceLocation EndLoc) { 9130 OMPClause *Res = nullptr; 9131 switch (Kind) { 9132 case OMPC_final: 9133 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9134 break; 9135 case OMPC_num_threads: 9136 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9137 break; 9138 case OMPC_safelen: 9139 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9140 break; 9141 case OMPC_simdlen: 9142 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9143 break; 9144 case OMPC_allocator: 9145 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9146 break; 9147 case OMPC_collapse: 9148 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9149 break; 9150 case OMPC_ordered: 9151 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9152 break; 9153 case OMPC_device: 9154 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9155 break; 9156 case OMPC_num_teams: 9157 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9158 break; 9159 case OMPC_thread_limit: 9160 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9161 break; 9162 case OMPC_priority: 9163 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9164 break; 9165 case OMPC_grainsize: 9166 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9167 break; 9168 case OMPC_num_tasks: 9169 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9170 break; 9171 case OMPC_hint: 9172 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9173 break; 9174 case OMPC_if: 9175 case OMPC_default: 9176 case OMPC_proc_bind: 9177 case OMPC_schedule: 9178 case OMPC_private: 9179 case OMPC_firstprivate: 9180 case OMPC_lastprivate: 9181 case OMPC_shared: 9182 case OMPC_reduction: 9183 case OMPC_task_reduction: 9184 case OMPC_in_reduction: 9185 case OMPC_linear: 9186 case OMPC_aligned: 9187 case OMPC_copyin: 9188 case OMPC_copyprivate: 9189 case OMPC_nowait: 9190 case OMPC_untied: 9191 case OMPC_mergeable: 9192 case OMPC_threadprivate: 9193 case OMPC_allocate: 9194 case OMPC_flush: 9195 case OMPC_read: 9196 case OMPC_write: 9197 case OMPC_update: 9198 case OMPC_capture: 9199 case OMPC_seq_cst: 9200 case OMPC_depend: 9201 case OMPC_threads: 9202 case OMPC_simd: 9203 case OMPC_map: 9204 case OMPC_nogroup: 9205 case OMPC_dist_schedule: 9206 case OMPC_defaultmap: 9207 case OMPC_unknown: 9208 case OMPC_uniform: 9209 case OMPC_to: 9210 case OMPC_from: 9211 case OMPC_use_device_ptr: 9212 case OMPC_is_device_ptr: 9213 case OMPC_unified_address: 9214 case OMPC_unified_shared_memory: 9215 case OMPC_reverse_offload: 9216 case OMPC_dynamic_allocators: 9217 case OMPC_atomic_default_mem_order: 9218 llvm_unreachable("Clause is not allowed."); 9219 } 9220 return Res; 9221 } 9222 9223 // An OpenMP directive such as 'target parallel' has two captured regions: 9224 // for the 'target' and 'parallel' respectively. This function returns 9225 // the region in which to capture expressions associated with a clause. 9226 // A return value of OMPD_unknown signifies that the expression should not 9227 // be captured. 9228 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9229 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9230 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9231 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9232 switch (CKind) { 9233 case OMPC_if: 9234 switch (DKind) { 9235 case OMPD_target_parallel: 9236 case OMPD_target_parallel_for: 9237 case OMPD_target_parallel_for_simd: 9238 // If this clause applies to the nested 'parallel' region, capture within 9239 // the 'target' region, otherwise do not capture. 9240 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9241 CaptureRegion = OMPD_target; 9242 break; 9243 case OMPD_target_teams_distribute_parallel_for: 9244 case OMPD_target_teams_distribute_parallel_for_simd: 9245 // If this clause applies to the nested 'parallel' region, capture within 9246 // the 'teams' region, otherwise do not capture. 9247 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9248 CaptureRegion = OMPD_teams; 9249 break; 9250 case OMPD_teams_distribute_parallel_for: 9251 case OMPD_teams_distribute_parallel_for_simd: 9252 CaptureRegion = OMPD_teams; 9253 break; 9254 case OMPD_target_update: 9255 case OMPD_target_enter_data: 9256 case OMPD_target_exit_data: 9257 CaptureRegion = OMPD_task; 9258 break; 9259 case OMPD_cancel: 9260 case OMPD_parallel: 9261 case OMPD_parallel_sections: 9262 case OMPD_parallel_for: 9263 case OMPD_parallel_for_simd: 9264 case OMPD_target: 9265 case OMPD_target_simd: 9266 case OMPD_target_teams: 9267 case OMPD_target_teams_distribute: 9268 case OMPD_target_teams_distribute_simd: 9269 case OMPD_distribute_parallel_for: 9270 case OMPD_distribute_parallel_for_simd: 9271 case OMPD_task: 9272 case OMPD_taskloop: 9273 case OMPD_taskloop_simd: 9274 case OMPD_target_data: 9275 // Do not capture if-clause expressions. 9276 break; 9277 case OMPD_threadprivate: 9278 case OMPD_allocate: 9279 case OMPD_taskyield: 9280 case OMPD_barrier: 9281 case OMPD_taskwait: 9282 case OMPD_cancellation_point: 9283 case OMPD_flush: 9284 case OMPD_declare_reduction: 9285 case OMPD_declare_mapper: 9286 case OMPD_declare_simd: 9287 case OMPD_declare_target: 9288 case OMPD_end_declare_target: 9289 case OMPD_teams: 9290 case OMPD_simd: 9291 case OMPD_for: 9292 case OMPD_for_simd: 9293 case OMPD_sections: 9294 case OMPD_section: 9295 case OMPD_single: 9296 case OMPD_master: 9297 case OMPD_critical: 9298 case OMPD_taskgroup: 9299 case OMPD_distribute: 9300 case OMPD_ordered: 9301 case OMPD_atomic: 9302 case OMPD_distribute_simd: 9303 case OMPD_teams_distribute: 9304 case OMPD_teams_distribute_simd: 9305 case OMPD_requires: 9306 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9307 case OMPD_unknown: 9308 llvm_unreachable("Unknown OpenMP directive"); 9309 } 9310 break; 9311 case OMPC_num_threads: 9312 switch (DKind) { 9313 case OMPD_target_parallel: 9314 case OMPD_target_parallel_for: 9315 case OMPD_target_parallel_for_simd: 9316 CaptureRegion = OMPD_target; 9317 break; 9318 case OMPD_teams_distribute_parallel_for: 9319 case OMPD_teams_distribute_parallel_for_simd: 9320 case OMPD_target_teams_distribute_parallel_for: 9321 case OMPD_target_teams_distribute_parallel_for_simd: 9322 CaptureRegion = OMPD_teams; 9323 break; 9324 case OMPD_parallel: 9325 case OMPD_parallel_sections: 9326 case OMPD_parallel_for: 9327 case OMPD_parallel_for_simd: 9328 case OMPD_distribute_parallel_for: 9329 case OMPD_distribute_parallel_for_simd: 9330 // Do not capture num_threads-clause expressions. 9331 break; 9332 case OMPD_target_data: 9333 case OMPD_target_enter_data: 9334 case OMPD_target_exit_data: 9335 case OMPD_target_update: 9336 case OMPD_target: 9337 case OMPD_target_simd: 9338 case OMPD_target_teams: 9339 case OMPD_target_teams_distribute: 9340 case OMPD_target_teams_distribute_simd: 9341 case OMPD_cancel: 9342 case OMPD_task: 9343 case OMPD_taskloop: 9344 case OMPD_taskloop_simd: 9345 case OMPD_threadprivate: 9346 case OMPD_allocate: 9347 case OMPD_taskyield: 9348 case OMPD_barrier: 9349 case OMPD_taskwait: 9350 case OMPD_cancellation_point: 9351 case OMPD_flush: 9352 case OMPD_declare_reduction: 9353 case OMPD_declare_mapper: 9354 case OMPD_declare_simd: 9355 case OMPD_declare_target: 9356 case OMPD_end_declare_target: 9357 case OMPD_teams: 9358 case OMPD_simd: 9359 case OMPD_for: 9360 case OMPD_for_simd: 9361 case OMPD_sections: 9362 case OMPD_section: 9363 case OMPD_single: 9364 case OMPD_master: 9365 case OMPD_critical: 9366 case OMPD_taskgroup: 9367 case OMPD_distribute: 9368 case OMPD_ordered: 9369 case OMPD_atomic: 9370 case OMPD_distribute_simd: 9371 case OMPD_teams_distribute: 9372 case OMPD_teams_distribute_simd: 9373 case OMPD_requires: 9374 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9375 case OMPD_unknown: 9376 llvm_unreachable("Unknown OpenMP directive"); 9377 } 9378 break; 9379 case OMPC_num_teams: 9380 switch (DKind) { 9381 case OMPD_target_teams: 9382 case OMPD_target_teams_distribute: 9383 case OMPD_target_teams_distribute_simd: 9384 case OMPD_target_teams_distribute_parallel_for: 9385 case OMPD_target_teams_distribute_parallel_for_simd: 9386 CaptureRegion = OMPD_target; 9387 break; 9388 case OMPD_teams_distribute_parallel_for: 9389 case OMPD_teams_distribute_parallel_for_simd: 9390 case OMPD_teams: 9391 case OMPD_teams_distribute: 9392 case OMPD_teams_distribute_simd: 9393 // Do not capture num_teams-clause expressions. 9394 break; 9395 case OMPD_distribute_parallel_for: 9396 case OMPD_distribute_parallel_for_simd: 9397 case OMPD_task: 9398 case OMPD_taskloop: 9399 case OMPD_taskloop_simd: 9400 case OMPD_target_data: 9401 case OMPD_target_enter_data: 9402 case OMPD_target_exit_data: 9403 case OMPD_target_update: 9404 case OMPD_cancel: 9405 case OMPD_parallel: 9406 case OMPD_parallel_sections: 9407 case OMPD_parallel_for: 9408 case OMPD_parallel_for_simd: 9409 case OMPD_target: 9410 case OMPD_target_simd: 9411 case OMPD_target_parallel: 9412 case OMPD_target_parallel_for: 9413 case OMPD_target_parallel_for_simd: 9414 case OMPD_threadprivate: 9415 case OMPD_allocate: 9416 case OMPD_taskyield: 9417 case OMPD_barrier: 9418 case OMPD_taskwait: 9419 case OMPD_cancellation_point: 9420 case OMPD_flush: 9421 case OMPD_declare_reduction: 9422 case OMPD_declare_mapper: 9423 case OMPD_declare_simd: 9424 case OMPD_declare_target: 9425 case OMPD_end_declare_target: 9426 case OMPD_simd: 9427 case OMPD_for: 9428 case OMPD_for_simd: 9429 case OMPD_sections: 9430 case OMPD_section: 9431 case OMPD_single: 9432 case OMPD_master: 9433 case OMPD_critical: 9434 case OMPD_taskgroup: 9435 case OMPD_distribute: 9436 case OMPD_ordered: 9437 case OMPD_atomic: 9438 case OMPD_distribute_simd: 9439 case OMPD_requires: 9440 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9441 case OMPD_unknown: 9442 llvm_unreachable("Unknown OpenMP directive"); 9443 } 9444 break; 9445 case OMPC_thread_limit: 9446 switch (DKind) { 9447 case OMPD_target_teams: 9448 case OMPD_target_teams_distribute: 9449 case OMPD_target_teams_distribute_simd: 9450 case OMPD_target_teams_distribute_parallel_for: 9451 case OMPD_target_teams_distribute_parallel_for_simd: 9452 CaptureRegion = OMPD_target; 9453 break; 9454 case OMPD_teams_distribute_parallel_for: 9455 case OMPD_teams_distribute_parallel_for_simd: 9456 case OMPD_teams: 9457 case OMPD_teams_distribute: 9458 case OMPD_teams_distribute_simd: 9459 // Do not capture thread_limit-clause expressions. 9460 break; 9461 case OMPD_distribute_parallel_for: 9462 case OMPD_distribute_parallel_for_simd: 9463 case OMPD_task: 9464 case OMPD_taskloop: 9465 case OMPD_taskloop_simd: 9466 case OMPD_target_data: 9467 case OMPD_target_enter_data: 9468 case OMPD_target_exit_data: 9469 case OMPD_target_update: 9470 case OMPD_cancel: 9471 case OMPD_parallel: 9472 case OMPD_parallel_sections: 9473 case OMPD_parallel_for: 9474 case OMPD_parallel_for_simd: 9475 case OMPD_target: 9476 case OMPD_target_simd: 9477 case OMPD_target_parallel: 9478 case OMPD_target_parallel_for: 9479 case OMPD_target_parallel_for_simd: 9480 case OMPD_threadprivate: 9481 case OMPD_allocate: 9482 case OMPD_taskyield: 9483 case OMPD_barrier: 9484 case OMPD_taskwait: 9485 case OMPD_cancellation_point: 9486 case OMPD_flush: 9487 case OMPD_declare_reduction: 9488 case OMPD_declare_mapper: 9489 case OMPD_declare_simd: 9490 case OMPD_declare_target: 9491 case OMPD_end_declare_target: 9492 case OMPD_simd: 9493 case OMPD_for: 9494 case OMPD_for_simd: 9495 case OMPD_sections: 9496 case OMPD_section: 9497 case OMPD_single: 9498 case OMPD_master: 9499 case OMPD_critical: 9500 case OMPD_taskgroup: 9501 case OMPD_distribute: 9502 case OMPD_ordered: 9503 case OMPD_atomic: 9504 case OMPD_distribute_simd: 9505 case OMPD_requires: 9506 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 9507 case OMPD_unknown: 9508 llvm_unreachable("Unknown OpenMP directive"); 9509 } 9510 break; 9511 case OMPC_schedule: 9512 switch (DKind) { 9513 case OMPD_parallel_for: 9514 case OMPD_parallel_for_simd: 9515 case OMPD_distribute_parallel_for: 9516 case OMPD_distribute_parallel_for_simd: 9517 case OMPD_teams_distribute_parallel_for: 9518 case OMPD_teams_distribute_parallel_for_simd: 9519 case OMPD_target_parallel_for: 9520 case OMPD_target_parallel_for_simd: 9521 case OMPD_target_teams_distribute_parallel_for: 9522 case OMPD_target_teams_distribute_parallel_for_simd: 9523 CaptureRegion = OMPD_parallel; 9524 break; 9525 case OMPD_for: 9526 case OMPD_for_simd: 9527 // Do not capture schedule-clause expressions. 9528 break; 9529 case OMPD_task: 9530 case OMPD_taskloop: 9531 case OMPD_taskloop_simd: 9532 case OMPD_target_data: 9533 case OMPD_target_enter_data: 9534 case OMPD_target_exit_data: 9535 case OMPD_target_update: 9536 case OMPD_teams: 9537 case OMPD_teams_distribute: 9538 case OMPD_teams_distribute_simd: 9539 case OMPD_target_teams_distribute: 9540 case OMPD_target_teams_distribute_simd: 9541 case OMPD_target: 9542 case OMPD_target_simd: 9543 case OMPD_target_parallel: 9544 case OMPD_cancel: 9545 case OMPD_parallel: 9546 case OMPD_parallel_sections: 9547 case OMPD_threadprivate: 9548 case OMPD_allocate: 9549 case OMPD_taskyield: 9550 case OMPD_barrier: 9551 case OMPD_taskwait: 9552 case OMPD_cancellation_point: 9553 case OMPD_flush: 9554 case OMPD_declare_reduction: 9555 case OMPD_declare_mapper: 9556 case OMPD_declare_simd: 9557 case OMPD_declare_target: 9558 case OMPD_end_declare_target: 9559 case OMPD_simd: 9560 case OMPD_sections: 9561 case OMPD_section: 9562 case OMPD_single: 9563 case OMPD_master: 9564 case OMPD_critical: 9565 case OMPD_taskgroup: 9566 case OMPD_distribute: 9567 case OMPD_ordered: 9568 case OMPD_atomic: 9569 case OMPD_distribute_simd: 9570 case OMPD_target_teams: 9571 case OMPD_requires: 9572 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9573 case OMPD_unknown: 9574 llvm_unreachable("Unknown OpenMP directive"); 9575 } 9576 break; 9577 case OMPC_dist_schedule: 9578 switch (DKind) { 9579 case OMPD_teams_distribute_parallel_for: 9580 case OMPD_teams_distribute_parallel_for_simd: 9581 case OMPD_teams_distribute: 9582 case OMPD_teams_distribute_simd: 9583 case OMPD_target_teams_distribute_parallel_for: 9584 case OMPD_target_teams_distribute_parallel_for_simd: 9585 case OMPD_target_teams_distribute: 9586 case OMPD_target_teams_distribute_simd: 9587 CaptureRegion = OMPD_teams; 9588 break; 9589 case OMPD_distribute_parallel_for: 9590 case OMPD_distribute_parallel_for_simd: 9591 case OMPD_distribute: 9592 case OMPD_distribute_simd: 9593 // Do not capture thread_limit-clause expressions. 9594 break; 9595 case OMPD_parallel_for: 9596 case OMPD_parallel_for_simd: 9597 case OMPD_target_parallel_for_simd: 9598 case OMPD_target_parallel_for: 9599 case OMPD_task: 9600 case OMPD_taskloop: 9601 case OMPD_taskloop_simd: 9602 case OMPD_target_data: 9603 case OMPD_target_enter_data: 9604 case OMPD_target_exit_data: 9605 case OMPD_target_update: 9606 case OMPD_teams: 9607 case OMPD_target: 9608 case OMPD_target_simd: 9609 case OMPD_target_parallel: 9610 case OMPD_cancel: 9611 case OMPD_parallel: 9612 case OMPD_parallel_sections: 9613 case OMPD_threadprivate: 9614 case OMPD_allocate: 9615 case OMPD_taskyield: 9616 case OMPD_barrier: 9617 case OMPD_taskwait: 9618 case OMPD_cancellation_point: 9619 case OMPD_flush: 9620 case OMPD_declare_reduction: 9621 case OMPD_declare_mapper: 9622 case OMPD_declare_simd: 9623 case OMPD_declare_target: 9624 case OMPD_end_declare_target: 9625 case OMPD_simd: 9626 case OMPD_for: 9627 case OMPD_for_simd: 9628 case OMPD_sections: 9629 case OMPD_section: 9630 case OMPD_single: 9631 case OMPD_master: 9632 case OMPD_critical: 9633 case OMPD_taskgroup: 9634 case OMPD_ordered: 9635 case OMPD_atomic: 9636 case OMPD_target_teams: 9637 case OMPD_requires: 9638 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9639 case OMPD_unknown: 9640 llvm_unreachable("Unknown OpenMP directive"); 9641 } 9642 break; 9643 case OMPC_device: 9644 switch (DKind) { 9645 case OMPD_target_update: 9646 case OMPD_target_enter_data: 9647 case OMPD_target_exit_data: 9648 case OMPD_target: 9649 case OMPD_target_simd: 9650 case OMPD_target_teams: 9651 case OMPD_target_parallel: 9652 case OMPD_target_teams_distribute: 9653 case OMPD_target_teams_distribute_simd: 9654 case OMPD_target_parallel_for: 9655 case OMPD_target_parallel_for_simd: 9656 case OMPD_target_teams_distribute_parallel_for: 9657 case OMPD_target_teams_distribute_parallel_for_simd: 9658 CaptureRegion = OMPD_task; 9659 break; 9660 case OMPD_target_data: 9661 // Do not capture device-clause expressions. 9662 break; 9663 case OMPD_teams_distribute_parallel_for: 9664 case OMPD_teams_distribute_parallel_for_simd: 9665 case OMPD_teams: 9666 case OMPD_teams_distribute: 9667 case OMPD_teams_distribute_simd: 9668 case OMPD_distribute_parallel_for: 9669 case OMPD_distribute_parallel_for_simd: 9670 case OMPD_task: 9671 case OMPD_taskloop: 9672 case OMPD_taskloop_simd: 9673 case OMPD_cancel: 9674 case OMPD_parallel: 9675 case OMPD_parallel_sections: 9676 case OMPD_parallel_for: 9677 case OMPD_parallel_for_simd: 9678 case OMPD_threadprivate: 9679 case OMPD_allocate: 9680 case OMPD_taskyield: 9681 case OMPD_barrier: 9682 case OMPD_taskwait: 9683 case OMPD_cancellation_point: 9684 case OMPD_flush: 9685 case OMPD_declare_reduction: 9686 case OMPD_declare_mapper: 9687 case OMPD_declare_simd: 9688 case OMPD_declare_target: 9689 case OMPD_end_declare_target: 9690 case OMPD_simd: 9691 case OMPD_for: 9692 case OMPD_for_simd: 9693 case OMPD_sections: 9694 case OMPD_section: 9695 case OMPD_single: 9696 case OMPD_master: 9697 case OMPD_critical: 9698 case OMPD_taskgroup: 9699 case OMPD_distribute: 9700 case OMPD_ordered: 9701 case OMPD_atomic: 9702 case OMPD_distribute_simd: 9703 case OMPD_requires: 9704 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9705 case OMPD_unknown: 9706 llvm_unreachable("Unknown OpenMP directive"); 9707 } 9708 break; 9709 case OMPC_firstprivate: 9710 case OMPC_lastprivate: 9711 case OMPC_reduction: 9712 case OMPC_task_reduction: 9713 case OMPC_in_reduction: 9714 case OMPC_linear: 9715 case OMPC_default: 9716 case OMPC_proc_bind: 9717 case OMPC_final: 9718 case OMPC_safelen: 9719 case OMPC_simdlen: 9720 case OMPC_allocator: 9721 case OMPC_collapse: 9722 case OMPC_private: 9723 case OMPC_shared: 9724 case OMPC_aligned: 9725 case OMPC_copyin: 9726 case OMPC_copyprivate: 9727 case OMPC_ordered: 9728 case OMPC_nowait: 9729 case OMPC_untied: 9730 case OMPC_mergeable: 9731 case OMPC_threadprivate: 9732 case OMPC_allocate: 9733 case OMPC_flush: 9734 case OMPC_read: 9735 case OMPC_write: 9736 case OMPC_update: 9737 case OMPC_capture: 9738 case OMPC_seq_cst: 9739 case OMPC_depend: 9740 case OMPC_threads: 9741 case OMPC_simd: 9742 case OMPC_map: 9743 case OMPC_priority: 9744 case OMPC_grainsize: 9745 case OMPC_nogroup: 9746 case OMPC_num_tasks: 9747 case OMPC_hint: 9748 case OMPC_defaultmap: 9749 case OMPC_unknown: 9750 case OMPC_uniform: 9751 case OMPC_to: 9752 case OMPC_from: 9753 case OMPC_use_device_ptr: 9754 case OMPC_is_device_ptr: 9755 case OMPC_unified_address: 9756 case OMPC_unified_shared_memory: 9757 case OMPC_reverse_offload: 9758 case OMPC_dynamic_allocators: 9759 case OMPC_atomic_default_mem_order: 9760 llvm_unreachable("Unexpected OpenMP clause."); 9761 } 9762 return CaptureRegion; 9763 } 9764 9765 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9766 Expr *Condition, SourceLocation StartLoc, 9767 SourceLocation LParenLoc, 9768 SourceLocation NameModifierLoc, 9769 SourceLocation ColonLoc, 9770 SourceLocation EndLoc) { 9771 Expr *ValExpr = Condition; 9772 Stmt *HelperValStmt = nullptr; 9773 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9774 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9775 !Condition->isInstantiationDependent() && 9776 !Condition->containsUnexpandedParameterPack()) { 9777 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9778 if (Val.isInvalid()) 9779 return nullptr; 9780 9781 ValExpr = Val.get(); 9782 9783 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9784 CaptureRegion = 9785 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9786 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9787 ValExpr = MakeFullExpr(ValExpr).get(); 9788 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9789 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9790 HelperValStmt = buildPreInits(Context, Captures); 9791 } 9792 } 9793 9794 return new (Context) 9795 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9796 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9797 } 9798 9799 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9800 SourceLocation StartLoc, 9801 SourceLocation LParenLoc, 9802 SourceLocation EndLoc) { 9803 Expr *ValExpr = Condition; 9804 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9805 !Condition->isInstantiationDependent() && 9806 !Condition->containsUnexpandedParameterPack()) { 9807 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9808 if (Val.isInvalid()) 9809 return nullptr; 9810 9811 ValExpr = MakeFullExpr(Val.get()).get(); 9812 } 9813 9814 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9815 } 9816 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9817 Expr *Op) { 9818 if (!Op) 9819 return ExprError(); 9820 9821 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9822 public: 9823 IntConvertDiagnoser() 9824 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9825 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9826 QualType T) override { 9827 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9828 } 9829 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9830 QualType T) override { 9831 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9832 } 9833 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9834 QualType T, 9835 QualType ConvTy) override { 9836 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9837 } 9838 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9839 QualType ConvTy) override { 9840 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9841 << ConvTy->isEnumeralType() << ConvTy; 9842 } 9843 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9844 QualType T) override { 9845 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9846 } 9847 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9848 QualType ConvTy) override { 9849 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9850 << ConvTy->isEnumeralType() << ConvTy; 9851 } 9852 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9853 QualType) override { 9854 llvm_unreachable("conversion functions are permitted"); 9855 } 9856 } ConvertDiagnoser; 9857 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9858 } 9859 9860 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9861 OpenMPClauseKind CKind, 9862 bool StrictlyPositive) { 9863 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9864 !ValExpr->isInstantiationDependent()) { 9865 SourceLocation Loc = ValExpr->getExprLoc(); 9866 ExprResult Value = 9867 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9868 if (Value.isInvalid()) 9869 return false; 9870 9871 ValExpr = Value.get(); 9872 // The expression must evaluate to a non-negative integer value. 9873 llvm::APSInt Result; 9874 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9875 Result.isSigned() && 9876 !((!StrictlyPositive && Result.isNonNegative()) || 9877 (StrictlyPositive && Result.isStrictlyPositive()))) { 9878 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9879 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9880 << ValExpr->getSourceRange(); 9881 return false; 9882 } 9883 } 9884 return true; 9885 } 9886 9887 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9888 SourceLocation StartLoc, 9889 SourceLocation LParenLoc, 9890 SourceLocation EndLoc) { 9891 Expr *ValExpr = NumThreads; 9892 Stmt *HelperValStmt = nullptr; 9893 9894 // OpenMP [2.5, Restrictions] 9895 // The num_threads expression must evaluate to a positive integer value. 9896 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9897 /*StrictlyPositive=*/true)) 9898 return nullptr; 9899 9900 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9901 OpenMPDirectiveKind CaptureRegion = 9902 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9903 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9904 ValExpr = MakeFullExpr(ValExpr).get(); 9905 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9906 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9907 HelperValStmt = buildPreInits(Context, Captures); 9908 } 9909 9910 return new (Context) OMPNumThreadsClause( 9911 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9912 } 9913 9914 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9915 OpenMPClauseKind CKind, 9916 bool StrictlyPositive) { 9917 if (!E) 9918 return ExprError(); 9919 if (E->isValueDependent() || E->isTypeDependent() || 9920 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9921 return E; 9922 llvm::APSInt Result; 9923 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9924 if (ICE.isInvalid()) 9925 return ExprError(); 9926 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9927 (!StrictlyPositive && !Result.isNonNegative())) { 9928 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9929 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9930 << E->getSourceRange(); 9931 return ExprError(); 9932 } 9933 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9934 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9935 << E->getSourceRange(); 9936 return ExprError(); 9937 } 9938 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9939 DSAStack->setAssociatedLoops(Result.getExtValue()); 9940 else if (CKind == OMPC_ordered) 9941 DSAStack->setAssociatedLoops(Result.getExtValue()); 9942 return ICE; 9943 } 9944 9945 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9946 SourceLocation LParenLoc, 9947 SourceLocation EndLoc) { 9948 // OpenMP [2.8.1, simd construct, Description] 9949 // The parameter of the safelen clause must be a constant 9950 // positive integer expression. 9951 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9952 if (Safelen.isInvalid()) 9953 return nullptr; 9954 return new (Context) 9955 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9956 } 9957 9958 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9959 SourceLocation LParenLoc, 9960 SourceLocation EndLoc) { 9961 // OpenMP [2.8.1, simd construct, Description] 9962 // The parameter of the simdlen clause must be a constant 9963 // positive integer expression. 9964 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9965 if (Simdlen.isInvalid()) 9966 return nullptr; 9967 return new (Context) 9968 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9969 } 9970 9971 /// Tries to find omp_allocator_handle_t type. 9972 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 9973 DSAStackTy *Stack) { 9974 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 9975 if (!OMPAllocatorHandleT.isNull()) 9976 return true; 9977 // Build the predefined allocator expressions. 9978 bool ErrorFound = false; 9979 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 9980 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 9981 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 9982 StringRef Allocator = 9983 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 9984 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 9985 auto *VD = dyn_cast_or_null<ValueDecl>( 9986 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 9987 if (!VD) { 9988 ErrorFound = true; 9989 break; 9990 } 9991 QualType AllocatorType = 9992 VD->getType().getNonLValueExprType(S.getASTContext()); 9993 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 9994 if (!Res.isUsable()) { 9995 ErrorFound = true; 9996 break; 9997 } 9998 if (OMPAllocatorHandleT.isNull()) 9999 OMPAllocatorHandleT = AllocatorType; 10000 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10001 ErrorFound = true; 10002 break; 10003 } 10004 Stack->setAllocator(AllocatorKind, Res.get()); 10005 } 10006 if (ErrorFound) { 10007 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10008 return false; 10009 } 10010 OMPAllocatorHandleT.addConst(); 10011 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10012 return true; 10013 } 10014 10015 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10016 SourceLocation LParenLoc, 10017 SourceLocation EndLoc) { 10018 // OpenMP [2.11.3, allocate Directive, Description] 10019 // allocator is an expression of omp_allocator_handle_t type. 10020 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10021 return nullptr; 10022 10023 ExprResult Allocator = DefaultLvalueConversion(A); 10024 if (Allocator.isInvalid()) 10025 return nullptr; 10026 Allocator = PerformImplicitConversion(Allocator.get(), 10027 DSAStack->getOMPAllocatorHandleT(), 10028 Sema::AA_Initializing, 10029 /*AllowExplicit=*/true); 10030 if (Allocator.isInvalid()) 10031 return nullptr; 10032 return new (Context) 10033 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10034 } 10035 10036 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10037 SourceLocation StartLoc, 10038 SourceLocation LParenLoc, 10039 SourceLocation EndLoc) { 10040 // OpenMP [2.7.1, loop construct, Description] 10041 // OpenMP [2.8.1, simd construct, Description] 10042 // OpenMP [2.9.6, distribute construct, Description] 10043 // The parameter of the collapse clause must be a constant 10044 // positive integer expression. 10045 ExprResult NumForLoopsResult = 10046 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10047 if (NumForLoopsResult.isInvalid()) 10048 return nullptr; 10049 return new (Context) 10050 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10051 } 10052 10053 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10054 SourceLocation EndLoc, 10055 SourceLocation LParenLoc, 10056 Expr *NumForLoops) { 10057 // OpenMP [2.7.1, loop construct, Description] 10058 // OpenMP [2.8.1, simd construct, Description] 10059 // OpenMP [2.9.6, distribute construct, Description] 10060 // The parameter of the ordered clause must be a constant 10061 // positive integer expression if any. 10062 if (NumForLoops && LParenLoc.isValid()) { 10063 ExprResult NumForLoopsResult = 10064 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10065 if (NumForLoopsResult.isInvalid()) 10066 return nullptr; 10067 NumForLoops = NumForLoopsResult.get(); 10068 } else { 10069 NumForLoops = nullptr; 10070 } 10071 auto *Clause = OMPOrderedClause::Create( 10072 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10073 StartLoc, LParenLoc, EndLoc); 10074 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10075 return Clause; 10076 } 10077 10078 OMPClause *Sema::ActOnOpenMPSimpleClause( 10079 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10080 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10081 OMPClause *Res = nullptr; 10082 switch (Kind) { 10083 case OMPC_default: 10084 Res = 10085 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10086 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10087 break; 10088 case OMPC_proc_bind: 10089 Res = ActOnOpenMPProcBindClause( 10090 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10091 LParenLoc, EndLoc); 10092 break; 10093 case OMPC_atomic_default_mem_order: 10094 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10095 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10096 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10097 break; 10098 case OMPC_if: 10099 case OMPC_final: 10100 case OMPC_num_threads: 10101 case OMPC_safelen: 10102 case OMPC_simdlen: 10103 case OMPC_allocator: 10104 case OMPC_collapse: 10105 case OMPC_schedule: 10106 case OMPC_private: 10107 case OMPC_firstprivate: 10108 case OMPC_lastprivate: 10109 case OMPC_shared: 10110 case OMPC_reduction: 10111 case OMPC_task_reduction: 10112 case OMPC_in_reduction: 10113 case OMPC_linear: 10114 case OMPC_aligned: 10115 case OMPC_copyin: 10116 case OMPC_copyprivate: 10117 case OMPC_ordered: 10118 case OMPC_nowait: 10119 case OMPC_untied: 10120 case OMPC_mergeable: 10121 case OMPC_threadprivate: 10122 case OMPC_allocate: 10123 case OMPC_flush: 10124 case OMPC_read: 10125 case OMPC_write: 10126 case OMPC_update: 10127 case OMPC_capture: 10128 case OMPC_seq_cst: 10129 case OMPC_depend: 10130 case OMPC_device: 10131 case OMPC_threads: 10132 case OMPC_simd: 10133 case OMPC_map: 10134 case OMPC_num_teams: 10135 case OMPC_thread_limit: 10136 case OMPC_priority: 10137 case OMPC_grainsize: 10138 case OMPC_nogroup: 10139 case OMPC_num_tasks: 10140 case OMPC_hint: 10141 case OMPC_dist_schedule: 10142 case OMPC_defaultmap: 10143 case OMPC_unknown: 10144 case OMPC_uniform: 10145 case OMPC_to: 10146 case OMPC_from: 10147 case OMPC_use_device_ptr: 10148 case OMPC_is_device_ptr: 10149 case OMPC_unified_address: 10150 case OMPC_unified_shared_memory: 10151 case OMPC_reverse_offload: 10152 case OMPC_dynamic_allocators: 10153 llvm_unreachable("Clause is not allowed."); 10154 } 10155 return Res; 10156 } 10157 10158 static std::string 10159 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10160 ArrayRef<unsigned> Exclude = llvm::None) { 10161 SmallString<256> Buffer; 10162 llvm::raw_svector_ostream Out(Buffer); 10163 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10164 unsigned Skipped = Exclude.size(); 10165 auto S = Exclude.begin(), E = Exclude.end(); 10166 for (unsigned I = First; I < Last; ++I) { 10167 if (std::find(S, E, I) != E) { 10168 --Skipped; 10169 continue; 10170 } 10171 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10172 if (I == Bound - Skipped) 10173 Out << " or "; 10174 else if (I != Bound + 1 - Skipped) 10175 Out << ", "; 10176 } 10177 return Out.str(); 10178 } 10179 10180 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10181 SourceLocation KindKwLoc, 10182 SourceLocation StartLoc, 10183 SourceLocation LParenLoc, 10184 SourceLocation EndLoc) { 10185 if (Kind == OMPC_DEFAULT_unknown) { 10186 static_assert(OMPC_DEFAULT_unknown > 0, 10187 "OMPC_DEFAULT_unknown not greater than 0"); 10188 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10189 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10190 /*Last=*/OMPC_DEFAULT_unknown) 10191 << getOpenMPClauseName(OMPC_default); 10192 return nullptr; 10193 } 10194 switch (Kind) { 10195 case OMPC_DEFAULT_none: 10196 DSAStack->setDefaultDSANone(KindKwLoc); 10197 break; 10198 case OMPC_DEFAULT_shared: 10199 DSAStack->setDefaultDSAShared(KindKwLoc); 10200 break; 10201 case OMPC_DEFAULT_unknown: 10202 llvm_unreachable("Clause kind is not allowed."); 10203 break; 10204 } 10205 return new (Context) 10206 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10207 } 10208 10209 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10210 SourceLocation KindKwLoc, 10211 SourceLocation StartLoc, 10212 SourceLocation LParenLoc, 10213 SourceLocation EndLoc) { 10214 if (Kind == OMPC_PROC_BIND_unknown) { 10215 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10216 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10217 /*Last=*/OMPC_PROC_BIND_unknown) 10218 << getOpenMPClauseName(OMPC_proc_bind); 10219 return nullptr; 10220 } 10221 return new (Context) 10222 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10223 } 10224 10225 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10226 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10227 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10228 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10229 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10230 << getListOfPossibleValues( 10231 OMPC_atomic_default_mem_order, /*First=*/0, 10232 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10233 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10234 return nullptr; 10235 } 10236 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10237 LParenLoc, EndLoc); 10238 } 10239 10240 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10241 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10242 SourceLocation StartLoc, SourceLocation LParenLoc, 10243 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10244 SourceLocation EndLoc) { 10245 OMPClause *Res = nullptr; 10246 switch (Kind) { 10247 case OMPC_schedule: 10248 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10249 assert(Argument.size() == NumberOfElements && 10250 ArgumentLoc.size() == NumberOfElements); 10251 Res = ActOnOpenMPScheduleClause( 10252 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10253 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10254 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10255 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10256 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10257 break; 10258 case OMPC_if: 10259 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10260 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10261 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10262 DelimLoc, EndLoc); 10263 break; 10264 case OMPC_dist_schedule: 10265 Res = ActOnOpenMPDistScheduleClause( 10266 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10267 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10268 break; 10269 case OMPC_defaultmap: 10270 enum { Modifier, DefaultmapKind }; 10271 Res = ActOnOpenMPDefaultmapClause( 10272 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10273 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10274 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10275 EndLoc); 10276 break; 10277 case OMPC_final: 10278 case OMPC_num_threads: 10279 case OMPC_safelen: 10280 case OMPC_simdlen: 10281 case OMPC_allocator: 10282 case OMPC_collapse: 10283 case OMPC_default: 10284 case OMPC_proc_bind: 10285 case OMPC_private: 10286 case OMPC_firstprivate: 10287 case OMPC_lastprivate: 10288 case OMPC_shared: 10289 case OMPC_reduction: 10290 case OMPC_task_reduction: 10291 case OMPC_in_reduction: 10292 case OMPC_linear: 10293 case OMPC_aligned: 10294 case OMPC_copyin: 10295 case OMPC_copyprivate: 10296 case OMPC_ordered: 10297 case OMPC_nowait: 10298 case OMPC_untied: 10299 case OMPC_mergeable: 10300 case OMPC_threadprivate: 10301 case OMPC_allocate: 10302 case OMPC_flush: 10303 case OMPC_read: 10304 case OMPC_write: 10305 case OMPC_update: 10306 case OMPC_capture: 10307 case OMPC_seq_cst: 10308 case OMPC_depend: 10309 case OMPC_device: 10310 case OMPC_threads: 10311 case OMPC_simd: 10312 case OMPC_map: 10313 case OMPC_num_teams: 10314 case OMPC_thread_limit: 10315 case OMPC_priority: 10316 case OMPC_grainsize: 10317 case OMPC_nogroup: 10318 case OMPC_num_tasks: 10319 case OMPC_hint: 10320 case OMPC_unknown: 10321 case OMPC_uniform: 10322 case OMPC_to: 10323 case OMPC_from: 10324 case OMPC_use_device_ptr: 10325 case OMPC_is_device_ptr: 10326 case OMPC_unified_address: 10327 case OMPC_unified_shared_memory: 10328 case OMPC_reverse_offload: 10329 case OMPC_dynamic_allocators: 10330 case OMPC_atomic_default_mem_order: 10331 llvm_unreachable("Clause is not allowed."); 10332 } 10333 return Res; 10334 } 10335 10336 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10337 OpenMPScheduleClauseModifier M2, 10338 SourceLocation M1Loc, SourceLocation M2Loc) { 10339 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10340 SmallVector<unsigned, 2> Excluded; 10341 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10342 Excluded.push_back(M2); 10343 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10344 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10345 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10346 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10347 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10348 << getListOfPossibleValues(OMPC_schedule, 10349 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10350 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10351 Excluded) 10352 << getOpenMPClauseName(OMPC_schedule); 10353 return true; 10354 } 10355 return false; 10356 } 10357 10358 OMPClause *Sema::ActOnOpenMPScheduleClause( 10359 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10360 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10361 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10362 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10363 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10364 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10365 return nullptr; 10366 // OpenMP, 2.7.1, Loop Construct, Restrictions 10367 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10368 // but not both. 10369 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10370 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10371 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10372 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10373 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10374 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10375 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10376 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10377 return nullptr; 10378 } 10379 if (Kind == OMPC_SCHEDULE_unknown) { 10380 std::string Values; 10381 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10382 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10383 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10384 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10385 Exclude); 10386 } else { 10387 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10388 /*Last=*/OMPC_SCHEDULE_unknown); 10389 } 10390 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10391 << Values << getOpenMPClauseName(OMPC_schedule); 10392 return nullptr; 10393 } 10394 // OpenMP, 2.7.1, Loop Construct, Restrictions 10395 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 10396 // schedule(guided). 10397 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 10398 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 10399 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 10400 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 10401 diag::err_omp_schedule_nonmonotonic_static); 10402 return nullptr; 10403 } 10404 Expr *ValExpr = ChunkSize; 10405 Stmt *HelperValStmt = nullptr; 10406 if (ChunkSize) { 10407 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10408 !ChunkSize->isInstantiationDependent() && 10409 !ChunkSize->containsUnexpandedParameterPack()) { 10410 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 10411 ExprResult Val = 10412 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10413 if (Val.isInvalid()) 10414 return nullptr; 10415 10416 ValExpr = Val.get(); 10417 10418 // OpenMP [2.7.1, Restrictions] 10419 // chunk_size must be a loop invariant integer expression with a positive 10420 // value. 10421 llvm::APSInt Result; 10422 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10423 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10424 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10425 << "schedule" << 1 << ChunkSize->getSourceRange(); 10426 return nullptr; 10427 } 10428 } else if (getOpenMPCaptureRegionForClause( 10429 DSAStack->getCurrentDirective(), OMPC_schedule) != 10430 OMPD_unknown && 10431 !CurContext->isDependentContext()) { 10432 ValExpr = MakeFullExpr(ValExpr).get(); 10433 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10434 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10435 HelperValStmt = buildPreInits(Context, Captures); 10436 } 10437 } 10438 } 10439 10440 return new (Context) 10441 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 10442 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 10443 } 10444 10445 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 10446 SourceLocation StartLoc, 10447 SourceLocation EndLoc) { 10448 OMPClause *Res = nullptr; 10449 switch (Kind) { 10450 case OMPC_ordered: 10451 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 10452 break; 10453 case OMPC_nowait: 10454 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 10455 break; 10456 case OMPC_untied: 10457 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 10458 break; 10459 case OMPC_mergeable: 10460 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 10461 break; 10462 case OMPC_read: 10463 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 10464 break; 10465 case OMPC_write: 10466 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 10467 break; 10468 case OMPC_update: 10469 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 10470 break; 10471 case OMPC_capture: 10472 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 10473 break; 10474 case OMPC_seq_cst: 10475 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 10476 break; 10477 case OMPC_threads: 10478 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 10479 break; 10480 case OMPC_simd: 10481 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 10482 break; 10483 case OMPC_nogroup: 10484 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 10485 break; 10486 case OMPC_unified_address: 10487 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 10488 break; 10489 case OMPC_unified_shared_memory: 10490 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10491 break; 10492 case OMPC_reverse_offload: 10493 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 10494 break; 10495 case OMPC_dynamic_allocators: 10496 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 10497 break; 10498 case OMPC_if: 10499 case OMPC_final: 10500 case OMPC_num_threads: 10501 case OMPC_safelen: 10502 case OMPC_simdlen: 10503 case OMPC_allocator: 10504 case OMPC_collapse: 10505 case OMPC_schedule: 10506 case OMPC_private: 10507 case OMPC_firstprivate: 10508 case OMPC_lastprivate: 10509 case OMPC_shared: 10510 case OMPC_reduction: 10511 case OMPC_task_reduction: 10512 case OMPC_in_reduction: 10513 case OMPC_linear: 10514 case OMPC_aligned: 10515 case OMPC_copyin: 10516 case OMPC_copyprivate: 10517 case OMPC_default: 10518 case OMPC_proc_bind: 10519 case OMPC_threadprivate: 10520 case OMPC_allocate: 10521 case OMPC_flush: 10522 case OMPC_depend: 10523 case OMPC_device: 10524 case OMPC_map: 10525 case OMPC_num_teams: 10526 case OMPC_thread_limit: 10527 case OMPC_priority: 10528 case OMPC_grainsize: 10529 case OMPC_num_tasks: 10530 case OMPC_hint: 10531 case OMPC_dist_schedule: 10532 case OMPC_defaultmap: 10533 case OMPC_unknown: 10534 case OMPC_uniform: 10535 case OMPC_to: 10536 case OMPC_from: 10537 case OMPC_use_device_ptr: 10538 case OMPC_is_device_ptr: 10539 case OMPC_atomic_default_mem_order: 10540 llvm_unreachable("Clause is not allowed."); 10541 } 10542 return Res; 10543 } 10544 10545 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 10546 SourceLocation EndLoc) { 10547 DSAStack->setNowaitRegion(); 10548 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 10549 } 10550 10551 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 10552 SourceLocation EndLoc) { 10553 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 10554 } 10555 10556 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 10557 SourceLocation EndLoc) { 10558 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10559 } 10560 10561 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10562 SourceLocation EndLoc) { 10563 return new (Context) OMPReadClause(StartLoc, EndLoc); 10564 } 10565 10566 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10567 SourceLocation EndLoc) { 10568 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10569 } 10570 10571 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10572 SourceLocation EndLoc) { 10573 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10574 } 10575 10576 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10577 SourceLocation EndLoc) { 10578 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10579 } 10580 10581 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10582 SourceLocation EndLoc) { 10583 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10584 } 10585 10586 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10587 SourceLocation EndLoc) { 10588 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10589 } 10590 10591 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 10592 SourceLocation EndLoc) { 10593 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 10594 } 10595 10596 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 10597 SourceLocation EndLoc) { 10598 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 10599 } 10600 10601 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 10602 SourceLocation EndLoc) { 10603 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 10604 } 10605 10606 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 10607 SourceLocation EndLoc) { 10608 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10609 } 10610 10611 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 10612 SourceLocation EndLoc) { 10613 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 10614 } 10615 10616 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 10617 SourceLocation EndLoc) { 10618 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 10619 } 10620 10621 OMPClause *Sema::ActOnOpenMPVarListClause( 10622 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 10623 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 10624 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 10625 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 10626 OpenMPLinearClauseKind LinKind, 10627 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 10628 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 10629 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 10630 SourceLocation StartLoc = Locs.StartLoc; 10631 SourceLocation LParenLoc = Locs.LParenLoc; 10632 SourceLocation EndLoc = Locs.EndLoc; 10633 OMPClause *Res = nullptr; 10634 switch (Kind) { 10635 case OMPC_private: 10636 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10637 break; 10638 case OMPC_firstprivate: 10639 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10640 break; 10641 case OMPC_lastprivate: 10642 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10643 break; 10644 case OMPC_shared: 10645 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 10646 break; 10647 case OMPC_reduction: 10648 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10649 EndLoc, ReductionOrMapperIdScopeSpec, 10650 ReductionOrMapperId); 10651 break; 10652 case OMPC_task_reduction: 10653 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10654 EndLoc, ReductionOrMapperIdScopeSpec, 10655 ReductionOrMapperId); 10656 break; 10657 case OMPC_in_reduction: 10658 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10659 EndLoc, ReductionOrMapperIdScopeSpec, 10660 ReductionOrMapperId); 10661 break; 10662 case OMPC_linear: 10663 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 10664 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 10665 break; 10666 case OMPC_aligned: 10667 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 10668 ColonLoc, EndLoc); 10669 break; 10670 case OMPC_copyin: 10671 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 10672 break; 10673 case OMPC_copyprivate: 10674 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10675 break; 10676 case OMPC_flush: 10677 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 10678 break; 10679 case OMPC_depend: 10680 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 10681 StartLoc, LParenLoc, EndLoc); 10682 break; 10683 case OMPC_map: 10684 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 10685 ReductionOrMapperIdScopeSpec, 10686 ReductionOrMapperId, MapType, IsMapTypeImplicit, 10687 DepLinMapLoc, ColonLoc, VarList, Locs); 10688 break; 10689 case OMPC_to: 10690 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 10691 ReductionOrMapperId, Locs); 10692 break; 10693 case OMPC_from: 10694 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 10695 ReductionOrMapperId, Locs); 10696 break; 10697 case OMPC_use_device_ptr: 10698 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 10699 break; 10700 case OMPC_is_device_ptr: 10701 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 10702 break; 10703 case OMPC_allocate: 10704 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 10705 ColonLoc, EndLoc); 10706 break; 10707 case OMPC_if: 10708 case OMPC_final: 10709 case OMPC_num_threads: 10710 case OMPC_safelen: 10711 case OMPC_simdlen: 10712 case OMPC_allocator: 10713 case OMPC_collapse: 10714 case OMPC_default: 10715 case OMPC_proc_bind: 10716 case OMPC_schedule: 10717 case OMPC_ordered: 10718 case OMPC_nowait: 10719 case OMPC_untied: 10720 case OMPC_mergeable: 10721 case OMPC_threadprivate: 10722 case OMPC_read: 10723 case OMPC_write: 10724 case OMPC_update: 10725 case OMPC_capture: 10726 case OMPC_seq_cst: 10727 case OMPC_device: 10728 case OMPC_threads: 10729 case OMPC_simd: 10730 case OMPC_num_teams: 10731 case OMPC_thread_limit: 10732 case OMPC_priority: 10733 case OMPC_grainsize: 10734 case OMPC_nogroup: 10735 case OMPC_num_tasks: 10736 case OMPC_hint: 10737 case OMPC_dist_schedule: 10738 case OMPC_defaultmap: 10739 case OMPC_unknown: 10740 case OMPC_uniform: 10741 case OMPC_unified_address: 10742 case OMPC_unified_shared_memory: 10743 case OMPC_reverse_offload: 10744 case OMPC_dynamic_allocators: 10745 case OMPC_atomic_default_mem_order: 10746 llvm_unreachable("Clause is not allowed."); 10747 } 10748 return Res; 10749 } 10750 10751 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10752 ExprObjectKind OK, SourceLocation Loc) { 10753 ExprResult Res = BuildDeclRefExpr( 10754 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10755 if (!Res.isUsable()) 10756 return ExprError(); 10757 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10758 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10759 if (!Res.isUsable()) 10760 return ExprError(); 10761 } 10762 if (VK != VK_LValue && Res.get()->isGLValue()) { 10763 Res = DefaultLvalueConversion(Res.get()); 10764 if (!Res.isUsable()) 10765 return ExprError(); 10766 } 10767 return Res; 10768 } 10769 10770 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10771 SourceLocation StartLoc, 10772 SourceLocation LParenLoc, 10773 SourceLocation EndLoc) { 10774 SmallVector<Expr *, 8> Vars; 10775 SmallVector<Expr *, 8> PrivateCopies; 10776 for (Expr *RefExpr : VarList) { 10777 assert(RefExpr && "NULL expr in OpenMP private clause."); 10778 SourceLocation ELoc; 10779 SourceRange ERange; 10780 Expr *SimpleRefExpr = RefExpr; 10781 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10782 if (Res.second) { 10783 // It will be analyzed later. 10784 Vars.push_back(RefExpr); 10785 PrivateCopies.push_back(nullptr); 10786 } 10787 ValueDecl *D = Res.first; 10788 if (!D) 10789 continue; 10790 10791 QualType Type = D->getType(); 10792 auto *VD = dyn_cast<VarDecl>(D); 10793 10794 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10795 // A variable that appears in a private clause must not have an incomplete 10796 // type or a reference type. 10797 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10798 continue; 10799 Type = Type.getNonReferenceType(); 10800 10801 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10802 // A variable that is privatized must not have a const-qualified type 10803 // unless it is of class type with a mutable member. This restriction does 10804 // not apply to the firstprivate clause. 10805 // 10806 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10807 // A variable that appears in a private clause must not have a 10808 // const-qualified type unless it is of class type with a mutable member. 10809 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10810 continue; 10811 10812 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10813 // in a Construct] 10814 // Variables with the predetermined data-sharing attributes may not be 10815 // listed in data-sharing attributes clauses, except for the cases 10816 // listed below. For these exceptions only, listing a predetermined 10817 // variable in a data-sharing attribute clause is allowed and overrides 10818 // the variable's predetermined data-sharing attributes. 10819 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10820 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10821 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10822 << getOpenMPClauseName(OMPC_private); 10823 reportOriginalDsa(*this, DSAStack, D, DVar); 10824 continue; 10825 } 10826 10827 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10828 // Variably modified types are not supported for tasks. 10829 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10830 isOpenMPTaskingDirective(CurrDir)) { 10831 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10832 << getOpenMPClauseName(OMPC_private) << Type 10833 << getOpenMPDirectiveName(CurrDir); 10834 bool IsDecl = 10835 !VD || 10836 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10837 Diag(D->getLocation(), 10838 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10839 << D; 10840 continue; 10841 } 10842 10843 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10844 // A list item cannot appear in both a map clause and a data-sharing 10845 // attribute clause on the same construct 10846 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10847 OpenMPClauseKind ConflictKind; 10848 if (DSAStack->checkMappableExprComponentListsForDecl( 10849 VD, /*CurrentRegionOnly=*/true, 10850 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10851 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10852 ConflictKind = WhereFoundClauseKind; 10853 return true; 10854 })) { 10855 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10856 << getOpenMPClauseName(OMPC_private) 10857 << getOpenMPClauseName(ConflictKind) 10858 << getOpenMPDirectiveName(CurrDir); 10859 reportOriginalDsa(*this, DSAStack, D, DVar); 10860 continue; 10861 } 10862 } 10863 10864 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10865 // A variable of class type (or array thereof) that appears in a private 10866 // clause requires an accessible, unambiguous default constructor for the 10867 // class type. 10868 // Generate helper private variable and initialize it with the default 10869 // value. The address of the original variable is replaced by the address of 10870 // the new private variable in CodeGen. This new variable is not added to 10871 // IdResolver, so the code in the OpenMP region uses original variable for 10872 // proper diagnostics. 10873 Type = Type.getUnqualifiedType(); 10874 VarDecl *VDPrivate = 10875 buildVarDecl(*this, ELoc, Type, D->getName(), 10876 D->hasAttrs() ? &D->getAttrs() : nullptr, 10877 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10878 ActOnUninitializedDecl(VDPrivate); 10879 if (VDPrivate->isInvalidDecl()) 10880 continue; 10881 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10882 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10883 10884 DeclRefExpr *Ref = nullptr; 10885 if (!VD && !CurContext->isDependentContext()) 10886 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10887 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10888 Vars.push_back((VD || CurContext->isDependentContext()) 10889 ? RefExpr->IgnoreParens() 10890 : Ref); 10891 PrivateCopies.push_back(VDPrivateRefExpr); 10892 } 10893 10894 if (Vars.empty()) 10895 return nullptr; 10896 10897 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10898 PrivateCopies); 10899 } 10900 10901 namespace { 10902 class DiagsUninitializedSeveretyRAII { 10903 private: 10904 DiagnosticsEngine &Diags; 10905 SourceLocation SavedLoc; 10906 bool IsIgnored = false; 10907 10908 public: 10909 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10910 bool IsIgnored) 10911 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10912 if (!IsIgnored) { 10913 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10914 /*Map*/ diag::Severity::Ignored, Loc); 10915 } 10916 } 10917 ~DiagsUninitializedSeveretyRAII() { 10918 if (!IsIgnored) 10919 Diags.popMappings(SavedLoc); 10920 } 10921 }; 10922 } 10923 10924 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10925 SourceLocation StartLoc, 10926 SourceLocation LParenLoc, 10927 SourceLocation EndLoc) { 10928 SmallVector<Expr *, 8> Vars; 10929 SmallVector<Expr *, 8> PrivateCopies; 10930 SmallVector<Expr *, 8> Inits; 10931 SmallVector<Decl *, 4> ExprCaptures; 10932 bool IsImplicitClause = 10933 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10934 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10935 10936 for (Expr *RefExpr : VarList) { 10937 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10938 SourceLocation ELoc; 10939 SourceRange ERange; 10940 Expr *SimpleRefExpr = RefExpr; 10941 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10942 if (Res.second) { 10943 // It will be analyzed later. 10944 Vars.push_back(RefExpr); 10945 PrivateCopies.push_back(nullptr); 10946 Inits.push_back(nullptr); 10947 } 10948 ValueDecl *D = Res.first; 10949 if (!D) 10950 continue; 10951 10952 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 10953 QualType Type = D->getType(); 10954 auto *VD = dyn_cast<VarDecl>(D); 10955 10956 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10957 // A variable that appears in a private clause must not have an incomplete 10958 // type or a reference type. 10959 if (RequireCompleteType(ELoc, Type, 10960 diag::err_omp_firstprivate_incomplete_type)) 10961 continue; 10962 Type = Type.getNonReferenceType(); 10963 10964 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10965 // A variable of class type (or array thereof) that appears in a private 10966 // clause requires an accessible, unambiguous copy constructor for the 10967 // class type. 10968 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10969 10970 // If an implicit firstprivate variable found it was checked already. 10971 DSAStackTy::DSAVarData TopDVar; 10972 if (!IsImplicitClause) { 10973 DSAStackTy::DSAVarData DVar = 10974 DSAStack->getTopDSA(D, /*FromParent=*/false); 10975 TopDVar = DVar; 10976 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10977 bool IsConstant = ElemType.isConstant(Context); 10978 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10979 // A list item that specifies a given variable may not appear in more 10980 // than one clause on the same directive, except that a variable may be 10981 // specified in both firstprivate and lastprivate clauses. 10982 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10983 // A list item may appear in a firstprivate or lastprivate clause but not 10984 // both. 10985 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10986 (isOpenMPDistributeDirective(CurrDir) || 10987 DVar.CKind != OMPC_lastprivate) && 10988 DVar.RefExpr) { 10989 Diag(ELoc, diag::err_omp_wrong_dsa) 10990 << getOpenMPClauseName(DVar.CKind) 10991 << getOpenMPClauseName(OMPC_firstprivate); 10992 reportOriginalDsa(*this, DSAStack, D, DVar); 10993 continue; 10994 } 10995 10996 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10997 // in a Construct] 10998 // Variables with the predetermined data-sharing attributes may not be 10999 // listed in data-sharing attributes clauses, except for the cases 11000 // listed below. For these exceptions only, listing a predetermined 11001 // variable in a data-sharing attribute clause is allowed and overrides 11002 // the variable's predetermined data-sharing attributes. 11003 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11004 // in a Construct, C/C++, p.2] 11005 // Variables with const-qualified type having no mutable member may be 11006 // listed in a firstprivate clause, even if they are static data members. 11007 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11008 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11009 Diag(ELoc, diag::err_omp_wrong_dsa) 11010 << getOpenMPClauseName(DVar.CKind) 11011 << getOpenMPClauseName(OMPC_firstprivate); 11012 reportOriginalDsa(*this, DSAStack, D, DVar); 11013 continue; 11014 } 11015 11016 // OpenMP [2.9.3.4, Restrictions, p.2] 11017 // A list item that is private within a parallel region must not appear 11018 // in a firstprivate clause on a worksharing construct if any of the 11019 // worksharing regions arising from the worksharing construct ever bind 11020 // to any of the parallel regions arising from the parallel construct. 11021 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11022 // A list item that is private within a teams region must not appear in a 11023 // firstprivate clause on a distribute construct if any of the distribute 11024 // regions arising from the distribute construct ever bind to any of the 11025 // teams regions arising from the teams construct. 11026 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11027 // A list item that appears in a reduction clause of a teams construct 11028 // must not appear in a firstprivate clause on a distribute construct if 11029 // any of the distribute regions arising from the distribute construct 11030 // ever bind to any of the teams regions arising from the teams construct. 11031 if ((isOpenMPWorksharingDirective(CurrDir) || 11032 isOpenMPDistributeDirective(CurrDir)) && 11033 !isOpenMPParallelDirective(CurrDir) && 11034 !isOpenMPTeamsDirective(CurrDir)) { 11035 DVar = DSAStack->getImplicitDSA(D, true); 11036 if (DVar.CKind != OMPC_shared && 11037 (isOpenMPParallelDirective(DVar.DKind) || 11038 isOpenMPTeamsDirective(DVar.DKind) || 11039 DVar.DKind == OMPD_unknown)) { 11040 Diag(ELoc, diag::err_omp_required_access) 11041 << getOpenMPClauseName(OMPC_firstprivate) 11042 << getOpenMPClauseName(OMPC_shared); 11043 reportOriginalDsa(*this, DSAStack, D, DVar); 11044 continue; 11045 } 11046 } 11047 // OpenMP [2.9.3.4, Restrictions, p.3] 11048 // A list item that appears in a reduction clause of a parallel construct 11049 // must not appear in a firstprivate clause on a worksharing or task 11050 // construct if any of the worksharing or task regions arising from the 11051 // worksharing or task construct ever bind to any of the parallel regions 11052 // arising from the parallel construct. 11053 // OpenMP [2.9.3.4, Restrictions, p.4] 11054 // A list item that appears in a reduction clause in worksharing 11055 // construct must not appear in a firstprivate clause in a task construct 11056 // encountered during execution of any of the worksharing regions arising 11057 // from the worksharing construct. 11058 if (isOpenMPTaskingDirective(CurrDir)) { 11059 DVar = DSAStack->hasInnermostDSA( 11060 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11061 [](OpenMPDirectiveKind K) { 11062 return isOpenMPParallelDirective(K) || 11063 isOpenMPWorksharingDirective(K) || 11064 isOpenMPTeamsDirective(K); 11065 }, 11066 /*FromParent=*/true); 11067 if (DVar.CKind == OMPC_reduction && 11068 (isOpenMPParallelDirective(DVar.DKind) || 11069 isOpenMPWorksharingDirective(DVar.DKind) || 11070 isOpenMPTeamsDirective(DVar.DKind))) { 11071 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11072 << getOpenMPDirectiveName(DVar.DKind); 11073 reportOriginalDsa(*this, DSAStack, D, DVar); 11074 continue; 11075 } 11076 } 11077 11078 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11079 // A list item cannot appear in both a map clause and a data-sharing 11080 // attribute clause on the same construct 11081 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11082 OpenMPClauseKind ConflictKind; 11083 if (DSAStack->checkMappableExprComponentListsForDecl( 11084 VD, /*CurrentRegionOnly=*/true, 11085 [&ConflictKind]( 11086 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11087 OpenMPClauseKind WhereFoundClauseKind) { 11088 ConflictKind = WhereFoundClauseKind; 11089 return true; 11090 })) { 11091 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11092 << getOpenMPClauseName(OMPC_firstprivate) 11093 << getOpenMPClauseName(ConflictKind) 11094 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11095 reportOriginalDsa(*this, DSAStack, D, DVar); 11096 continue; 11097 } 11098 } 11099 } 11100 11101 // Variably modified types are not supported for tasks. 11102 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11103 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11104 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11105 << getOpenMPClauseName(OMPC_firstprivate) << Type 11106 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11107 bool IsDecl = 11108 !VD || 11109 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11110 Diag(D->getLocation(), 11111 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11112 << D; 11113 continue; 11114 } 11115 11116 Type = Type.getUnqualifiedType(); 11117 VarDecl *VDPrivate = 11118 buildVarDecl(*this, ELoc, Type, D->getName(), 11119 D->hasAttrs() ? &D->getAttrs() : nullptr, 11120 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11121 // Generate helper private variable and initialize it with the value of the 11122 // original variable. The address of the original variable is replaced by 11123 // the address of the new private variable in the CodeGen. This new variable 11124 // is not added to IdResolver, so the code in the OpenMP region uses 11125 // original variable for proper diagnostics and variable capturing. 11126 Expr *VDInitRefExpr = nullptr; 11127 // For arrays generate initializer for single element and replace it by the 11128 // original array element in CodeGen. 11129 if (Type->isArrayType()) { 11130 VarDecl *VDInit = 11131 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11132 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11133 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11134 ElemType = ElemType.getUnqualifiedType(); 11135 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11136 ".firstprivate.temp"); 11137 InitializedEntity Entity = 11138 InitializedEntity::InitializeVariable(VDInitTemp); 11139 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11140 11141 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11142 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11143 if (Result.isInvalid()) 11144 VDPrivate->setInvalidDecl(); 11145 else 11146 VDPrivate->setInit(Result.getAs<Expr>()); 11147 // Remove temp variable declaration. 11148 Context.Deallocate(VDInitTemp); 11149 } else { 11150 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11151 ".firstprivate.temp"); 11152 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11153 RefExpr->getExprLoc()); 11154 AddInitializerToDecl(VDPrivate, 11155 DefaultLvalueConversion(VDInitRefExpr).get(), 11156 /*DirectInit=*/false); 11157 } 11158 if (VDPrivate->isInvalidDecl()) { 11159 if (IsImplicitClause) { 11160 Diag(RefExpr->getExprLoc(), 11161 diag::note_omp_task_predetermined_firstprivate_here); 11162 } 11163 continue; 11164 } 11165 CurContext->addDecl(VDPrivate); 11166 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11167 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11168 RefExpr->getExprLoc()); 11169 DeclRefExpr *Ref = nullptr; 11170 if (!VD && !CurContext->isDependentContext()) { 11171 if (TopDVar.CKind == OMPC_lastprivate) { 11172 Ref = TopDVar.PrivateCopy; 11173 } else { 11174 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11175 if (!isOpenMPCapturedDecl(D)) 11176 ExprCaptures.push_back(Ref->getDecl()); 11177 } 11178 } 11179 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11180 Vars.push_back((VD || CurContext->isDependentContext()) 11181 ? RefExpr->IgnoreParens() 11182 : Ref); 11183 PrivateCopies.push_back(VDPrivateRefExpr); 11184 Inits.push_back(VDInitRefExpr); 11185 } 11186 11187 if (Vars.empty()) 11188 return nullptr; 11189 11190 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11191 Vars, PrivateCopies, Inits, 11192 buildPreInits(Context, ExprCaptures)); 11193 } 11194 11195 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11196 SourceLocation StartLoc, 11197 SourceLocation LParenLoc, 11198 SourceLocation EndLoc) { 11199 SmallVector<Expr *, 8> Vars; 11200 SmallVector<Expr *, 8> SrcExprs; 11201 SmallVector<Expr *, 8> DstExprs; 11202 SmallVector<Expr *, 8> AssignmentOps; 11203 SmallVector<Decl *, 4> ExprCaptures; 11204 SmallVector<Expr *, 4> ExprPostUpdates; 11205 for (Expr *RefExpr : VarList) { 11206 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11207 SourceLocation ELoc; 11208 SourceRange ERange; 11209 Expr *SimpleRefExpr = RefExpr; 11210 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11211 if (Res.second) { 11212 // It will be analyzed later. 11213 Vars.push_back(RefExpr); 11214 SrcExprs.push_back(nullptr); 11215 DstExprs.push_back(nullptr); 11216 AssignmentOps.push_back(nullptr); 11217 } 11218 ValueDecl *D = Res.first; 11219 if (!D) 11220 continue; 11221 11222 QualType Type = D->getType(); 11223 auto *VD = dyn_cast<VarDecl>(D); 11224 11225 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11226 // A variable that appears in a lastprivate clause must not have an 11227 // incomplete type or a reference type. 11228 if (RequireCompleteType(ELoc, Type, 11229 diag::err_omp_lastprivate_incomplete_type)) 11230 continue; 11231 Type = Type.getNonReferenceType(); 11232 11233 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11234 // A variable that is privatized must not have a const-qualified type 11235 // unless it is of class type with a mutable member. This restriction does 11236 // not apply to the firstprivate clause. 11237 // 11238 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11239 // A variable that appears in a lastprivate clause must not have a 11240 // const-qualified type unless it is of class type with a mutable member. 11241 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11242 continue; 11243 11244 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11245 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11246 // in a Construct] 11247 // Variables with the predetermined data-sharing attributes may not be 11248 // listed in data-sharing attributes clauses, except for the cases 11249 // listed below. 11250 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11251 // A list item may appear in a firstprivate or lastprivate clause but not 11252 // both. 11253 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11254 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11255 (isOpenMPDistributeDirective(CurrDir) || 11256 DVar.CKind != OMPC_firstprivate) && 11257 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11258 Diag(ELoc, diag::err_omp_wrong_dsa) 11259 << getOpenMPClauseName(DVar.CKind) 11260 << getOpenMPClauseName(OMPC_lastprivate); 11261 reportOriginalDsa(*this, DSAStack, D, DVar); 11262 continue; 11263 } 11264 11265 // OpenMP [2.14.3.5, Restrictions, p.2] 11266 // A list item that is private within a parallel region, or that appears in 11267 // the reduction clause of a parallel construct, must not appear in a 11268 // lastprivate clause on a worksharing construct if any of the corresponding 11269 // worksharing regions ever binds to any of the corresponding parallel 11270 // regions. 11271 DSAStackTy::DSAVarData TopDVar = DVar; 11272 if (isOpenMPWorksharingDirective(CurrDir) && 11273 !isOpenMPParallelDirective(CurrDir) && 11274 !isOpenMPTeamsDirective(CurrDir)) { 11275 DVar = DSAStack->getImplicitDSA(D, true); 11276 if (DVar.CKind != OMPC_shared) { 11277 Diag(ELoc, diag::err_omp_required_access) 11278 << getOpenMPClauseName(OMPC_lastprivate) 11279 << getOpenMPClauseName(OMPC_shared); 11280 reportOriginalDsa(*this, DSAStack, D, DVar); 11281 continue; 11282 } 11283 } 11284 11285 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11286 // A variable of class type (or array thereof) that appears in a 11287 // lastprivate clause requires an accessible, unambiguous default 11288 // constructor for the class type, unless the list item is also specified 11289 // in a firstprivate clause. 11290 // A variable of class type (or array thereof) that appears in a 11291 // lastprivate clause requires an accessible, unambiguous copy assignment 11292 // operator for the class type. 11293 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11294 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11295 Type.getUnqualifiedType(), ".lastprivate.src", 11296 D->hasAttrs() ? &D->getAttrs() : nullptr); 11297 DeclRefExpr *PseudoSrcExpr = 11298 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11299 VarDecl *DstVD = 11300 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11301 D->hasAttrs() ? &D->getAttrs() : nullptr); 11302 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11303 // For arrays generate assignment operation for single element and replace 11304 // it by the original array element in CodeGen. 11305 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11306 PseudoDstExpr, PseudoSrcExpr); 11307 if (AssignmentOp.isInvalid()) 11308 continue; 11309 AssignmentOp = 11310 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11311 if (AssignmentOp.isInvalid()) 11312 continue; 11313 11314 DeclRefExpr *Ref = nullptr; 11315 if (!VD && !CurContext->isDependentContext()) { 11316 if (TopDVar.CKind == OMPC_firstprivate) { 11317 Ref = TopDVar.PrivateCopy; 11318 } else { 11319 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11320 if (!isOpenMPCapturedDecl(D)) 11321 ExprCaptures.push_back(Ref->getDecl()); 11322 } 11323 if (TopDVar.CKind == OMPC_firstprivate || 11324 (!isOpenMPCapturedDecl(D) && 11325 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11326 ExprResult RefRes = DefaultLvalueConversion(Ref); 11327 if (!RefRes.isUsable()) 11328 continue; 11329 ExprResult PostUpdateRes = 11330 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11331 RefRes.get()); 11332 if (!PostUpdateRes.isUsable()) 11333 continue; 11334 ExprPostUpdates.push_back( 11335 IgnoredValueConversions(PostUpdateRes.get()).get()); 11336 } 11337 } 11338 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11339 Vars.push_back((VD || CurContext->isDependentContext()) 11340 ? RefExpr->IgnoreParens() 11341 : Ref); 11342 SrcExprs.push_back(PseudoSrcExpr); 11343 DstExprs.push_back(PseudoDstExpr); 11344 AssignmentOps.push_back(AssignmentOp.get()); 11345 } 11346 11347 if (Vars.empty()) 11348 return nullptr; 11349 11350 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11351 Vars, SrcExprs, DstExprs, AssignmentOps, 11352 buildPreInits(Context, ExprCaptures), 11353 buildPostUpdate(*this, ExprPostUpdates)); 11354 } 11355 11356 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11357 SourceLocation StartLoc, 11358 SourceLocation LParenLoc, 11359 SourceLocation EndLoc) { 11360 SmallVector<Expr *, 8> Vars; 11361 for (Expr *RefExpr : VarList) { 11362 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11363 SourceLocation ELoc; 11364 SourceRange ERange; 11365 Expr *SimpleRefExpr = RefExpr; 11366 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11367 if (Res.second) { 11368 // It will be analyzed later. 11369 Vars.push_back(RefExpr); 11370 } 11371 ValueDecl *D = Res.first; 11372 if (!D) 11373 continue; 11374 11375 auto *VD = dyn_cast<VarDecl>(D); 11376 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11377 // in a Construct] 11378 // Variables with the predetermined data-sharing attributes may not be 11379 // listed in data-sharing attributes clauses, except for the cases 11380 // listed below. For these exceptions only, listing a predetermined 11381 // variable in a data-sharing attribute clause is allowed and overrides 11382 // the variable's predetermined data-sharing attributes. 11383 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11384 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 11385 DVar.RefExpr) { 11386 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11387 << getOpenMPClauseName(OMPC_shared); 11388 reportOriginalDsa(*this, DSAStack, D, DVar); 11389 continue; 11390 } 11391 11392 DeclRefExpr *Ref = nullptr; 11393 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 11394 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11395 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 11396 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 11397 ? RefExpr->IgnoreParens() 11398 : Ref); 11399 } 11400 11401 if (Vars.empty()) 11402 return nullptr; 11403 11404 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 11405 } 11406 11407 namespace { 11408 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 11409 DSAStackTy *Stack; 11410 11411 public: 11412 bool VisitDeclRefExpr(DeclRefExpr *E) { 11413 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 11414 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 11415 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 11416 return false; 11417 if (DVar.CKind != OMPC_unknown) 11418 return true; 11419 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 11420 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 11421 /*FromParent=*/true); 11422 return DVarPrivate.CKind != OMPC_unknown; 11423 } 11424 return false; 11425 } 11426 bool VisitStmt(Stmt *S) { 11427 for (Stmt *Child : S->children()) { 11428 if (Child && Visit(Child)) 11429 return true; 11430 } 11431 return false; 11432 } 11433 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 11434 }; 11435 } // namespace 11436 11437 namespace { 11438 // Transform MemberExpression for specified FieldDecl of current class to 11439 // DeclRefExpr to specified OMPCapturedExprDecl. 11440 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 11441 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 11442 ValueDecl *Field = nullptr; 11443 DeclRefExpr *CapturedExpr = nullptr; 11444 11445 public: 11446 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 11447 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 11448 11449 ExprResult TransformMemberExpr(MemberExpr *E) { 11450 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 11451 E->getMemberDecl() == Field) { 11452 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 11453 return CapturedExpr; 11454 } 11455 return BaseTransform::TransformMemberExpr(E); 11456 } 11457 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 11458 }; 11459 } // namespace 11460 11461 template <typename T, typename U> 11462 static T filterLookupForUDReductionAndMapper( 11463 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 11464 for (U &Set : Lookups) { 11465 for (auto *D : Set) { 11466 if (T Res = Gen(cast<ValueDecl>(D))) 11467 return Res; 11468 } 11469 } 11470 return T(); 11471 } 11472 11473 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 11474 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 11475 11476 for (auto RD : D->redecls()) { 11477 // Don't bother with extra checks if we already know this one isn't visible. 11478 if (RD == D) 11479 continue; 11480 11481 auto ND = cast<NamedDecl>(RD); 11482 if (LookupResult::isVisible(SemaRef, ND)) 11483 return ND; 11484 } 11485 11486 return nullptr; 11487 } 11488 11489 static void 11490 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 11491 SourceLocation Loc, QualType Ty, 11492 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 11493 // Find all of the associated namespaces and classes based on the 11494 // arguments we have. 11495 Sema::AssociatedNamespaceSet AssociatedNamespaces; 11496 Sema::AssociatedClassSet AssociatedClasses; 11497 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 11498 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 11499 AssociatedClasses); 11500 11501 // C++ [basic.lookup.argdep]p3: 11502 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11503 // and let Y be the lookup set produced by argument dependent 11504 // lookup (defined as follows). If X contains [...] then Y is 11505 // empty. Otherwise Y is the set of declarations found in the 11506 // namespaces associated with the argument types as described 11507 // below. The set of declarations found by the lookup of the name 11508 // is the union of X and Y. 11509 // 11510 // Here, we compute Y and add its members to the overloaded 11511 // candidate set. 11512 for (auto *NS : AssociatedNamespaces) { 11513 // When considering an associated namespace, the lookup is the 11514 // same as the lookup performed when the associated namespace is 11515 // used as a qualifier (3.4.3.2) except that: 11516 // 11517 // -- Any using-directives in the associated namespace are 11518 // ignored. 11519 // 11520 // -- Any namespace-scope friend functions declared in 11521 // associated classes are visible within their respective 11522 // namespaces even if they are not visible during an ordinary 11523 // lookup (11.4). 11524 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11525 for (auto *D : R) { 11526 auto *Underlying = D; 11527 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11528 Underlying = USD->getTargetDecl(); 11529 11530 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11531 !isa<OMPDeclareMapperDecl>(Underlying)) 11532 continue; 11533 11534 if (!SemaRef.isVisible(D)) { 11535 D = findAcceptableDecl(SemaRef, D); 11536 if (!D) 11537 continue; 11538 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11539 Underlying = USD->getTargetDecl(); 11540 } 11541 Lookups.emplace_back(); 11542 Lookups.back().addDecl(Underlying); 11543 } 11544 } 11545 } 11546 11547 static ExprResult 11548 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11549 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11550 const DeclarationNameInfo &ReductionId, QualType Ty, 11551 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11552 if (ReductionIdScopeSpec.isInvalid()) 11553 return ExprError(); 11554 SmallVector<UnresolvedSet<8>, 4> Lookups; 11555 if (S) { 11556 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11557 Lookup.suppressDiagnostics(); 11558 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11559 NamedDecl *D = Lookup.getRepresentativeDecl(); 11560 do { 11561 S = S->getParent(); 11562 } while (S && !S->isDeclScope(D)); 11563 if (S) 11564 S = S->getParent(); 11565 Lookups.emplace_back(); 11566 Lookups.back().append(Lookup.begin(), Lookup.end()); 11567 Lookup.clear(); 11568 } 11569 } else if (auto *ULE = 11570 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11571 Lookups.push_back(UnresolvedSet<8>()); 11572 Decl *PrevD = nullptr; 11573 for (NamedDecl *D : ULE->decls()) { 11574 if (D == PrevD) 11575 Lookups.push_back(UnresolvedSet<8>()); 11576 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11577 Lookups.back().addDecl(DRD); 11578 PrevD = D; 11579 } 11580 } 11581 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11582 Ty->isInstantiationDependentType() || 11583 Ty->containsUnexpandedParameterPack() || 11584 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11585 return !D->isInvalidDecl() && 11586 (D->getType()->isDependentType() || 11587 D->getType()->isInstantiationDependentType() || 11588 D->getType()->containsUnexpandedParameterPack()); 11589 })) { 11590 UnresolvedSet<8> ResSet; 11591 for (const UnresolvedSet<8> &Set : Lookups) { 11592 if (Set.empty()) 11593 continue; 11594 ResSet.append(Set.begin(), Set.end()); 11595 // The last item marks the end of all declarations at the specified scope. 11596 ResSet.addDecl(Set[Set.size() - 1]); 11597 } 11598 return UnresolvedLookupExpr::Create( 11599 SemaRef.Context, /*NamingClass=*/nullptr, 11600 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 11601 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 11602 } 11603 // Lookup inside the classes. 11604 // C++ [over.match.oper]p3: 11605 // For a unary operator @ with an operand of a type whose 11606 // cv-unqualified version is T1, and for a binary operator @ with 11607 // a left operand of a type whose cv-unqualified version is T1 and 11608 // a right operand of a type whose cv-unqualified version is T2, 11609 // three sets of candidate functions, designated member 11610 // candidates, non-member candidates and built-in candidates, are 11611 // constructed as follows: 11612 // -- If T1 is a complete class type or a class currently being 11613 // defined, the set of member candidates is the result of the 11614 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 11615 // the set of member candidates is empty. 11616 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11617 Lookup.suppressDiagnostics(); 11618 if (const auto *TyRec = Ty->getAs<RecordType>()) { 11619 // Complete the type if it can be completed. 11620 // If the type is neither complete nor being defined, bail out now. 11621 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 11622 TyRec->getDecl()->getDefinition()) { 11623 Lookup.clear(); 11624 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 11625 if (Lookup.empty()) { 11626 Lookups.emplace_back(); 11627 Lookups.back().append(Lookup.begin(), Lookup.end()); 11628 } 11629 } 11630 } 11631 // Perform ADL. 11632 if (SemaRef.getLangOpts().CPlusPlus) 11633 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 11634 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11635 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 11636 if (!D->isInvalidDecl() && 11637 SemaRef.Context.hasSameType(D->getType(), Ty)) 11638 return D; 11639 return nullptr; 11640 })) 11641 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 11642 VK_LValue, Loc); 11643 if (SemaRef.getLangOpts().CPlusPlus) { 11644 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11645 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 11646 if (!D->isInvalidDecl() && 11647 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 11648 !Ty.isMoreQualifiedThan(D->getType())) 11649 return D; 11650 return nullptr; 11651 })) { 11652 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 11653 /*DetectVirtual=*/false); 11654 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 11655 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 11656 VD->getType().getUnqualifiedType()))) { 11657 if (SemaRef.CheckBaseClassAccess( 11658 Loc, VD->getType(), Ty, Paths.front(), 11659 /*DiagID=*/0) != Sema::AR_inaccessible) { 11660 SemaRef.BuildBasePathArray(Paths, BasePath); 11661 return SemaRef.BuildDeclRefExpr( 11662 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 11663 } 11664 } 11665 } 11666 } 11667 } 11668 if (ReductionIdScopeSpec.isSet()) { 11669 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 11670 return ExprError(); 11671 } 11672 return ExprEmpty(); 11673 } 11674 11675 namespace { 11676 /// Data for the reduction-based clauses. 11677 struct ReductionData { 11678 /// List of original reduction items. 11679 SmallVector<Expr *, 8> Vars; 11680 /// List of private copies of the reduction items. 11681 SmallVector<Expr *, 8> Privates; 11682 /// LHS expressions for the reduction_op expressions. 11683 SmallVector<Expr *, 8> LHSs; 11684 /// RHS expressions for the reduction_op expressions. 11685 SmallVector<Expr *, 8> RHSs; 11686 /// Reduction operation expression. 11687 SmallVector<Expr *, 8> ReductionOps; 11688 /// Taskgroup descriptors for the corresponding reduction items in 11689 /// in_reduction clauses. 11690 SmallVector<Expr *, 8> TaskgroupDescriptors; 11691 /// List of captures for clause. 11692 SmallVector<Decl *, 4> ExprCaptures; 11693 /// List of postupdate expressions. 11694 SmallVector<Expr *, 4> ExprPostUpdates; 11695 ReductionData() = delete; 11696 /// Reserves required memory for the reduction data. 11697 ReductionData(unsigned Size) { 11698 Vars.reserve(Size); 11699 Privates.reserve(Size); 11700 LHSs.reserve(Size); 11701 RHSs.reserve(Size); 11702 ReductionOps.reserve(Size); 11703 TaskgroupDescriptors.reserve(Size); 11704 ExprCaptures.reserve(Size); 11705 ExprPostUpdates.reserve(Size); 11706 } 11707 /// Stores reduction item and reduction operation only (required for dependent 11708 /// reduction item). 11709 void push(Expr *Item, Expr *ReductionOp) { 11710 Vars.emplace_back(Item); 11711 Privates.emplace_back(nullptr); 11712 LHSs.emplace_back(nullptr); 11713 RHSs.emplace_back(nullptr); 11714 ReductionOps.emplace_back(ReductionOp); 11715 TaskgroupDescriptors.emplace_back(nullptr); 11716 } 11717 /// Stores reduction data. 11718 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11719 Expr *TaskgroupDescriptor) { 11720 Vars.emplace_back(Item); 11721 Privates.emplace_back(Private); 11722 LHSs.emplace_back(LHS); 11723 RHSs.emplace_back(RHS); 11724 ReductionOps.emplace_back(ReductionOp); 11725 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11726 } 11727 }; 11728 } // namespace 11729 11730 static bool checkOMPArraySectionConstantForReduction( 11731 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11732 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11733 const Expr *Length = OASE->getLength(); 11734 if (Length == nullptr) { 11735 // For array sections of the form [1:] or [:], we would need to analyze 11736 // the lower bound... 11737 if (OASE->getColonLoc().isValid()) 11738 return false; 11739 11740 // This is an array subscript which has implicit length 1! 11741 SingleElement = true; 11742 ArraySizes.push_back(llvm::APSInt::get(1)); 11743 } else { 11744 Expr::EvalResult Result; 11745 if (!Length->EvaluateAsInt(Result, Context)) 11746 return false; 11747 11748 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11749 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11750 ArraySizes.push_back(ConstantLengthValue); 11751 } 11752 11753 // Get the base of this array section and walk up from there. 11754 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11755 11756 // We require length = 1 for all array sections except the right-most to 11757 // guarantee that the memory region is contiguous and has no holes in it. 11758 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11759 Length = TempOASE->getLength(); 11760 if (Length == nullptr) { 11761 // For array sections of the form [1:] or [:], we would need to analyze 11762 // the lower bound... 11763 if (OASE->getColonLoc().isValid()) 11764 return false; 11765 11766 // This is an array subscript which has implicit length 1! 11767 ArraySizes.push_back(llvm::APSInt::get(1)); 11768 } else { 11769 Expr::EvalResult Result; 11770 if (!Length->EvaluateAsInt(Result, Context)) 11771 return false; 11772 11773 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11774 if (ConstantLengthValue.getSExtValue() != 1) 11775 return false; 11776 11777 ArraySizes.push_back(ConstantLengthValue); 11778 } 11779 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11780 } 11781 11782 // If we have a single element, we don't need to add the implicit lengths. 11783 if (!SingleElement) { 11784 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11785 // Has implicit length 1! 11786 ArraySizes.push_back(llvm::APSInt::get(1)); 11787 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11788 } 11789 } 11790 11791 // This array section can be privatized as a single value or as a constant 11792 // sized array. 11793 return true; 11794 } 11795 11796 static bool actOnOMPReductionKindClause( 11797 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11798 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11799 SourceLocation ColonLoc, SourceLocation EndLoc, 11800 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11801 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11802 DeclarationName DN = ReductionId.getName(); 11803 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11804 BinaryOperatorKind BOK = BO_Comma; 11805 11806 ASTContext &Context = S.Context; 11807 // OpenMP [2.14.3.6, reduction clause] 11808 // C 11809 // reduction-identifier is either an identifier or one of the following 11810 // operators: +, -, *, &, |, ^, && and || 11811 // C++ 11812 // reduction-identifier is either an id-expression or one of the following 11813 // operators: +, -, *, &, |, ^, && and || 11814 switch (OOK) { 11815 case OO_Plus: 11816 case OO_Minus: 11817 BOK = BO_Add; 11818 break; 11819 case OO_Star: 11820 BOK = BO_Mul; 11821 break; 11822 case OO_Amp: 11823 BOK = BO_And; 11824 break; 11825 case OO_Pipe: 11826 BOK = BO_Or; 11827 break; 11828 case OO_Caret: 11829 BOK = BO_Xor; 11830 break; 11831 case OO_AmpAmp: 11832 BOK = BO_LAnd; 11833 break; 11834 case OO_PipePipe: 11835 BOK = BO_LOr; 11836 break; 11837 case OO_New: 11838 case OO_Delete: 11839 case OO_Array_New: 11840 case OO_Array_Delete: 11841 case OO_Slash: 11842 case OO_Percent: 11843 case OO_Tilde: 11844 case OO_Exclaim: 11845 case OO_Equal: 11846 case OO_Less: 11847 case OO_Greater: 11848 case OO_LessEqual: 11849 case OO_GreaterEqual: 11850 case OO_PlusEqual: 11851 case OO_MinusEqual: 11852 case OO_StarEqual: 11853 case OO_SlashEqual: 11854 case OO_PercentEqual: 11855 case OO_CaretEqual: 11856 case OO_AmpEqual: 11857 case OO_PipeEqual: 11858 case OO_LessLess: 11859 case OO_GreaterGreater: 11860 case OO_LessLessEqual: 11861 case OO_GreaterGreaterEqual: 11862 case OO_EqualEqual: 11863 case OO_ExclaimEqual: 11864 case OO_Spaceship: 11865 case OO_PlusPlus: 11866 case OO_MinusMinus: 11867 case OO_Comma: 11868 case OO_ArrowStar: 11869 case OO_Arrow: 11870 case OO_Call: 11871 case OO_Subscript: 11872 case OO_Conditional: 11873 case OO_Coawait: 11874 case NUM_OVERLOADED_OPERATORS: 11875 llvm_unreachable("Unexpected reduction identifier"); 11876 case OO_None: 11877 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11878 if (II->isStr("max")) 11879 BOK = BO_GT; 11880 else if (II->isStr("min")) 11881 BOK = BO_LT; 11882 } 11883 break; 11884 } 11885 SourceRange ReductionIdRange; 11886 if (ReductionIdScopeSpec.isValid()) 11887 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11888 else 11889 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11890 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11891 11892 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11893 bool FirstIter = true; 11894 for (Expr *RefExpr : VarList) { 11895 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11896 // OpenMP [2.1, C/C++] 11897 // A list item is a variable or array section, subject to the restrictions 11898 // specified in Section 2.4 on page 42 and in each of the sections 11899 // describing clauses and directives for which a list appears. 11900 // OpenMP [2.14.3.3, Restrictions, p.1] 11901 // A variable that is part of another variable (as an array or 11902 // structure element) cannot appear in a private clause. 11903 if (!FirstIter && IR != ER) 11904 ++IR; 11905 FirstIter = false; 11906 SourceLocation ELoc; 11907 SourceRange ERange; 11908 Expr *SimpleRefExpr = RefExpr; 11909 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11910 /*AllowArraySection=*/true); 11911 if (Res.second) { 11912 // Try to find 'declare reduction' corresponding construct before using 11913 // builtin/overloaded operators. 11914 QualType Type = Context.DependentTy; 11915 CXXCastPath BasePath; 11916 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11917 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11918 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11919 Expr *ReductionOp = nullptr; 11920 if (S.CurContext->isDependentContext() && 11921 (DeclareReductionRef.isUnset() || 11922 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11923 ReductionOp = DeclareReductionRef.get(); 11924 // It will be analyzed later. 11925 RD.push(RefExpr, ReductionOp); 11926 } 11927 ValueDecl *D = Res.first; 11928 if (!D) 11929 continue; 11930 11931 Expr *TaskgroupDescriptor = nullptr; 11932 QualType Type; 11933 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11934 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11935 if (ASE) { 11936 Type = ASE->getType().getNonReferenceType(); 11937 } else if (OASE) { 11938 QualType BaseType = 11939 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11940 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11941 Type = ATy->getElementType(); 11942 else 11943 Type = BaseType->getPointeeType(); 11944 Type = Type.getNonReferenceType(); 11945 } else { 11946 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11947 } 11948 auto *VD = dyn_cast<VarDecl>(D); 11949 11950 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11951 // A variable that appears in a private clause must not have an incomplete 11952 // type or a reference type. 11953 if (S.RequireCompleteType(ELoc, D->getType(), 11954 diag::err_omp_reduction_incomplete_type)) 11955 continue; 11956 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11957 // A list item that appears in a reduction clause must not be 11958 // const-qualified. 11959 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 11960 /*AcceptIfMutable*/ false, ASE || OASE)) 11961 continue; 11962 11963 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 11964 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 11965 // If a list-item is a reference type then it must bind to the same object 11966 // for all threads of the team. 11967 if (!ASE && !OASE) { 11968 if (VD) { 11969 VarDecl *VDDef = VD->getDefinition(); 11970 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11971 DSARefChecker Check(Stack); 11972 if (Check.Visit(VDDef->getInit())) { 11973 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11974 << getOpenMPClauseName(ClauseKind) << ERange; 11975 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11976 continue; 11977 } 11978 } 11979 } 11980 11981 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11982 // in a Construct] 11983 // Variables with the predetermined data-sharing attributes may not be 11984 // listed in data-sharing attributes clauses, except for the cases 11985 // listed below. For these exceptions only, listing a predetermined 11986 // variable in a data-sharing attribute clause is allowed and overrides 11987 // the variable's predetermined data-sharing attributes. 11988 // OpenMP [2.14.3.6, Restrictions, p.3] 11989 // Any number of reduction clauses can be specified on the directive, 11990 // but a list item can appear only once in the reduction clauses for that 11991 // directive. 11992 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11993 if (DVar.CKind == OMPC_reduction) { 11994 S.Diag(ELoc, diag::err_omp_once_referenced) 11995 << getOpenMPClauseName(ClauseKind); 11996 if (DVar.RefExpr) 11997 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 11998 continue; 11999 } 12000 if (DVar.CKind != OMPC_unknown) { 12001 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12002 << getOpenMPClauseName(DVar.CKind) 12003 << getOpenMPClauseName(OMPC_reduction); 12004 reportOriginalDsa(S, Stack, D, DVar); 12005 continue; 12006 } 12007 12008 // OpenMP [2.14.3.6, Restrictions, p.1] 12009 // A list item that appears in a reduction clause of a worksharing 12010 // construct must be shared in the parallel regions to which any of the 12011 // worksharing regions arising from the worksharing construct bind. 12012 if (isOpenMPWorksharingDirective(CurrDir) && 12013 !isOpenMPParallelDirective(CurrDir) && 12014 !isOpenMPTeamsDirective(CurrDir)) { 12015 DVar = Stack->getImplicitDSA(D, true); 12016 if (DVar.CKind != OMPC_shared) { 12017 S.Diag(ELoc, diag::err_omp_required_access) 12018 << getOpenMPClauseName(OMPC_reduction) 12019 << getOpenMPClauseName(OMPC_shared); 12020 reportOriginalDsa(S, Stack, D, DVar); 12021 continue; 12022 } 12023 } 12024 } 12025 12026 // Try to find 'declare reduction' corresponding construct before using 12027 // builtin/overloaded operators. 12028 CXXCastPath BasePath; 12029 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12030 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12031 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12032 if (DeclareReductionRef.isInvalid()) 12033 continue; 12034 if (S.CurContext->isDependentContext() && 12035 (DeclareReductionRef.isUnset() || 12036 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12037 RD.push(RefExpr, DeclareReductionRef.get()); 12038 continue; 12039 } 12040 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12041 // Not allowed reduction identifier is found. 12042 S.Diag(ReductionId.getBeginLoc(), 12043 diag::err_omp_unknown_reduction_identifier) 12044 << Type << ReductionIdRange; 12045 continue; 12046 } 12047 12048 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12049 // The type of a list item that appears in a reduction clause must be valid 12050 // for the reduction-identifier. For a max or min reduction in C, the type 12051 // of the list item must be an allowed arithmetic data type: char, int, 12052 // float, double, or _Bool, possibly modified with long, short, signed, or 12053 // unsigned. For a max or min reduction in C++, the type of the list item 12054 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12055 // double, or bool, possibly modified with long, short, signed, or unsigned. 12056 if (DeclareReductionRef.isUnset()) { 12057 if ((BOK == BO_GT || BOK == BO_LT) && 12058 !(Type->isScalarType() || 12059 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12060 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12061 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12062 if (!ASE && !OASE) { 12063 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12064 VarDecl::DeclarationOnly; 12065 S.Diag(D->getLocation(), 12066 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12067 << D; 12068 } 12069 continue; 12070 } 12071 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12072 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12073 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12074 << getOpenMPClauseName(ClauseKind); 12075 if (!ASE && !OASE) { 12076 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12077 VarDecl::DeclarationOnly; 12078 S.Diag(D->getLocation(), 12079 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12080 << D; 12081 } 12082 continue; 12083 } 12084 } 12085 12086 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12087 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12088 D->hasAttrs() ? &D->getAttrs() : nullptr); 12089 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12090 D->hasAttrs() ? &D->getAttrs() : nullptr); 12091 QualType PrivateTy = Type; 12092 12093 // Try if we can determine constant lengths for all array sections and avoid 12094 // the VLA. 12095 bool ConstantLengthOASE = false; 12096 if (OASE) { 12097 bool SingleElement; 12098 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12099 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12100 Context, OASE, SingleElement, ArraySizes); 12101 12102 // If we don't have a single element, we must emit a constant array type. 12103 if (ConstantLengthOASE && !SingleElement) { 12104 for (llvm::APSInt &Size : ArraySizes) 12105 PrivateTy = Context.getConstantArrayType( 12106 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12107 } 12108 } 12109 12110 if ((OASE && !ConstantLengthOASE) || 12111 (!OASE && !ASE && 12112 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12113 if (!Context.getTargetInfo().isVLASupported() && 12114 S.shouldDiagnoseTargetSupportFromOpenMP()) { 12115 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12116 S.Diag(ELoc, diag::note_vla_unsupported); 12117 continue; 12118 } 12119 // For arrays/array sections only: 12120 // Create pseudo array type for private copy. The size for this array will 12121 // be generated during codegen. 12122 // For array subscripts or single variables Private Ty is the same as Type 12123 // (type of the variable or single array element). 12124 PrivateTy = Context.getVariableArrayType( 12125 Type, 12126 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12127 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12128 } else if (!ASE && !OASE && 12129 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12130 PrivateTy = D->getType().getNonReferenceType(); 12131 } 12132 // Private copy. 12133 VarDecl *PrivateVD = 12134 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12135 D->hasAttrs() ? &D->getAttrs() : nullptr, 12136 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12137 // Add initializer for private variable. 12138 Expr *Init = nullptr; 12139 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12140 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12141 if (DeclareReductionRef.isUsable()) { 12142 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12143 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12144 if (DRD->getInitializer()) { 12145 Init = DRDRef; 12146 RHSVD->setInit(DRDRef); 12147 RHSVD->setInitStyle(VarDecl::CallInit); 12148 } 12149 } else { 12150 switch (BOK) { 12151 case BO_Add: 12152 case BO_Xor: 12153 case BO_Or: 12154 case BO_LOr: 12155 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12156 if (Type->isScalarType() || Type->isAnyComplexType()) 12157 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12158 break; 12159 case BO_Mul: 12160 case BO_LAnd: 12161 if (Type->isScalarType() || Type->isAnyComplexType()) { 12162 // '*' and '&&' reduction ops - initializer is '1'. 12163 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12164 } 12165 break; 12166 case BO_And: { 12167 // '&' reduction op - initializer is '~0'. 12168 QualType OrigType = Type; 12169 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12170 Type = ComplexTy->getElementType(); 12171 if (Type->isRealFloatingType()) { 12172 llvm::APFloat InitValue = 12173 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12174 /*isIEEE=*/true); 12175 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12176 Type, ELoc); 12177 } else if (Type->isScalarType()) { 12178 uint64_t Size = Context.getTypeSize(Type); 12179 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12180 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12181 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12182 } 12183 if (Init && OrigType->isAnyComplexType()) { 12184 // Init = 0xFFFF + 0xFFFFi; 12185 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12186 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12187 } 12188 Type = OrigType; 12189 break; 12190 } 12191 case BO_LT: 12192 case BO_GT: { 12193 // 'min' reduction op - initializer is 'Largest representable number in 12194 // the reduction list item type'. 12195 // 'max' reduction op - initializer is 'Least representable number in 12196 // the reduction list item type'. 12197 if (Type->isIntegerType() || Type->isPointerType()) { 12198 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12199 uint64_t Size = Context.getTypeSize(Type); 12200 QualType IntTy = 12201 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12202 llvm::APInt InitValue = 12203 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12204 : llvm::APInt::getMinValue(Size) 12205 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12206 : llvm::APInt::getMaxValue(Size); 12207 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12208 if (Type->isPointerType()) { 12209 // Cast to pointer type. 12210 ExprResult CastExpr = S.BuildCStyleCastExpr( 12211 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12212 if (CastExpr.isInvalid()) 12213 continue; 12214 Init = CastExpr.get(); 12215 } 12216 } else if (Type->isRealFloatingType()) { 12217 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12218 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12219 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12220 Type, ELoc); 12221 } 12222 break; 12223 } 12224 case BO_PtrMemD: 12225 case BO_PtrMemI: 12226 case BO_MulAssign: 12227 case BO_Div: 12228 case BO_Rem: 12229 case BO_Sub: 12230 case BO_Shl: 12231 case BO_Shr: 12232 case BO_LE: 12233 case BO_GE: 12234 case BO_EQ: 12235 case BO_NE: 12236 case BO_Cmp: 12237 case BO_AndAssign: 12238 case BO_XorAssign: 12239 case BO_OrAssign: 12240 case BO_Assign: 12241 case BO_AddAssign: 12242 case BO_SubAssign: 12243 case BO_DivAssign: 12244 case BO_RemAssign: 12245 case BO_ShlAssign: 12246 case BO_ShrAssign: 12247 case BO_Comma: 12248 llvm_unreachable("Unexpected reduction operation"); 12249 } 12250 } 12251 if (Init && DeclareReductionRef.isUnset()) 12252 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12253 else if (!Init) 12254 S.ActOnUninitializedDecl(RHSVD); 12255 if (RHSVD->isInvalidDecl()) 12256 continue; 12257 if (!RHSVD->hasInit() && 12258 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12259 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12260 << Type << ReductionIdRange; 12261 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12262 VarDecl::DeclarationOnly; 12263 S.Diag(D->getLocation(), 12264 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12265 << D; 12266 continue; 12267 } 12268 // Store initializer for single element in private copy. Will be used during 12269 // codegen. 12270 PrivateVD->setInit(RHSVD->getInit()); 12271 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12272 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12273 ExprResult ReductionOp; 12274 if (DeclareReductionRef.isUsable()) { 12275 QualType RedTy = DeclareReductionRef.get()->getType(); 12276 QualType PtrRedTy = Context.getPointerType(RedTy); 12277 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12278 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12279 if (!BasePath.empty()) { 12280 LHS = S.DefaultLvalueConversion(LHS.get()); 12281 RHS = S.DefaultLvalueConversion(RHS.get()); 12282 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12283 CK_UncheckedDerivedToBase, LHS.get(), 12284 &BasePath, LHS.get()->getValueKind()); 12285 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12286 CK_UncheckedDerivedToBase, RHS.get(), 12287 &BasePath, RHS.get()->getValueKind()); 12288 } 12289 FunctionProtoType::ExtProtoInfo EPI; 12290 QualType Params[] = {PtrRedTy, PtrRedTy}; 12291 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12292 auto *OVE = new (Context) OpaqueValueExpr( 12293 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12294 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12295 Expr *Args[] = {LHS.get(), RHS.get()}; 12296 ReductionOp = 12297 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12298 } else { 12299 ReductionOp = S.BuildBinOp( 12300 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12301 if (ReductionOp.isUsable()) { 12302 if (BOK != BO_LT && BOK != BO_GT) { 12303 ReductionOp = 12304 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12305 BO_Assign, LHSDRE, ReductionOp.get()); 12306 } else { 12307 auto *ConditionalOp = new (Context) 12308 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12309 Type, VK_LValue, OK_Ordinary); 12310 ReductionOp = 12311 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12312 BO_Assign, LHSDRE, ConditionalOp); 12313 } 12314 if (ReductionOp.isUsable()) 12315 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12316 /*DiscardedValue*/ false); 12317 } 12318 if (!ReductionOp.isUsable()) 12319 continue; 12320 } 12321 12322 // OpenMP [2.15.4.6, Restrictions, p.2] 12323 // A list item that appears in an in_reduction clause of a task construct 12324 // must appear in a task_reduction clause of a construct associated with a 12325 // taskgroup region that includes the participating task in its taskgroup 12326 // set. The construct associated with the innermost region that meets this 12327 // condition must specify the same reduction-identifier as the in_reduction 12328 // clause. 12329 if (ClauseKind == OMPC_in_reduction) { 12330 SourceRange ParentSR; 12331 BinaryOperatorKind ParentBOK; 12332 const Expr *ParentReductionOp; 12333 Expr *ParentBOKTD, *ParentReductionOpTD; 12334 DSAStackTy::DSAVarData ParentBOKDSA = 12335 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12336 ParentBOKTD); 12337 DSAStackTy::DSAVarData ParentReductionOpDSA = 12338 Stack->getTopMostTaskgroupReductionData( 12339 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12340 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12341 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12342 if (!IsParentBOK && !IsParentReductionOp) { 12343 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12344 continue; 12345 } 12346 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12347 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12348 IsParentReductionOp) { 12349 bool EmitError = true; 12350 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12351 llvm::FoldingSetNodeID RedId, ParentRedId; 12352 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12353 DeclareReductionRef.get()->Profile(RedId, Context, 12354 /*Canonical=*/true); 12355 EmitError = RedId != ParentRedId; 12356 } 12357 if (EmitError) { 12358 S.Diag(ReductionId.getBeginLoc(), 12359 diag::err_omp_reduction_identifier_mismatch) 12360 << ReductionIdRange << RefExpr->getSourceRange(); 12361 S.Diag(ParentSR.getBegin(), 12362 diag::note_omp_previous_reduction_identifier) 12363 << ParentSR 12364 << (IsParentBOK ? ParentBOKDSA.RefExpr 12365 : ParentReductionOpDSA.RefExpr) 12366 ->getSourceRange(); 12367 continue; 12368 } 12369 } 12370 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12371 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12372 } 12373 12374 DeclRefExpr *Ref = nullptr; 12375 Expr *VarsExpr = RefExpr->IgnoreParens(); 12376 if (!VD && !S.CurContext->isDependentContext()) { 12377 if (ASE || OASE) { 12378 TransformExprToCaptures RebuildToCapture(S, D); 12379 VarsExpr = 12380 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 12381 Ref = RebuildToCapture.getCapturedExpr(); 12382 } else { 12383 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 12384 } 12385 if (!S.isOpenMPCapturedDecl(D)) { 12386 RD.ExprCaptures.emplace_back(Ref->getDecl()); 12387 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12388 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 12389 if (!RefRes.isUsable()) 12390 continue; 12391 ExprResult PostUpdateRes = 12392 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12393 RefRes.get()); 12394 if (!PostUpdateRes.isUsable()) 12395 continue; 12396 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 12397 Stack->getCurrentDirective() == OMPD_taskgroup) { 12398 S.Diag(RefExpr->getExprLoc(), 12399 diag::err_omp_reduction_non_addressable_expression) 12400 << RefExpr->getSourceRange(); 12401 continue; 12402 } 12403 RD.ExprPostUpdates.emplace_back( 12404 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 12405 } 12406 } 12407 } 12408 // All reduction items are still marked as reduction (to do not increase 12409 // code base size). 12410 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 12411 if (CurrDir == OMPD_taskgroup) { 12412 if (DeclareReductionRef.isUsable()) 12413 Stack->addTaskgroupReductionData(D, ReductionIdRange, 12414 DeclareReductionRef.get()); 12415 else 12416 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 12417 } 12418 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 12419 TaskgroupDescriptor); 12420 } 12421 return RD.Vars.empty(); 12422 } 12423 12424 OMPClause *Sema::ActOnOpenMPReductionClause( 12425 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12426 SourceLocation ColonLoc, SourceLocation EndLoc, 12427 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12428 ArrayRef<Expr *> UnresolvedReductions) { 12429 ReductionData RD(VarList.size()); 12430 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 12431 StartLoc, LParenLoc, ColonLoc, EndLoc, 12432 ReductionIdScopeSpec, ReductionId, 12433 UnresolvedReductions, RD)) 12434 return nullptr; 12435 12436 return OMPReductionClause::Create( 12437 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12438 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12439 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12440 buildPreInits(Context, RD.ExprCaptures), 12441 buildPostUpdate(*this, RD.ExprPostUpdates)); 12442 } 12443 12444 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 12445 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12446 SourceLocation ColonLoc, SourceLocation EndLoc, 12447 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12448 ArrayRef<Expr *> UnresolvedReductions) { 12449 ReductionData RD(VarList.size()); 12450 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 12451 StartLoc, LParenLoc, ColonLoc, EndLoc, 12452 ReductionIdScopeSpec, ReductionId, 12453 UnresolvedReductions, RD)) 12454 return nullptr; 12455 12456 return OMPTaskReductionClause::Create( 12457 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12458 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12459 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12460 buildPreInits(Context, RD.ExprCaptures), 12461 buildPostUpdate(*this, RD.ExprPostUpdates)); 12462 } 12463 12464 OMPClause *Sema::ActOnOpenMPInReductionClause( 12465 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12466 SourceLocation ColonLoc, SourceLocation EndLoc, 12467 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12468 ArrayRef<Expr *> UnresolvedReductions) { 12469 ReductionData RD(VarList.size()); 12470 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 12471 StartLoc, LParenLoc, ColonLoc, EndLoc, 12472 ReductionIdScopeSpec, ReductionId, 12473 UnresolvedReductions, RD)) 12474 return nullptr; 12475 12476 return OMPInReductionClause::Create( 12477 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12478 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12479 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 12480 buildPreInits(Context, RD.ExprCaptures), 12481 buildPostUpdate(*this, RD.ExprPostUpdates)); 12482 } 12483 12484 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 12485 SourceLocation LinLoc) { 12486 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 12487 LinKind == OMPC_LINEAR_unknown) { 12488 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 12489 return true; 12490 } 12491 return false; 12492 } 12493 12494 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 12495 OpenMPLinearClauseKind LinKind, 12496 QualType Type) { 12497 const auto *VD = dyn_cast_or_null<VarDecl>(D); 12498 // A variable must not have an incomplete type or a reference type. 12499 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 12500 return true; 12501 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 12502 !Type->isReferenceType()) { 12503 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12504 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12505 return true; 12506 } 12507 Type = Type.getNonReferenceType(); 12508 12509 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12510 // A variable that is privatized must not have a const-qualified type 12511 // unless it is of class type with a mutable member. This restriction does 12512 // not apply to the firstprivate clause. 12513 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12514 return true; 12515 12516 // A list item must be of integral or pointer type. 12517 Type = Type.getUnqualifiedType().getCanonicalType(); 12518 const auto *Ty = Type.getTypePtrOrNull(); 12519 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12520 !Ty->isPointerType())) { 12521 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12522 if (D) { 12523 bool IsDecl = 12524 !VD || 12525 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12526 Diag(D->getLocation(), 12527 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12528 << D; 12529 } 12530 return true; 12531 } 12532 return false; 12533 } 12534 12535 OMPClause *Sema::ActOnOpenMPLinearClause( 12536 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12537 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12538 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12539 SmallVector<Expr *, 8> Vars; 12540 SmallVector<Expr *, 8> Privates; 12541 SmallVector<Expr *, 8> Inits; 12542 SmallVector<Decl *, 4> ExprCaptures; 12543 SmallVector<Expr *, 4> ExprPostUpdates; 12544 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12545 LinKind = OMPC_LINEAR_val; 12546 for (Expr *RefExpr : VarList) { 12547 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12548 SourceLocation ELoc; 12549 SourceRange ERange; 12550 Expr *SimpleRefExpr = RefExpr; 12551 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12552 if (Res.second) { 12553 // It will be analyzed later. 12554 Vars.push_back(RefExpr); 12555 Privates.push_back(nullptr); 12556 Inits.push_back(nullptr); 12557 } 12558 ValueDecl *D = Res.first; 12559 if (!D) 12560 continue; 12561 12562 QualType Type = D->getType(); 12563 auto *VD = dyn_cast<VarDecl>(D); 12564 12565 // OpenMP [2.14.3.7, linear clause] 12566 // A list-item cannot appear in more than one linear clause. 12567 // A list-item that appears in a linear clause cannot appear in any 12568 // other data-sharing attribute clause. 12569 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12570 if (DVar.RefExpr) { 12571 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12572 << getOpenMPClauseName(OMPC_linear); 12573 reportOriginalDsa(*this, DSAStack, D, DVar); 12574 continue; 12575 } 12576 12577 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12578 continue; 12579 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12580 12581 // Build private copy of original var. 12582 VarDecl *Private = 12583 buildVarDecl(*this, ELoc, Type, D->getName(), 12584 D->hasAttrs() ? &D->getAttrs() : nullptr, 12585 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12586 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 12587 // Build var to save initial value. 12588 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 12589 Expr *InitExpr; 12590 DeclRefExpr *Ref = nullptr; 12591 if (!VD && !CurContext->isDependentContext()) { 12592 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12593 if (!isOpenMPCapturedDecl(D)) { 12594 ExprCaptures.push_back(Ref->getDecl()); 12595 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12596 ExprResult RefRes = DefaultLvalueConversion(Ref); 12597 if (!RefRes.isUsable()) 12598 continue; 12599 ExprResult PostUpdateRes = 12600 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 12601 SimpleRefExpr, RefRes.get()); 12602 if (!PostUpdateRes.isUsable()) 12603 continue; 12604 ExprPostUpdates.push_back( 12605 IgnoredValueConversions(PostUpdateRes.get()).get()); 12606 } 12607 } 12608 } 12609 if (LinKind == OMPC_LINEAR_uval) 12610 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 12611 else 12612 InitExpr = VD ? SimpleRefExpr : Ref; 12613 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 12614 /*DirectInit=*/false); 12615 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 12616 12617 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 12618 Vars.push_back((VD || CurContext->isDependentContext()) 12619 ? RefExpr->IgnoreParens() 12620 : Ref); 12621 Privates.push_back(PrivateRef); 12622 Inits.push_back(InitRef); 12623 } 12624 12625 if (Vars.empty()) 12626 return nullptr; 12627 12628 Expr *StepExpr = Step; 12629 Expr *CalcStepExpr = nullptr; 12630 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 12631 !Step->isInstantiationDependent() && 12632 !Step->containsUnexpandedParameterPack()) { 12633 SourceLocation StepLoc = Step->getBeginLoc(); 12634 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 12635 if (Val.isInvalid()) 12636 return nullptr; 12637 StepExpr = Val.get(); 12638 12639 // Build var to save the step value. 12640 VarDecl *SaveVar = 12641 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 12642 ExprResult SaveRef = 12643 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 12644 ExprResult CalcStep = 12645 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 12646 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 12647 12648 // Warn about zero linear step (it would be probably better specified as 12649 // making corresponding variables 'const'). 12650 llvm::APSInt Result; 12651 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 12652 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 12653 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 12654 << (Vars.size() > 1); 12655 if (!IsConstant && CalcStep.isUsable()) { 12656 // Calculate the step beforehand instead of doing this on each iteration. 12657 // (This is not used if the number of iterations may be kfold-ed). 12658 CalcStepExpr = CalcStep.get(); 12659 } 12660 } 12661 12662 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 12663 ColonLoc, EndLoc, Vars, Privates, Inits, 12664 StepExpr, CalcStepExpr, 12665 buildPreInits(Context, ExprCaptures), 12666 buildPostUpdate(*this, ExprPostUpdates)); 12667 } 12668 12669 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 12670 Expr *NumIterations, Sema &SemaRef, 12671 Scope *S, DSAStackTy *Stack) { 12672 // Walk the vars and build update/final expressions for the CodeGen. 12673 SmallVector<Expr *, 8> Updates; 12674 SmallVector<Expr *, 8> Finals; 12675 Expr *Step = Clause.getStep(); 12676 Expr *CalcStep = Clause.getCalcStep(); 12677 // OpenMP [2.14.3.7, linear clause] 12678 // If linear-step is not specified it is assumed to be 1. 12679 if (!Step) 12680 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12681 else if (CalcStep) 12682 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12683 bool HasErrors = false; 12684 auto CurInit = Clause.inits().begin(); 12685 auto CurPrivate = Clause.privates().begin(); 12686 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12687 for (Expr *RefExpr : Clause.varlists()) { 12688 SourceLocation ELoc; 12689 SourceRange ERange; 12690 Expr *SimpleRefExpr = RefExpr; 12691 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12692 ValueDecl *D = Res.first; 12693 if (Res.second || !D) { 12694 Updates.push_back(nullptr); 12695 Finals.push_back(nullptr); 12696 HasErrors = true; 12697 continue; 12698 } 12699 auto &&Info = Stack->isLoopControlVariable(D); 12700 // OpenMP [2.15.11, distribute simd Construct] 12701 // A list item may not appear in a linear clause, unless it is the loop 12702 // iteration variable. 12703 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12704 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12705 SemaRef.Diag(ELoc, 12706 diag::err_omp_linear_distribute_var_non_loop_iteration); 12707 Updates.push_back(nullptr); 12708 Finals.push_back(nullptr); 12709 HasErrors = true; 12710 continue; 12711 } 12712 Expr *InitExpr = *CurInit; 12713 12714 // Build privatized reference to the current linear var. 12715 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12716 Expr *CapturedRef; 12717 if (LinKind == OMPC_LINEAR_uval) 12718 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12719 else 12720 CapturedRef = 12721 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12722 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12723 /*RefersToCapture=*/true); 12724 12725 // Build update: Var = InitExpr + IV * Step 12726 ExprResult Update; 12727 if (!Info.first) 12728 Update = 12729 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12730 InitExpr, IV, Step, /* Subtract */ false); 12731 else 12732 Update = *CurPrivate; 12733 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12734 /*DiscardedValue*/ false); 12735 12736 // Build final: Var = InitExpr + NumIterations * Step 12737 ExprResult Final; 12738 if (!Info.first) 12739 Final = 12740 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12741 InitExpr, NumIterations, Step, /*Subtract=*/false); 12742 else 12743 Final = *CurPrivate; 12744 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12745 /*DiscardedValue*/ false); 12746 12747 if (!Update.isUsable() || !Final.isUsable()) { 12748 Updates.push_back(nullptr); 12749 Finals.push_back(nullptr); 12750 HasErrors = true; 12751 } else { 12752 Updates.push_back(Update.get()); 12753 Finals.push_back(Final.get()); 12754 } 12755 ++CurInit; 12756 ++CurPrivate; 12757 } 12758 Clause.setUpdates(Updates); 12759 Clause.setFinals(Finals); 12760 return HasErrors; 12761 } 12762 12763 OMPClause *Sema::ActOnOpenMPAlignedClause( 12764 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12765 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12766 SmallVector<Expr *, 8> Vars; 12767 for (Expr *RefExpr : VarList) { 12768 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12769 SourceLocation ELoc; 12770 SourceRange ERange; 12771 Expr *SimpleRefExpr = RefExpr; 12772 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12773 if (Res.second) { 12774 // It will be analyzed later. 12775 Vars.push_back(RefExpr); 12776 } 12777 ValueDecl *D = Res.first; 12778 if (!D) 12779 continue; 12780 12781 QualType QType = D->getType(); 12782 auto *VD = dyn_cast<VarDecl>(D); 12783 12784 // OpenMP [2.8.1, simd construct, Restrictions] 12785 // The type of list items appearing in the aligned clause must be 12786 // array, pointer, reference to array, or reference to pointer. 12787 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12788 const Type *Ty = QType.getTypePtrOrNull(); 12789 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12790 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12791 << QType << getLangOpts().CPlusPlus << ERange; 12792 bool IsDecl = 12793 !VD || 12794 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12795 Diag(D->getLocation(), 12796 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12797 << D; 12798 continue; 12799 } 12800 12801 // OpenMP [2.8.1, simd construct, Restrictions] 12802 // A list-item cannot appear in more than one aligned clause. 12803 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12804 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12805 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12806 << getOpenMPClauseName(OMPC_aligned); 12807 continue; 12808 } 12809 12810 DeclRefExpr *Ref = nullptr; 12811 if (!VD && isOpenMPCapturedDecl(D)) 12812 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12813 Vars.push_back(DefaultFunctionArrayConversion( 12814 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12815 .get()); 12816 } 12817 12818 // OpenMP [2.8.1, simd construct, Description] 12819 // The parameter of the aligned clause, alignment, must be a constant 12820 // positive integer expression. 12821 // If no optional parameter is specified, implementation-defined default 12822 // alignments for SIMD instructions on the target platforms are assumed. 12823 if (Alignment != nullptr) { 12824 ExprResult AlignResult = 12825 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12826 if (AlignResult.isInvalid()) 12827 return nullptr; 12828 Alignment = AlignResult.get(); 12829 } 12830 if (Vars.empty()) 12831 return nullptr; 12832 12833 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12834 EndLoc, Vars, Alignment); 12835 } 12836 12837 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12838 SourceLocation StartLoc, 12839 SourceLocation LParenLoc, 12840 SourceLocation EndLoc) { 12841 SmallVector<Expr *, 8> Vars; 12842 SmallVector<Expr *, 8> SrcExprs; 12843 SmallVector<Expr *, 8> DstExprs; 12844 SmallVector<Expr *, 8> AssignmentOps; 12845 for (Expr *RefExpr : VarList) { 12846 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12847 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12848 // It will be analyzed later. 12849 Vars.push_back(RefExpr); 12850 SrcExprs.push_back(nullptr); 12851 DstExprs.push_back(nullptr); 12852 AssignmentOps.push_back(nullptr); 12853 continue; 12854 } 12855 12856 SourceLocation ELoc = RefExpr->getExprLoc(); 12857 // OpenMP [2.1, C/C++] 12858 // A list item is a variable name. 12859 // OpenMP [2.14.4.1, Restrictions, p.1] 12860 // A list item that appears in a copyin clause must be threadprivate. 12861 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12862 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12863 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12864 << 0 << RefExpr->getSourceRange(); 12865 continue; 12866 } 12867 12868 Decl *D = DE->getDecl(); 12869 auto *VD = cast<VarDecl>(D); 12870 12871 QualType Type = VD->getType(); 12872 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12873 // It will be analyzed later. 12874 Vars.push_back(DE); 12875 SrcExprs.push_back(nullptr); 12876 DstExprs.push_back(nullptr); 12877 AssignmentOps.push_back(nullptr); 12878 continue; 12879 } 12880 12881 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12882 // A list item that appears in a copyin clause must be threadprivate. 12883 if (!DSAStack->isThreadPrivate(VD)) { 12884 Diag(ELoc, diag::err_omp_required_access) 12885 << getOpenMPClauseName(OMPC_copyin) 12886 << getOpenMPDirectiveName(OMPD_threadprivate); 12887 continue; 12888 } 12889 12890 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12891 // A variable of class type (or array thereof) that appears in a 12892 // copyin clause requires an accessible, unambiguous copy assignment 12893 // operator for the class type. 12894 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12895 VarDecl *SrcVD = 12896 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12897 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12898 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12899 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12900 VarDecl *DstVD = 12901 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12902 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12903 DeclRefExpr *PseudoDstExpr = 12904 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12905 // For arrays generate assignment operation for single element and replace 12906 // it by the original array element in CodeGen. 12907 ExprResult AssignmentOp = 12908 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12909 PseudoSrcExpr); 12910 if (AssignmentOp.isInvalid()) 12911 continue; 12912 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12913 /*DiscardedValue*/ false); 12914 if (AssignmentOp.isInvalid()) 12915 continue; 12916 12917 DSAStack->addDSA(VD, DE, OMPC_copyin); 12918 Vars.push_back(DE); 12919 SrcExprs.push_back(PseudoSrcExpr); 12920 DstExprs.push_back(PseudoDstExpr); 12921 AssignmentOps.push_back(AssignmentOp.get()); 12922 } 12923 12924 if (Vars.empty()) 12925 return nullptr; 12926 12927 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12928 SrcExprs, DstExprs, AssignmentOps); 12929 } 12930 12931 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12932 SourceLocation StartLoc, 12933 SourceLocation LParenLoc, 12934 SourceLocation EndLoc) { 12935 SmallVector<Expr *, 8> Vars; 12936 SmallVector<Expr *, 8> SrcExprs; 12937 SmallVector<Expr *, 8> DstExprs; 12938 SmallVector<Expr *, 8> AssignmentOps; 12939 for (Expr *RefExpr : VarList) { 12940 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12941 SourceLocation ELoc; 12942 SourceRange ERange; 12943 Expr *SimpleRefExpr = RefExpr; 12944 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12945 if (Res.second) { 12946 // It will be analyzed later. 12947 Vars.push_back(RefExpr); 12948 SrcExprs.push_back(nullptr); 12949 DstExprs.push_back(nullptr); 12950 AssignmentOps.push_back(nullptr); 12951 } 12952 ValueDecl *D = Res.first; 12953 if (!D) 12954 continue; 12955 12956 QualType Type = D->getType(); 12957 auto *VD = dyn_cast<VarDecl>(D); 12958 12959 // OpenMP [2.14.4.2, Restrictions, p.2] 12960 // A list item that appears in a copyprivate clause may not appear in a 12961 // private or firstprivate clause on the single construct. 12962 if (!VD || !DSAStack->isThreadPrivate(VD)) { 12963 DSAStackTy::DSAVarData DVar = 12964 DSAStack->getTopDSA(D, /*FromParent=*/false); 12965 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 12966 DVar.RefExpr) { 12967 Diag(ELoc, diag::err_omp_wrong_dsa) 12968 << getOpenMPClauseName(DVar.CKind) 12969 << getOpenMPClauseName(OMPC_copyprivate); 12970 reportOriginalDsa(*this, DSAStack, D, DVar); 12971 continue; 12972 } 12973 12974 // OpenMP [2.11.4.2, Restrictions, p.1] 12975 // All list items that appear in a copyprivate clause must be either 12976 // threadprivate or private in the enclosing context. 12977 if (DVar.CKind == OMPC_unknown) { 12978 DVar = DSAStack->getImplicitDSA(D, false); 12979 if (DVar.CKind == OMPC_shared) { 12980 Diag(ELoc, diag::err_omp_required_access) 12981 << getOpenMPClauseName(OMPC_copyprivate) 12982 << "threadprivate or private in the enclosing context"; 12983 reportOriginalDsa(*this, DSAStack, D, DVar); 12984 continue; 12985 } 12986 } 12987 } 12988 12989 // Variably modified types are not supported. 12990 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12991 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12992 << getOpenMPClauseName(OMPC_copyprivate) << Type 12993 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12994 bool IsDecl = 12995 !VD || 12996 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12997 Diag(D->getLocation(), 12998 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12999 << D; 13000 continue; 13001 } 13002 13003 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13004 // A variable of class type (or array thereof) that appears in a 13005 // copyin clause requires an accessible, unambiguous copy assignment 13006 // operator for the class type. 13007 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13008 .getUnqualifiedType(); 13009 VarDecl *SrcVD = 13010 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13011 D->hasAttrs() ? &D->getAttrs() : nullptr); 13012 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13013 VarDecl *DstVD = 13014 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13015 D->hasAttrs() ? &D->getAttrs() : nullptr); 13016 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13017 ExprResult AssignmentOp = BuildBinOp( 13018 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13019 if (AssignmentOp.isInvalid()) 13020 continue; 13021 AssignmentOp = 13022 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13023 if (AssignmentOp.isInvalid()) 13024 continue; 13025 13026 // No need to mark vars as copyprivate, they are already threadprivate or 13027 // implicitly private. 13028 assert(VD || isOpenMPCapturedDecl(D)); 13029 Vars.push_back( 13030 VD ? RefExpr->IgnoreParens() 13031 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13032 SrcExprs.push_back(PseudoSrcExpr); 13033 DstExprs.push_back(PseudoDstExpr); 13034 AssignmentOps.push_back(AssignmentOp.get()); 13035 } 13036 13037 if (Vars.empty()) 13038 return nullptr; 13039 13040 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13041 Vars, SrcExprs, DstExprs, AssignmentOps); 13042 } 13043 13044 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13045 SourceLocation StartLoc, 13046 SourceLocation LParenLoc, 13047 SourceLocation EndLoc) { 13048 if (VarList.empty()) 13049 return nullptr; 13050 13051 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13052 } 13053 13054 OMPClause * 13055 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13056 SourceLocation DepLoc, SourceLocation ColonLoc, 13057 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13058 SourceLocation LParenLoc, SourceLocation EndLoc) { 13059 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13060 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13061 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13062 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13063 return nullptr; 13064 } 13065 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13066 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13067 DepKind == OMPC_DEPEND_sink)) { 13068 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13069 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13070 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13071 /*Last=*/OMPC_DEPEND_unknown, Except) 13072 << getOpenMPClauseName(OMPC_depend); 13073 return nullptr; 13074 } 13075 SmallVector<Expr *, 8> Vars; 13076 DSAStackTy::OperatorOffsetTy OpsOffs; 13077 llvm::APSInt DepCounter(/*BitWidth=*/32); 13078 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13079 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13080 if (const Expr *OrderedCountExpr = 13081 DSAStack->getParentOrderedRegionParam().first) { 13082 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13083 TotalDepCount.setIsUnsigned(/*Val=*/true); 13084 } 13085 } 13086 for (Expr *RefExpr : VarList) { 13087 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13088 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13089 // It will be analyzed later. 13090 Vars.push_back(RefExpr); 13091 continue; 13092 } 13093 13094 SourceLocation ELoc = RefExpr->getExprLoc(); 13095 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13096 if (DepKind == OMPC_DEPEND_sink) { 13097 if (DSAStack->getParentOrderedRegionParam().first && 13098 DepCounter >= TotalDepCount) { 13099 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13100 continue; 13101 } 13102 ++DepCounter; 13103 // OpenMP [2.13.9, Summary] 13104 // depend(dependence-type : vec), where dependence-type is: 13105 // 'sink' and where vec is the iteration vector, which has the form: 13106 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13107 // where n is the value specified by the ordered clause in the loop 13108 // directive, xi denotes the loop iteration variable of the i-th nested 13109 // loop associated with the loop directive, and di is a constant 13110 // non-negative integer. 13111 if (CurContext->isDependentContext()) { 13112 // It will be analyzed later. 13113 Vars.push_back(RefExpr); 13114 continue; 13115 } 13116 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13117 OverloadedOperatorKind OOK = OO_None; 13118 SourceLocation OOLoc; 13119 Expr *LHS = SimpleExpr; 13120 Expr *RHS = nullptr; 13121 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13122 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13123 OOLoc = BO->getOperatorLoc(); 13124 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13125 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13126 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13127 OOK = OCE->getOperator(); 13128 OOLoc = OCE->getOperatorLoc(); 13129 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13130 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13131 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13132 OOK = MCE->getMethodDecl() 13133 ->getNameInfo() 13134 .getName() 13135 .getCXXOverloadedOperator(); 13136 OOLoc = MCE->getCallee()->getExprLoc(); 13137 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13138 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13139 } 13140 SourceLocation ELoc; 13141 SourceRange ERange; 13142 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13143 if (Res.second) { 13144 // It will be analyzed later. 13145 Vars.push_back(RefExpr); 13146 } 13147 ValueDecl *D = Res.first; 13148 if (!D) 13149 continue; 13150 13151 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13152 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13153 continue; 13154 } 13155 if (RHS) { 13156 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13157 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13158 if (RHSRes.isInvalid()) 13159 continue; 13160 } 13161 if (!CurContext->isDependentContext() && 13162 DSAStack->getParentOrderedRegionParam().first && 13163 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13164 const ValueDecl *VD = 13165 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13166 if (VD) 13167 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13168 << 1 << VD; 13169 else 13170 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13171 continue; 13172 } 13173 OpsOffs.emplace_back(RHS, OOK); 13174 } else { 13175 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13176 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13177 (ASE && 13178 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13179 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13180 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13181 << RefExpr->getSourceRange(); 13182 continue; 13183 } 13184 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 13185 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 13186 ExprResult Res = 13187 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 13188 getDiagnostics().setSuppressAllDiagnostics(Suppress); 13189 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13190 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13191 << RefExpr->getSourceRange(); 13192 continue; 13193 } 13194 } 13195 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13196 } 13197 13198 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13199 TotalDepCount > VarList.size() && 13200 DSAStack->getParentOrderedRegionParam().first && 13201 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13202 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13203 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13204 } 13205 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13206 Vars.empty()) 13207 return nullptr; 13208 13209 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13210 DepKind, DepLoc, ColonLoc, Vars, 13211 TotalDepCount.getZExtValue()); 13212 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13213 DSAStack->isParentOrderedRegion()) 13214 DSAStack->addDoacrossDependClause(C, OpsOffs); 13215 return C; 13216 } 13217 13218 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13219 SourceLocation LParenLoc, 13220 SourceLocation EndLoc) { 13221 Expr *ValExpr = Device; 13222 Stmt *HelperValStmt = nullptr; 13223 13224 // OpenMP [2.9.1, Restrictions] 13225 // The device expression must evaluate to a non-negative integer value. 13226 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13227 /*StrictlyPositive=*/false)) 13228 return nullptr; 13229 13230 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13231 OpenMPDirectiveKind CaptureRegion = 13232 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13233 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13234 ValExpr = MakeFullExpr(ValExpr).get(); 13235 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13236 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13237 HelperValStmt = buildPreInits(Context, Captures); 13238 } 13239 13240 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13241 StartLoc, LParenLoc, EndLoc); 13242 } 13243 13244 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13245 DSAStackTy *Stack, QualType QTy, 13246 bool FullCheck = true) { 13247 NamedDecl *ND; 13248 if (QTy->isIncompleteType(&ND)) { 13249 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13250 return false; 13251 } 13252 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13253 !QTy.isTrivialType(SemaRef.Context)) 13254 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13255 return true; 13256 } 13257 13258 /// Return true if it can be proven that the provided array expression 13259 /// (array section or array subscript) does NOT specify the whole size of the 13260 /// array whose base type is \a BaseQTy. 13261 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13262 const Expr *E, 13263 QualType BaseQTy) { 13264 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13265 13266 // If this is an array subscript, it refers to the whole size if the size of 13267 // the dimension is constant and equals 1. Also, an array section assumes the 13268 // format of an array subscript if no colon is used. 13269 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13270 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13271 return ATy->getSize().getSExtValue() != 1; 13272 // Size can't be evaluated statically. 13273 return false; 13274 } 13275 13276 assert(OASE && "Expecting array section if not an array subscript."); 13277 const Expr *LowerBound = OASE->getLowerBound(); 13278 const Expr *Length = OASE->getLength(); 13279 13280 // If there is a lower bound that does not evaluates to zero, we are not 13281 // covering the whole dimension. 13282 if (LowerBound) { 13283 Expr::EvalResult Result; 13284 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13285 return false; // Can't get the integer value as a constant. 13286 13287 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13288 if (ConstLowerBound.getSExtValue()) 13289 return true; 13290 } 13291 13292 // If we don't have a length we covering the whole dimension. 13293 if (!Length) 13294 return false; 13295 13296 // If the base is a pointer, we don't have a way to get the size of the 13297 // pointee. 13298 if (BaseQTy->isPointerType()) 13299 return false; 13300 13301 // We can only check if the length is the same as the size of the dimension 13302 // if we have a constant array. 13303 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13304 if (!CATy) 13305 return false; 13306 13307 Expr::EvalResult Result; 13308 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13309 return false; // Can't get the integer value as a constant. 13310 13311 llvm::APSInt ConstLength = Result.Val.getInt(); 13312 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13313 } 13314 13315 // Return true if it can be proven that the provided array expression (array 13316 // section or array subscript) does NOT specify a single element of the array 13317 // whose base type is \a BaseQTy. 13318 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13319 const Expr *E, 13320 QualType BaseQTy) { 13321 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13322 13323 // An array subscript always refer to a single element. Also, an array section 13324 // assumes the format of an array subscript if no colon is used. 13325 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13326 return false; 13327 13328 assert(OASE && "Expecting array section if not an array subscript."); 13329 const Expr *Length = OASE->getLength(); 13330 13331 // If we don't have a length we have to check if the array has unitary size 13332 // for this dimension. Also, we should always expect a length if the base type 13333 // is pointer. 13334 if (!Length) { 13335 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13336 return ATy->getSize().getSExtValue() != 1; 13337 // We cannot assume anything. 13338 return false; 13339 } 13340 13341 // Check if the length evaluates to 1. 13342 Expr::EvalResult Result; 13343 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13344 return false; // Can't get the integer value as a constant. 13345 13346 llvm::APSInt ConstLength = Result.Val.getInt(); 13347 return ConstLength.getSExtValue() != 1; 13348 } 13349 13350 // Return the expression of the base of the mappable expression or null if it 13351 // cannot be determined and do all the necessary checks to see if the expression 13352 // is valid as a standalone mappable expression. In the process, record all the 13353 // components of the expression. 13354 static const Expr *checkMapClauseExpressionBase( 13355 Sema &SemaRef, Expr *E, 13356 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13357 OpenMPClauseKind CKind, bool NoDiagnose) { 13358 SourceLocation ELoc = E->getExprLoc(); 13359 SourceRange ERange = E->getSourceRange(); 13360 13361 // The base of elements of list in a map clause have to be either: 13362 // - a reference to variable or field. 13363 // - a member expression. 13364 // - an array expression. 13365 // 13366 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 13367 // reference to 'r'. 13368 // 13369 // If we have: 13370 // 13371 // struct SS { 13372 // Bla S; 13373 // foo() { 13374 // #pragma omp target map (S.Arr[:12]); 13375 // } 13376 // } 13377 // 13378 // We want to retrieve the member expression 'this->S'; 13379 13380 const Expr *RelevantExpr = nullptr; 13381 13382 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 13383 // If a list item is an array section, it must specify contiguous storage. 13384 // 13385 // For this restriction it is sufficient that we make sure only references 13386 // to variables or fields and array expressions, and that no array sections 13387 // exist except in the rightmost expression (unless they cover the whole 13388 // dimension of the array). E.g. these would be invalid: 13389 // 13390 // r.ArrS[3:5].Arr[6:7] 13391 // 13392 // r.ArrS[3:5].x 13393 // 13394 // but these would be valid: 13395 // r.ArrS[3].Arr[6:7] 13396 // 13397 // r.ArrS[3].x 13398 13399 bool AllowUnitySizeArraySection = true; 13400 bool AllowWholeSizeArraySection = true; 13401 13402 while (!RelevantExpr) { 13403 E = E->IgnoreParenImpCasts(); 13404 13405 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 13406 if (!isa<VarDecl>(CurE->getDecl())) 13407 return nullptr; 13408 13409 RelevantExpr = CurE; 13410 13411 // If we got a reference to a declaration, we should not expect any array 13412 // section before that. 13413 AllowUnitySizeArraySection = false; 13414 AllowWholeSizeArraySection = false; 13415 13416 // Record the component. 13417 CurComponents.emplace_back(CurE, CurE->getDecl()); 13418 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 13419 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 13420 13421 if (isa<CXXThisExpr>(BaseE)) 13422 // We found a base expression: this->Val. 13423 RelevantExpr = CurE; 13424 else 13425 E = BaseE; 13426 13427 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 13428 if (!NoDiagnose) { 13429 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 13430 << CurE->getSourceRange(); 13431 return nullptr; 13432 } 13433 if (RelevantExpr) 13434 return nullptr; 13435 continue; 13436 } 13437 13438 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 13439 13440 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 13441 // A bit-field cannot appear in a map clause. 13442 // 13443 if (FD->isBitField()) { 13444 if (!NoDiagnose) { 13445 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 13446 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 13447 return nullptr; 13448 } 13449 if (RelevantExpr) 13450 return nullptr; 13451 continue; 13452 } 13453 13454 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13455 // If the type of a list item is a reference to a type T then the type 13456 // will be considered to be T for all purposes of this clause. 13457 QualType CurType = BaseE->getType().getNonReferenceType(); 13458 13459 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 13460 // A list item cannot be a variable that is a member of a structure with 13461 // a union type. 13462 // 13463 if (CurType->isUnionType()) { 13464 if (!NoDiagnose) { 13465 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 13466 << CurE->getSourceRange(); 13467 return nullptr; 13468 } 13469 continue; 13470 } 13471 13472 // If we got a member expression, we should not expect any array section 13473 // before that: 13474 // 13475 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 13476 // If a list item is an element of a structure, only the rightmost symbol 13477 // of the variable reference can be an array section. 13478 // 13479 AllowUnitySizeArraySection = false; 13480 AllowWholeSizeArraySection = false; 13481 13482 // Record the component. 13483 CurComponents.emplace_back(CurE, FD); 13484 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 13485 E = CurE->getBase()->IgnoreParenImpCasts(); 13486 13487 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 13488 if (!NoDiagnose) { 13489 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13490 << 0 << CurE->getSourceRange(); 13491 return nullptr; 13492 } 13493 continue; 13494 } 13495 13496 // If we got an array subscript that express the whole dimension we 13497 // can have any array expressions before. If it only expressing part of 13498 // the dimension, we can only have unitary-size array expressions. 13499 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 13500 E->getType())) 13501 AllowWholeSizeArraySection = false; 13502 13503 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13504 Expr::EvalResult Result; 13505 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13506 if (!Result.Val.getInt().isNullValue()) { 13507 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13508 diag::err_omp_invalid_map_this_expr); 13509 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13510 diag::note_omp_invalid_subscript_on_this_ptr_map); 13511 } 13512 } 13513 RelevantExpr = TE; 13514 } 13515 13516 // Record the component - we don't have any declaration associated. 13517 CurComponents.emplace_back(CurE, nullptr); 13518 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13519 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13520 E = CurE->getBase()->IgnoreParenImpCasts(); 13521 13522 QualType CurType = 13523 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13524 13525 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13526 // If the type of a list item is a reference to a type T then the type 13527 // will be considered to be T for all purposes of this clause. 13528 if (CurType->isReferenceType()) 13529 CurType = CurType->getPointeeType(); 13530 13531 bool IsPointer = CurType->isAnyPointerType(); 13532 13533 if (!IsPointer && !CurType->isArrayType()) { 13534 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13535 << 0 << CurE->getSourceRange(); 13536 return nullptr; 13537 } 13538 13539 bool NotWhole = 13540 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13541 bool NotUnity = 13542 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13543 13544 if (AllowWholeSizeArraySection) { 13545 // Any array section is currently allowed. Allowing a whole size array 13546 // section implies allowing a unity array section as well. 13547 // 13548 // If this array section refers to the whole dimension we can still 13549 // accept other array sections before this one, except if the base is a 13550 // pointer. Otherwise, only unitary sections are accepted. 13551 if (NotWhole || IsPointer) 13552 AllowWholeSizeArraySection = false; 13553 } else if (AllowUnitySizeArraySection && NotUnity) { 13554 // A unity or whole array section is not allowed and that is not 13555 // compatible with the properties of the current array section. 13556 SemaRef.Diag( 13557 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13558 << CurE->getSourceRange(); 13559 return nullptr; 13560 } 13561 13562 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13563 Expr::EvalResult ResultR; 13564 Expr::EvalResult ResultL; 13565 if (CurE->getLength()->EvaluateAsInt(ResultR, 13566 SemaRef.getASTContext())) { 13567 if (!ResultR.Val.getInt().isOneValue()) { 13568 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13569 diag::err_omp_invalid_map_this_expr); 13570 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13571 diag::note_omp_invalid_length_on_this_ptr_mapping); 13572 } 13573 } 13574 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 13575 ResultL, SemaRef.getASTContext())) { 13576 if (!ResultL.Val.getInt().isNullValue()) { 13577 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13578 diag::err_omp_invalid_map_this_expr); 13579 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13580 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 13581 } 13582 } 13583 RelevantExpr = TE; 13584 } 13585 13586 // Record the component - we don't have any declaration associated. 13587 CurComponents.emplace_back(CurE, nullptr); 13588 } else { 13589 if (!NoDiagnose) { 13590 // If nothing else worked, this is not a valid map clause expression. 13591 SemaRef.Diag( 13592 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 13593 << ERange; 13594 } 13595 return nullptr; 13596 } 13597 } 13598 13599 return RelevantExpr; 13600 } 13601 13602 // Return true if expression E associated with value VD has conflicts with other 13603 // map information. 13604 static bool checkMapConflicts( 13605 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 13606 bool CurrentRegionOnly, 13607 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 13608 OpenMPClauseKind CKind) { 13609 assert(VD && E); 13610 SourceLocation ELoc = E->getExprLoc(); 13611 SourceRange ERange = E->getSourceRange(); 13612 13613 // In order to easily check the conflicts we need to match each component of 13614 // the expression under test with the components of the expressions that are 13615 // already in the stack. 13616 13617 assert(!CurComponents.empty() && "Map clause expression with no components!"); 13618 assert(CurComponents.back().getAssociatedDeclaration() == VD && 13619 "Map clause expression with unexpected base!"); 13620 13621 // Variables to help detecting enclosing problems in data environment nests. 13622 bool IsEnclosedByDataEnvironmentExpr = false; 13623 const Expr *EnclosingExpr = nullptr; 13624 13625 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 13626 VD, CurrentRegionOnly, 13627 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 13628 ERange, CKind, &EnclosingExpr, 13629 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 13630 StackComponents, 13631 OpenMPClauseKind) { 13632 assert(!StackComponents.empty() && 13633 "Map clause expression with no components!"); 13634 assert(StackComponents.back().getAssociatedDeclaration() == VD && 13635 "Map clause expression with unexpected base!"); 13636 (void)VD; 13637 13638 // The whole expression in the stack. 13639 const Expr *RE = StackComponents.front().getAssociatedExpression(); 13640 13641 // Expressions must start from the same base. Here we detect at which 13642 // point both expressions diverge from each other and see if we can 13643 // detect if the memory referred to both expressions is contiguous and 13644 // do not overlap. 13645 auto CI = CurComponents.rbegin(); 13646 auto CE = CurComponents.rend(); 13647 auto SI = StackComponents.rbegin(); 13648 auto SE = StackComponents.rend(); 13649 for (; CI != CE && SI != SE; ++CI, ++SI) { 13650 13651 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 13652 // At most one list item can be an array item derived from a given 13653 // variable in map clauses of the same construct. 13654 if (CurrentRegionOnly && 13655 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 13656 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 13657 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 13658 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 13659 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 13660 diag::err_omp_multiple_array_items_in_map_clause) 13661 << CI->getAssociatedExpression()->getSourceRange(); 13662 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 13663 diag::note_used_here) 13664 << SI->getAssociatedExpression()->getSourceRange(); 13665 return true; 13666 } 13667 13668 // Do both expressions have the same kind? 13669 if (CI->getAssociatedExpression()->getStmtClass() != 13670 SI->getAssociatedExpression()->getStmtClass()) 13671 break; 13672 13673 // Are we dealing with different variables/fields? 13674 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13675 break; 13676 } 13677 // Check if the extra components of the expressions in the enclosing 13678 // data environment are redundant for the current base declaration. 13679 // If they are, the maps completely overlap, which is legal. 13680 for (; SI != SE; ++SI) { 13681 QualType Type; 13682 if (const auto *ASE = 13683 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13684 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13685 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13686 SI->getAssociatedExpression())) { 13687 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13688 Type = 13689 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13690 } 13691 if (Type.isNull() || Type->isAnyPointerType() || 13692 checkArrayExpressionDoesNotReferToWholeSize( 13693 SemaRef, SI->getAssociatedExpression(), Type)) 13694 break; 13695 } 13696 13697 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13698 // List items of map clauses in the same construct must not share 13699 // original storage. 13700 // 13701 // If the expressions are exactly the same or one is a subset of the 13702 // other, it means they are sharing storage. 13703 if (CI == CE && SI == SE) { 13704 if (CurrentRegionOnly) { 13705 if (CKind == OMPC_map) { 13706 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13707 } else { 13708 assert(CKind == OMPC_to || CKind == OMPC_from); 13709 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13710 << ERange; 13711 } 13712 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13713 << RE->getSourceRange(); 13714 return true; 13715 } 13716 // If we find the same expression in the enclosing data environment, 13717 // that is legal. 13718 IsEnclosedByDataEnvironmentExpr = true; 13719 return false; 13720 } 13721 13722 QualType DerivedType = 13723 std::prev(CI)->getAssociatedDeclaration()->getType(); 13724 SourceLocation DerivedLoc = 13725 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13726 13727 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13728 // If the type of a list item is a reference to a type T then the type 13729 // will be considered to be T for all purposes of this clause. 13730 DerivedType = DerivedType.getNonReferenceType(); 13731 13732 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13733 // A variable for which the type is pointer and an array section 13734 // derived from that variable must not appear as list items of map 13735 // clauses of the same construct. 13736 // 13737 // Also, cover one of the cases in: 13738 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13739 // If any part of the original storage of a list item has corresponding 13740 // storage in the device data environment, all of the original storage 13741 // must have corresponding storage in the device data environment. 13742 // 13743 if (DerivedType->isAnyPointerType()) { 13744 if (CI == CE || SI == SE) { 13745 SemaRef.Diag( 13746 DerivedLoc, 13747 diag::err_omp_pointer_mapped_along_with_derived_section) 13748 << DerivedLoc; 13749 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13750 << RE->getSourceRange(); 13751 return true; 13752 } 13753 if (CI->getAssociatedExpression()->getStmtClass() != 13754 SI->getAssociatedExpression()->getStmtClass() || 13755 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13756 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13757 assert(CI != CE && SI != SE); 13758 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13759 << DerivedLoc; 13760 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13761 << RE->getSourceRange(); 13762 return true; 13763 } 13764 } 13765 13766 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13767 // List items of map clauses in the same construct must not share 13768 // original storage. 13769 // 13770 // An expression is a subset of the other. 13771 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13772 if (CKind == OMPC_map) { 13773 if (CI != CE || SI != SE) { 13774 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13775 // a pointer. 13776 auto Begin = 13777 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13778 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13779 auto It = Begin; 13780 while (It != End && !It->getAssociatedDeclaration()) 13781 std::advance(It, 1); 13782 assert(It != End && 13783 "Expected at least one component with the declaration."); 13784 if (It != Begin && It->getAssociatedDeclaration() 13785 ->getType() 13786 .getCanonicalType() 13787 ->isAnyPointerType()) { 13788 IsEnclosedByDataEnvironmentExpr = false; 13789 EnclosingExpr = nullptr; 13790 return false; 13791 } 13792 } 13793 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13794 } else { 13795 assert(CKind == OMPC_to || CKind == OMPC_from); 13796 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13797 << ERange; 13798 } 13799 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13800 << RE->getSourceRange(); 13801 return true; 13802 } 13803 13804 // The current expression uses the same base as other expression in the 13805 // data environment but does not contain it completely. 13806 if (!CurrentRegionOnly && SI != SE) 13807 EnclosingExpr = RE; 13808 13809 // The current expression is a subset of the expression in the data 13810 // environment. 13811 IsEnclosedByDataEnvironmentExpr |= 13812 (!CurrentRegionOnly && CI != CE && SI == SE); 13813 13814 return false; 13815 }); 13816 13817 if (CurrentRegionOnly) 13818 return FoundError; 13819 13820 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13821 // If any part of the original storage of a list item has corresponding 13822 // storage in the device data environment, all of the original storage must 13823 // have corresponding storage in the device data environment. 13824 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13825 // If a list item is an element of a structure, and a different element of 13826 // the structure has a corresponding list item in the device data environment 13827 // prior to a task encountering the construct associated with the map clause, 13828 // then the list item must also have a corresponding list item in the device 13829 // data environment prior to the task encountering the construct. 13830 // 13831 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13832 SemaRef.Diag(ELoc, 13833 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13834 << ERange; 13835 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13836 << EnclosingExpr->getSourceRange(); 13837 return true; 13838 } 13839 13840 return FoundError; 13841 } 13842 13843 // Look up the user-defined mapper given the mapper name and mapped type, and 13844 // build a reference to it. 13845 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13846 CXXScopeSpec &MapperIdScopeSpec, 13847 const DeclarationNameInfo &MapperId, 13848 QualType Type, 13849 Expr *UnresolvedMapper) { 13850 if (MapperIdScopeSpec.isInvalid()) 13851 return ExprError(); 13852 // Find all user-defined mappers with the given MapperId. 13853 SmallVector<UnresolvedSet<8>, 4> Lookups; 13854 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13855 Lookup.suppressDiagnostics(); 13856 if (S) { 13857 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13858 NamedDecl *D = Lookup.getRepresentativeDecl(); 13859 while (S && !S->isDeclScope(D)) 13860 S = S->getParent(); 13861 if (S) 13862 S = S->getParent(); 13863 Lookups.emplace_back(); 13864 Lookups.back().append(Lookup.begin(), Lookup.end()); 13865 Lookup.clear(); 13866 } 13867 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13868 // Extract the user-defined mappers with the given MapperId. 13869 Lookups.push_back(UnresolvedSet<8>()); 13870 for (NamedDecl *D : ULE->decls()) { 13871 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13872 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13873 Lookups.back().addDecl(DMD); 13874 } 13875 } 13876 // Defer the lookup for dependent types. The results will be passed through 13877 // UnresolvedMapper on instantiation. 13878 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13879 Type->isInstantiationDependentType() || 13880 Type->containsUnexpandedParameterPack() || 13881 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13882 return !D->isInvalidDecl() && 13883 (D->getType()->isDependentType() || 13884 D->getType()->isInstantiationDependentType() || 13885 D->getType()->containsUnexpandedParameterPack()); 13886 })) { 13887 UnresolvedSet<8> URS; 13888 for (const UnresolvedSet<8> &Set : Lookups) { 13889 if (Set.empty()) 13890 continue; 13891 URS.append(Set.begin(), Set.end()); 13892 } 13893 return UnresolvedLookupExpr::Create( 13894 SemaRef.Context, /*NamingClass=*/nullptr, 13895 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13896 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13897 } 13898 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13899 // The type must be of struct, union or class type in C and C++ 13900 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13901 return ExprEmpty(); 13902 SourceLocation Loc = MapperId.getLoc(); 13903 // Perform argument dependent lookup. 13904 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13905 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13906 // Return the first user-defined mapper with the desired type. 13907 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13908 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13909 if (!D->isInvalidDecl() && 13910 SemaRef.Context.hasSameType(D->getType(), Type)) 13911 return D; 13912 return nullptr; 13913 })) 13914 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13915 // Find the first user-defined mapper with a type derived from the desired 13916 // type. 13917 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13918 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13919 if (!D->isInvalidDecl() && 13920 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13921 !Type.isMoreQualifiedThan(D->getType())) 13922 return D; 13923 return nullptr; 13924 })) { 13925 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13926 /*DetectVirtual=*/false); 13927 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13928 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13929 VD->getType().getUnqualifiedType()))) { 13930 if (SemaRef.CheckBaseClassAccess( 13931 Loc, VD->getType(), Type, Paths.front(), 13932 /*DiagID=*/0) != Sema::AR_inaccessible) { 13933 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13934 } 13935 } 13936 } 13937 } 13938 // Report error if a mapper is specified, but cannot be found. 13939 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13940 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13941 << Type << MapperId.getName(); 13942 return ExprError(); 13943 } 13944 return ExprEmpty(); 13945 } 13946 13947 namespace { 13948 // Utility struct that gathers all the related lists associated with a mappable 13949 // expression. 13950 struct MappableVarListInfo { 13951 // The list of expressions. 13952 ArrayRef<Expr *> VarList; 13953 // The list of processed expressions. 13954 SmallVector<Expr *, 16> ProcessedVarList; 13955 // The mappble components for each expression. 13956 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 13957 // The base declaration of the variable. 13958 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 13959 // The reference to the user-defined mapper associated with every expression. 13960 SmallVector<Expr *, 16> UDMapperList; 13961 13962 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 13963 // We have a list of components and base declarations for each entry in the 13964 // variable list. 13965 VarComponents.reserve(VarList.size()); 13966 VarBaseDeclarations.reserve(VarList.size()); 13967 } 13968 }; 13969 } 13970 13971 // Check the validity of the provided variable list for the provided clause kind 13972 // \a CKind. In the check process the valid expressions, mappable expression 13973 // components, variables, and user-defined mappers are extracted and used to 13974 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 13975 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 13976 // and \a MapperId are expected to be valid if the clause kind is 'map'. 13977 static void checkMappableExpressionList( 13978 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 13979 MappableVarListInfo &MVLI, SourceLocation StartLoc, 13980 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 13981 ArrayRef<Expr *> UnresolvedMappers, 13982 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 13983 bool IsMapTypeImplicit = false) { 13984 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 13985 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 13986 "Unexpected clause kind with mappable expressions!"); 13987 13988 // If the identifier of user-defined mapper is not specified, it is "default". 13989 // We do not change the actual name in this clause to distinguish whether a 13990 // mapper is specified explicitly, i.e., it is not explicitly specified when 13991 // MapperId.getName() is empty. 13992 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 13993 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 13994 MapperId.setName(DeclNames.getIdentifier( 13995 &SemaRef.getASTContext().Idents.get("default"))); 13996 } 13997 13998 // Iterators to find the current unresolved mapper expression. 13999 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14000 bool UpdateUMIt = false; 14001 Expr *UnresolvedMapper = nullptr; 14002 14003 // Keep track of the mappable components and base declarations in this clause. 14004 // Each entry in the list is going to have a list of components associated. We 14005 // record each set of the components so that we can build the clause later on. 14006 // In the end we should have the same amount of declarations and component 14007 // lists. 14008 14009 for (Expr *RE : MVLI.VarList) { 14010 assert(RE && "Null expr in omp to/from/map clause"); 14011 SourceLocation ELoc = RE->getExprLoc(); 14012 14013 // Find the current unresolved mapper expression. 14014 if (UpdateUMIt && UMIt != UMEnd) { 14015 UMIt++; 14016 assert( 14017 UMIt != UMEnd && 14018 "Expect the size of UnresolvedMappers to match with that of VarList"); 14019 } 14020 UpdateUMIt = true; 14021 if (UMIt != UMEnd) 14022 UnresolvedMapper = *UMIt; 14023 14024 const Expr *VE = RE->IgnoreParenLValueCasts(); 14025 14026 if (VE->isValueDependent() || VE->isTypeDependent() || 14027 VE->isInstantiationDependent() || 14028 VE->containsUnexpandedParameterPack()) { 14029 // Try to find the associated user-defined mapper. 14030 ExprResult ER = buildUserDefinedMapperRef( 14031 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14032 VE->getType().getCanonicalType(), UnresolvedMapper); 14033 if (ER.isInvalid()) 14034 continue; 14035 MVLI.UDMapperList.push_back(ER.get()); 14036 // We can only analyze this information once the missing information is 14037 // resolved. 14038 MVLI.ProcessedVarList.push_back(RE); 14039 continue; 14040 } 14041 14042 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14043 14044 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14045 SemaRef.Diag(ELoc, 14046 diag::err_omp_expected_named_var_member_or_array_expression) 14047 << RE->getSourceRange(); 14048 continue; 14049 } 14050 14051 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14052 ValueDecl *CurDeclaration = nullptr; 14053 14054 // Obtain the array or member expression bases if required. Also, fill the 14055 // components array with all the components identified in the process. 14056 const Expr *BE = checkMapClauseExpressionBase( 14057 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14058 if (!BE) 14059 continue; 14060 14061 assert(!CurComponents.empty() && 14062 "Invalid mappable expression information."); 14063 14064 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14065 // Add store "this" pointer to class in DSAStackTy for future checking 14066 DSAS->addMappedClassesQualTypes(TE->getType()); 14067 // Try to find the associated user-defined mapper. 14068 ExprResult ER = buildUserDefinedMapperRef( 14069 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14070 VE->getType().getCanonicalType(), UnresolvedMapper); 14071 if (ER.isInvalid()) 14072 continue; 14073 MVLI.UDMapperList.push_back(ER.get()); 14074 // Skip restriction checking for variable or field declarations 14075 MVLI.ProcessedVarList.push_back(RE); 14076 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14077 MVLI.VarComponents.back().append(CurComponents.begin(), 14078 CurComponents.end()); 14079 MVLI.VarBaseDeclarations.push_back(nullptr); 14080 continue; 14081 } 14082 14083 // For the following checks, we rely on the base declaration which is 14084 // expected to be associated with the last component. The declaration is 14085 // expected to be a variable or a field (if 'this' is being mapped). 14086 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14087 assert(CurDeclaration && "Null decl on map clause."); 14088 assert( 14089 CurDeclaration->isCanonicalDecl() && 14090 "Expecting components to have associated only canonical declarations."); 14091 14092 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14093 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14094 14095 assert((VD || FD) && "Only variables or fields are expected here!"); 14096 (void)FD; 14097 14098 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14099 // threadprivate variables cannot appear in a map clause. 14100 // OpenMP 4.5 [2.10.5, target update Construct] 14101 // threadprivate variables cannot appear in a from clause. 14102 if (VD && DSAS->isThreadPrivate(VD)) { 14103 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14104 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14105 << getOpenMPClauseName(CKind); 14106 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14107 continue; 14108 } 14109 14110 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14111 // A list item cannot appear in both a map clause and a data-sharing 14112 // attribute clause on the same construct. 14113 14114 // Check conflicts with other map clause expressions. We check the conflicts 14115 // with the current construct separately from the enclosing data 14116 // environment, because the restrictions are different. We only have to 14117 // check conflicts across regions for the map clauses. 14118 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14119 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14120 break; 14121 if (CKind == OMPC_map && 14122 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14123 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14124 break; 14125 14126 // OpenMP 4.5 [2.10.5, target update Construct] 14127 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14128 // If the type of a list item is a reference to a type T then the type will 14129 // be considered to be T for all purposes of this clause. 14130 auto I = llvm::find_if( 14131 CurComponents, 14132 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14133 return MC.getAssociatedDeclaration(); 14134 }); 14135 assert(I != CurComponents.end() && "Null decl on map clause."); 14136 QualType Type = 14137 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14138 14139 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14140 // A list item in a to or from clause must have a mappable type. 14141 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14142 // A list item must have a mappable type. 14143 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14144 DSAS, Type)) 14145 continue; 14146 14147 if (CKind == OMPC_map) { 14148 // target enter data 14149 // OpenMP [2.10.2, Restrictions, p. 99] 14150 // A map-type must be specified in all map clauses and must be either 14151 // to or alloc. 14152 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14153 if (DKind == OMPD_target_enter_data && 14154 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14155 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14156 << (IsMapTypeImplicit ? 1 : 0) 14157 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14158 << getOpenMPDirectiveName(DKind); 14159 continue; 14160 } 14161 14162 // target exit_data 14163 // OpenMP [2.10.3, Restrictions, p. 102] 14164 // A map-type must be specified in all map clauses and must be either 14165 // from, release, or delete. 14166 if (DKind == OMPD_target_exit_data && 14167 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14168 MapType == OMPC_MAP_delete)) { 14169 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14170 << (IsMapTypeImplicit ? 1 : 0) 14171 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14172 << getOpenMPDirectiveName(DKind); 14173 continue; 14174 } 14175 14176 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14177 // A list item cannot appear in both a map clause and a data-sharing 14178 // attribute clause on the same construct 14179 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 14180 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14181 if (isOpenMPPrivate(DVar.CKind)) { 14182 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14183 << getOpenMPClauseName(DVar.CKind) 14184 << getOpenMPClauseName(OMPC_map) 14185 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14186 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14187 continue; 14188 } 14189 } 14190 } 14191 14192 // Try to find the associated user-defined mapper. 14193 ExprResult ER = buildUserDefinedMapperRef( 14194 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14195 Type.getCanonicalType(), UnresolvedMapper); 14196 if (ER.isInvalid()) 14197 continue; 14198 MVLI.UDMapperList.push_back(ER.get()); 14199 14200 // Save the current expression. 14201 MVLI.ProcessedVarList.push_back(RE); 14202 14203 // Store the components in the stack so that they can be used to check 14204 // against other clauses later on. 14205 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14206 /*WhereFoundClauseKind=*/OMPC_map); 14207 14208 // Save the components and declaration to create the clause. For purposes of 14209 // the clause creation, any component list that has has base 'this' uses 14210 // null as base declaration. 14211 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14212 MVLI.VarComponents.back().append(CurComponents.begin(), 14213 CurComponents.end()); 14214 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14215 : CurDeclaration); 14216 } 14217 } 14218 14219 OMPClause *Sema::ActOnOpenMPMapClause( 14220 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14221 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14222 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14223 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14224 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14225 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14226 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14227 OMPC_MAP_MODIFIER_unknown, 14228 OMPC_MAP_MODIFIER_unknown}; 14229 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14230 14231 // Process map-type-modifiers, flag errors for duplicate modifiers. 14232 unsigned Count = 0; 14233 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14234 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14235 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14236 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14237 continue; 14238 } 14239 assert(Count < OMPMapClause::NumberOfModifiers && 14240 "Modifiers exceed the allowed number of map type modifiers"); 14241 Modifiers[Count] = MapTypeModifiers[I]; 14242 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14243 ++Count; 14244 } 14245 14246 MappableVarListInfo MVLI(VarList); 14247 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14248 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14249 MapType, IsMapTypeImplicit); 14250 14251 // We need to produce a map clause even if we don't have variables so that 14252 // other diagnostics related with non-existing map clauses are accurate. 14253 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14254 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14255 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14256 MapperIdScopeSpec.getWithLocInContext(Context), 14257 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14258 } 14259 14260 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14261 TypeResult ParsedType) { 14262 assert(ParsedType.isUsable()); 14263 14264 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14265 if (ReductionType.isNull()) 14266 return QualType(); 14267 14268 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14269 // A type name in a declare reduction directive cannot be a function type, an 14270 // array type, a reference type, or a type qualified with const, volatile or 14271 // restrict. 14272 if (ReductionType.hasQualifiers()) { 14273 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14274 return QualType(); 14275 } 14276 14277 if (ReductionType->isFunctionType()) { 14278 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14279 return QualType(); 14280 } 14281 if (ReductionType->isReferenceType()) { 14282 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14283 return QualType(); 14284 } 14285 if (ReductionType->isArrayType()) { 14286 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14287 return QualType(); 14288 } 14289 return ReductionType; 14290 } 14291 14292 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14293 Scope *S, DeclContext *DC, DeclarationName Name, 14294 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14295 AccessSpecifier AS, Decl *PrevDeclInScope) { 14296 SmallVector<Decl *, 8> Decls; 14297 Decls.reserve(ReductionTypes.size()); 14298 14299 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14300 forRedeclarationInCurContext()); 14301 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14302 // A reduction-identifier may not be re-declared in the current scope for the 14303 // same type or for a type that is compatible according to the base language 14304 // rules. 14305 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14306 OMPDeclareReductionDecl *PrevDRD = nullptr; 14307 bool InCompoundScope = true; 14308 if (S != nullptr) { 14309 // Find previous declaration with the same name not referenced in other 14310 // declarations. 14311 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14312 InCompoundScope = 14313 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14314 LookupName(Lookup, S); 14315 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14316 /*AllowInlineNamespace=*/false); 14317 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14318 LookupResult::Filter Filter = Lookup.makeFilter(); 14319 while (Filter.hasNext()) { 14320 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14321 if (InCompoundScope) { 14322 auto I = UsedAsPrevious.find(PrevDecl); 14323 if (I == UsedAsPrevious.end()) 14324 UsedAsPrevious[PrevDecl] = false; 14325 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14326 UsedAsPrevious[D] = true; 14327 } 14328 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14329 PrevDecl->getLocation(); 14330 } 14331 Filter.done(); 14332 if (InCompoundScope) { 14333 for (const auto &PrevData : UsedAsPrevious) { 14334 if (!PrevData.second) { 14335 PrevDRD = PrevData.first; 14336 break; 14337 } 14338 } 14339 } 14340 } else if (PrevDeclInScope != nullptr) { 14341 auto *PrevDRDInScope = PrevDRD = 14342 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14343 do { 14344 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14345 PrevDRDInScope->getLocation(); 14346 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14347 } while (PrevDRDInScope != nullptr); 14348 } 14349 for (const auto &TyData : ReductionTypes) { 14350 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14351 bool Invalid = false; 14352 if (I != PreviousRedeclTypes.end()) { 14353 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14354 << TyData.first; 14355 Diag(I->second, diag::note_previous_definition); 14356 Invalid = true; 14357 } 14358 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 14359 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 14360 Name, TyData.first, PrevDRD); 14361 DC->addDecl(DRD); 14362 DRD->setAccess(AS); 14363 Decls.push_back(DRD); 14364 if (Invalid) 14365 DRD->setInvalidDecl(); 14366 else 14367 PrevDRD = DRD; 14368 } 14369 14370 return DeclGroupPtrTy::make( 14371 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 14372 } 14373 14374 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 14375 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14376 14377 // Enter new function scope. 14378 PushFunctionScope(); 14379 setFunctionHasBranchProtectedScope(); 14380 getCurFunction()->setHasOMPDeclareReductionCombiner(); 14381 14382 if (S != nullptr) 14383 PushDeclContext(S, DRD); 14384 else 14385 CurContext = DRD; 14386 14387 PushExpressionEvaluationContext( 14388 ExpressionEvaluationContext::PotentiallyEvaluated); 14389 14390 QualType ReductionType = DRD->getType(); 14391 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 14392 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 14393 // uses semantics of argument handles by value, but it should be passed by 14394 // reference. C lang does not support references, so pass all parameters as 14395 // pointers. 14396 // Create 'T omp_in;' variable. 14397 VarDecl *OmpInParm = 14398 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 14399 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 14400 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 14401 // uses semantics of argument handles by value, but it should be passed by 14402 // reference. C lang does not support references, so pass all parameters as 14403 // pointers. 14404 // Create 'T omp_out;' variable. 14405 VarDecl *OmpOutParm = 14406 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 14407 if (S != nullptr) { 14408 PushOnScopeChains(OmpInParm, S); 14409 PushOnScopeChains(OmpOutParm, S); 14410 } else { 14411 DRD->addDecl(OmpInParm); 14412 DRD->addDecl(OmpOutParm); 14413 } 14414 Expr *InE = 14415 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 14416 Expr *OutE = 14417 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 14418 DRD->setCombinerData(InE, OutE); 14419 } 14420 14421 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 14422 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14423 DiscardCleanupsInEvaluationContext(); 14424 PopExpressionEvaluationContext(); 14425 14426 PopDeclContext(); 14427 PopFunctionScopeInfo(); 14428 14429 if (Combiner != nullptr) 14430 DRD->setCombiner(Combiner); 14431 else 14432 DRD->setInvalidDecl(); 14433 } 14434 14435 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 14436 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14437 14438 // Enter new function scope. 14439 PushFunctionScope(); 14440 setFunctionHasBranchProtectedScope(); 14441 14442 if (S != nullptr) 14443 PushDeclContext(S, DRD); 14444 else 14445 CurContext = DRD; 14446 14447 PushExpressionEvaluationContext( 14448 ExpressionEvaluationContext::PotentiallyEvaluated); 14449 14450 QualType ReductionType = DRD->getType(); 14451 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 14452 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 14453 // uses semantics of argument handles by value, but it should be passed by 14454 // reference. C lang does not support references, so pass all parameters as 14455 // pointers. 14456 // Create 'T omp_priv;' variable. 14457 VarDecl *OmpPrivParm = 14458 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 14459 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 14460 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 14461 // uses semantics of argument handles by value, but it should be passed by 14462 // reference. C lang does not support references, so pass all parameters as 14463 // pointers. 14464 // Create 'T omp_orig;' variable. 14465 VarDecl *OmpOrigParm = 14466 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 14467 if (S != nullptr) { 14468 PushOnScopeChains(OmpPrivParm, S); 14469 PushOnScopeChains(OmpOrigParm, S); 14470 } else { 14471 DRD->addDecl(OmpPrivParm); 14472 DRD->addDecl(OmpOrigParm); 14473 } 14474 Expr *OrigE = 14475 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 14476 Expr *PrivE = 14477 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 14478 DRD->setInitializerData(OrigE, PrivE); 14479 return OmpPrivParm; 14480 } 14481 14482 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 14483 VarDecl *OmpPrivParm) { 14484 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14485 DiscardCleanupsInEvaluationContext(); 14486 PopExpressionEvaluationContext(); 14487 14488 PopDeclContext(); 14489 PopFunctionScopeInfo(); 14490 14491 if (Initializer != nullptr) { 14492 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 14493 } else if (OmpPrivParm->hasInit()) { 14494 DRD->setInitializer(OmpPrivParm->getInit(), 14495 OmpPrivParm->isDirectInit() 14496 ? OMPDeclareReductionDecl::DirectInit 14497 : OMPDeclareReductionDecl::CopyInit); 14498 } else { 14499 DRD->setInvalidDecl(); 14500 } 14501 } 14502 14503 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14504 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14505 for (Decl *D : DeclReductions.get()) { 14506 if (IsValid) { 14507 if (S) 14508 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14509 /*AddToContext=*/false); 14510 } else { 14511 D->setInvalidDecl(); 14512 } 14513 } 14514 return DeclReductions; 14515 } 14516 14517 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14518 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14519 QualType T = TInfo->getType(); 14520 if (D.isInvalidType()) 14521 return true; 14522 14523 if (getLangOpts().CPlusPlus) { 14524 // Check that there are no default arguments (C++ only). 14525 CheckExtraCXXDefaultArguments(D); 14526 } 14527 14528 return CreateParsedType(T, TInfo); 14529 } 14530 14531 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14532 TypeResult ParsedType) { 14533 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14534 14535 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14536 assert(!MapperType.isNull() && "Expect valid mapper type"); 14537 14538 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14539 // The type must be of struct, union or class type in C and C++ 14540 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14541 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14542 return QualType(); 14543 } 14544 return MapperType; 14545 } 14546 14547 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14548 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14549 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14550 Decl *PrevDeclInScope) { 14551 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14552 forRedeclarationInCurContext()); 14553 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14554 // A mapper-identifier may not be redeclared in the current scope for the 14555 // same type or for a type that is compatible according to the base language 14556 // rules. 14557 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14558 OMPDeclareMapperDecl *PrevDMD = nullptr; 14559 bool InCompoundScope = true; 14560 if (S != nullptr) { 14561 // Find previous declaration with the same name not referenced in other 14562 // declarations. 14563 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14564 InCompoundScope = 14565 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14566 LookupName(Lookup, S); 14567 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14568 /*AllowInlineNamespace=*/false); 14569 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14570 LookupResult::Filter Filter = Lookup.makeFilter(); 14571 while (Filter.hasNext()) { 14572 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14573 if (InCompoundScope) { 14574 auto I = UsedAsPrevious.find(PrevDecl); 14575 if (I == UsedAsPrevious.end()) 14576 UsedAsPrevious[PrevDecl] = false; 14577 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 14578 UsedAsPrevious[D] = true; 14579 } 14580 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14581 PrevDecl->getLocation(); 14582 } 14583 Filter.done(); 14584 if (InCompoundScope) { 14585 for (const auto &PrevData : UsedAsPrevious) { 14586 if (!PrevData.second) { 14587 PrevDMD = PrevData.first; 14588 break; 14589 } 14590 } 14591 } 14592 } else if (PrevDeclInScope) { 14593 auto *PrevDMDInScope = PrevDMD = 14594 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 14595 do { 14596 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 14597 PrevDMDInScope->getLocation(); 14598 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 14599 } while (PrevDMDInScope != nullptr); 14600 } 14601 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 14602 bool Invalid = false; 14603 if (I != PreviousRedeclTypes.end()) { 14604 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 14605 << MapperType << Name; 14606 Diag(I->second, diag::note_previous_definition); 14607 Invalid = true; 14608 } 14609 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 14610 MapperType, VN, PrevDMD); 14611 DC->addDecl(DMD); 14612 DMD->setAccess(AS); 14613 if (Invalid) 14614 DMD->setInvalidDecl(); 14615 14616 // Enter new function scope. 14617 PushFunctionScope(); 14618 setFunctionHasBranchProtectedScope(); 14619 14620 CurContext = DMD; 14621 14622 return DMD; 14623 } 14624 14625 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 14626 Scope *S, 14627 QualType MapperType, 14628 SourceLocation StartLoc, 14629 DeclarationName VN) { 14630 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 14631 if (S) 14632 PushOnScopeChains(VD, S); 14633 else 14634 DMD->addDecl(VD); 14635 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 14636 DMD->setMapperVarRef(MapperVarRefExpr); 14637 } 14638 14639 Sema::DeclGroupPtrTy 14640 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 14641 ArrayRef<OMPClause *> ClauseList) { 14642 PopDeclContext(); 14643 PopFunctionScopeInfo(); 14644 14645 if (D) { 14646 if (S) 14647 PushOnScopeChains(D, S, /*AddToContext=*/false); 14648 D->CreateClauses(Context, ClauseList); 14649 } 14650 14651 return DeclGroupPtrTy::make(DeclGroupRef(D)); 14652 } 14653 14654 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 14655 SourceLocation StartLoc, 14656 SourceLocation LParenLoc, 14657 SourceLocation EndLoc) { 14658 Expr *ValExpr = NumTeams; 14659 Stmt *HelperValStmt = nullptr; 14660 14661 // OpenMP [teams Constrcut, Restrictions] 14662 // The num_teams expression must evaluate to a positive integer value. 14663 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 14664 /*StrictlyPositive=*/true)) 14665 return nullptr; 14666 14667 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14668 OpenMPDirectiveKind CaptureRegion = 14669 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 14670 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14671 ValExpr = MakeFullExpr(ValExpr).get(); 14672 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14673 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14674 HelperValStmt = buildPreInits(Context, Captures); 14675 } 14676 14677 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14678 StartLoc, LParenLoc, EndLoc); 14679 } 14680 14681 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14682 SourceLocation StartLoc, 14683 SourceLocation LParenLoc, 14684 SourceLocation EndLoc) { 14685 Expr *ValExpr = ThreadLimit; 14686 Stmt *HelperValStmt = nullptr; 14687 14688 // OpenMP [teams Constrcut, Restrictions] 14689 // The thread_limit expression must evaluate to a positive integer value. 14690 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14691 /*StrictlyPositive=*/true)) 14692 return nullptr; 14693 14694 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14695 OpenMPDirectiveKind CaptureRegion = 14696 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14697 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14698 ValExpr = MakeFullExpr(ValExpr).get(); 14699 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14700 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14701 HelperValStmt = buildPreInits(Context, Captures); 14702 } 14703 14704 return new (Context) OMPThreadLimitClause( 14705 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14706 } 14707 14708 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14709 SourceLocation StartLoc, 14710 SourceLocation LParenLoc, 14711 SourceLocation EndLoc) { 14712 Expr *ValExpr = Priority; 14713 14714 // OpenMP [2.9.1, task Constrcut] 14715 // The priority-value is a non-negative numerical scalar expression. 14716 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14717 /*StrictlyPositive=*/false)) 14718 return nullptr; 14719 14720 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14721 } 14722 14723 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14724 SourceLocation StartLoc, 14725 SourceLocation LParenLoc, 14726 SourceLocation EndLoc) { 14727 Expr *ValExpr = Grainsize; 14728 14729 // OpenMP [2.9.2, taskloop Constrcut] 14730 // The parameter of the grainsize clause must be a positive integer 14731 // expression. 14732 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14733 /*StrictlyPositive=*/true)) 14734 return nullptr; 14735 14736 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14737 } 14738 14739 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14740 SourceLocation StartLoc, 14741 SourceLocation LParenLoc, 14742 SourceLocation EndLoc) { 14743 Expr *ValExpr = NumTasks; 14744 14745 // OpenMP [2.9.2, taskloop Constrcut] 14746 // The parameter of the num_tasks clause must be a positive integer 14747 // expression. 14748 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14749 /*StrictlyPositive=*/true)) 14750 return nullptr; 14751 14752 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14753 } 14754 14755 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14756 SourceLocation LParenLoc, 14757 SourceLocation EndLoc) { 14758 // OpenMP [2.13.2, critical construct, Description] 14759 // ... where hint-expression is an integer constant expression that evaluates 14760 // to a valid lock hint. 14761 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14762 if (HintExpr.isInvalid()) 14763 return nullptr; 14764 return new (Context) 14765 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14766 } 14767 14768 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14769 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14770 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14771 SourceLocation EndLoc) { 14772 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14773 std::string Values; 14774 Values += "'"; 14775 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14776 Values += "'"; 14777 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14778 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14779 return nullptr; 14780 } 14781 Expr *ValExpr = ChunkSize; 14782 Stmt *HelperValStmt = nullptr; 14783 if (ChunkSize) { 14784 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14785 !ChunkSize->isInstantiationDependent() && 14786 !ChunkSize->containsUnexpandedParameterPack()) { 14787 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14788 ExprResult Val = 14789 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14790 if (Val.isInvalid()) 14791 return nullptr; 14792 14793 ValExpr = Val.get(); 14794 14795 // OpenMP [2.7.1, Restrictions] 14796 // chunk_size must be a loop invariant integer expression with a positive 14797 // value. 14798 llvm::APSInt Result; 14799 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14800 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14801 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14802 << "dist_schedule" << ChunkSize->getSourceRange(); 14803 return nullptr; 14804 } 14805 } else if (getOpenMPCaptureRegionForClause( 14806 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14807 OMPD_unknown && 14808 !CurContext->isDependentContext()) { 14809 ValExpr = MakeFullExpr(ValExpr).get(); 14810 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14811 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14812 HelperValStmt = buildPreInits(Context, Captures); 14813 } 14814 } 14815 } 14816 14817 return new (Context) 14818 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14819 Kind, ValExpr, HelperValStmt); 14820 } 14821 14822 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14823 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14824 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14825 SourceLocation KindLoc, SourceLocation EndLoc) { 14826 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14827 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14828 std::string Value; 14829 SourceLocation Loc; 14830 Value += "'"; 14831 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14832 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14833 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14834 Loc = MLoc; 14835 } else { 14836 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14837 OMPC_DEFAULTMAP_scalar); 14838 Loc = KindLoc; 14839 } 14840 Value += "'"; 14841 Diag(Loc, diag::err_omp_unexpected_clause_value) 14842 << Value << getOpenMPClauseName(OMPC_defaultmap); 14843 return nullptr; 14844 } 14845 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14846 14847 return new (Context) 14848 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14849 } 14850 14851 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14852 DeclContext *CurLexicalContext = getCurLexicalContext(); 14853 if (!CurLexicalContext->isFileContext() && 14854 !CurLexicalContext->isExternCContext() && 14855 !CurLexicalContext->isExternCXXContext() && 14856 !isa<CXXRecordDecl>(CurLexicalContext) && 14857 !isa<ClassTemplateDecl>(CurLexicalContext) && 14858 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14859 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14860 Diag(Loc, diag::err_omp_region_not_file_context); 14861 return false; 14862 } 14863 ++DeclareTargetNestingLevel; 14864 return true; 14865 } 14866 14867 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14868 assert(DeclareTargetNestingLevel > 0 && 14869 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14870 --DeclareTargetNestingLevel; 14871 } 14872 14873 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14874 CXXScopeSpec &ScopeSpec, 14875 const DeclarationNameInfo &Id, 14876 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14877 NamedDeclSetType &SameDirectiveDecls) { 14878 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14879 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14880 14881 if (Lookup.isAmbiguous()) 14882 return; 14883 Lookup.suppressDiagnostics(); 14884 14885 if (!Lookup.isSingleResult()) { 14886 VarOrFuncDeclFilterCCC CCC(*this); 14887 if (TypoCorrection Corrected = 14888 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 14889 CTK_ErrorRecovery)) { 14890 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14891 << Id.getName()); 14892 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14893 return; 14894 } 14895 14896 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14897 return; 14898 } 14899 14900 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14901 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14902 isa<FunctionTemplateDecl>(ND)) { 14903 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14904 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14905 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14906 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14907 cast<ValueDecl>(ND)); 14908 if (!Res) { 14909 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14910 ND->addAttr(A); 14911 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14912 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14913 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14914 } else if (*Res != MT) { 14915 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14916 << Id.getName(); 14917 } 14918 } else { 14919 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14920 } 14921 } 14922 14923 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14924 Sema &SemaRef, Decl *D) { 14925 if (!D || !isa<VarDecl>(D)) 14926 return; 14927 auto *VD = cast<VarDecl>(D); 14928 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14929 return; 14930 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14931 SemaRef.Diag(SL, diag::note_used_here) << SR; 14932 } 14933 14934 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14935 Sema &SemaRef, DSAStackTy *Stack, 14936 ValueDecl *VD) { 14937 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14938 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14939 /*FullCheck=*/false); 14940 } 14941 14942 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14943 SourceLocation IdLoc) { 14944 if (!D || D->isInvalidDecl()) 14945 return; 14946 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14947 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 14948 if (auto *VD = dyn_cast<VarDecl>(D)) { 14949 // Only global variables can be marked as declare target. 14950 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 14951 !VD->isStaticDataMember()) 14952 return; 14953 // 2.10.6: threadprivate variable cannot appear in a declare target 14954 // directive. 14955 if (DSAStack->isThreadPrivate(VD)) { 14956 Diag(SL, diag::err_omp_threadprivate_in_target); 14957 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 14958 return; 14959 } 14960 } 14961 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 14962 D = FTD->getTemplatedDecl(); 14963 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 14964 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14965 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 14966 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 14967 assert(IdLoc.isValid() && "Source location is expected"); 14968 Diag(IdLoc, diag::err_omp_function_in_link_clause); 14969 Diag(FD->getLocation(), diag::note_defined_here) << FD; 14970 return; 14971 } 14972 } 14973 if (auto *VD = dyn_cast<ValueDecl>(D)) { 14974 // Problem if any with var declared with incomplete type will be reported 14975 // as normal, so no need to check it here. 14976 if ((E || !VD->getType()->isIncompleteType()) && 14977 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 14978 return; 14979 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 14980 // Checking declaration inside declare target region. 14981 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 14982 isa<FunctionTemplateDecl>(D)) { 14983 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 14984 Context, OMPDeclareTargetDeclAttr::MT_To); 14985 D->addAttr(A); 14986 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14987 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 14988 } 14989 return; 14990 } 14991 } 14992 if (!E) 14993 return; 14994 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 14995 } 14996 14997 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 14998 CXXScopeSpec &MapperIdScopeSpec, 14999 DeclarationNameInfo &MapperId, 15000 const OMPVarListLocTy &Locs, 15001 ArrayRef<Expr *> UnresolvedMappers) { 15002 MappableVarListInfo MVLI(VarList); 15003 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15004 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15005 if (MVLI.ProcessedVarList.empty()) 15006 return nullptr; 15007 15008 return OMPToClause::Create( 15009 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15010 MVLI.VarComponents, MVLI.UDMapperList, 15011 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15012 } 15013 15014 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15015 CXXScopeSpec &MapperIdScopeSpec, 15016 DeclarationNameInfo &MapperId, 15017 const OMPVarListLocTy &Locs, 15018 ArrayRef<Expr *> UnresolvedMappers) { 15019 MappableVarListInfo MVLI(VarList); 15020 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15021 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15022 if (MVLI.ProcessedVarList.empty()) 15023 return nullptr; 15024 15025 return OMPFromClause::Create( 15026 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15027 MVLI.VarComponents, MVLI.UDMapperList, 15028 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15029 } 15030 15031 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15032 const OMPVarListLocTy &Locs) { 15033 MappableVarListInfo MVLI(VarList); 15034 SmallVector<Expr *, 8> PrivateCopies; 15035 SmallVector<Expr *, 8> Inits; 15036 15037 for (Expr *RefExpr : VarList) { 15038 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15039 SourceLocation ELoc; 15040 SourceRange ERange; 15041 Expr *SimpleRefExpr = RefExpr; 15042 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15043 if (Res.second) { 15044 // It will be analyzed later. 15045 MVLI.ProcessedVarList.push_back(RefExpr); 15046 PrivateCopies.push_back(nullptr); 15047 Inits.push_back(nullptr); 15048 } 15049 ValueDecl *D = Res.first; 15050 if (!D) 15051 continue; 15052 15053 QualType Type = D->getType(); 15054 Type = Type.getNonReferenceType().getUnqualifiedType(); 15055 15056 auto *VD = dyn_cast<VarDecl>(D); 15057 15058 // Item should be a pointer or reference to pointer. 15059 if (!Type->isPointerType()) { 15060 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15061 << 0 << RefExpr->getSourceRange(); 15062 continue; 15063 } 15064 15065 // Build the private variable and the expression that refers to it. 15066 auto VDPrivate = 15067 buildVarDecl(*this, ELoc, Type, D->getName(), 15068 D->hasAttrs() ? &D->getAttrs() : nullptr, 15069 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15070 if (VDPrivate->isInvalidDecl()) 15071 continue; 15072 15073 CurContext->addDecl(VDPrivate); 15074 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15075 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15076 15077 // Add temporary variable to initialize the private copy of the pointer. 15078 VarDecl *VDInit = 15079 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15080 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15081 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15082 AddInitializerToDecl(VDPrivate, 15083 DefaultLvalueConversion(VDInitRefExpr).get(), 15084 /*DirectInit=*/false); 15085 15086 // If required, build a capture to implement the privatization initialized 15087 // with the current list item value. 15088 DeclRefExpr *Ref = nullptr; 15089 if (!VD) 15090 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15091 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15092 PrivateCopies.push_back(VDPrivateRefExpr); 15093 Inits.push_back(VDInitRefExpr); 15094 15095 // We need to add a data sharing attribute for this variable to make sure it 15096 // is correctly captured. A variable that shows up in a use_device_ptr has 15097 // similar properties of a first private variable. 15098 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15099 15100 // Create a mappable component for the list item. List items in this clause 15101 // only need a component. 15102 MVLI.VarBaseDeclarations.push_back(D); 15103 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15104 MVLI.VarComponents.back().push_back( 15105 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15106 } 15107 15108 if (MVLI.ProcessedVarList.empty()) 15109 return nullptr; 15110 15111 return OMPUseDevicePtrClause::Create( 15112 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15113 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15114 } 15115 15116 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15117 const OMPVarListLocTy &Locs) { 15118 MappableVarListInfo MVLI(VarList); 15119 for (Expr *RefExpr : VarList) { 15120 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15121 SourceLocation ELoc; 15122 SourceRange ERange; 15123 Expr *SimpleRefExpr = RefExpr; 15124 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15125 if (Res.second) { 15126 // It will be analyzed later. 15127 MVLI.ProcessedVarList.push_back(RefExpr); 15128 } 15129 ValueDecl *D = Res.first; 15130 if (!D) 15131 continue; 15132 15133 QualType Type = D->getType(); 15134 // item should be a pointer or array or reference to pointer or array 15135 if (!Type.getNonReferenceType()->isPointerType() && 15136 !Type.getNonReferenceType()->isArrayType()) { 15137 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15138 << 0 << RefExpr->getSourceRange(); 15139 continue; 15140 } 15141 15142 // Check if the declaration in the clause does not show up in any data 15143 // sharing attribute. 15144 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15145 if (isOpenMPPrivate(DVar.CKind)) { 15146 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15147 << getOpenMPClauseName(DVar.CKind) 15148 << getOpenMPClauseName(OMPC_is_device_ptr) 15149 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15150 reportOriginalDsa(*this, DSAStack, D, DVar); 15151 continue; 15152 } 15153 15154 const Expr *ConflictExpr; 15155 if (DSAStack->checkMappableExprComponentListsForDecl( 15156 D, /*CurrentRegionOnly=*/true, 15157 [&ConflictExpr]( 15158 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15159 OpenMPClauseKind) -> bool { 15160 ConflictExpr = R.front().getAssociatedExpression(); 15161 return true; 15162 })) { 15163 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15164 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15165 << ConflictExpr->getSourceRange(); 15166 continue; 15167 } 15168 15169 // Store the components in the stack so that they can be used to check 15170 // against other clauses later on. 15171 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15172 DSAStack->addMappableExpressionComponents( 15173 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15174 15175 // Record the expression we've just processed. 15176 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15177 15178 // Create a mappable component for the list item. List items in this clause 15179 // only need a component. We use a null declaration to signal fields in 15180 // 'this'. 15181 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15182 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15183 "Unexpected device pointer expression!"); 15184 MVLI.VarBaseDeclarations.push_back( 15185 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15186 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15187 MVLI.VarComponents.back().push_back(MC); 15188 } 15189 15190 if (MVLI.ProcessedVarList.empty()) 15191 return nullptr; 15192 15193 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15194 MVLI.VarBaseDeclarations, 15195 MVLI.VarComponents); 15196 } 15197 15198 OMPClause *Sema::ActOnOpenMPAllocateClause( 15199 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15200 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15201 if (Allocator) { 15202 // OpenMP [2.11.4 allocate Clause, Description] 15203 // allocator is an expression of omp_allocator_handle_t type. 15204 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15205 return nullptr; 15206 15207 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15208 if (AllocatorRes.isInvalid()) 15209 return nullptr; 15210 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15211 DSAStack->getOMPAllocatorHandleT(), 15212 Sema::AA_Initializing, 15213 /*AllowExplicit=*/true); 15214 if (AllocatorRes.isInvalid()) 15215 return nullptr; 15216 Allocator = AllocatorRes.get(); 15217 } else { 15218 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15219 // allocate clauses that appear on a target construct or on constructs in a 15220 // target region must specify an allocator expression unless a requires 15221 // directive with the dynamic_allocators clause is present in the same 15222 // compilation unit. 15223 if (LangOpts.OpenMPIsDevice && 15224 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15225 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15226 } 15227 // Analyze and build list of variables. 15228 SmallVector<Expr *, 8> Vars; 15229 for (Expr *RefExpr : VarList) { 15230 assert(RefExpr && "NULL expr in OpenMP private clause."); 15231 SourceLocation ELoc; 15232 SourceRange ERange; 15233 Expr *SimpleRefExpr = RefExpr; 15234 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15235 if (Res.second) { 15236 // It will be analyzed later. 15237 Vars.push_back(RefExpr); 15238 } 15239 ValueDecl *D = Res.first; 15240 if (!D) 15241 continue; 15242 15243 auto *VD = dyn_cast<VarDecl>(D); 15244 DeclRefExpr *Ref = nullptr; 15245 if (!VD && !CurContext->isDependentContext()) 15246 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15247 Vars.push_back((VD || CurContext->isDependentContext()) 15248 ? RefExpr->IgnoreParens() 15249 : Ref); 15250 } 15251 15252 if (Vars.empty()) 15253 return nullptr; 15254 15255 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15256 ColonLoc, EndLoc, Vars); 15257 } 15258