1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 const Decl *PossiblyLoopCounter = nullptr; 143 bool NowaitRegion = false; 144 bool CancelRegion = false; 145 bool LoopStart = false; 146 bool BodyComplete = false; 147 SourceLocation InnerTeamsRegionLoc; 148 /// Reference to the taskgroup task_reduction reference expression. 149 Expr *TaskgroupReductionRef = nullptr; 150 llvm::DenseSet<QualType> MappedClassesQualTypes; 151 /// List of globals marked as declare target link in this target region 152 /// (isOpenMPTargetExecutionDirective(Directive) == true). 153 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 154 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 155 Scope *CurScope, SourceLocation Loc) 156 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 157 ConstructLoc(Loc) {} 158 SharingMapTy() = default; 159 }; 160 161 using StackTy = SmallVector<SharingMapTy, 4>; 162 163 /// Stack of used declaration and their data-sharing attributes. 164 DeclSAMapTy Threadprivates; 165 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 166 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 167 /// true, if check for DSA must be from parent directive, false, if 168 /// from current directive. 169 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 170 Sema &SemaRef; 171 bool ForceCapturing = false; 172 /// true if all the vaiables in the target executable directives must be 173 /// captured by reference. 174 bool ForceCaptureByReferenceInTargetExecutable = false; 175 CriticalsWithHintsTy Criticals; 176 unsigned IgnoredStackElements = 0; 177 178 /// Iterators over the stack iterate in order from innermost to outermost 179 /// directive. 180 using const_iterator = StackTy::const_reverse_iterator; 181 const_iterator begin() const { 182 return Stack.empty() ? const_iterator() 183 : Stack.back().first.rbegin() + IgnoredStackElements; 184 } 185 const_iterator end() const { 186 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 187 } 188 using iterator = StackTy::reverse_iterator; 189 iterator begin() { 190 return Stack.empty() ? iterator() 191 : Stack.back().first.rbegin() + IgnoredStackElements; 192 } 193 iterator end() { 194 return Stack.empty() ? iterator() : Stack.back().first.rend(); 195 } 196 197 // Convenience operations to get at the elements of the stack. 198 199 bool isStackEmpty() const { 200 return Stack.empty() || 201 Stack.back().second != CurrentNonCapturingFunctionScope || 202 Stack.back().first.size() <= IgnoredStackElements; 203 } 204 size_t getStackSize() const { 205 return isStackEmpty() ? 0 206 : Stack.back().first.size() - IgnoredStackElements; 207 } 208 209 SharingMapTy *getTopOfStackOrNull() { 210 size_t Size = getStackSize(); 211 if (Size == 0) 212 return nullptr; 213 return &Stack.back().first[Size - 1]; 214 } 215 const SharingMapTy *getTopOfStackOrNull() const { 216 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 217 } 218 SharingMapTy &getTopOfStack() { 219 assert(!isStackEmpty() && "no current directive"); 220 return *getTopOfStackOrNull(); 221 } 222 const SharingMapTy &getTopOfStack() const { 223 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 224 } 225 226 SharingMapTy *getSecondOnStackOrNull() { 227 size_t Size = getStackSize(); 228 if (Size <= 1) 229 return nullptr; 230 return &Stack.back().first[Size - 2]; 231 } 232 const SharingMapTy *getSecondOnStackOrNull() const { 233 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 234 } 235 236 /// Get the stack element at a certain level (previously returned by 237 /// \c getNestingLevel). 238 /// 239 /// Note that nesting levels count from outermost to innermost, and this is 240 /// the reverse of our iteration order where new inner levels are pushed at 241 /// the front of the stack. 242 SharingMapTy &getStackElemAtLevel(unsigned Level) { 243 assert(Level < getStackSize() && "no such stack element"); 244 return Stack.back().first[Level]; 245 } 246 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 247 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 248 } 249 250 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 251 252 /// Checks if the variable is a local for OpenMP region. 253 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 254 255 /// Vector of previously declared requires directives 256 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 257 /// omp_allocator_handle_t type. 258 QualType OMPAllocatorHandleT; 259 /// Expression for the predefined allocators. 260 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 261 nullptr}; 262 /// Vector of previously encountered target directives 263 SmallVector<SourceLocation, 2> TargetLocations; 264 265 public: 266 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 267 268 /// Sets omp_allocator_handle_t type. 269 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 270 /// Gets omp_allocator_handle_t type. 271 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 272 /// Sets the given default allocator. 273 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 274 Expr *Allocator) { 275 OMPPredefinedAllocators[AllocatorKind] = Allocator; 276 } 277 /// Returns the specified default allocator. 278 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 279 return OMPPredefinedAllocators[AllocatorKind]; 280 } 281 282 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 283 OpenMPClauseKind getClauseParsingMode() const { 284 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 285 return ClauseKindMode; 286 } 287 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 288 289 bool isBodyComplete() const { 290 const SharingMapTy *Top = getTopOfStackOrNull(); 291 return Top && Top->BodyComplete; 292 } 293 void setBodyComplete() { 294 getTopOfStack().BodyComplete = true; 295 } 296 297 bool isForceVarCapturing() const { return ForceCapturing; } 298 void setForceVarCapturing(bool V) { ForceCapturing = V; } 299 300 void setForceCaptureByReferenceInTargetExecutable(bool V) { 301 ForceCaptureByReferenceInTargetExecutable = V; 302 } 303 bool isForceCaptureByReferenceInTargetExecutable() const { 304 return ForceCaptureByReferenceInTargetExecutable; 305 } 306 307 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 308 Scope *CurScope, SourceLocation Loc) { 309 assert(!IgnoredStackElements && 310 "cannot change stack while ignoring elements"); 311 if (Stack.empty() || 312 Stack.back().second != CurrentNonCapturingFunctionScope) 313 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 314 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 315 Stack.back().first.back().DefaultAttrLoc = Loc; 316 } 317 318 void pop() { 319 assert(!IgnoredStackElements && 320 "cannot change stack while ignoring elements"); 321 assert(!Stack.back().first.empty() && 322 "Data-sharing attributes stack is empty!"); 323 Stack.back().first.pop_back(); 324 } 325 326 /// RAII object to temporarily leave the scope of a directive when we want to 327 /// logically operate in its parent. 328 class ParentDirectiveScope { 329 DSAStackTy &Self; 330 bool Active; 331 public: 332 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 333 : Self(Self), Active(false) { 334 if (Activate) 335 enable(); 336 } 337 ~ParentDirectiveScope() { disable(); } 338 void disable() { 339 if (Active) { 340 --Self.IgnoredStackElements; 341 Active = false; 342 } 343 } 344 void enable() { 345 if (!Active) { 346 ++Self.IgnoredStackElements; 347 Active = true; 348 } 349 } 350 }; 351 352 /// Marks that we're started loop parsing. 353 void loopInit() { 354 assert(isOpenMPLoopDirective(getCurrentDirective()) && 355 "Expected loop-based directive."); 356 getTopOfStack().LoopStart = true; 357 } 358 /// Start capturing of the variables in the loop context. 359 void loopStart() { 360 assert(isOpenMPLoopDirective(getCurrentDirective()) && 361 "Expected loop-based directive."); 362 getTopOfStack().LoopStart = false; 363 } 364 /// true, if variables are captured, false otherwise. 365 bool isLoopStarted() const { 366 assert(isOpenMPLoopDirective(getCurrentDirective()) && 367 "Expected loop-based directive."); 368 return !getTopOfStack().LoopStart; 369 } 370 /// Marks (or clears) declaration as possibly loop counter. 371 void resetPossibleLoopCounter(const Decl *D = nullptr) { 372 getTopOfStack().PossiblyLoopCounter = 373 D ? D->getCanonicalDecl() : D; 374 } 375 /// Gets the possible loop counter decl. 376 const Decl *getPossiblyLoopCunter() const { 377 return getTopOfStack().PossiblyLoopCounter; 378 } 379 /// Start new OpenMP region stack in new non-capturing function. 380 void pushFunction() { 381 assert(!IgnoredStackElements && 382 "cannot change stack while ignoring elements"); 383 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 384 assert(!isa<CapturingScopeInfo>(CurFnScope)); 385 CurrentNonCapturingFunctionScope = CurFnScope; 386 } 387 /// Pop region stack for non-capturing function. 388 void popFunction(const FunctionScopeInfo *OldFSI) { 389 assert(!IgnoredStackElements && 390 "cannot change stack while ignoring elements"); 391 if (!Stack.empty() && Stack.back().second == OldFSI) { 392 assert(Stack.back().first.empty()); 393 Stack.pop_back(); 394 } 395 CurrentNonCapturingFunctionScope = nullptr; 396 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 397 if (!isa<CapturingScopeInfo>(FSI)) { 398 CurrentNonCapturingFunctionScope = FSI; 399 break; 400 } 401 } 402 } 403 404 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 405 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 406 } 407 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 408 getCriticalWithHint(const DeclarationNameInfo &Name) const { 409 auto I = Criticals.find(Name.getAsString()); 410 if (I != Criticals.end()) 411 return I->second; 412 return std::make_pair(nullptr, llvm::APSInt()); 413 } 414 /// If 'aligned' declaration for given variable \a D was not seen yet, 415 /// add it and return NULL; otherwise return previous occurrence's expression 416 /// for diagnostics. 417 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 418 419 /// Register specified variable as loop control variable. 420 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 421 /// Check if the specified variable is a loop control variable for 422 /// current region. 423 /// \return The index of the loop control variable in the list of associated 424 /// for-loops (from outer to inner). 425 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 426 /// Check if the specified variable is a loop control variable for 427 /// parent region. 428 /// \return The index of the loop control variable in the list of associated 429 /// for-loops (from outer to inner). 430 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 431 /// Get the loop control variable for the I-th loop (or nullptr) in 432 /// parent directive. 433 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 434 435 /// Adds explicit data sharing attribute to the specified declaration. 436 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 437 DeclRefExpr *PrivateCopy = nullptr); 438 439 /// Adds additional information for the reduction items with the reduction id 440 /// represented as an operator. 441 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 442 BinaryOperatorKind BOK); 443 /// Adds additional information for the reduction items with the reduction id 444 /// represented as reduction identifier. 445 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 446 const Expr *ReductionRef); 447 /// Returns the location and reduction operation from the innermost parent 448 /// region for the given \p D. 449 const DSAVarData 450 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 451 BinaryOperatorKind &BOK, 452 Expr *&TaskgroupDescriptor) const; 453 /// Returns the location and reduction operation from the innermost parent 454 /// region for the given \p D. 455 const DSAVarData 456 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 457 const Expr *&ReductionRef, 458 Expr *&TaskgroupDescriptor) const; 459 /// Return reduction reference expression for the current taskgroup. 460 Expr *getTaskgroupReductionRef() const { 461 assert(getTopOfStack().Directive == OMPD_taskgroup && 462 "taskgroup reference expression requested for non taskgroup " 463 "directive."); 464 return getTopOfStack().TaskgroupReductionRef; 465 } 466 /// Checks if the given \p VD declaration is actually a taskgroup reduction 467 /// descriptor variable at the \p Level of OpenMP regions. 468 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 469 return getStackElemAtLevel(Level).TaskgroupReductionRef && 470 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 471 ->getDecl() == VD; 472 } 473 474 /// Returns data sharing attributes from top of the stack for the 475 /// specified declaration. 476 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 477 /// Returns data-sharing attributes for the specified declaration. 478 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 479 /// Checks if the specified variables has data-sharing attributes which 480 /// match specified \a CPred predicate in any directive which matches \a DPred 481 /// predicate. 482 const DSAVarData 483 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 484 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 485 bool FromParent) const; 486 /// Checks if the specified variables has data-sharing attributes which 487 /// match specified \a CPred predicate in any innermost directive which 488 /// matches \a DPred predicate. 489 const DSAVarData 490 hasInnermostDSA(ValueDecl *D, 491 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 492 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 493 bool FromParent) const; 494 /// Checks if the specified variables has explicit data-sharing 495 /// attributes which match specified \a CPred predicate at the specified 496 /// OpenMP region. 497 bool hasExplicitDSA(const ValueDecl *D, 498 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 499 unsigned Level, bool NotLastprivate = false) const; 500 501 /// Returns true if the directive at level \Level matches in the 502 /// specified \a DPred predicate. 503 bool hasExplicitDirective( 504 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 505 unsigned Level) const; 506 507 /// Finds a directive which matches specified \a DPred predicate. 508 bool hasDirective( 509 const llvm::function_ref<bool( 510 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 511 DPred, 512 bool FromParent) const; 513 514 /// Returns currently analyzed directive. 515 OpenMPDirectiveKind getCurrentDirective() const { 516 const SharingMapTy *Top = getTopOfStackOrNull(); 517 return Top ? Top->Directive : OMPD_unknown; 518 } 519 /// Returns directive kind at specified level. 520 OpenMPDirectiveKind getDirective(unsigned Level) const { 521 assert(!isStackEmpty() && "No directive at specified level."); 522 return getStackElemAtLevel(Level).Directive; 523 } 524 /// Returns parent directive. 525 OpenMPDirectiveKind getParentDirective() const { 526 const SharingMapTy *Parent = getSecondOnStackOrNull(); 527 return Parent ? Parent->Directive : OMPD_unknown; 528 } 529 530 /// Add requires decl to internal vector 531 void addRequiresDecl(OMPRequiresDecl *RD) { 532 RequiresDecls.push_back(RD); 533 } 534 535 /// Checks if the defined 'requires' directive has specified type of clause. 536 template <typename ClauseType> 537 bool hasRequiresDeclWithClause() { 538 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 539 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 540 return isa<ClauseType>(C); 541 }); 542 }); 543 } 544 545 /// Checks for a duplicate clause amongst previously declared requires 546 /// directives 547 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 548 bool IsDuplicate = false; 549 for (OMPClause *CNew : ClauseList) { 550 for (const OMPRequiresDecl *D : RequiresDecls) { 551 for (const OMPClause *CPrev : D->clauselists()) { 552 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 553 SemaRef.Diag(CNew->getBeginLoc(), 554 diag::err_omp_requires_clause_redeclaration) 555 << getOpenMPClauseName(CNew->getClauseKind()); 556 SemaRef.Diag(CPrev->getBeginLoc(), 557 diag::note_omp_requires_previous_clause) 558 << getOpenMPClauseName(CPrev->getClauseKind()); 559 IsDuplicate = true; 560 } 561 } 562 } 563 } 564 return IsDuplicate; 565 } 566 567 /// Add location of previously encountered target to internal vector 568 void addTargetDirLocation(SourceLocation LocStart) { 569 TargetLocations.push_back(LocStart); 570 } 571 572 // Return previously encountered target region locations. 573 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 574 return TargetLocations; 575 } 576 577 /// Set default data sharing attribute to none. 578 void setDefaultDSANone(SourceLocation Loc) { 579 getTopOfStack().DefaultAttr = DSA_none; 580 getTopOfStack().DefaultAttrLoc = Loc; 581 } 582 /// Set default data sharing attribute to shared. 583 void setDefaultDSAShared(SourceLocation Loc) { 584 getTopOfStack().DefaultAttr = DSA_shared; 585 getTopOfStack().DefaultAttrLoc = Loc; 586 } 587 /// Set default data mapping attribute to 'tofrom:scalar'. 588 void setDefaultDMAToFromScalar(SourceLocation Loc) { 589 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 590 getTopOfStack().DefaultMapAttrLoc = Loc; 591 } 592 593 DefaultDataSharingAttributes getDefaultDSA() const { 594 return isStackEmpty() ? DSA_unspecified 595 : getTopOfStack().DefaultAttr; 596 } 597 SourceLocation getDefaultDSALocation() const { 598 return isStackEmpty() ? SourceLocation() 599 : getTopOfStack().DefaultAttrLoc; 600 } 601 DefaultMapAttributes getDefaultDMA() const { 602 return isStackEmpty() ? DMA_unspecified 603 : getTopOfStack().DefaultMapAttr; 604 } 605 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 606 return getStackElemAtLevel(Level).DefaultMapAttr; 607 } 608 SourceLocation getDefaultDMALocation() const { 609 return isStackEmpty() ? SourceLocation() 610 : getTopOfStack().DefaultMapAttrLoc; 611 } 612 613 /// Checks if the specified variable is a threadprivate. 614 bool isThreadPrivate(VarDecl *D) { 615 const DSAVarData DVar = getTopDSA(D, false); 616 return isOpenMPThreadPrivate(DVar.CKind); 617 } 618 619 /// Marks current region as ordered (it has an 'ordered' clause). 620 void setOrderedRegion(bool IsOrdered, const Expr *Param, 621 OMPOrderedClause *Clause) { 622 if (IsOrdered) 623 getTopOfStack().OrderedRegion.emplace(Param, Clause); 624 else 625 getTopOfStack().OrderedRegion.reset(); 626 } 627 /// Returns true, if region is ordered (has associated 'ordered' clause), 628 /// false - otherwise. 629 bool isOrderedRegion() const { 630 if (const SharingMapTy *Top = getTopOfStackOrNull()) 631 return Top->OrderedRegion.hasValue(); 632 return false; 633 } 634 /// Returns optional parameter for the ordered region. 635 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 636 if (const SharingMapTy *Top = getTopOfStackOrNull()) 637 if (Top->OrderedRegion.hasValue()) 638 return Top->OrderedRegion.getValue(); 639 return std::make_pair(nullptr, nullptr); 640 } 641 /// Returns true, if parent region is ordered (has associated 642 /// 'ordered' clause), false - otherwise. 643 bool isParentOrderedRegion() const { 644 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 645 return Parent->OrderedRegion.hasValue(); 646 return false; 647 } 648 /// Returns optional parameter for the ordered region. 649 std::pair<const Expr *, OMPOrderedClause *> 650 getParentOrderedRegionParam() const { 651 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 652 if (Parent->OrderedRegion.hasValue()) 653 return Parent->OrderedRegion.getValue(); 654 return std::make_pair(nullptr, nullptr); 655 } 656 /// Marks current region as nowait (it has a 'nowait' clause). 657 void setNowaitRegion(bool IsNowait = true) { 658 getTopOfStack().NowaitRegion = IsNowait; 659 } 660 /// Returns true, if parent region is nowait (has associated 661 /// 'nowait' clause), false - otherwise. 662 bool isParentNowaitRegion() const { 663 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 664 return Parent->NowaitRegion; 665 return false; 666 } 667 /// Marks parent region as cancel region. 668 void setParentCancelRegion(bool Cancel = true) { 669 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 670 Parent->CancelRegion |= Cancel; 671 } 672 /// Return true if current region has inner cancel construct. 673 bool isCancelRegion() const { 674 const SharingMapTy *Top = getTopOfStackOrNull(); 675 return Top ? Top->CancelRegion : false; 676 } 677 678 /// Set collapse value for the region. 679 void setAssociatedLoops(unsigned Val) { 680 getTopOfStack().AssociatedLoops = Val; 681 } 682 /// Return collapse value for region. 683 unsigned getAssociatedLoops() const { 684 const SharingMapTy *Top = getTopOfStackOrNull(); 685 return Top ? Top->AssociatedLoops : 0; 686 } 687 688 /// Marks current target region as one with closely nested teams 689 /// region. 690 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 691 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 692 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 693 } 694 /// Returns true, if current region has closely nested teams region. 695 bool hasInnerTeamsRegion() const { 696 return getInnerTeamsRegionLoc().isValid(); 697 } 698 /// Returns location of the nested teams region (if any). 699 SourceLocation getInnerTeamsRegionLoc() const { 700 const SharingMapTy *Top = getTopOfStackOrNull(); 701 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 702 } 703 704 Scope *getCurScope() const { 705 const SharingMapTy *Top = getTopOfStackOrNull(); 706 return Top ? Top->CurScope : nullptr; 707 } 708 SourceLocation getConstructLoc() const { 709 const SharingMapTy *Top = getTopOfStackOrNull(); 710 return Top ? Top->ConstructLoc : SourceLocation(); 711 } 712 713 /// Do the check specified in \a Check to all component lists and return true 714 /// if any issue is found. 715 bool checkMappableExprComponentListsForDecl( 716 const ValueDecl *VD, bool CurrentRegionOnly, 717 const llvm::function_ref< 718 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 719 OpenMPClauseKind)> 720 Check) const { 721 if (isStackEmpty()) 722 return false; 723 auto SI = begin(); 724 auto SE = end(); 725 726 if (SI == SE) 727 return false; 728 729 if (CurrentRegionOnly) 730 SE = std::next(SI); 731 else 732 std::advance(SI, 1); 733 734 for (; SI != SE; ++SI) { 735 auto MI = SI->MappedExprComponents.find(VD); 736 if (MI != SI->MappedExprComponents.end()) 737 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 738 MI->second.Components) 739 if (Check(L, MI->second.Kind)) 740 return true; 741 } 742 return false; 743 } 744 745 /// Do the check specified in \a Check to all component lists at a given level 746 /// and return true if any issue is found. 747 bool checkMappableExprComponentListsForDeclAtLevel( 748 const ValueDecl *VD, unsigned Level, 749 const llvm::function_ref< 750 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 751 OpenMPClauseKind)> 752 Check) const { 753 if (getStackSize() <= Level) 754 return false; 755 756 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 757 auto MI = StackElem.MappedExprComponents.find(VD); 758 if (MI != StackElem.MappedExprComponents.end()) 759 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 760 MI->second.Components) 761 if (Check(L, MI->second.Kind)) 762 return true; 763 return false; 764 } 765 766 /// Create a new mappable expression component list associated with a given 767 /// declaration and initialize it with the provided list of components. 768 void addMappableExpressionComponents( 769 const ValueDecl *VD, 770 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 771 OpenMPClauseKind WhereFoundClauseKind) { 772 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 773 // Create new entry and append the new components there. 774 MEC.Components.resize(MEC.Components.size() + 1); 775 MEC.Components.back().append(Components.begin(), Components.end()); 776 MEC.Kind = WhereFoundClauseKind; 777 } 778 779 unsigned getNestingLevel() const { 780 assert(!isStackEmpty()); 781 return getStackSize() - 1; 782 } 783 void addDoacrossDependClause(OMPDependClause *C, 784 const OperatorOffsetTy &OpsOffs) { 785 SharingMapTy *Parent = getSecondOnStackOrNull(); 786 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 787 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 788 } 789 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 790 getDoacrossDependClauses() const { 791 const SharingMapTy &StackElem = getTopOfStack(); 792 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 793 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 794 return llvm::make_range(Ref.begin(), Ref.end()); 795 } 796 return llvm::make_range(StackElem.DoacrossDepends.end(), 797 StackElem.DoacrossDepends.end()); 798 } 799 800 // Store types of classes which have been explicitly mapped 801 void addMappedClassesQualTypes(QualType QT) { 802 SharingMapTy &StackElem = getTopOfStack(); 803 StackElem.MappedClassesQualTypes.insert(QT); 804 } 805 806 // Return set of mapped classes types 807 bool isClassPreviouslyMapped(QualType QT) const { 808 const SharingMapTy &StackElem = getTopOfStack(); 809 return StackElem.MappedClassesQualTypes.count(QT) != 0; 810 } 811 812 /// Adds global declare target to the parent target region. 813 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 814 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 815 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 816 "Expected declare target link global."); 817 for (auto &Elem : *this) { 818 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 819 Elem.DeclareTargetLinkVarDecls.push_back(E); 820 return; 821 } 822 } 823 } 824 825 /// Returns the list of globals with declare target link if current directive 826 /// is target. 827 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 828 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 829 "Expected target executable directive."); 830 return getTopOfStack().DeclareTargetLinkVarDecls; 831 } 832 }; 833 834 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 835 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 836 } 837 838 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 839 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 840 DKind == OMPD_unknown; 841 } 842 843 } // namespace 844 845 static const Expr *getExprAsWritten(const Expr *E) { 846 if (const auto *FE = dyn_cast<FullExpr>(E)) 847 E = FE->getSubExpr(); 848 849 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 850 E = MTE->GetTemporaryExpr(); 851 852 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 853 E = Binder->getSubExpr(); 854 855 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 856 E = ICE->getSubExprAsWritten(); 857 return E->IgnoreParens(); 858 } 859 860 static Expr *getExprAsWritten(Expr *E) { 861 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 862 } 863 864 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 865 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 866 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 867 D = ME->getMemberDecl(); 868 const auto *VD = dyn_cast<VarDecl>(D); 869 const auto *FD = dyn_cast<FieldDecl>(D); 870 if (VD != nullptr) { 871 VD = VD->getCanonicalDecl(); 872 D = VD; 873 } else { 874 assert(FD); 875 FD = FD->getCanonicalDecl(); 876 D = FD; 877 } 878 return D; 879 } 880 881 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 882 return const_cast<ValueDecl *>( 883 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 884 } 885 886 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 887 ValueDecl *D) const { 888 D = getCanonicalDecl(D); 889 auto *VD = dyn_cast<VarDecl>(D); 890 const auto *FD = dyn_cast<FieldDecl>(D); 891 DSAVarData DVar; 892 if (Iter == end()) { 893 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 894 // in a region but not in construct] 895 // File-scope or namespace-scope variables referenced in called routines 896 // in the region are shared unless they appear in a threadprivate 897 // directive. 898 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 899 DVar.CKind = OMPC_shared; 900 901 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 902 // in a region but not in construct] 903 // Variables with static storage duration that are declared in called 904 // routines in the region are shared. 905 if (VD && VD->hasGlobalStorage()) 906 DVar.CKind = OMPC_shared; 907 908 // Non-static data members are shared by default. 909 if (FD) 910 DVar.CKind = OMPC_shared; 911 912 return DVar; 913 } 914 915 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 916 // in a Construct, C/C++, predetermined, p.1] 917 // Variables with automatic storage duration that are declared in a scope 918 // inside the construct are private. 919 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 920 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 921 DVar.CKind = OMPC_private; 922 return DVar; 923 } 924 925 DVar.DKind = Iter->Directive; 926 // Explicitly specified attributes and local variables with predetermined 927 // attributes. 928 if (Iter->SharingMap.count(D)) { 929 const DSAInfo &Data = Iter->SharingMap.lookup(D); 930 DVar.RefExpr = Data.RefExpr.getPointer(); 931 DVar.PrivateCopy = Data.PrivateCopy; 932 DVar.CKind = Data.Attributes; 933 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 934 return DVar; 935 } 936 937 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 938 // in a Construct, C/C++, implicitly determined, p.1] 939 // In a parallel or task construct, the data-sharing attributes of these 940 // variables are determined by the default clause, if present. 941 switch (Iter->DefaultAttr) { 942 case DSA_shared: 943 DVar.CKind = OMPC_shared; 944 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 945 return DVar; 946 case DSA_none: 947 return DVar; 948 case DSA_unspecified: 949 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 950 // in a Construct, implicitly determined, p.2] 951 // In a parallel construct, if no default clause is present, these 952 // variables are shared. 953 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 954 if (isOpenMPParallelDirective(DVar.DKind) || 955 isOpenMPTeamsDirective(DVar.DKind)) { 956 DVar.CKind = OMPC_shared; 957 return DVar; 958 } 959 960 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 961 // in a Construct, implicitly determined, p.4] 962 // In a task construct, if no default clause is present, a variable that in 963 // the enclosing context is determined to be shared by all implicit tasks 964 // bound to the current team is shared. 965 if (isOpenMPTaskingDirective(DVar.DKind)) { 966 DSAVarData DVarTemp; 967 const_iterator I = Iter, E = end(); 968 do { 969 ++I; 970 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 971 // Referenced in a Construct, implicitly determined, p.6] 972 // In a task construct, if no default clause is present, a variable 973 // whose data-sharing attribute is not determined by the rules above is 974 // firstprivate. 975 DVarTemp = getDSA(I, D); 976 if (DVarTemp.CKind != OMPC_shared) { 977 DVar.RefExpr = nullptr; 978 DVar.CKind = OMPC_firstprivate; 979 return DVar; 980 } 981 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 982 DVar.CKind = 983 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 984 return DVar; 985 } 986 } 987 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 988 // in a Construct, implicitly determined, p.3] 989 // For constructs other than task, if no default clause is present, these 990 // variables inherit their data-sharing attributes from the enclosing 991 // context. 992 return getDSA(++Iter, D); 993 } 994 995 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 996 const Expr *NewDE) { 997 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 998 D = getCanonicalDecl(D); 999 SharingMapTy &StackElem = getTopOfStack(); 1000 auto It = StackElem.AlignedMap.find(D); 1001 if (It == StackElem.AlignedMap.end()) { 1002 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1003 StackElem.AlignedMap[D] = NewDE; 1004 return nullptr; 1005 } 1006 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1007 return It->second; 1008 } 1009 1010 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1011 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1012 D = getCanonicalDecl(D); 1013 SharingMapTy &StackElem = getTopOfStack(); 1014 StackElem.LCVMap.try_emplace( 1015 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1016 } 1017 1018 const DSAStackTy::LCDeclInfo 1019 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1020 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1021 D = getCanonicalDecl(D); 1022 const SharingMapTy &StackElem = getTopOfStack(); 1023 auto It = StackElem.LCVMap.find(D); 1024 if (It != StackElem.LCVMap.end()) 1025 return It->second; 1026 return {0, nullptr}; 1027 } 1028 1029 const DSAStackTy::LCDeclInfo 1030 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1031 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1032 assert(Parent && "Data-sharing attributes stack is empty"); 1033 D = getCanonicalDecl(D); 1034 auto It = Parent->LCVMap.find(D); 1035 if (It != Parent->LCVMap.end()) 1036 return It->second; 1037 return {0, nullptr}; 1038 } 1039 1040 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1041 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1042 assert(Parent && "Data-sharing attributes stack is empty"); 1043 if (Parent->LCVMap.size() < I) 1044 return nullptr; 1045 for (const auto &Pair : Parent->LCVMap) 1046 if (Pair.second.first == I) 1047 return Pair.first; 1048 return nullptr; 1049 } 1050 1051 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1052 DeclRefExpr *PrivateCopy) { 1053 D = getCanonicalDecl(D); 1054 if (A == OMPC_threadprivate) { 1055 DSAInfo &Data = Threadprivates[D]; 1056 Data.Attributes = A; 1057 Data.RefExpr.setPointer(E); 1058 Data.PrivateCopy = nullptr; 1059 } else { 1060 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1061 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1062 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1063 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1064 (isLoopControlVariable(D).first && A == OMPC_private)); 1065 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1066 Data.RefExpr.setInt(/*IntVal=*/true); 1067 return; 1068 } 1069 const bool IsLastprivate = 1070 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1071 Data.Attributes = A; 1072 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1073 Data.PrivateCopy = PrivateCopy; 1074 if (PrivateCopy) { 1075 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1076 Data.Attributes = A; 1077 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1078 Data.PrivateCopy = nullptr; 1079 } 1080 } 1081 } 1082 1083 /// Build a variable declaration for OpenMP loop iteration variable. 1084 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1085 StringRef Name, const AttrVec *Attrs = nullptr, 1086 DeclRefExpr *OrigRef = nullptr) { 1087 DeclContext *DC = SemaRef.CurContext; 1088 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1089 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1090 auto *Decl = 1091 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1092 if (Attrs) { 1093 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1094 I != E; ++I) 1095 Decl->addAttr(*I); 1096 } 1097 Decl->setImplicit(); 1098 if (OrigRef) { 1099 Decl->addAttr( 1100 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1101 } 1102 return Decl; 1103 } 1104 1105 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1106 SourceLocation Loc, 1107 bool RefersToCapture = false) { 1108 D->setReferenced(); 1109 D->markUsed(S.Context); 1110 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1111 SourceLocation(), D, RefersToCapture, Loc, Ty, 1112 VK_LValue); 1113 } 1114 1115 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1116 BinaryOperatorKind BOK) { 1117 D = getCanonicalDecl(D); 1118 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1119 assert( 1120 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1121 "Additional reduction info may be specified only for reduction items."); 1122 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1123 assert(ReductionData.ReductionRange.isInvalid() && 1124 getTopOfStack().Directive == OMPD_taskgroup && 1125 "Additional reduction info may be specified only once for reduction " 1126 "items."); 1127 ReductionData.set(BOK, SR); 1128 Expr *&TaskgroupReductionRef = 1129 getTopOfStack().TaskgroupReductionRef; 1130 if (!TaskgroupReductionRef) { 1131 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1132 SemaRef.Context.VoidPtrTy, ".task_red."); 1133 TaskgroupReductionRef = 1134 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1135 } 1136 } 1137 1138 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1139 const Expr *ReductionRef) { 1140 D = getCanonicalDecl(D); 1141 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1142 assert( 1143 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1144 "Additional reduction info may be specified only for reduction items."); 1145 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1146 assert(ReductionData.ReductionRange.isInvalid() && 1147 getTopOfStack().Directive == OMPD_taskgroup && 1148 "Additional reduction info may be specified only once for reduction " 1149 "items."); 1150 ReductionData.set(ReductionRef, SR); 1151 Expr *&TaskgroupReductionRef = 1152 getTopOfStack().TaskgroupReductionRef; 1153 if (!TaskgroupReductionRef) { 1154 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1155 SemaRef.Context.VoidPtrTy, ".task_red."); 1156 TaskgroupReductionRef = 1157 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1158 } 1159 } 1160 1161 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1162 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1163 Expr *&TaskgroupDescriptor) const { 1164 D = getCanonicalDecl(D); 1165 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1166 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1167 const DSAInfo &Data = I->SharingMap.lookup(D); 1168 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1169 continue; 1170 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1171 if (!ReductionData.ReductionOp || 1172 ReductionData.ReductionOp.is<const Expr *>()) 1173 return DSAVarData(); 1174 SR = ReductionData.ReductionRange; 1175 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1176 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1177 "expression for the descriptor is not " 1178 "set."); 1179 TaskgroupDescriptor = I->TaskgroupReductionRef; 1180 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1181 Data.PrivateCopy, I->DefaultAttrLoc); 1182 } 1183 return DSAVarData(); 1184 } 1185 1186 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1187 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1188 Expr *&TaskgroupDescriptor) const { 1189 D = getCanonicalDecl(D); 1190 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1191 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1192 const DSAInfo &Data = I->SharingMap.lookup(D); 1193 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1194 continue; 1195 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1196 if (!ReductionData.ReductionOp || 1197 !ReductionData.ReductionOp.is<const Expr *>()) 1198 return DSAVarData(); 1199 SR = ReductionData.ReductionRange; 1200 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1201 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1202 "expression for the descriptor is not " 1203 "set."); 1204 TaskgroupDescriptor = I->TaskgroupReductionRef; 1205 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1206 Data.PrivateCopy, I->DefaultAttrLoc); 1207 } 1208 return DSAVarData(); 1209 } 1210 1211 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1212 D = D->getCanonicalDecl(); 1213 for (const_iterator E = end(); I != E; ++I) { 1214 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1215 isOpenMPTargetExecutionDirective(I->Directive)) { 1216 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1217 Scope *CurScope = getCurScope(); 1218 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1219 CurScope = CurScope->getParent(); 1220 return CurScope != TopScope; 1221 } 1222 } 1223 return false; 1224 } 1225 1226 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1227 bool AcceptIfMutable = true, 1228 bool *IsClassType = nullptr) { 1229 ASTContext &Context = SemaRef.getASTContext(); 1230 Type = Type.getNonReferenceType().getCanonicalType(); 1231 bool IsConstant = Type.isConstant(Context); 1232 Type = Context.getBaseElementType(Type); 1233 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1234 ? Type->getAsCXXRecordDecl() 1235 : nullptr; 1236 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1237 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1238 RD = CTD->getTemplatedDecl(); 1239 if (IsClassType) 1240 *IsClassType = RD; 1241 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1242 RD->hasDefinition() && RD->hasMutableFields()); 1243 } 1244 1245 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1246 QualType Type, OpenMPClauseKind CKind, 1247 SourceLocation ELoc, 1248 bool AcceptIfMutable = true, 1249 bool ListItemNotVar = false) { 1250 ASTContext &Context = SemaRef.getASTContext(); 1251 bool IsClassType; 1252 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1253 unsigned Diag = ListItemNotVar 1254 ? diag::err_omp_const_list_item 1255 : IsClassType ? diag::err_omp_const_not_mutable_variable 1256 : diag::err_omp_const_variable; 1257 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1258 if (!ListItemNotVar && D) { 1259 const VarDecl *VD = dyn_cast<VarDecl>(D); 1260 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1261 VarDecl::DeclarationOnly; 1262 SemaRef.Diag(D->getLocation(), 1263 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1264 << D; 1265 } 1266 return true; 1267 } 1268 return false; 1269 } 1270 1271 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1272 bool FromParent) { 1273 D = getCanonicalDecl(D); 1274 DSAVarData DVar; 1275 1276 auto *VD = dyn_cast<VarDecl>(D); 1277 auto TI = Threadprivates.find(D); 1278 if (TI != Threadprivates.end()) { 1279 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1280 DVar.CKind = OMPC_threadprivate; 1281 return DVar; 1282 } 1283 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1284 DVar.RefExpr = buildDeclRefExpr( 1285 SemaRef, VD, D->getType().getNonReferenceType(), 1286 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1287 DVar.CKind = OMPC_threadprivate; 1288 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1289 return DVar; 1290 } 1291 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1292 // in a Construct, C/C++, predetermined, p.1] 1293 // Variables appearing in threadprivate directives are threadprivate. 1294 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1295 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1296 SemaRef.getLangOpts().OpenMPUseTLS && 1297 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1298 (VD && VD->getStorageClass() == SC_Register && 1299 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1300 DVar.RefExpr = buildDeclRefExpr( 1301 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1302 DVar.CKind = OMPC_threadprivate; 1303 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1304 return DVar; 1305 } 1306 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1307 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1308 !isLoopControlVariable(D).first) { 1309 const_iterator IterTarget = 1310 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1311 return isOpenMPTargetExecutionDirective(Data.Directive); 1312 }); 1313 if (IterTarget != end()) { 1314 const_iterator ParentIterTarget = IterTarget + 1; 1315 for (const_iterator Iter = begin(); 1316 Iter != ParentIterTarget; ++Iter) { 1317 if (isOpenMPLocal(VD, Iter)) { 1318 DVar.RefExpr = 1319 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1320 D->getLocation()); 1321 DVar.CKind = OMPC_threadprivate; 1322 return DVar; 1323 } 1324 } 1325 if (!isClauseParsingMode() || IterTarget != begin()) { 1326 auto DSAIter = IterTarget->SharingMap.find(D); 1327 if (DSAIter != IterTarget->SharingMap.end() && 1328 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1329 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1330 DVar.CKind = OMPC_threadprivate; 1331 return DVar; 1332 } 1333 const_iterator End = end(); 1334 if (!SemaRef.isOpenMPCapturedByRef( 1335 D, std::distance(ParentIterTarget, End))) { 1336 DVar.RefExpr = 1337 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1338 IterTarget->ConstructLoc); 1339 DVar.CKind = OMPC_threadprivate; 1340 return DVar; 1341 } 1342 } 1343 } 1344 } 1345 1346 if (isStackEmpty()) 1347 // Not in OpenMP execution region and top scope was already checked. 1348 return DVar; 1349 1350 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1351 // in a Construct, C/C++, predetermined, p.4] 1352 // Static data members are shared. 1353 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1354 // in a Construct, C/C++, predetermined, p.7] 1355 // Variables with static storage duration that are declared in a scope 1356 // inside the construct are shared. 1357 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1358 if (VD && VD->isStaticDataMember()) { 1359 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1360 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1361 return DVar; 1362 1363 DVar.CKind = OMPC_shared; 1364 return DVar; 1365 } 1366 1367 // The predetermined shared attribute for const-qualified types having no 1368 // mutable members was removed after OpenMP 3.1. 1369 if (SemaRef.LangOpts.OpenMP <= 31) { 1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1371 // in a Construct, C/C++, predetermined, p.6] 1372 // Variables with const qualified type having no mutable member are 1373 // shared. 1374 if (isConstNotMutableType(SemaRef, D->getType())) { 1375 // Variables with const-qualified type having no mutable member may be 1376 // listed in a firstprivate clause, even if they are static data members. 1377 DSAVarData DVarTemp = hasInnermostDSA( 1378 D, 1379 [](OpenMPClauseKind C) { 1380 return C == OMPC_firstprivate || C == OMPC_shared; 1381 }, 1382 MatchesAlways, FromParent); 1383 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1384 return DVarTemp; 1385 1386 DVar.CKind = OMPC_shared; 1387 return DVar; 1388 } 1389 } 1390 1391 // Explicitly specified attributes and local variables with predetermined 1392 // attributes. 1393 const_iterator I = begin(); 1394 const_iterator EndI = end(); 1395 if (FromParent && I != EndI) 1396 ++I; 1397 auto It = I->SharingMap.find(D); 1398 if (It != I->SharingMap.end()) { 1399 const DSAInfo &Data = It->getSecond(); 1400 DVar.RefExpr = Data.RefExpr.getPointer(); 1401 DVar.PrivateCopy = Data.PrivateCopy; 1402 DVar.CKind = Data.Attributes; 1403 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1404 DVar.DKind = I->Directive; 1405 } 1406 1407 return DVar; 1408 } 1409 1410 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1411 bool FromParent) const { 1412 if (isStackEmpty()) { 1413 const_iterator I; 1414 return getDSA(I, D); 1415 } 1416 D = getCanonicalDecl(D); 1417 const_iterator StartI = begin(); 1418 const_iterator EndI = end(); 1419 if (FromParent && StartI != EndI) 1420 ++StartI; 1421 return getDSA(StartI, D); 1422 } 1423 1424 const DSAStackTy::DSAVarData 1425 DSAStackTy::hasDSA(ValueDecl *D, 1426 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1427 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1428 bool FromParent) const { 1429 if (isStackEmpty()) 1430 return {}; 1431 D = getCanonicalDecl(D); 1432 const_iterator I = begin(); 1433 const_iterator EndI = end(); 1434 if (FromParent && I != EndI) 1435 ++I; 1436 for (; I != EndI; ++I) { 1437 if (!DPred(I->Directive) && 1438 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1439 continue; 1440 const_iterator NewI = I; 1441 DSAVarData DVar = getDSA(NewI, D); 1442 if (I == NewI && CPred(DVar.CKind)) 1443 return DVar; 1444 } 1445 return {}; 1446 } 1447 1448 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1449 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1450 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1451 bool FromParent) const { 1452 if (isStackEmpty()) 1453 return {}; 1454 D = getCanonicalDecl(D); 1455 const_iterator StartI = begin(); 1456 const_iterator EndI = end(); 1457 if (FromParent && StartI != EndI) 1458 ++StartI; 1459 if (StartI == EndI || !DPred(StartI->Directive)) 1460 return {}; 1461 const_iterator NewI = StartI; 1462 DSAVarData DVar = getDSA(NewI, D); 1463 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1464 } 1465 1466 bool DSAStackTy::hasExplicitDSA( 1467 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1468 unsigned Level, bool NotLastprivate) const { 1469 if (getStackSize() <= Level) 1470 return false; 1471 D = getCanonicalDecl(D); 1472 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1473 auto I = StackElem.SharingMap.find(D); 1474 if (I != StackElem.SharingMap.end() && 1475 I->getSecond().RefExpr.getPointer() && 1476 CPred(I->getSecond().Attributes) && 1477 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1478 return true; 1479 // Check predetermined rules for the loop control variables. 1480 auto LI = StackElem.LCVMap.find(D); 1481 if (LI != StackElem.LCVMap.end()) 1482 return CPred(OMPC_private); 1483 return false; 1484 } 1485 1486 bool DSAStackTy::hasExplicitDirective( 1487 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1488 unsigned Level) const { 1489 if (getStackSize() <= Level) 1490 return false; 1491 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1492 return DPred(StackElem.Directive); 1493 } 1494 1495 bool DSAStackTy::hasDirective( 1496 const llvm::function_ref<bool(OpenMPDirectiveKind, 1497 const DeclarationNameInfo &, SourceLocation)> 1498 DPred, 1499 bool FromParent) const { 1500 // We look only in the enclosing region. 1501 size_t Skip = FromParent ? 2 : 1; 1502 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1503 I != E; ++I) { 1504 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1505 return true; 1506 } 1507 return false; 1508 } 1509 1510 void Sema::InitDataSharingAttributesStack() { 1511 VarDataSharingAttributesStack = new DSAStackTy(*this); 1512 } 1513 1514 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1515 1516 void Sema::pushOpenMPFunctionRegion() { 1517 DSAStack->pushFunction(); 1518 } 1519 1520 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1521 DSAStack->popFunction(OldFSI); 1522 } 1523 1524 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1525 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1526 "Expected OpenMP device compilation."); 1527 return !S.isInOpenMPTargetExecutionDirective() && 1528 !S.isInOpenMPDeclareTargetContext(); 1529 } 1530 1531 /// Do we know that we will eventually codegen the given function? 1532 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1533 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1534 "Expected OpenMP device compilation."); 1535 // Templates are emitted when they're instantiated. 1536 if (FD->isDependentContext()) 1537 return false; 1538 1539 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1540 FD->getCanonicalDecl())) 1541 return true; 1542 1543 // Otherwise, the function is known-emitted if it's in our set of 1544 // known-emitted functions. 1545 return S.DeviceKnownEmittedFns.count(FD) > 0; 1546 } 1547 1548 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1549 unsigned DiagID) { 1550 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1551 "Expected OpenMP device compilation."); 1552 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1553 !isKnownEmitted(*this, getCurFunctionDecl())) 1554 ? DeviceDiagBuilder::K_Deferred 1555 : DeviceDiagBuilder::K_Immediate, 1556 Loc, DiagID, getCurFunctionDecl(), *this); 1557 } 1558 1559 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1560 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1561 "Expected OpenMP device compilation."); 1562 assert(Callee && "Callee may not be null."); 1563 FunctionDecl *Caller = getCurFunctionDecl(); 1564 1565 // If the caller is known-emitted, mark the callee as known-emitted. 1566 // Otherwise, mark the call in our call graph so we can traverse it later. 1567 if (!isOpenMPDeviceDelayedContext(*this) || 1568 (Caller && isKnownEmitted(*this, Caller))) 1569 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1570 else if (Caller) 1571 DeviceCallGraph[Caller].insert({Callee, Loc}); 1572 } 1573 1574 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1575 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1576 "OpenMP device compilation mode is expected."); 1577 QualType Ty = E->getType(); 1578 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1579 ((Ty->isFloat128Type() || 1580 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1581 !Context.getTargetInfo().hasFloat128Type()) || 1582 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1583 !Context.getTargetInfo().hasInt128Type())) 1584 targetDiag(E->getExprLoc(), diag::err_type_unsupported) 1585 << Ty << E->getSourceRange(); 1586 } 1587 1588 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1589 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1590 1591 ASTContext &Ctx = getASTContext(); 1592 bool IsByRef = true; 1593 1594 // Find the directive that is associated with the provided scope. 1595 D = cast<ValueDecl>(D->getCanonicalDecl()); 1596 QualType Ty = D->getType(); 1597 1598 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1599 // This table summarizes how a given variable should be passed to the device 1600 // given its type and the clauses where it appears. This table is based on 1601 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1602 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1603 // 1604 // ========================================================================= 1605 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1606 // | |(tofrom:scalar)| | pvt | | | | 1607 // ========================================================================= 1608 // | scl | | | | - | | bycopy| 1609 // | scl | | - | x | - | - | bycopy| 1610 // | scl | | x | - | - | - | null | 1611 // | scl | x | | | - | | byref | 1612 // | scl | x | - | x | - | - | bycopy| 1613 // | scl | x | x | - | - | - | null | 1614 // | scl | | - | - | - | x | byref | 1615 // | scl | x | - | - | - | x | byref | 1616 // 1617 // | agg | n.a. | | | - | | byref | 1618 // | agg | n.a. | - | x | - | - | byref | 1619 // | agg | n.a. | x | - | - | - | null | 1620 // | agg | n.a. | - | - | - | x | byref | 1621 // | agg | n.a. | - | - | - | x[] | byref | 1622 // 1623 // | ptr | n.a. | | | - | | bycopy| 1624 // | ptr | n.a. | - | x | - | - | bycopy| 1625 // | ptr | n.a. | x | - | - | - | null | 1626 // | ptr | n.a. | - | - | - | x | byref | 1627 // | ptr | n.a. | - | - | - | x[] | bycopy| 1628 // | ptr | n.a. | - | - | x | | bycopy| 1629 // | ptr | n.a. | - | - | x | x | bycopy| 1630 // | ptr | n.a. | - | - | x | x[] | bycopy| 1631 // ========================================================================= 1632 // Legend: 1633 // scl - scalar 1634 // ptr - pointer 1635 // agg - aggregate 1636 // x - applies 1637 // - - invalid in this combination 1638 // [] - mapped with an array section 1639 // byref - should be mapped by reference 1640 // byval - should be mapped by value 1641 // null - initialize a local variable to null on the device 1642 // 1643 // Observations: 1644 // - All scalar declarations that show up in a map clause have to be passed 1645 // by reference, because they may have been mapped in the enclosing data 1646 // environment. 1647 // - If the scalar value does not fit the size of uintptr, it has to be 1648 // passed by reference, regardless the result in the table above. 1649 // - For pointers mapped by value that have either an implicit map or an 1650 // array section, the runtime library may pass the NULL value to the 1651 // device instead of the value passed to it by the compiler. 1652 1653 if (Ty->isReferenceType()) 1654 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1655 1656 // Locate map clauses and see if the variable being captured is referred to 1657 // in any of those clauses. Here we only care about variables, not fields, 1658 // because fields are part of aggregates. 1659 bool IsVariableUsedInMapClause = false; 1660 bool IsVariableAssociatedWithSection = false; 1661 1662 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1663 D, Level, 1664 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1665 OMPClauseMappableExprCommon::MappableExprComponentListRef 1666 MapExprComponents, 1667 OpenMPClauseKind WhereFoundClauseKind) { 1668 // Only the map clause information influences how a variable is 1669 // captured. E.g. is_device_ptr does not require changing the default 1670 // behavior. 1671 if (WhereFoundClauseKind != OMPC_map) 1672 return false; 1673 1674 auto EI = MapExprComponents.rbegin(); 1675 auto EE = MapExprComponents.rend(); 1676 1677 assert(EI != EE && "Invalid map expression!"); 1678 1679 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1680 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1681 1682 ++EI; 1683 if (EI == EE) 1684 return false; 1685 1686 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1687 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1688 isa<MemberExpr>(EI->getAssociatedExpression())) { 1689 IsVariableAssociatedWithSection = true; 1690 // There is nothing more we need to know about this variable. 1691 return true; 1692 } 1693 1694 // Keep looking for more map info. 1695 return false; 1696 }); 1697 1698 if (IsVariableUsedInMapClause) { 1699 // If variable is identified in a map clause it is always captured by 1700 // reference except if it is a pointer that is dereferenced somehow. 1701 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1702 } else { 1703 // By default, all the data that has a scalar type is mapped by copy 1704 // (except for reduction variables). 1705 IsByRef = 1706 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1707 !Ty->isAnyPointerType()) || 1708 !Ty->isScalarType() || 1709 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1710 DSAStack->hasExplicitDSA( 1711 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1712 } 1713 } 1714 1715 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1716 IsByRef = 1717 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1718 !Ty->isAnyPointerType()) || 1719 !DSAStack->hasExplicitDSA( 1720 D, 1721 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1722 Level, /*NotLastprivate=*/true)) && 1723 // If the variable is artificial and must be captured by value - try to 1724 // capture by value. 1725 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1726 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1727 } 1728 1729 // When passing data by copy, we need to make sure it fits the uintptr size 1730 // and alignment, because the runtime library only deals with uintptr types. 1731 // If it does not fit the uintptr size, we need to pass the data by reference 1732 // instead. 1733 if (!IsByRef && 1734 (Ctx.getTypeSizeInChars(Ty) > 1735 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1736 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1737 IsByRef = true; 1738 } 1739 1740 return IsByRef; 1741 } 1742 1743 unsigned Sema::getOpenMPNestingLevel() const { 1744 assert(getLangOpts().OpenMP); 1745 return DSAStack->getNestingLevel(); 1746 } 1747 1748 bool Sema::isInOpenMPTargetExecutionDirective() const { 1749 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1750 !DSAStack->isClauseParsingMode()) || 1751 DSAStack->hasDirective( 1752 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1753 SourceLocation) -> bool { 1754 return isOpenMPTargetExecutionDirective(K); 1755 }, 1756 false); 1757 } 1758 1759 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1760 unsigned StopAt) { 1761 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1762 D = getCanonicalDecl(D); 1763 1764 // If we want to determine whether the variable should be captured from the 1765 // perspective of the current capturing scope, and we've already left all the 1766 // capturing scopes of the top directive on the stack, check from the 1767 // perspective of its parent directive (if any) instead. 1768 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1769 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1770 1771 // If we are attempting to capture a global variable in a directive with 1772 // 'target' we return true so that this global is also mapped to the device. 1773 // 1774 auto *VD = dyn_cast<VarDecl>(D); 1775 if (VD && !VD->hasLocalStorage() && 1776 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1777 if (isInOpenMPDeclareTargetContext()) { 1778 // Try to mark variable as declare target if it is used in capturing 1779 // regions. 1780 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1781 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1782 return nullptr; 1783 } else if (isInOpenMPTargetExecutionDirective()) { 1784 // If the declaration is enclosed in a 'declare target' directive, 1785 // then it should not be captured. 1786 // 1787 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1788 return nullptr; 1789 return VD; 1790 } 1791 } 1792 // Capture variables captured by reference in lambdas for target-based 1793 // directives. 1794 // FIXME: Triggering capture from here is completely inappropriate. 1795 if (VD && !DSAStack->isClauseParsingMode()) { 1796 if (const auto *RD = VD->getType() 1797 .getCanonicalType() 1798 .getNonReferenceType() 1799 ->getAsCXXRecordDecl()) { 1800 bool SavedForceCaptureByReferenceInTargetExecutable = 1801 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1802 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1803 InParentDirectiveRAII.disable(); 1804 if (RD->isLambda()) { 1805 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1806 FieldDecl *ThisCapture; 1807 RD->getCaptureFields(Captures, ThisCapture); 1808 for (const LambdaCapture &LC : RD->captures()) { 1809 if (LC.getCaptureKind() == LCK_ByRef) { 1810 VarDecl *VD = LC.getCapturedVar(); 1811 DeclContext *VDC = VD->getDeclContext(); 1812 if (!VDC->Encloses(CurContext)) 1813 continue; 1814 DSAStackTy::DSAVarData DVarPrivate = 1815 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1816 // Do not capture already captured variables. 1817 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1818 DVarPrivate.CKind == OMPC_unknown && 1819 !DSAStack->checkMappableExprComponentListsForDecl( 1820 D, /*CurrentRegionOnly=*/true, 1821 [](OMPClauseMappableExprCommon:: 1822 MappableExprComponentListRef, 1823 OpenMPClauseKind) { return true; })) 1824 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1825 } else if (LC.getCaptureKind() == LCK_This) { 1826 QualType ThisTy = getCurrentThisType(); 1827 if (!ThisTy.isNull() && 1828 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1829 CheckCXXThisCapture(LC.getLocation()); 1830 } 1831 } 1832 } 1833 if (CheckScopeInfo && DSAStack->isBodyComplete()) 1834 InParentDirectiveRAII.enable(); 1835 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1836 SavedForceCaptureByReferenceInTargetExecutable); 1837 } 1838 } 1839 1840 if (CheckScopeInfo) { 1841 bool OpenMPFound = false; 1842 for (unsigned I = StopAt + 1; I > 0; --I) { 1843 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1844 if(!isa<CapturingScopeInfo>(FSI)) 1845 return nullptr; 1846 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1847 if (RSI->CapRegionKind == CR_OpenMP) { 1848 OpenMPFound = true; 1849 break; 1850 } 1851 } 1852 if (!OpenMPFound) 1853 return nullptr; 1854 } 1855 1856 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1857 (!DSAStack->isClauseParsingMode() || 1858 DSAStack->getParentDirective() != OMPD_unknown)) { 1859 auto &&Info = DSAStack->isLoopControlVariable(D); 1860 if (Info.first || 1861 (VD && VD->hasLocalStorage() && 1862 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1863 (VD && DSAStack->isForceVarCapturing())) 1864 return VD ? VD : Info.second; 1865 DSAStackTy::DSAVarData DVarPrivate = 1866 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1867 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1868 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1869 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1870 [](OpenMPDirectiveKind) { return true; }, 1871 DSAStack->isClauseParsingMode()); 1872 // The variable is not private or it is the variable in the directive with 1873 // default(none) clause and not used in any clause. 1874 if (DVarPrivate.CKind != OMPC_unknown || 1875 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1876 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1877 } 1878 return nullptr; 1879 } 1880 1881 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1882 unsigned Level) const { 1883 SmallVector<OpenMPDirectiveKind, 4> Regions; 1884 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1885 FunctionScopesIndex -= Regions.size(); 1886 } 1887 1888 void Sema::startOpenMPLoop() { 1889 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1890 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1891 DSAStack->loopInit(); 1892 } 1893 1894 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1895 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1896 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1897 if (DSAStack->getAssociatedLoops() > 0 && 1898 !DSAStack->isLoopStarted()) { 1899 DSAStack->resetPossibleLoopCounter(D); 1900 DSAStack->loopStart(); 1901 return true; 1902 } 1903 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1904 DSAStack->isLoopControlVariable(D).first) && 1905 !DSAStack->hasExplicitDSA( 1906 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1907 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1908 return true; 1909 } 1910 return DSAStack->hasExplicitDSA( 1911 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1912 (DSAStack->isClauseParsingMode() && 1913 DSAStack->getClauseParsingMode() == OMPC_private) || 1914 // Consider taskgroup reduction descriptor variable a private to avoid 1915 // possible capture in the region. 1916 (DSAStack->hasExplicitDirective( 1917 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1918 Level) && 1919 DSAStack->isTaskgroupReductionRef(D, Level)); 1920 } 1921 1922 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1923 unsigned Level) { 1924 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1925 D = getCanonicalDecl(D); 1926 OpenMPClauseKind OMPC = OMPC_unknown; 1927 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1928 const unsigned NewLevel = I - 1; 1929 if (DSAStack->hasExplicitDSA(D, 1930 [&OMPC](const OpenMPClauseKind K) { 1931 if (isOpenMPPrivate(K)) { 1932 OMPC = K; 1933 return true; 1934 } 1935 return false; 1936 }, 1937 NewLevel)) 1938 break; 1939 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1940 D, NewLevel, 1941 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1942 OpenMPClauseKind) { return true; })) { 1943 OMPC = OMPC_map; 1944 break; 1945 } 1946 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1947 NewLevel)) { 1948 OMPC = OMPC_map; 1949 if (D->getType()->isScalarType() && 1950 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1951 DefaultMapAttributes::DMA_tofrom_scalar) 1952 OMPC = OMPC_firstprivate; 1953 break; 1954 } 1955 } 1956 if (OMPC != OMPC_unknown) 1957 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1958 } 1959 1960 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1961 unsigned Level) const { 1962 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1963 // Return true if the current level is no longer enclosed in a target region. 1964 1965 const auto *VD = dyn_cast<VarDecl>(D); 1966 return VD && !VD->hasLocalStorage() && 1967 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1968 Level); 1969 } 1970 1971 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1972 1973 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1974 const DeclarationNameInfo &DirName, 1975 Scope *CurScope, SourceLocation Loc) { 1976 DSAStack->push(DKind, DirName, CurScope, Loc); 1977 PushExpressionEvaluationContext( 1978 ExpressionEvaluationContext::PotentiallyEvaluated); 1979 } 1980 1981 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1982 DSAStack->setClauseParsingMode(K); 1983 } 1984 1985 void Sema::EndOpenMPClause() { 1986 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1987 } 1988 1989 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 1990 ArrayRef<OMPClause *> Clauses); 1991 1992 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1993 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1994 // A variable of class type (or array thereof) that appears in a lastprivate 1995 // clause requires an accessible, unambiguous default constructor for the 1996 // class type, unless the list item is also specified in a firstprivate 1997 // clause. 1998 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1999 for (OMPClause *C : D->clauses()) { 2000 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2001 SmallVector<Expr *, 8> PrivateCopies; 2002 for (Expr *DE : Clause->varlists()) { 2003 if (DE->isValueDependent() || DE->isTypeDependent()) { 2004 PrivateCopies.push_back(nullptr); 2005 continue; 2006 } 2007 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2008 auto *VD = cast<VarDecl>(DRE->getDecl()); 2009 QualType Type = VD->getType().getNonReferenceType(); 2010 const DSAStackTy::DSAVarData DVar = 2011 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2012 if (DVar.CKind == OMPC_lastprivate) { 2013 // Generate helper private variable and initialize it with the 2014 // default value. The address of the original variable is replaced 2015 // by the address of the new private variable in CodeGen. This new 2016 // variable is not added to IdResolver, so the code in the OpenMP 2017 // region uses original variable for proper diagnostics. 2018 VarDecl *VDPrivate = buildVarDecl( 2019 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2020 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2021 ActOnUninitializedDecl(VDPrivate); 2022 if (VDPrivate->isInvalidDecl()) { 2023 PrivateCopies.push_back(nullptr); 2024 continue; 2025 } 2026 PrivateCopies.push_back(buildDeclRefExpr( 2027 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2028 } else { 2029 // The variable is also a firstprivate, so initialization sequence 2030 // for private copy is generated already. 2031 PrivateCopies.push_back(nullptr); 2032 } 2033 } 2034 Clause->setPrivateCopies(PrivateCopies); 2035 } 2036 } 2037 // Check allocate clauses. 2038 if (!CurContext->isDependentContext()) 2039 checkAllocateClauses(*this, DSAStack, D->clauses()); 2040 } 2041 2042 DSAStack->pop(); 2043 DiscardCleanupsInEvaluationContext(); 2044 PopExpressionEvaluationContext(); 2045 } 2046 2047 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2048 Expr *NumIterations, Sema &SemaRef, 2049 Scope *S, DSAStackTy *Stack); 2050 2051 namespace { 2052 2053 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2054 private: 2055 Sema &SemaRef; 2056 2057 public: 2058 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2059 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2060 NamedDecl *ND = Candidate.getCorrectionDecl(); 2061 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2062 return VD->hasGlobalStorage() && 2063 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2064 SemaRef.getCurScope()); 2065 } 2066 return false; 2067 } 2068 2069 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2070 return llvm::make_unique<VarDeclFilterCCC>(*this); 2071 } 2072 2073 }; 2074 2075 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2076 private: 2077 Sema &SemaRef; 2078 2079 public: 2080 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2081 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2082 NamedDecl *ND = Candidate.getCorrectionDecl(); 2083 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2084 isa<FunctionDecl>(ND))) { 2085 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2086 SemaRef.getCurScope()); 2087 } 2088 return false; 2089 } 2090 2091 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2092 return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this); 2093 } 2094 }; 2095 2096 } // namespace 2097 2098 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2099 CXXScopeSpec &ScopeSpec, 2100 const DeclarationNameInfo &Id, 2101 OpenMPDirectiveKind Kind) { 2102 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2103 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2104 2105 if (Lookup.isAmbiguous()) 2106 return ExprError(); 2107 2108 VarDecl *VD; 2109 if (!Lookup.isSingleResult()) { 2110 VarDeclFilterCCC CCC(*this); 2111 if (TypoCorrection Corrected = 2112 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2113 CTK_ErrorRecovery)) { 2114 diagnoseTypo(Corrected, 2115 PDiag(Lookup.empty() 2116 ? diag::err_undeclared_var_use_suggest 2117 : diag::err_omp_expected_var_arg_suggest) 2118 << Id.getName()); 2119 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2120 } else { 2121 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2122 : diag::err_omp_expected_var_arg) 2123 << Id.getName(); 2124 return ExprError(); 2125 } 2126 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2127 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2128 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2129 return ExprError(); 2130 } 2131 Lookup.suppressDiagnostics(); 2132 2133 // OpenMP [2.9.2, Syntax, C/C++] 2134 // Variables must be file-scope, namespace-scope, or static block-scope. 2135 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2136 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2137 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2138 bool IsDecl = 2139 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2140 Diag(VD->getLocation(), 2141 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2142 << VD; 2143 return ExprError(); 2144 } 2145 2146 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2147 NamedDecl *ND = CanonicalVD; 2148 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2149 // A threadprivate directive for file-scope variables must appear outside 2150 // any definition or declaration. 2151 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2152 !getCurLexicalContext()->isTranslationUnit()) { 2153 Diag(Id.getLoc(), diag::err_omp_var_scope) 2154 << getOpenMPDirectiveName(Kind) << VD; 2155 bool IsDecl = 2156 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2157 Diag(VD->getLocation(), 2158 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2159 << VD; 2160 return ExprError(); 2161 } 2162 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2163 // A threadprivate directive for static class member variables must appear 2164 // in the class definition, in the same scope in which the member 2165 // variables are declared. 2166 if (CanonicalVD->isStaticDataMember() && 2167 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2168 Diag(Id.getLoc(), diag::err_omp_var_scope) 2169 << getOpenMPDirectiveName(Kind) << VD; 2170 bool IsDecl = 2171 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2172 Diag(VD->getLocation(), 2173 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2174 << VD; 2175 return ExprError(); 2176 } 2177 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2178 // A threadprivate directive for namespace-scope variables must appear 2179 // outside any definition or declaration other than the namespace 2180 // definition itself. 2181 if (CanonicalVD->getDeclContext()->isNamespace() && 2182 (!getCurLexicalContext()->isFileContext() || 2183 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2184 Diag(Id.getLoc(), diag::err_omp_var_scope) 2185 << getOpenMPDirectiveName(Kind) << VD; 2186 bool IsDecl = 2187 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2188 Diag(VD->getLocation(), 2189 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2190 << VD; 2191 return ExprError(); 2192 } 2193 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2194 // A threadprivate directive for static block-scope variables must appear 2195 // in the scope of the variable and not in a nested scope. 2196 if (CanonicalVD->isLocalVarDecl() && CurScope && 2197 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2198 Diag(Id.getLoc(), diag::err_omp_var_scope) 2199 << getOpenMPDirectiveName(Kind) << VD; 2200 bool IsDecl = 2201 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2202 Diag(VD->getLocation(), 2203 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2204 << VD; 2205 return ExprError(); 2206 } 2207 2208 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2209 // A threadprivate directive must lexically precede all references to any 2210 // of the variables in its list. 2211 if (Kind == OMPD_threadprivate && VD->isUsed() && 2212 !DSAStack->isThreadPrivate(VD)) { 2213 Diag(Id.getLoc(), diag::err_omp_var_used) 2214 << getOpenMPDirectiveName(Kind) << VD; 2215 return ExprError(); 2216 } 2217 2218 QualType ExprType = VD->getType().getNonReferenceType(); 2219 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2220 SourceLocation(), VD, 2221 /*RefersToEnclosingVariableOrCapture=*/false, 2222 Id.getLoc(), ExprType, VK_LValue); 2223 } 2224 2225 Sema::DeclGroupPtrTy 2226 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2227 ArrayRef<Expr *> VarList) { 2228 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2229 CurContext->addDecl(D); 2230 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2231 } 2232 return nullptr; 2233 } 2234 2235 namespace { 2236 class LocalVarRefChecker final 2237 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2238 Sema &SemaRef; 2239 2240 public: 2241 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2242 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2243 if (VD->hasLocalStorage()) { 2244 SemaRef.Diag(E->getBeginLoc(), 2245 diag::err_omp_local_var_in_threadprivate_init) 2246 << E->getSourceRange(); 2247 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2248 << VD << VD->getSourceRange(); 2249 return true; 2250 } 2251 } 2252 return false; 2253 } 2254 bool VisitStmt(const Stmt *S) { 2255 for (const Stmt *Child : S->children()) { 2256 if (Child && Visit(Child)) 2257 return true; 2258 } 2259 return false; 2260 } 2261 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2262 }; 2263 } // namespace 2264 2265 OMPThreadPrivateDecl * 2266 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2267 SmallVector<Expr *, 8> Vars; 2268 for (Expr *RefExpr : VarList) { 2269 auto *DE = cast<DeclRefExpr>(RefExpr); 2270 auto *VD = cast<VarDecl>(DE->getDecl()); 2271 SourceLocation ILoc = DE->getExprLoc(); 2272 2273 // Mark variable as used. 2274 VD->setReferenced(); 2275 VD->markUsed(Context); 2276 2277 QualType QType = VD->getType(); 2278 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2279 // It will be analyzed later. 2280 Vars.push_back(DE); 2281 continue; 2282 } 2283 2284 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2285 // A threadprivate variable must not have an incomplete type. 2286 if (RequireCompleteType(ILoc, VD->getType(), 2287 diag::err_omp_threadprivate_incomplete_type)) { 2288 continue; 2289 } 2290 2291 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2292 // A threadprivate variable must not have a reference type. 2293 if (VD->getType()->isReferenceType()) { 2294 Diag(ILoc, diag::err_omp_ref_type_arg) 2295 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2296 bool IsDecl = 2297 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2298 Diag(VD->getLocation(), 2299 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2300 << VD; 2301 continue; 2302 } 2303 2304 // Check if this is a TLS variable. If TLS is not being supported, produce 2305 // the corresponding diagnostic. 2306 if ((VD->getTLSKind() != VarDecl::TLS_None && 2307 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2308 getLangOpts().OpenMPUseTLS && 2309 getASTContext().getTargetInfo().isTLSSupported())) || 2310 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2311 !VD->isLocalVarDecl())) { 2312 Diag(ILoc, diag::err_omp_var_thread_local) 2313 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2314 bool IsDecl = 2315 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2316 Diag(VD->getLocation(), 2317 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2318 << VD; 2319 continue; 2320 } 2321 2322 // Check if initial value of threadprivate variable reference variable with 2323 // local storage (it is not supported by runtime). 2324 if (const Expr *Init = VD->getAnyInitializer()) { 2325 LocalVarRefChecker Checker(*this); 2326 if (Checker.Visit(Init)) 2327 continue; 2328 } 2329 2330 Vars.push_back(RefExpr); 2331 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2332 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2333 Context, SourceRange(Loc, Loc))); 2334 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2335 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2336 } 2337 OMPThreadPrivateDecl *D = nullptr; 2338 if (!Vars.empty()) { 2339 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2340 Vars); 2341 D->setAccess(AS_public); 2342 } 2343 return D; 2344 } 2345 2346 static OMPAllocateDeclAttr::AllocatorTypeTy 2347 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2348 if (!Allocator) 2349 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2350 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2351 Allocator->isInstantiationDependent() || 2352 Allocator->containsUnexpandedParameterPack()) 2353 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2354 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2355 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2356 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2357 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2358 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2359 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2360 llvm::FoldingSetNodeID AEId, DAEId; 2361 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2362 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2363 if (AEId == DAEId) { 2364 AllocatorKindRes = AllocatorKind; 2365 break; 2366 } 2367 } 2368 return AllocatorKindRes; 2369 } 2370 2371 static bool checkPreviousOMPAllocateAttribute( 2372 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2373 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2374 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2375 return false; 2376 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2377 Expr *PrevAllocator = A->getAllocator(); 2378 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2379 getAllocatorKind(S, Stack, PrevAllocator); 2380 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2381 if (AllocatorsMatch && 2382 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2383 Allocator && PrevAllocator) { 2384 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2385 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2386 llvm::FoldingSetNodeID AEId, PAEId; 2387 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2388 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2389 AllocatorsMatch = AEId == PAEId; 2390 } 2391 if (!AllocatorsMatch) { 2392 SmallString<256> AllocatorBuffer; 2393 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2394 if (Allocator) 2395 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2396 SmallString<256> PrevAllocatorBuffer; 2397 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2398 if (PrevAllocator) 2399 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2400 S.getPrintingPolicy()); 2401 2402 SourceLocation AllocatorLoc = 2403 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2404 SourceRange AllocatorRange = 2405 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2406 SourceLocation PrevAllocatorLoc = 2407 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2408 SourceRange PrevAllocatorRange = 2409 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2410 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2411 << (Allocator ? 1 : 0) << AllocatorStream.str() 2412 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2413 << AllocatorRange; 2414 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2415 << PrevAllocatorRange; 2416 return true; 2417 } 2418 return false; 2419 } 2420 2421 static void 2422 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2423 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2424 Expr *Allocator, SourceRange SR) { 2425 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2426 return; 2427 if (Allocator && 2428 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2429 Allocator->isInstantiationDependent() || 2430 Allocator->containsUnexpandedParameterPack())) 2431 return; 2432 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2433 Allocator, SR); 2434 VD->addAttr(A); 2435 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2436 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2437 } 2438 2439 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2440 SourceLocation Loc, ArrayRef<Expr *> VarList, 2441 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2442 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2443 Expr *Allocator = nullptr; 2444 if (Clauses.empty()) { 2445 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2446 // allocate directives that appear in a target region must specify an 2447 // allocator clause unless a requires directive with the dynamic_allocators 2448 // clause is present in the same compilation unit. 2449 if (LangOpts.OpenMPIsDevice && 2450 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2451 targetDiag(Loc, diag::err_expected_allocator_clause); 2452 } else { 2453 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2454 } 2455 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2456 getAllocatorKind(*this, DSAStack, Allocator); 2457 SmallVector<Expr *, 8> Vars; 2458 for (Expr *RefExpr : VarList) { 2459 auto *DE = cast<DeclRefExpr>(RefExpr); 2460 auto *VD = cast<VarDecl>(DE->getDecl()); 2461 2462 // Check if this is a TLS variable or global register. 2463 if (VD->getTLSKind() != VarDecl::TLS_None || 2464 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2465 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2466 !VD->isLocalVarDecl())) 2467 continue; 2468 2469 // If the used several times in the allocate directive, the same allocator 2470 // must be used. 2471 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2472 AllocatorKind, Allocator)) 2473 continue; 2474 2475 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2476 // If a list item has a static storage type, the allocator expression in the 2477 // allocator clause must be a constant expression that evaluates to one of 2478 // the predefined memory allocator values. 2479 if (Allocator && VD->hasGlobalStorage()) { 2480 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2481 Diag(Allocator->getExprLoc(), 2482 diag::err_omp_expected_predefined_allocator) 2483 << Allocator->getSourceRange(); 2484 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2485 VarDecl::DeclarationOnly; 2486 Diag(VD->getLocation(), 2487 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2488 << VD; 2489 continue; 2490 } 2491 } 2492 2493 Vars.push_back(RefExpr); 2494 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2495 DE->getSourceRange()); 2496 } 2497 if (Vars.empty()) 2498 return nullptr; 2499 if (!Owner) 2500 Owner = getCurLexicalContext(); 2501 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2502 D->setAccess(AS_public); 2503 Owner->addDecl(D); 2504 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2505 } 2506 2507 Sema::DeclGroupPtrTy 2508 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2509 ArrayRef<OMPClause *> ClauseList) { 2510 OMPRequiresDecl *D = nullptr; 2511 if (!CurContext->isFileContext()) { 2512 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2513 } else { 2514 D = CheckOMPRequiresDecl(Loc, ClauseList); 2515 if (D) { 2516 CurContext->addDecl(D); 2517 DSAStack->addRequiresDecl(D); 2518 } 2519 } 2520 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2521 } 2522 2523 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2524 ArrayRef<OMPClause *> ClauseList) { 2525 /// For target specific clauses, the requires directive cannot be 2526 /// specified after the handling of any of the target regions in the 2527 /// current compilation unit. 2528 ArrayRef<SourceLocation> TargetLocations = 2529 DSAStack->getEncounteredTargetLocs(); 2530 if (!TargetLocations.empty()) { 2531 for (const OMPClause *CNew : ClauseList) { 2532 // Check if any of the requires clauses affect target regions. 2533 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2534 isa<OMPUnifiedAddressClause>(CNew) || 2535 isa<OMPReverseOffloadClause>(CNew) || 2536 isa<OMPDynamicAllocatorsClause>(CNew)) { 2537 Diag(Loc, diag::err_omp_target_before_requires) 2538 << getOpenMPClauseName(CNew->getClauseKind()); 2539 for (SourceLocation TargetLoc : TargetLocations) { 2540 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2541 } 2542 } 2543 } 2544 } 2545 2546 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2547 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2548 ClauseList); 2549 return nullptr; 2550 } 2551 2552 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2553 const ValueDecl *D, 2554 const DSAStackTy::DSAVarData &DVar, 2555 bool IsLoopIterVar = false) { 2556 if (DVar.RefExpr) { 2557 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2558 << getOpenMPClauseName(DVar.CKind); 2559 return; 2560 } 2561 enum { 2562 PDSA_StaticMemberShared, 2563 PDSA_StaticLocalVarShared, 2564 PDSA_LoopIterVarPrivate, 2565 PDSA_LoopIterVarLinear, 2566 PDSA_LoopIterVarLastprivate, 2567 PDSA_ConstVarShared, 2568 PDSA_GlobalVarShared, 2569 PDSA_TaskVarFirstprivate, 2570 PDSA_LocalVarPrivate, 2571 PDSA_Implicit 2572 } Reason = PDSA_Implicit; 2573 bool ReportHint = false; 2574 auto ReportLoc = D->getLocation(); 2575 auto *VD = dyn_cast<VarDecl>(D); 2576 if (IsLoopIterVar) { 2577 if (DVar.CKind == OMPC_private) 2578 Reason = PDSA_LoopIterVarPrivate; 2579 else if (DVar.CKind == OMPC_lastprivate) 2580 Reason = PDSA_LoopIterVarLastprivate; 2581 else 2582 Reason = PDSA_LoopIterVarLinear; 2583 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2584 DVar.CKind == OMPC_firstprivate) { 2585 Reason = PDSA_TaskVarFirstprivate; 2586 ReportLoc = DVar.ImplicitDSALoc; 2587 } else if (VD && VD->isStaticLocal()) 2588 Reason = PDSA_StaticLocalVarShared; 2589 else if (VD && VD->isStaticDataMember()) 2590 Reason = PDSA_StaticMemberShared; 2591 else if (VD && VD->isFileVarDecl()) 2592 Reason = PDSA_GlobalVarShared; 2593 else if (D->getType().isConstant(SemaRef.getASTContext())) 2594 Reason = PDSA_ConstVarShared; 2595 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2596 ReportHint = true; 2597 Reason = PDSA_LocalVarPrivate; 2598 } 2599 if (Reason != PDSA_Implicit) { 2600 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2601 << Reason << ReportHint 2602 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2603 } else if (DVar.ImplicitDSALoc.isValid()) { 2604 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2605 << getOpenMPClauseName(DVar.CKind); 2606 } 2607 } 2608 2609 namespace { 2610 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2611 DSAStackTy *Stack; 2612 Sema &SemaRef; 2613 bool ErrorFound = false; 2614 CapturedStmt *CS = nullptr; 2615 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2616 llvm::SmallVector<Expr *, 4> ImplicitMap; 2617 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2618 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2619 2620 void VisitSubCaptures(OMPExecutableDirective *S) { 2621 // Check implicitly captured variables. 2622 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2623 return; 2624 for (const CapturedStmt::Capture &Cap : 2625 S->getInnermostCapturedStmt()->captures()) { 2626 if (!Cap.capturesVariable()) 2627 continue; 2628 VarDecl *VD = Cap.getCapturedVar(); 2629 // Do not try to map the variable if it or its sub-component was mapped 2630 // already. 2631 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2632 Stack->checkMappableExprComponentListsForDecl( 2633 VD, /*CurrentRegionOnly=*/true, 2634 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2635 OpenMPClauseKind) { return true; })) 2636 continue; 2637 DeclRefExpr *DRE = buildDeclRefExpr( 2638 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2639 Cap.getLocation(), /*RefersToCapture=*/true); 2640 Visit(DRE); 2641 } 2642 } 2643 2644 public: 2645 void VisitDeclRefExpr(DeclRefExpr *E) { 2646 if (E->isTypeDependent() || E->isValueDependent() || 2647 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2648 return; 2649 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2650 // Check the datasharing rules for the expressions in the clauses. 2651 if (!CS) { 2652 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2653 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2654 Visit(CED->getInit()); 2655 return; 2656 } 2657 } 2658 VD = VD->getCanonicalDecl(); 2659 // Skip internally declared variables. 2660 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2661 return; 2662 2663 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2664 // Check if the variable has explicit DSA set and stop analysis if it so. 2665 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2666 return; 2667 2668 // Skip internally declared static variables. 2669 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2670 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2671 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2672 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2673 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2674 return; 2675 2676 SourceLocation ELoc = E->getExprLoc(); 2677 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2678 // The default(none) clause requires that each variable that is referenced 2679 // in the construct, and does not have a predetermined data-sharing 2680 // attribute, must have its data-sharing attribute explicitly determined 2681 // by being listed in a data-sharing attribute clause. 2682 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2683 isImplicitOrExplicitTaskingRegion(DKind) && 2684 VarsWithInheritedDSA.count(VD) == 0) { 2685 VarsWithInheritedDSA[VD] = E; 2686 return; 2687 } 2688 2689 if (isOpenMPTargetExecutionDirective(DKind) && 2690 !Stack->isLoopControlVariable(VD).first) { 2691 if (!Stack->checkMappableExprComponentListsForDecl( 2692 VD, /*CurrentRegionOnly=*/true, 2693 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2694 StackComponents, 2695 OpenMPClauseKind) { 2696 // Variable is used if it has been marked as an array, array 2697 // section or the variable iself. 2698 return StackComponents.size() == 1 || 2699 std::all_of( 2700 std::next(StackComponents.rbegin()), 2701 StackComponents.rend(), 2702 [](const OMPClauseMappableExprCommon:: 2703 MappableComponent &MC) { 2704 return MC.getAssociatedDeclaration() == 2705 nullptr && 2706 (isa<OMPArraySectionExpr>( 2707 MC.getAssociatedExpression()) || 2708 isa<ArraySubscriptExpr>( 2709 MC.getAssociatedExpression())); 2710 }); 2711 })) { 2712 bool IsFirstprivate = false; 2713 // By default lambdas are captured as firstprivates. 2714 if (const auto *RD = 2715 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2716 IsFirstprivate = RD->isLambda(); 2717 IsFirstprivate = 2718 IsFirstprivate || 2719 (VD->getType().getNonReferenceType()->isScalarType() && 2720 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2721 if (IsFirstprivate) 2722 ImplicitFirstprivate.emplace_back(E); 2723 else 2724 ImplicitMap.emplace_back(E); 2725 return; 2726 } 2727 } 2728 2729 // OpenMP [2.9.3.6, Restrictions, p.2] 2730 // A list item that appears in a reduction clause of the innermost 2731 // enclosing worksharing or parallel construct may not be accessed in an 2732 // explicit task. 2733 DVar = Stack->hasInnermostDSA( 2734 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2735 [](OpenMPDirectiveKind K) { 2736 return isOpenMPParallelDirective(K) || 2737 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2738 }, 2739 /*FromParent=*/true); 2740 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2741 ErrorFound = true; 2742 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2743 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2744 return; 2745 } 2746 2747 // Define implicit data-sharing attributes for task. 2748 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2749 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2750 !Stack->isLoopControlVariable(VD).first) { 2751 ImplicitFirstprivate.push_back(E); 2752 return; 2753 } 2754 2755 // Store implicitly used globals with declare target link for parent 2756 // target. 2757 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2758 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2759 Stack->addToParentTargetRegionLinkGlobals(E); 2760 return; 2761 } 2762 } 2763 } 2764 void VisitMemberExpr(MemberExpr *E) { 2765 if (E->isTypeDependent() || E->isValueDependent() || 2766 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2767 return; 2768 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2769 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2770 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2771 if (!FD) 2772 return; 2773 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2774 // Check if the variable has explicit DSA set and stop analysis if it 2775 // so. 2776 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2777 return; 2778 2779 if (isOpenMPTargetExecutionDirective(DKind) && 2780 !Stack->isLoopControlVariable(FD).first && 2781 !Stack->checkMappableExprComponentListsForDecl( 2782 FD, /*CurrentRegionOnly=*/true, 2783 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2784 StackComponents, 2785 OpenMPClauseKind) { 2786 return isa<CXXThisExpr>( 2787 cast<MemberExpr>( 2788 StackComponents.back().getAssociatedExpression()) 2789 ->getBase() 2790 ->IgnoreParens()); 2791 })) { 2792 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2793 // A bit-field cannot appear in a map clause. 2794 // 2795 if (FD->isBitField()) 2796 return; 2797 2798 // Check to see if the member expression is referencing a class that 2799 // has already been explicitly mapped 2800 if (Stack->isClassPreviouslyMapped(TE->getType())) 2801 return; 2802 2803 ImplicitMap.emplace_back(E); 2804 return; 2805 } 2806 2807 SourceLocation ELoc = E->getExprLoc(); 2808 // OpenMP [2.9.3.6, Restrictions, p.2] 2809 // A list item that appears in a reduction clause of the innermost 2810 // enclosing worksharing or parallel construct may not be accessed in 2811 // an explicit task. 2812 DVar = Stack->hasInnermostDSA( 2813 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2814 [](OpenMPDirectiveKind K) { 2815 return isOpenMPParallelDirective(K) || 2816 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2817 }, 2818 /*FromParent=*/true); 2819 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2820 ErrorFound = true; 2821 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2822 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2823 return; 2824 } 2825 2826 // Define implicit data-sharing attributes for task. 2827 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2828 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2829 !Stack->isLoopControlVariable(FD).first) { 2830 // Check if there is a captured expression for the current field in the 2831 // region. Do not mark it as firstprivate unless there is no captured 2832 // expression. 2833 // TODO: try to make it firstprivate. 2834 if (DVar.CKind != OMPC_unknown) 2835 ImplicitFirstprivate.push_back(E); 2836 } 2837 return; 2838 } 2839 if (isOpenMPTargetExecutionDirective(DKind)) { 2840 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2841 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2842 /*NoDiagnose=*/true)) 2843 return; 2844 const auto *VD = cast<ValueDecl>( 2845 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2846 if (!Stack->checkMappableExprComponentListsForDecl( 2847 VD, /*CurrentRegionOnly=*/true, 2848 [&CurComponents]( 2849 OMPClauseMappableExprCommon::MappableExprComponentListRef 2850 StackComponents, 2851 OpenMPClauseKind) { 2852 auto CCI = CurComponents.rbegin(); 2853 auto CCE = CurComponents.rend(); 2854 for (const auto &SC : llvm::reverse(StackComponents)) { 2855 // Do both expressions have the same kind? 2856 if (CCI->getAssociatedExpression()->getStmtClass() != 2857 SC.getAssociatedExpression()->getStmtClass()) 2858 if (!(isa<OMPArraySectionExpr>( 2859 SC.getAssociatedExpression()) && 2860 isa<ArraySubscriptExpr>( 2861 CCI->getAssociatedExpression()))) 2862 return false; 2863 2864 const Decl *CCD = CCI->getAssociatedDeclaration(); 2865 const Decl *SCD = SC.getAssociatedDeclaration(); 2866 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2867 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2868 if (SCD != CCD) 2869 return false; 2870 std::advance(CCI, 1); 2871 if (CCI == CCE) 2872 break; 2873 } 2874 return true; 2875 })) { 2876 Visit(E->getBase()); 2877 } 2878 } else { 2879 Visit(E->getBase()); 2880 } 2881 } 2882 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2883 for (OMPClause *C : S->clauses()) { 2884 // Skip analysis of arguments of implicitly defined firstprivate clause 2885 // for task|target directives. 2886 // Skip analysis of arguments of implicitly defined map clause for target 2887 // directives. 2888 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2889 C->isImplicit())) { 2890 for (Stmt *CC : C->children()) { 2891 if (CC) 2892 Visit(CC); 2893 } 2894 } 2895 } 2896 // Check implicitly captured variables. 2897 VisitSubCaptures(S); 2898 } 2899 void VisitStmt(Stmt *S) { 2900 for (Stmt *C : S->children()) { 2901 if (C) { 2902 // Check implicitly captured variables in the task-based directives to 2903 // check if they must be firstprivatized. 2904 Visit(C); 2905 } 2906 } 2907 } 2908 2909 bool isErrorFound() const { return ErrorFound; } 2910 ArrayRef<Expr *> getImplicitFirstprivate() const { 2911 return ImplicitFirstprivate; 2912 } 2913 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2914 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2915 return VarsWithInheritedDSA; 2916 } 2917 2918 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2919 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2920 // Process declare target link variables for the target directives. 2921 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2922 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2923 Visit(E); 2924 } 2925 } 2926 }; 2927 } // namespace 2928 2929 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2930 switch (DKind) { 2931 case OMPD_parallel: 2932 case OMPD_parallel_for: 2933 case OMPD_parallel_for_simd: 2934 case OMPD_parallel_sections: 2935 case OMPD_teams: 2936 case OMPD_teams_distribute: 2937 case OMPD_teams_distribute_simd: { 2938 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2939 QualType KmpInt32PtrTy = 2940 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2941 Sema::CapturedParamNameType Params[] = { 2942 std::make_pair(".global_tid.", KmpInt32PtrTy), 2943 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2944 std::make_pair(StringRef(), QualType()) // __context with shared vars 2945 }; 2946 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2947 Params); 2948 break; 2949 } 2950 case OMPD_target_teams: 2951 case OMPD_target_parallel: 2952 case OMPD_target_parallel_for: 2953 case OMPD_target_parallel_for_simd: 2954 case OMPD_target_teams_distribute: 2955 case OMPD_target_teams_distribute_simd: { 2956 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2957 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2958 QualType KmpInt32PtrTy = 2959 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2960 QualType Args[] = {VoidPtrTy}; 2961 FunctionProtoType::ExtProtoInfo EPI; 2962 EPI.Variadic = true; 2963 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2964 Sema::CapturedParamNameType Params[] = { 2965 std::make_pair(".global_tid.", KmpInt32Ty), 2966 std::make_pair(".part_id.", KmpInt32PtrTy), 2967 std::make_pair(".privates.", VoidPtrTy), 2968 std::make_pair( 2969 ".copy_fn.", 2970 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2971 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2972 std::make_pair(StringRef(), QualType()) // __context with shared vars 2973 }; 2974 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2975 Params); 2976 // Mark this captured region as inlined, because we don't use outlined 2977 // function directly. 2978 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2979 AlwaysInlineAttr::CreateImplicit( 2980 Context, AlwaysInlineAttr::Keyword_forceinline)); 2981 Sema::CapturedParamNameType ParamsTarget[] = { 2982 std::make_pair(StringRef(), QualType()) // __context with shared vars 2983 }; 2984 // Start a captured region for 'target' with no implicit parameters. 2985 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2986 ParamsTarget); 2987 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2988 std::make_pair(".global_tid.", KmpInt32PtrTy), 2989 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2990 std::make_pair(StringRef(), QualType()) // __context with shared vars 2991 }; 2992 // Start a captured region for 'teams' or 'parallel'. Both regions have 2993 // the same implicit parameters. 2994 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2995 ParamsTeamsOrParallel); 2996 break; 2997 } 2998 case OMPD_target: 2999 case OMPD_target_simd: { 3000 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3001 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3002 QualType KmpInt32PtrTy = 3003 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3004 QualType Args[] = {VoidPtrTy}; 3005 FunctionProtoType::ExtProtoInfo EPI; 3006 EPI.Variadic = true; 3007 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3008 Sema::CapturedParamNameType Params[] = { 3009 std::make_pair(".global_tid.", KmpInt32Ty), 3010 std::make_pair(".part_id.", KmpInt32PtrTy), 3011 std::make_pair(".privates.", VoidPtrTy), 3012 std::make_pair( 3013 ".copy_fn.", 3014 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3015 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3016 std::make_pair(StringRef(), QualType()) // __context with shared vars 3017 }; 3018 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3019 Params); 3020 // Mark this captured region as inlined, because we don't use outlined 3021 // function directly. 3022 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3023 AlwaysInlineAttr::CreateImplicit( 3024 Context, AlwaysInlineAttr::Keyword_forceinline)); 3025 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3026 std::make_pair(StringRef(), QualType())); 3027 break; 3028 } 3029 case OMPD_simd: 3030 case OMPD_for: 3031 case OMPD_for_simd: 3032 case OMPD_sections: 3033 case OMPD_section: 3034 case OMPD_single: 3035 case OMPD_master: 3036 case OMPD_critical: 3037 case OMPD_taskgroup: 3038 case OMPD_distribute: 3039 case OMPD_distribute_simd: 3040 case OMPD_ordered: 3041 case OMPD_atomic: 3042 case OMPD_target_data: { 3043 Sema::CapturedParamNameType Params[] = { 3044 std::make_pair(StringRef(), QualType()) // __context with shared vars 3045 }; 3046 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3047 Params); 3048 break; 3049 } 3050 case OMPD_task: { 3051 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3052 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3053 QualType KmpInt32PtrTy = 3054 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3055 QualType Args[] = {VoidPtrTy}; 3056 FunctionProtoType::ExtProtoInfo EPI; 3057 EPI.Variadic = true; 3058 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3059 Sema::CapturedParamNameType Params[] = { 3060 std::make_pair(".global_tid.", KmpInt32Ty), 3061 std::make_pair(".part_id.", KmpInt32PtrTy), 3062 std::make_pair(".privates.", VoidPtrTy), 3063 std::make_pair( 3064 ".copy_fn.", 3065 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3066 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3067 std::make_pair(StringRef(), QualType()) // __context with shared vars 3068 }; 3069 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3070 Params); 3071 // Mark this captured region as inlined, because we don't use outlined 3072 // function directly. 3073 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3074 AlwaysInlineAttr::CreateImplicit( 3075 Context, AlwaysInlineAttr::Keyword_forceinline)); 3076 break; 3077 } 3078 case OMPD_taskloop: 3079 case OMPD_taskloop_simd: { 3080 QualType KmpInt32Ty = 3081 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3082 .withConst(); 3083 QualType KmpUInt64Ty = 3084 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3085 .withConst(); 3086 QualType KmpInt64Ty = 3087 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3088 .withConst(); 3089 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3090 QualType KmpInt32PtrTy = 3091 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3092 QualType Args[] = {VoidPtrTy}; 3093 FunctionProtoType::ExtProtoInfo EPI; 3094 EPI.Variadic = true; 3095 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3096 Sema::CapturedParamNameType Params[] = { 3097 std::make_pair(".global_tid.", KmpInt32Ty), 3098 std::make_pair(".part_id.", KmpInt32PtrTy), 3099 std::make_pair(".privates.", VoidPtrTy), 3100 std::make_pair( 3101 ".copy_fn.", 3102 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3103 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3104 std::make_pair(".lb.", KmpUInt64Ty), 3105 std::make_pair(".ub.", KmpUInt64Ty), 3106 std::make_pair(".st.", KmpInt64Ty), 3107 std::make_pair(".liter.", KmpInt32Ty), 3108 std::make_pair(".reductions.", VoidPtrTy), 3109 std::make_pair(StringRef(), QualType()) // __context with shared vars 3110 }; 3111 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3112 Params); 3113 // Mark this captured region as inlined, because we don't use outlined 3114 // function directly. 3115 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3116 AlwaysInlineAttr::CreateImplicit( 3117 Context, AlwaysInlineAttr::Keyword_forceinline)); 3118 break; 3119 } 3120 case OMPD_distribute_parallel_for_simd: 3121 case OMPD_distribute_parallel_for: { 3122 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3123 QualType KmpInt32PtrTy = 3124 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3125 Sema::CapturedParamNameType Params[] = { 3126 std::make_pair(".global_tid.", KmpInt32PtrTy), 3127 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3128 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3129 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3130 std::make_pair(StringRef(), QualType()) // __context with shared vars 3131 }; 3132 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3133 Params); 3134 break; 3135 } 3136 case OMPD_target_teams_distribute_parallel_for: 3137 case OMPD_target_teams_distribute_parallel_for_simd: { 3138 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3139 QualType KmpInt32PtrTy = 3140 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3141 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3142 3143 QualType Args[] = {VoidPtrTy}; 3144 FunctionProtoType::ExtProtoInfo EPI; 3145 EPI.Variadic = true; 3146 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3147 Sema::CapturedParamNameType Params[] = { 3148 std::make_pair(".global_tid.", KmpInt32Ty), 3149 std::make_pair(".part_id.", KmpInt32PtrTy), 3150 std::make_pair(".privates.", VoidPtrTy), 3151 std::make_pair( 3152 ".copy_fn.", 3153 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3154 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3155 std::make_pair(StringRef(), QualType()) // __context with shared vars 3156 }; 3157 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3158 Params); 3159 // Mark this captured region as inlined, because we don't use outlined 3160 // function directly. 3161 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3162 AlwaysInlineAttr::CreateImplicit( 3163 Context, AlwaysInlineAttr::Keyword_forceinline)); 3164 Sema::CapturedParamNameType ParamsTarget[] = { 3165 std::make_pair(StringRef(), QualType()) // __context with shared vars 3166 }; 3167 // Start a captured region for 'target' with no implicit parameters. 3168 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3169 ParamsTarget); 3170 3171 Sema::CapturedParamNameType ParamsTeams[] = { 3172 std::make_pair(".global_tid.", KmpInt32PtrTy), 3173 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3174 std::make_pair(StringRef(), QualType()) // __context with shared vars 3175 }; 3176 // Start a captured region for 'target' with no implicit parameters. 3177 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3178 ParamsTeams); 3179 3180 Sema::CapturedParamNameType ParamsParallel[] = { 3181 std::make_pair(".global_tid.", KmpInt32PtrTy), 3182 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3183 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3184 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3185 std::make_pair(StringRef(), QualType()) // __context with shared vars 3186 }; 3187 // Start a captured region for 'teams' or 'parallel'. Both regions have 3188 // the same implicit parameters. 3189 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3190 ParamsParallel); 3191 break; 3192 } 3193 3194 case OMPD_teams_distribute_parallel_for: 3195 case OMPD_teams_distribute_parallel_for_simd: { 3196 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3197 QualType KmpInt32PtrTy = 3198 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3199 3200 Sema::CapturedParamNameType ParamsTeams[] = { 3201 std::make_pair(".global_tid.", KmpInt32PtrTy), 3202 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3203 std::make_pair(StringRef(), QualType()) // __context with shared vars 3204 }; 3205 // Start a captured region for 'target' with no implicit parameters. 3206 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3207 ParamsTeams); 3208 3209 Sema::CapturedParamNameType ParamsParallel[] = { 3210 std::make_pair(".global_tid.", KmpInt32PtrTy), 3211 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3212 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3213 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3214 std::make_pair(StringRef(), QualType()) // __context with shared vars 3215 }; 3216 // Start a captured region for 'teams' or 'parallel'. Both regions have 3217 // the same implicit parameters. 3218 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3219 ParamsParallel); 3220 break; 3221 } 3222 case OMPD_target_update: 3223 case OMPD_target_enter_data: 3224 case OMPD_target_exit_data: { 3225 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3226 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3227 QualType KmpInt32PtrTy = 3228 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3229 QualType Args[] = {VoidPtrTy}; 3230 FunctionProtoType::ExtProtoInfo EPI; 3231 EPI.Variadic = true; 3232 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3233 Sema::CapturedParamNameType Params[] = { 3234 std::make_pair(".global_tid.", KmpInt32Ty), 3235 std::make_pair(".part_id.", KmpInt32PtrTy), 3236 std::make_pair(".privates.", VoidPtrTy), 3237 std::make_pair( 3238 ".copy_fn.", 3239 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3240 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3241 std::make_pair(StringRef(), QualType()) // __context with shared vars 3242 }; 3243 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3244 Params); 3245 // Mark this captured region as inlined, because we don't use outlined 3246 // function directly. 3247 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3248 AlwaysInlineAttr::CreateImplicit( 3249 Context, AlwaysInlineAttr::Keyword_forceinline)); 3250 break; 3251 } 3252 case OMPD_threadprivate: 3253 case OMPD_allocate: 3254 case OMPD_taskyield: 3255 case OMPD_barrier: 3256 case OMPD_taskwait: 3257 case OMPD_cancellation_point: 3258 case OMPD_cancel: 3259 case OMPD_flush: 3260 case OMPD_declare_reduction: 3261 case OMPD_declare_mapper: 3262 case OMPD_declare_simd: 3263 case OMPD_declare_target: 3264 case OMPD_end_declare_target: 3265 case OMPD_requires: 3266 llvm_unreachable("OpenMP Directive is not allowed"); 3267 case OMPD_unknown: 3268 llvm_unreachable("Unknown OpenMP directive"); 3269 } 3270 } 3271 3272 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3273 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3274 getOpenMPCaptureRegions(CaptureRegions, DKind); 3275 return CaptureRegions.size(); 3276 } 3277 3278 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3279 Expr *CaptureExpr, bool WithInit, 3280 bool AsExpression) { 3281 assert(CaptureExpr); 3282 ASTContext &C = S.getASTContext(); 3283 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3284 QualType Ty = Init->getType(); 3285 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3286 if (S.getLangOpts().CPlusPlus) { 3287 Ty = C.getLValueReferenceType(Ty); 3288 } else { 3289 Ty = C.getPointerType(Ty); 3290 ExprResult Res = 3291 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3292 if (!Res.isUsable()) 3293 return nullptr; 3294 Init = Res.get(); 3295 } 3296 WithInit = true; 3297 } 3298 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3299 CaptureExpr->getBeginLoc()); 3300 if (!WithInit) 3301 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3302 S.CurContext->addHiddenDecl(CED); 3303 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3304 return CED; 3305 } 3306 3307 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3308 bool WithInit) { 3309 OMPCapturedExprDecl *CD; 3310 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3311 CD = cast<OMPCapturedExprDecl>(VD); 3312 else 3313 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3314 /*AsExpression=*/false); 3315 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3316 CaptureExpr->getExprLoc()); 3317 } 3318 3319 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3320 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3321 if (!Ref) { 3322 OMPCapturedExprDecl *CD = buildCaptureDecl( 3323 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3324 /*WithInit=*/true, /*AsExpression=*/true); 3325 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3326 CaptureExpr->getExprLoc()); 3327 } 3328 ExprResult Res = Ref; 3329 if (!S.getLangOpts().CPlusPlus && 3330 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3331 Ref->getType()->isPointerType()) { 3332 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3333 if (!Res.isUsable()) 3334 return ExprError(); 3335 } 3336 return S.DefaultLvalueConversion(Res.get()); 3337 } 3338 3339 namespace { 3340 // OpenMP directives parsed in this section are represented as a 3341 // CapturedStatement with an associated statement. If a syntax error 3342 // is detected during the parsing of the associated statement, the 3343 // compiler must abort processing and close the CapturedStatement. 3344 // 3345 // Combined directives such as 'target parallel' have more than one 3346 // nested CapturedStatements. This RAII ensures that we unwind out 3347 // of all the nested CapturedStatements when an error is found. 3348 class CaptureRegionUnwinderRAII { 3349 private: 3350 Sema &S; 3351 bool &ErrorFound; 3352 OpenMPDirectiveKind DKind = OMPD_unknown; 3353 3354 public: 3355 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3356 OpenMPDirectiveKind DKind) 3357 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3358 ~CaptureRegionUnwinderRAII() { 3359 if (ErrorFound) { 3360 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3361 while (--ThisCaptureLevel >= 0) 3362 S.ActOnCapturedRegionError(); 3363 } 3364 } 3365 }; 3366 } // namespace 3367 3368 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3369 ArrayRef<OMPClause *> Clauses) { 3370 bool ErrorFound = false; 3371 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3372 *this, ErrorFound, DSAStack->getCurrentDirective()); 3373 if (!S.isUsable()) { 3374 ErrorFound = true; 3375 return StmtError(); 3376 } 3377 3378 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3379 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3380 OMPOrderedClause *OC = nullptr; 3381 OMPScheduleClause *SC = nullptr; 3382 SmallVector<const OMPLinearClause *, 4> LCs; 3383 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3384 // This is required for proper codegen. 3385 for (OMPClause *Clause : Clauses) { 3386 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3387 Clause->getClauseKind() == OMPC_in_reduction) { 3388 // Capture taskgroup task_reduction descriptors inside the tasking regions 3389 // with the corresponding in_reduction items. 3390 auto *IRC = cast<OMPInReductionClause>(Clause); 3391 for (Expr *E : IRC->taskgroup_descriptors()) 3392 if (E) 3393 MarkDeclarationsReferencedInExpr(E); 3394 } 3395 if (isOpenMPPrivate(Clause->getClauseKind()) || 3396 Clause->getClauseKind() == OMPC_copyprivate || 3397 (getLangOpts().OpenMPUseTLS && 3398 getASTContext().getTargetInfo().isTLSSupported() && 3399 Clause->getClauseKind() == OMPC_copyin)) { 3400 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3401 // Mark all variables in private list clauses as used in inner region. 3402 for (Stmt *VarRef : Clause->children()) { 3403 if (auto *E = cast_or_null<Expr>(VarRef)) { 3404 MarkDeclarationsReferencedInExpr(E); 3405 } 3406 } 3407 DSAStack->setForceVarCapturing(/*V=*/false); 3408 } else if (CaptureRegions.size() > 1 || 3409 CaptureRegions.back() != OMPD_unknown) { 3410 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3411 PICs.push_back(C); 3412 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3413 if (Expr *E = C->getPostUpdateExpr()) 3414 MarkDeclarationsReferencedInExpr(E); 3415 } 3416 } 3417 if (Clause->getClauseKind() == OMPC_schedule) 3418 SC = cast<OMPScheduleClause>(Clause); 3419 else if (Clause->getClauseKind() == OMPC_ordered) 3420 OC = cast<OMPOrderedClause>(Clause); 3421 else if (Clause->getClauseKind() == OMPC_linear) 3422 LCs.push_back(cast<OMPLinearClause>(Clause)); 3423 } 3424 // OpenMP, 2.7.1 Loop Construct, Restrictions 3425 // The nonmonotonic modifier cannot be specified if an ordered clause is 3426 // specified. 3427 if (SC && 3428 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3429 SC->getSecondScheduleModifier() == 3430 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3431 OC) { 3432 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3433 ? SC->getFirstScheduleModifierLoc() 3434 : SC->getSecondScheduleModifierLoc(), 3435 diag::err_omp_schedule_nonmonotonic_ordered) 3436 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3437 ErrorFound = true; 3438 } 3439 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3440 for (const OMPLinearClause *C : LCs) { 3441 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3442 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3443 } 3444 ErrorFound = true; 3445 } 3446 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3447 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3448 OC->getNumForLoops()) { 3449 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3450 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3451 ErrorFound = true; 3452 } 3453 if (ErrorFound) { 3454 return StmtError(); 3455 } 3456 StmtResult SR = S; 3457 unsigned CompletedRegions = 0; 3458 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3459 // Mark all variables in private list clauses as used in inner region. 3460 // Required for proper codegen of combined directives. 3461 // TODO: add processing for other clauses. 3462 if (ThisCaptureRegion != OMPD_unknown) { 3463 for (const clang::OMPClauseWithPreInit *C : PICs) { 3464 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3465 // Find the particular capture region for the clause if the 3466 // directive is a combined one with multiple capture regions. 3467 // If the directive is not a combined one, the capture region 3468 // associated with the clause is OMPD_unknown and is generated 3469 // only once. 3470 if (CaptureRegion == ThisCaptureRegion || 3471 CaptureRegion == OMPD_unknown) { 3472 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3473 for (Decl *D : DS->decls()) 3474 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3475 } 3476 } 3477 } 3478 } 3479 if (++CompletedRegions == CaptureRegions.size()) 3480 DSAStack->setBodyComplete(); 3481 SR = ActOnCapturedRegionEnd(SR.get()); 3482 } 3483 return SR; 3484 } 3485 3486 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3487 OpenMPDirectiveKind CancelRegion, 3488 SourceLocation StartLoc) { 3489 // CancelRegion is only needed for cancel and cancellation_point. 3490 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3491 return false; 3492 3493 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3494 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3495 return false; 3496 3497 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3498 << getOpenMPDirectiveName(CancelRegion); 3499 return true; 3500 } 3501 3502 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3503 OpenMPDirectiveKind CurrentRegion, 3504 const DeclarationNameInfo &CurrentName, 3505 OpenMPDirectiveKind CancelRegion, 3506 SourceLocation StartLoc) { 3507 if (Stack->getCurScope()) { 3508 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3509 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3510 bool NestingProhibited = false; 3511 bool CloseNesting = true; 3512 bool OrphanSeen = false; 3513 enum { 3514 NoRecommend, 3515 ShouldBeInParallelRegion, 3516 ShouldBeInOrderedRegion, 3517 ShouldBeInTargetRegion, 3518 ShouldBeInTeamsRegion 3519 } Recommend = NoRecommend; 3520 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3521 // OpenMP [2.16, Nesting of Regions] 3522 // OpenMP constructs may not be nested inside a simd region. 3523 // OpenMP [2.8.1,simd Construct, Restrictions] 3524 // An ordered construct with the simd clause is the only OpenMP 3525 // construct that can appear in the simd region. 3526 // Allowing a SIMD construct nested in another SIMD construct is an 3527 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3528 // message. 3529 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3530 ? diag::err_omp_prohibited_region_simd 3531 : diag::warn_omp_nesting_simd); 3532 return CurrentRegion != OMPD_simd; 3533 } 3534 if (ParentRegion == OMPD_atomic) { 3535 // OpenMP [2.16, Nesting of Regions] 3536 // OpenMP constructs may not be nested inside an atomic region. 3537 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3538 return true; 3539 } 3540 if (CurrentRegion == OMPD_section) { 3541 // OpenMP [2.7.2, sections Construct, Restrictions] 3542 // Orphaned section directives are prohibited. That is, the section 3543 // directives must appear within the sections construct and must not be 3544 // encountered elsewhere in the sections region. 3545 if (ParentRegion != OMPD_sections && 3546 ParentRegion != OMPD_parallel_sections) { 3547 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3548 << (ParentRegion != OMPD_unknown) 3549 << getOpenMPDirectiveName(ParentRegion); 3550 return true; 3551 } 3552 return false; 3553 } 3554 // Allow some constructs (except teams and cancellation constructs) to be 3555 // orphaned (they could be used in functions, called from OpenMP regions 3556 // with the required preconditions). 3557 if (ParentRegion == OMPD_unknown && 3558 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3559 CurrentRegion != OMPD_cancellation_point && 3560 CurrentRegion != OMPD_cancel) 3561 return false; 3562 if (CurrentRegion == OMPD_cancellation_point || 3563 CurrentRegion == OMPD_cancel) { 3564 // OpenMP [2.16, Nesting of Regions] 3565 // A cancellation point construct for which construct-type-clause is 3566 // taskgroup must be nested inside a task construct. A cancellation 3567 // point construct for which construct-type-clause is not taskgroup must 3568 // be closely nested inside an OpenMP construct that matches the type 3569 // specified in construct-type-clause. 3570 // A cancel construct for which construct-type-clause is taskgroup must be 3571 // nested inside a task construct. A cancel construct for which 3572 // construct-type-clause is not taskgroup must be closely nested inside an 3573 // OpenMP construct that matches the type specified in 3574 // construct-type-clause. 3575 NestingProhibited = 3576 !((CancelRegion == OMPD_parallel && 3577 (ParentRegion == OMPD_parallel || 3578 ParentRegion == OMPD_target_parallel)) || 3579 (CancelRegion == OMPD_for && 3580 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3581 ParentRegion == OMPD_target_parallel_for || 3582 ParentRegion == OMPD_distribute_parallel_for || 3583 ParentRegion == OMPD_teams_distribute_parallel_for || 3584 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3585 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3586 (CancelRegion == OMPD_sections && 3587 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3588 ParentRegion == OMPD_parallel_sections))); 3589 OrphanSeen = ParentRegion == OMPD_unknown; 3590 } else if (CurrentRegion == OMPD_master) { 3591 // OpenMP [2.16, Nesting of Regions] 3592 // A master region may not be closely nested inside a worksharing, 3593 // atomic, or explicit task region. 3594 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3595 isOpenMPTaskingDirective(ParentRegion); 3596 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3597 // OpenMP [2.16, Nesting of Regions] 3598 // A critical region may not be nested (closely or otherwise) inside a 3599 // critical region with the same name. Note that this restriction is not 3600 // sufficient to prevent deadlock. 3601 SourceLocation PreviousCriticalLoc; 3602 bool DeadLock = Stack->hasDirective( 3603 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3604 const DeclarationNameInfo &DNI, 3605 SourceLocation Loc) { 3606 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3607 PreviousCriticalLoc = Loc; 3608 return true; 3609 } 3610 return false; 3611 }, 3612 false /* skip top directive */); 3613 if (DeadLock) { 3614 SemaRef.Diag(StartLoc, 3615 diag::err_omp_prohibited_region_critical_same_name) 3616 << CurrentName.getName(); 3617 if (PreviousCriticalLoc.isValid()) 3618 SemaRef.Diag(PreviousCriticalLoc, 3619 diag::note_omp_previous_critical_region); 3620 return true; 3621 } 3622 } else if (CurrentRegion == OMPD_barrier) { 3623 // OpenMP [2.16, Nesting of Regions] 3624 // A barrier region may not be closely nested inside a worksharing, 3625 // explicit task, critical, ordered, atomic, or master region. 3626 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3627 isOpenMPTaskingDirective(ParentRegion) || 3628 ParentRegion == OMPD_master || 3629 ParentRegion == OMPD_critical || 3630 ParentRegion == OMPD_ordered; 3631 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3632 !isOpenMPParallelDirective(CurrentRegion) && 3633 !isOpenMPTeamsDirective(CurrentRegion)) { 3634 // OpenMP [2.16, Nesting of Regions] 3635 // A worksharing region may not be closely nested inside a worksharing, 3636 // explicit task, critical, ordered, atomic, or master region. 3637 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3638 isOpenMPTaskingDirective(ParentRegion) || 3639 ParentRegion == OMPD_master || 3640 ParentRegion == OMPD_critical || 3641 ParentRegion == OMPD_ordered; 3642 Recommend = ShouldBeInParallelRegion; 3643 } else if (CurrentRegion == OMPD_ordered) { 3644 // OpenMP [2.16, Nesting of Regions] 3645 // An ordered region may not be closely nested inside a critical, 3646 // atomic, or explicit task region. 3647 // An ordered region must be closely nested inside a loop region (or 3648 // parallel loop region) with an ordered clause. 3649 // OpenMP [2.8.1,simd Construct, Restrictions] 3650 // An ordered construct with the simd clause is the only OpenMP construct 3651 // that can appear in the simd region. 3652 NestingProhibited = ParentRegion == OMPD_critical || 3653 isOpenMPTaskingDirective(ParentRegion) || 3654 !(isOpenMPSimdDirective(ParentRegion) || 3655 Stack->isParentOrderedRegion()); 3656 Recommend = ShouldBeInOrderedRegion; 3657 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3658 // OpenMP [2.16, Nesting of Regions] 3659 // If specified, a teams construct must be contained within a target 3660 // construct. 3661 NestingProhibited = ParentRegion != OMPD_target; 3662 OrphanSeen = ParentRegion == OMPD_unknown; 3663 Recommend = ShouldBeInTargetRegion; 3664 } 3665 if (!NestingProhibited && 3666 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3667 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3668 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3669 // OpenMP [2.16, Nesting of Regions] 3670 // distribute, parallel, parallel sections, parallel workshare, and the 3671 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3672 // constructs that can be closely nested in the teams region. 3673 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3674 !isOpenMPDistributeDirective(CurrentRegion); 3675 Recommend = ShouldBeInParallelRegion; 3676 } 3677 if (!NestingProhibited && 3678 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3679 // OpenMP 4.5 [2.17 Nesting of Regions] 3680 // The region associated with the distribute construct must be strictly 3681 // nested inside a teams region 3682 NestingProhibited = 3683 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3684 Recommend = ShouldBeInTeamsRegion; 3685 } 3686 if (!NestingProhibited && 3687 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3688 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3689 // OpenMP 4.5 [2.17 Nesting of Regions] 3690 // If a target, target update, target data, target enter data, or 3691 // target exit data construct is encountered during execution of a 3692 // target region, the behavior is unspecified. 3693 NestingProhibited = Stack->hasDirective( 3694 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3695 SourceLocation) { 3696 if (isOpenMPTargetExecutionDirective(K)) { 3697 OffendingRegion = K; 3698 return true; 3699 } 3700 return false; 3701 }, 3702 false /* don't skip top directive */); 3703 CloseNesting = false; 3704 } 3705 if (NestingProhibited) { 3706 if (OrphanSeen) { 3707 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3708 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3709 } else { 3710 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3711 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3712 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3713 } 3714 return true; 3715 } 3716 } 3717 return false; 3718 } 3719 3720 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3721 ArrayRef<OMPClause *> Clauses, 3722 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3723 bool ErrorFound = false; 3724 unsigned NamedModifiersNumber = 0; 3725 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3726 OMPD_unknown + 1); 3727 SmallVector<SourceLocation, 4> NameModifierLoc; 3728 for (const OMPClause *C : Clauses) { 3729 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3730 // At most one if clause without a directive-name-modifier can appear on 3731 // the directive. 3732 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3733 if (FoundNameModifiers[CurNM]) { 3734 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3735 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3736 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3737 ErrorFound = true; 3738 } else if (CurNM != OMPD_unknown) { 3739 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3740 ++NamedModifiersNumber; 3741 } 3742 FoundNameModifiers[CurNM] = IC; 3743 if (CurNM == OMPD_unknown) 3744 continue; 3745 // Check if the specified name modifier is allowed for the current 3746 // directive. 3747 // At most one if clause with the particular directive-name-modifier can 3748 // appear on the directive. 3749 bool MatchFound = false; 3750 for (auto NM : AllowedNameModifiers) { 3751 if (CurNM == NM) { 3752 MatchFound = true; 3753 break; 3754 } 3755 } 3756 if (!MatchFound) { 3757 S.Diag(IC->getNameModifierLoc(), 3758 diag::err_omp_wrong_if_directive_name_modifier) 3759 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3760 ErrorFound = true; 3761 } 3762 } 3763 } 3764 // If any if clause on the directive includes a directive-name-modifier then 3765 // all if clauses on the directive must include a directive-name-modifier. 3766 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3767 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3768 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3769 diag::err_omp_no_more_if_clause); 3770 } else { 3771 std::string Values; 3772 std::string Sep(", "); 3773 unsigned AllowedCnt = 0; 3774 unsigned TotalAllowedNum = 3775 AllowedNameModifiers.size() - NamedModifiersNumber; 3776 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3777 ++Cnt) { 3778 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3779 if (!FoundNameModifiers[NM]) { 3780 Values += "'"; 3781 Values += getOpenMPDirectiveName(NM); 3782 Values += "'"; 3783 if (AllowedCnt + 2 == TotalAllowedNum) 3784 Values += " or "; 3785 else if (AllowedCnt + 1 != TotalAllowedNum) 3786 Values += Sep; 3787 ++AllowedCnt; 3788 } 3789 } 3790 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3791 diag::err_omp_unnamed_if_clause) 3792 << (TotalAllowedNum > 1) << Values; 3793 } 3794 for (SourceLocation Loc : NameModifierLoc) { 3795 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3796 } 3797 ErrorFound = true; 3798 } 3799 return ErrorFound; 3800 } 3801 3802 static std::pair<ValueDecl *, bool> 3803 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 3804 SourceRange &ERange, bool AllowArraySection = false) { 3805 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 3806 RefExpr->containsUnexpandedParameterPack()) 3807 return std::make_pair(nullptr, true); 3808 3809 // OpenMP [3.1, C/C++] 3810 // A list item is a variable name. 3811 // OpenMP [2.9.3.3, Restrictions, p.1] 3812 // A variable that is part of another variable (as an array or 3813 // structure element) cannot appear in a private clause. 3814 RefExpr = RefExpr->IgnoreParens(); 3815 enum { 3816 NoArrayExpr = -1, 3817 ArraySubscript = 0, 3818 OMPArraySection = 1 3819 } IsArrayExpr = NoArrayExpr; 3820 if (AllowArraySection) { 3821 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 3822 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 3823 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3824 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3825 RefExpr = Base; 3826 IsArrayExpr = ArraySubscript; 3827 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 3828 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 3829 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 3830 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 3831 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 3832 Base = TempASE->getBase()->IgnoreParenImpCasts(); 3833 RefExpr = Base; 3834 IsArrayExpr = OMPArraySection; 3835 } 3836 } 3837 ELoc = RefExpr->getExprLoc(); 3838 ERange = RefExpr->getSourceRange(); 3839 RefExpr = RefExpr->IgnoreParenImpCasts(); 3840 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 3841 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 3842 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 3843 (S.getCurrentThisType().isNull() || !ME || 3844 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 3845 !isa<FieldDecl>(ME->getMemberDecl()))) { 3846 if (IsArrayExpr != NoArrayExpr) { 3847 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 3848 << ERange; 3849 } else { 3850 S.Diag(ELoc, 3851 AllowArraySection 3852 ? diag::err_omp_expected_var_name_member_expr_or_array_item 3853 : diag::err_omp_expected_var_name_member_expr) 3854 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 3855 } 3856 return std::make_pair(nullptr, false); 3857 } 3858 return std::make_pair( 3859 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 3860 } 3861 3862 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 3863 ArrayRef<OMPClause *> Clauses) { 3864 assert(!S.CurContext->isDependentContext() && 3865 "Expected non-dependent context."); 3866 auto AllocateRange = 3867 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 3868 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 3869 DeclToCopy; 3870 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 3871 return isOpenMPPrivate(C->getClauseKind()); 3872 }); 3873 for (OMPClause *Cl : PrivateRange) { 3874 MutableArrayRef<Expr *>::iterator I, It, Et; 3875 if (Cl->getClauseKind() == OMPC_private) { 3876 auto *PC = cast<OMPPrivateClause>(Cl); 3877 I = PC->private_copies().begin(); 3878 It = PC->varlist_begin(); 3879 Et = PC->varlist_end(); 3880 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 3881 auto *PC = cast<OMPFirstprivateClause>(Cl); 3882 I = PC->private_copies().begin(); 3883 It = PC->varlist_begin(); 3884 Et = PC->varlist_end(); 3885 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 3886 auto *PC = cast<OMPLastprivateClause>(Cl); 3887 I = PC->private_copies().begin(); 3888 It = PC->varlist_begin(); 3889 Et = PC->varlist_end(); 3890 } else if (Cl->getClauseKind() == OMPC_linear) { 3891 auto *PC = cast<OMPLinearClause>(Cl); 3892 I = PC->privates().begin(); 3893 It = PC->varlist_begin(); 3894 Et = PC->varlist_end(); 3895 } else if (Cl->getClauseKind() == OMPC_reduction) { 3896 auto *PC = cast<OMPReductionClause>(Cl); 3897 I = PC->privates().begin(); 3898 It = PC->varlist_begin(); 3899 Et = PC->varlist_end(); 3900 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 3901 auto *PC = cast<OMPTaskReductionClause>(Cl); 3902 I = PC->privates().begin(); 3903 It = PC->varlist_begin(); 3904 Et = PC->varlist_end(); 3905 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 3906 auto *PC = cast<OMPInReductionClause>(Cl); 3907 I = PC->privates().begin(); 3908 It = PC->varlist_begin(); 3909 Et = PC->varlist_end(); 3910 } else { 3911 llvm_unreachable("Expected private clause."); 3912 } 3913 for (Expr *E : llvm::make_range(It, Et)) { 3914 if (!*I) { 3915 ++I; 3916 continue; 3917 } 3918 SourceLocation ELoc; 3919 SourceRange ERange; 3920 Expr *SimpleRefExpr = E; 3921 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 3922 /*AllowArraySection=*/true); 3923 DeclToCopy.try_emplace(Res.first, 3924 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 3925 ++I; 3926 } 3927 } 3928 for (OMPClause *C : AllocateRange) { 3929 auto *AC = cast<OMPAllocateClause>(C); 3930 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3931 getAllocatorKind(S, Stack, AC->getAllocator()); 3932 // OpenMP, 2.11.4 allocate Clause, Restrictions. 3933 // For task, taskloop or target directives, allocation requests to memory 3934 // allocators with the trait access set to thread result in unspecified 3935 // behavior. 3936 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 3937 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 3938 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 3939 S.Diag(AC->getAllocator()->getExprLoc(), 3940 diag::warn_omp_allocate_thread_on_task_target_directive) 3941 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3942 } 3943 for (Expr *E : AC->varlists()) { 3944 SourceLocation ELoc; 3945 SourceRange ERange; 3946 Expr *SimpleRefExpr = E; 3947 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 3948 ValueDecl *VD = Res.first; 3949 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 3950 if (!isOpenMPPrivate(Data.CKind)) { 3951 S.Diag(E->getExprLoc(), 3952 diag::err_omp_expected_private_copy_for_allocate); 3953 continue; 3954 } 3955 VarDecl *PrivateVD = DeclToCopy[VD]; 3956 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 3957 AllocatorKind, AC->getAllocator())) 3958 continue; 3959 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 3960 E->getSourceRange()); 3961 } 3962 } 3963 } 3964 3965 StmtResult Sema::ActOnOpenMPExecutableDirective( 3966 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3967 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3968 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3969 StmtResult Res = StmtError(); 3970 // First check CancelRegion which is then used in checkNestingOfRegions. 3971 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3972 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3973 StartLoc)) 3974 return StmtError(); 3975 3976 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3977 VarsWithInheritedDSAType VarsWithInheritedDSA; 3978 bool ErrorFound = false; 3979 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3980 if (AStmt && !CurContext->isDependentContext()) { 3981 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3982 3983 // Check default data sharing attributes for referenced variables. 3984 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3985 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3986 Stmt *S = AStmt; 3987 while (--ThisCaptureLevel >= 0) 3988 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3989 DSAChecker.Visit(S); 3990 if (DSAChecker.isErrorFound()) 3991 return StmtError(); 3992 // Generate list of implicitly defined firstprivate variables. 3993 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3994 3995 SmallVector<Expr *, 4> ImplicitFirstprivates( 3996 DSAChecker.getImplicitFirstprivate().begin(), 3997 DSAChecker.getImplicitFirstprivate().end()); 3998 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3999 DSAChecker.getImplicitMap().end()); 4000 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4001 for (OMPClause *C : Clauses) { 4002 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4003 for (Expr *E : IRC->taskgroup_descriptors()) 4004 if (E) 4005 ImplicitFirstprivates.emplace_back(E); 4006 } 4007 } 4008 if (!ImplicitFirstprivates.empty()) { 4009 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4010 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4011 SourceLocation())) { 4012 ClausesWithImplicit.push_back(Implicit); 4013 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4014 ImplicitFirstprivates.size(); 4015 } else { 4016 ErrorFound = true; 4017 } 4018 } 4019 if (!ImplicitMaps.empty()) { 4020 CXXScopeSpec MapperIdScopeSpec; 4021 DeclarationNameInfo MapperId; 4022 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4023 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4024 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4025 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4026 ClausesWithImplicit.emplace_back(Implicit); 4027 ErrorFound |= 4028 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4029 } else { 4030 ErrorFound = true; 4031 } 4032 } 4033 } 4034 4035 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4036 switch (Kind) { 4037 case OMPD_parallel: 4038 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4039 EndLoc); 4040 AllowedNameModifiers.push_back(OMPD_parallel); 4041 break; 4042 case OMPD_simd: 4043 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4044 VarsWithInheritedDSA); 4045 break; 4046 case OMPD_for: 4047 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4048 VarsWithInheritedDSA); 4049 break; 4050 case OMPD_for_simd: 4051 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4052 EndLoc, VarsWithInheritedDSA); 4053 break; 4054 case OMPD_sections: 4055 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4056 EndLoc); 4057 break; 4058 case OMPD_section: 4059 assert(ClausesWithImplicit.empty() && 4060 "No clauses are allowed for 'omp section' directive"); 4061 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4062 break; 4063 case OMPD_single: 4064 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4065 EndLoc); 4066 break; 4067 case OMPD_master: 4068 assert(ClausesWithImplicit.empty() && 4069 "No clauses are allowed for 'omp master' directive"); 4070 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4071 break; 4072 case OMPD_critical: 4073 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4074 StartLoc, EndLoc); 4075 break; 4076 case OMPD_parallel_for: 4077 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4078 EndLoc, VarsWithInheritedDSA); 4079 AllowedNameModifiers.push_back(OMPD_parallel); 4080 break; 4081 case OMPD_parallel_for_simd: 4082 Res = ActOnOpenMPParallelForSimdDirective( 4083 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4084 AllowedNameModifiers.push_back(OMPD_parallel); 4085 break; 4086 case OMPD_parallel_sections: 4087 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4088 StartLoc, EndLoc); 4089 AllowedNameModifiers.push_back(OMPD_parallel); 4090 break; 4091 case OMPD_task: 4092 Res = 4093 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4094 AllowedNameModifiers.push_back(OMPD_task); 4095 break; 4096 case OMPD_taskyield: 4097 assert(ClausesWithImplicit.empty() && 4098 "No clauses are allowed for 'omp taskyield' directive"); 4099 assert(AStmt == nullptr && 4100 "No associated statement allowed for 'omp taskyield' directive"); 4101 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4102 break; 4103 case OMPD_barrier: 4104 assert(ClausesWithImplicit.empty() && 4105 "No clauses are allowed for 'omp barrier' directive"); 4106 assert(AStmt == nullptr && 4107 "No associated statement allowed for 'omp barrier' directive"); 4108 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4109 break; 4110 case OMPD_taskwait: 4111 assert(ClausesWithImplicit.empty() && 4112 "No clauses are allowed for 'omp taskwait' directive"); 4113 assert(AStmt == nullptr && 4114 "No associated statement allowed for 'omp taskwait' directive"); 4115 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4116 break; 4117 case OMPD_taskgroup: 4118 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4119 EndLoc); 4120 break; 4121 case OMPD_flush: 4122 assert(AStmt == nullptr && 4123 "No associated statement allowed for 'omp flush' directive"); 4124 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4125 break; 4126 case OMPD_ordered: 4127 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4128 EndLoc); 4129 break; 4130 case OMPD_atomic: 4131 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4132 EndLoc); 4133 break; 4134 case OMPD_teams: 4135 Res = 4136 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4137 break; 4138 case OMPD_target: 4139 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4140 EndLoc); 4141 AllowedNameModifiers.push_back(OMPD_target); 4142 break; 4143 case OMPD_target_parallel: 4144 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4145 StartLoc, EndLoc); 4146 AllowedNameModifiers.push_back(OMPD_target); 4147 AllowedNameModifiers.push_back(OMPD_parallel); 4148 break; 4149 case OMPD_target_parallel_for: 4150 Res = ActOnOpenMPTargetParallelForDirective( 4151 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4152 AllowedNameModifiers.push_back(OMPD_target); 4153 AllowedNameModifiers.push_back(OMPD_parallel); 4154 break; 4155 case OMPD_cancellation_point: 4156 assert(ClausesWithImplicit.empty() && 4157 "No clauses are allowed for 'omp cancellation point' directive"); 4158 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4159 "cancellation point' directive"); 4160 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4161 break; 4162 case OMPD_cancel: 4163 assert(AStmt == nullptr && 4164 "No associated statement allowed for 'omp cancel' directive"); 4165 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4166 CancelRegion); 4167 AllowedNameModifiers.push_back(OMPD_cancel); 4168 break; 4169 case OMPD_target_data: 4170 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4171 EndLoc); 4172 AllowedNameModifiers.push_back(OMPD_target_data); 4173 break; 4174 case OMPD_target_enter_data: 4175 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4176 EndLoc, AStmt); 4177 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4178 break; 4179 case OMPD_target_exit_data: 4180 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4181 EndLoc, AStmt); 4182 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4183 break; 4184 case OMPD_taskloop: 4185 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4186 EndLoc, VarsWithInheritedDSA); 4187 AllowedNameModifiers.push_back(OMPD_taskloop); 4188 break; 4189 case OMPD_taskloop_simd: 4190 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4191 EndLoc, VarsWithInheritedDSA); 4192 AllowedNameModifiers.push_back(OMPD_taskloop); 4193 break; 4194 case OMPD_distribute: 4195 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4196 EndLoc, VarsWithInheritedDSA); 4197 break; 4198 case OMPD_target_update: 4199 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4200 EndLoc, AStmt); 4201 AllowedNameModifiers.push_back(OMPD_target_update); 4202 break; 4203 case OMPD_distribute_parallel_for: 4204 Res = ActOnOpenMPDistributeParallelForDirective( 4205 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4206 AllowedNameModifiers.push_back(OMPD_parallel); 4207 break; 4208 case OMPD_distribute_parallel_for_simd: 4209 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4210 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4211 AllowedNameModifiers.push_back(OMPD_parallel); 4212 break; 4213 case OMPD_distribute_simd: 4214 Res = ActOnOpenMPDistributeSimdDirective( 4215 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4216 break; 4217 case OMPD_target_parallel_for_simd: 4218 Res = ActOnOpenMPTargetParallelForSimdDirective( 4219 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4220 AllowedNameModifiers.push_back(OMPD_target); 4221 AllowedNameModifiers.push_back(OMPD_parallel); 4222 break; 4223 case OMPD_target_simd: 4224 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4225 EndLoc, VarsWithInheritedDSA); 4226 AllowedNameModifiers.push_back(OMPD_target); 4227 break; 4228 case OMPD_teams_distribute: 4229 Res = ActOnOpenMPTeamsDistributeDirective( 4230 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4231 break; 4232 case OMPD_teams_distribute_simd: 4233 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4234 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4235 break; 4236 case OMPD_teams_distribute_parallel_for_simd: 4237 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4238 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4239 AllowedNameModifiers.push_back(OMPD_parallel); 4240 break; 4241 case OMPD_teams_distribute_parallel_for: 4242 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4243 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4244 AllowedNameModifiers.push_back(OMPD_parallel); 4245 break; 4246 case OMPD_target_teams: 4247 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4248 EndLoc); 4249 AllowedNameModifiers.push_back(OMPD_target); 4250 break; 4251 case OMPD_target_teams_distribute: 4252 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4253 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4254 AllowedNameModifiers.push_back(OMPD_target); 4255 break; 4256 case OMPD_target_teams_distribute_parallel_for: 4257 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4258 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4259 AllowedNameModifiers.push_back(OMPD_target); 4260 AllowedNameModifiers.push_back(OMPD_parallel); 4261 break; 4262 case OMPD_target_teams_distribute_parallel_for_simd: 4263 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4264 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4265 AllowedNameModifiers.push_back(OMPD_target); 4266 AllowedNameModifiers.push_back(OMPD_parallel); 4267 break; 4268 case OMPD_target_teams_distribute_simd: 4269 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4270 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4271 AllowedNameModifiers.push_back(OMPD_target); 4272 break; 4273 case OMPD_declare_target: 4274 case OMPD_end_declare_target: 4275 case OMPD_threadprivate: 4276 case OMPD_allocate: 4277 case OMPD_declare_reduction: 4278 case OMPD_declare_mapper: 4279 case OMPD_declare_simd: 4280 case OMPD_requires: 4281 llvm_unreachable("OpenMP Directive is not allowed"); 4282 case OMPD_unknown: 4283 llvm_unreachable("Unknown OpenMP directive"); 4284 } 4285 4286 ErrorFound = Res.isInvalid() || ErrorFound; 4287 4288 // Check variables in the clauses if default(none) was specified. 4289 if (DSAStack->getDefaultDSA() == DSA_none) { 4290 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4291 for (OMPClause *C : Clauses) { 4292 switch (C->getClauseKind()) { 4293 case OMPC_num_threads: 4294 case OMPC_dist_schedule: 4295 // Do not analyse if no parent teams directive. 4296 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4297 break; 4298 continue; 4299 case OMPC_if: 4300 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4301 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4302 break; 4303 continue; 4304 case OMPC_schedule: 4305 break; 4306 case OMPC_ordered: 4307 case OMPC_device: 4308 case OMPC_num_teams: 4309 case OMPC_thread_limit: 4310 case OMPC_priority: 4311 case OMPC_grainsize: 4312 case OMPC_num_tasks: 4313 case OMPC_hint: 4314 case OMPC_collapse: 4315 case OMPC_safelen: 4316 case OMPC_simdlen: 4317 case OMPC_final: 4318 case OMPC_default: 4319 case OMPC_proc_bind: 4320 case OMPC_private: 4321 case OMPC_firstprivate: 4322 case OMPC_lastprivate: 4323 case OMPC_shared: 4324 case OMPC_reduction: 4325 case OMPC_task_reduction: 4326 case OMPC_in_reduction: 4327 case OMPC_linear: 4328 case OMPC_aligned: 4329 case OMPC_copyin: 4330 case OMPC_copyprivate: 4331 case OMPC_nowait: 4332 case OMPC_untied: 4333 case OMPC_mergeable: 4334 case OMPC_allocate: 4335 case OMPC_read: 4336 case OMPC_write: 4337 case OMPC_update: 4338 case OMPC_capture: 4339 case OMPC_seq_cst: 4340 case OMPC_depend: 4341 case OMPC_threads: 4342 case OMPC_simd: 4343 case OMPC_map: 4344 case OMPC_nogroup: 4345 case OMPC_defaultmap: 4346 case OMPC_to: 4347 case OMPC_from: 4348 case OMPC_use_device_ptr: 4349 case OMPC_is_device_ptr: 4350 continue; 4351 case OMPC_allocator: 4352 case OMPC_flush: 4353 case OMPC_threadprivate: 4354 case OMPC_uniform: 4355 case OMPC_unknown: 4356 case OMPC_unified_address: 4357 case OMPC_unified_shared_memory: 4358 case OMPC_reverse_offload: 4359 case OMPC_dynamic_allocators: 4360 case OMPC_atomic_default_mem_order: 4361 llvm_unreachable("Unexpected clause"); 4362 } 4363 for (Stmt *CC : C->children()) { 4364 if (CC) 4365 DSAChecker.Visit(CC); 4366 } 4367 } 4368 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4369 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4370 } 4371 for (const auto &P : VarsWithInheritedDSA) { 4372 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4373 << P.first << P.second->getSourceRange(); 4374 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4375 } 4376 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 4377 4378 if (!AllowedNameModifiers.empty()) 4379 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4380 ErrorFound; 4381 4382 if (ErrorFound) 4383 return StmtError(); 4384 4385 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4386 Res.getAs<OMPExecutableDirective>() 4387 ->getStructuredBlock() 4388 ->setIsOMPStructuredBlock(true); 4389 } 4390 4391 if (!CurContext->isDependentContext() && 4392 isOpenMPTargetExecutionDirective(Kind) && 4393 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4394 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4395 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4396 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4397 // Register target to DSA Stack. 4398 DSAStack->addTargetDirLocation(StartLoc); 4399 } 4400 4401 return Res; 4402 } 4403 4404 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4405 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4406 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4407 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4408 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4409 assert(Aligneds.size() == Alignments.size()); 4410 assert(Linears.size() == LinModifiers.size()); 4411 assert(Linears.size() == Steps.size()); 4412 if (!DG || DG.get().isNull()) 4413 return DeclGroupPtrTy(); 4414 4415 if (!DG.get().isSingleDecl()) { 4416 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 4417 return DG; 4418 } 4419 Decl *ADecl = DG.get().getSingleDecl(); 4420 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4421 ADecl = FTD->getTemplatedDecl(); 4422 4423 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4424 if (!FD) { 4425 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4426 return DeclGroupPtrTy(); 4427 } 4428 4429 // OpenMP [2.8.2, declare simd construct, Description] 4430 // The parameter of the simdlen clause must be a constant positive integer 4431 // expression. 4432 ExprResult SL; 4433 if (Simdlen) 4434 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4435 // OpenMP [2.8.2, declare simd construct, Description] 4436 // The special this pointer can be used as if was one of the arguments to the 4437 // function in any of the linear, aligned, or uniform clauses. 4438 // The uniform clause declares one or more arguments to have an invariant 4439 // value for all concurrent invocations of the function in the execution of a 4440 // single SIMD loop. 4441 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4442 const Expr *UniformedLinearThis = nullptr; 4443 for (const Expr *E : Uniforms) { 4444 E = E->IgnoreParenImpCasts(); 4445 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4446 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4447 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4448 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4449 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4450 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4451 continue; 4452 } 4453 if (isa<CXXThisExpr>(E)) { 4454 UniformedLinearThis = E; 4455 continue; 4456 } 4457 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4458 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4459 } 4460 // OpenMP [2.8.2, declare simd construct, Description] 4461 // The aligned clause declares that the object to which each list item points 4462 // is aligned to the number of bytes expressed in the optional parameter of 4463 // the aligned clause. 4464 // The special this pointer can be used as if was one of the arguments to the 4465 // function in any of the linear, aligned, or uniform clauses. 4466 // The type of list items appearing in the aligned clause must be array, 4467 // pointer, reference to array, or reference to pointer. 4468 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4469 const Expr *AlignedThis = nullptr; 4470 for (const Expr *E : Aligneds) { 4471 E = E->IgnoreParenImpCasts(); 4472 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4473 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4474 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4475 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4476 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4477 ->getCanonicalDecl() == CanonPVD) { 4478 // OpenMP [2.8.1, simd construct, Restrictions] 4479 // A list-item cannot appear in more than one aligned clause. 4480 if (AlignedArgs.count(CanonPVD) > 0) { 4481 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4482 << 1 << E->getSourceRange(); 4483 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4484 diag::note_omp_explicit_dsa) 4485 << getOpenMPClauseName(OMPC_aligned); 4486 continue; 4487 } 4488 AlignedArgs[CanonPVD] = E; 4489 QualType QTy = PVD->getType() 4490 .getNonReferenceType() 4491 .getUnqualifiedType() 4492 .getCanonicalType(); 4493 const Type *Ty = QTy.getTypePtrOrNull(); 4494 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4495 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4496 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4497 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4498 } 4499 continue; 4500 } 4501 } 4502 if (isa<CXXThisExpr>(E)) { 4503 if (AlignedThis) { 4504 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4505 << 2 << E->getSourceRange(); 4506 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4507 << getOpenMPClauseName(OMPC_aligned); 4508 } 4509 AlignedThis = E; 4510 continue; 4511 } 4512 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4513 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4514 } 4515 // The optional parameter of the aligned clause, alignment, must be a constant 4516 // positive integer expression. If no optional parameter is specified, 4517 // implementation-defined default alignments for SIMD instructions on the 4518 // target platforms are assumed. 4519 SmallVector<const Expr *, 4> NewAligns; 4520 for (Expr *E : Alignments) { 4521 ExprResult Align; 4522 if (E) 4523 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4524 NewAligns.push_back(Align.get()); 4525 } 4526 // OpenMP [2.8.2, declare simd construct, Description] 4527 // The linear clause declares one or more list items to be private to a SIMD 4528 // lane and to have a linear relationship with respect to the iteration space 4529 // of a loop. 4530 // The special this pointer can be used as if was one of the arguments to the 4531 // function in any of the linear, aligned, or uniform clauses. 4532 // When a linear-step expression is specified in a linear clause it must be 4533 // either a constant integer expression or an integer-typed parameter that is 4534 // specified in a uniform clause on the directive. 4535 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4536 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4537 auto MI = LinModifiers.begin(); 4538 for (const Expr *E : Linears) { 4539 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4540 ++MI; 4541 E = E->IgnoreParenImpCasts(); 4542 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4543 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4544 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4545 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4546 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4547 ->getCanonicalDecl() == CanonPVD) { 4548 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4549 // A list-item cannot appear in more than one linear clause. 4550 if (LinearArgs.count(CanonPVD) > 0) { 4551 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4552 << getOpenMPClauseName(OMPC_linear) 4553 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4554 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4555 diag::note_omp_explicit_dsa) 4556 << getOpenMPClauseName(OMPC_linear); 4557 continue; 4558 } 4559 // Each argument can appear in at most one uniform or linear clause. 4560 if (UniformedArgs.count(CanonPVD) > 0) { 4561 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4562 << getOpenMPClauseName(OMPC_linear) 4563 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4564 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4565 diag::note_omp_explicit_dsa) 4566 << getOpenMPClauseName(OMPC_uniform); 4567 continue; 4568 } 4569 LinearArgs[CanonPVD] = E; 4570 if (E->isValueDependent() || E->isTypeDependent() || 4571 E->isInstantiationDependent() || 4572 E->containsUnexpandedParameterPack()) 4573 continue; 4574 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4575 PVD->getOriginalType()); 4576 continue; 4577 } 4578 } 4579 if (isa<CXXThisExpr>(E)) { 4580 if (UniformedLinearThis) { 4581 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4582 << getOpenMPClauseName(OMPC_linear) 4583 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4584 << E->getSourceRange(); 4585 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4586 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4587 : OMPC_linear); 4588 continue; 4589 } 4590 UniformedLinearThis = E; 4591 if (E->isValueDependent() || E->isTypeDependent() || 4592 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4593 continue; 4594 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4595 E->getType()); 4596 continue; 4597 } 4598 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4599 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4600 } 4601 Expr *Step = nullptr; 4602 Expr *NewStep = nullptr; 4603 SmallVector<Expr *, 4> NewSteps; 4604 for (Expr *E : Steps) { 4605 // Skip the same step expression, it was checked already. 4606 if (Step == E || !E) { 4607 NewSteps.push_back(E ? NewStep : nullptr); 4608 continue; 4609 } 4610 Step = E; 4611 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4612 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4613 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4614 if (UniformedArgs.count(CanonPVD) == 0) { 4615 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4616 << Step->getSourceRange(); 4617 } else if (E->isValueDependent() || E->isTypeDependent() || 4618 E->isInstantiationDependent() || 4619 E->containsUnexpandedParameterPack() || 4620 CanonPVD->getType()->hasIntegerRepresentation()) { 4621 NewSteps.push_back(Step); 4622 } else { 4623 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4624 << Step->getSourceRange(); 4625 } 4626 continue; 4627 } 4628 NewStep = Step; 4629 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4630 !Step->isInstantiationDependent() && 4631 !Step->containsUnexpandedParameterPack()) { 4632 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4633 .get(); 4634 if (NewStep) 4635 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4636 } 4637 NewSteps.push_back(NewStep); 4638 } 4639 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4640 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4641 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4642 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4643 const_cast<Expr **>(Linears.data()), Linears.size(), 4644 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4645 NewSteps.data(), NewSteps.size(), SR); 4646 ADecl->addAttr(NewAttr); 4647 return ConvertDeclToDeclGroup(ADecl); 4648 } 4649 4650 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4651 Stmt *AStmt, 4652 SourceLocation StartLoc, 4653 SourceLocation EndLoc) { 4654 if (!AStmt) 4655 return StmtError(); 4656 4657 auto *CS = cast<CapturedStmt>(AStmt); 4658 // 1.2.2 OpenMP Language Terminology 4659 // Structured block - An executable statement with a single entry at the 4660 // top and a single exit at the bottom. 4661 // The point of exit cannot be a branch out of the structured block. 4662 // longjmp() and throw() must not violate the entry/exit criteria. 4663 CS->getCapturedDecl()->setNothrow(); 4664 4665 setFunctionHasBranchProtectedScope(); 4666 4667 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4668 DSAStack->isCancelRegion()); 4669 } 4670 4671 namespace { 4672 /// Helper class for checking canonical form of the OpenMP loops and 4673 /// extracting iteration space of each loop in the loop nest, that will be used 4674 /// for IR generation. 4675 class OpenMPIterationSpaceChecker { 4676 /// Reference to Sema. 4677 Sema &SemaRef; 4678 /// Data-sharing stack. 4679 DSAStackTy &Stack; 4680 /// A location for diagnostics (when there is no some better location). 4681 SourceLocation DefaultLoc; 4682 /// A location for diagnostics (when increment is not compatible). 4683 SourceLocation ConditionLoc; 4684 /// A source location for referring to loop init later. 4685 SourceRange InitSrcRange; 4686 /// A source location for referring to condition later. 4687 SourceRange ConditionSrcRange; 4688 /// A source location for referring to increment later. 4689 SourceRange IncrementSrcRange; 4690 /// Loop variable. 4691 ValueDecl *LCDecl = nullptr; 4692 /// Reference to loop variable. 4693 Expr *LCRef = nullptr; 4694 /// Lower bound (initializer for the var). 4695 Expr *LB = nullptr; 4696 /// Upper bound. 4697 Expr *UB = nullptr; 4698 /// Loop step (increment). 4699 Expr *Step = nullptr; 4700 /// This flag is true when condition is one of: 4701 /// Var < UB 4702 /// Var <= UB 4703 /// UB > Var 4704 /// UB >= Var 4705 /// This will have no value when the condition is != 4706 llvm::Optional<bool> TestIsLessOp; 4707 /// This flag is true when condition is strict ( < or > ). 4708 bool TestIsStrictOp = false; 4709 /// This flag is true when step is subtracted on each iteration. 4710 bool SubtractStep = false; 4711 /// The outer loop counter this loop depends on (if any). 4712 const ValueDecl *DepDecl = nullptr; 4713 /// Contains number of loop (starts from 1) on which loop counter init 4714 /// expression of this loop depends on. 4715 Optional<unsigned> InitDependOnLC; 4716 /// Contains number of loop (starts from 1) on which loop counter condition 4717 /// expression of this loop depends on. 4718 Optional<unsigned> CondDependOnLC; 4719 /// Checks if the provide statement depends on the loop counter. 4720 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 4721 4722 public: 4723 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 4724 SourceLocation DefaultLoc) 4725 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 4726 ConditionLoc(DefaultLoc) {} 4727 /// Check init-expr for canonical loop form and save loop counter 4728 /// variable - #Var and its initialization value - #LB. 4729 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4730 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4731 /// for less/greater and for strict/non-strict comparison. 4732 bool checkAndSetCond(Expr *S); 4733 /// Check incr-expr for canonical loop form and return true if it 4734 /// does not conform, otherwise save loop step (#Step). 4735 bool checkAndSetInc(Expr *S); 4736 /// Return the loop counter variable. 4737 ValueDecl *getLoopDecl() const { return LCDecl; } 4738 /// Return the reference expression to loop counter variable. 4739 Expr *getLoopDeclRefExpr() const { return LCRef; } 4740 /// Source range of the loop init. 4741 SourceRange getInitSrcRange() const { return InitSrcRange; } 4742 /// Source range of the loop condition. 4743 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4744 /// Source range of the loop increment. 4745 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4746 /// True if the step should be subtracted. 4747 bool shouldSubtractStep() const { return SubtractStep; } 4748 /// True, if the compare operator is strict (<, > or !=). 4749 bool isStrictTestOp() const { return TestIsStrictOp; } 4750 /// Build the expression to calculate the number of iterations. 4751 Expr *buildNumIterations( 4752 Scope *S, const bool LimitedType, 4753 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4754 /// Build the precondition expression for the loops. 4755 Expr * 4756 buildPreCond(Scope *S, Expr *Cond, 4757 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4758 /// Build reference expression to the counter be used for codegen. 4759 DeclRefExpr * 4760 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4761 DSAStackTy &DSA) const; 4762 /// Build reference expression to the private counter be used for 4763 /// codegen. 4764 Expr *buildPrivateCounterVar() const; 4765 /// Build initialization of the counter be used for codegen. 4766 Expr *buildCounterInit() const; 4767 /// Build step of the counter be used for codegen. 4768 Expr *buildCounterStep() const; 4769 /// Build loop data with counter value for depend clauses in ordered 4770 /// directives. 4771 Expr * 4772 buildOrderedLoopData(Scope *S, Expr *Counter, 4773 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4774 SourceLocation Loc, Expr *Inc = nullptr, 4775 OverloadedOperatorKind OOK = OO_Amp); 4776 /// Return true if any expression is dependent. 4777 bool dependent() const; 4778 4779 private: 4780 /// Check the right-hand side of an assignment in the increment 4781 /// expression. 4782 bool checkAndSetIncRHS(Expr *RHS); 4783 /// Helper to set loop counter variable and its initializer. 4784 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 4785 bool EmitDiags); 4786 /// Helper to set upper bound. 4787 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4788 SourceRange SR, SourceLocation SL); 4789 /// Helper to set loop increment. 4790 bool setStep(Expr *NewStep, bool Subtract); 4791 }; 4792 4793 bool OpenMPIterationSpaceChecker::dependent() const { 4794 if (!LCDecl) { 4795 assert(!LB && !UB && !Step); 4796 return false; 4797 } 4798 return LCDecl->getType()->isDependentType() || 4799 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4800 (Step && Step->isValueDependent()); 4801 } 4802 4803 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4804 Expr *NewLCRefExpr, 4805 Expr *NewLB, bool EmitDiags) { 4806 // State consistency checking to ensure correct usage. 4807 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4808 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4809 if (!NewLCDecl || !NewLB) 4810 return true; 4811 LCDecl = getCanonicalDecl(NewLCDecl); 4812 LCRef = NewLCRefExpr; 4813 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4814 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4815 if ((Ctor->isCopyOrMoveConstructor() || 4816 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4817 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4818 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4819 LB = NewLB; 4820 if (EmitDiags) 4821 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 4822 return false; 4823 } 4824 4825 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4826 llvm::Optional<bool> LessOp, 4827 bool StrictOp, SourceRange SR, 4828 SourceLocation SL) { 4829 // State consistency checking to ensure correct usage. 4830 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4831 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4832 if (!NewUB) 4833 return true; 4834 UB = NewUB; 4835 if (LessOp) 4836 TestIsLessOp = LessOp; 4837 TestIsStrictOp = StrictOp; 4838 ConditionSrcRange = SR; 4839 ConditionLoc = SL; 4840 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 4841 return false; 4842 } 4843 4844 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4845 // State consistency checking to ensure correct usage. 4846 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4847 if (!NewStep) 4848 return true; 4849 if (!NewStep->isValueDependent()) { 4850 // Check that the step is integer expression. 4851 SourceLocation StepLoc = NewStep->getBeginLoc(); 4852 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4853 StepLoc, getExprAsWritten(NewStep)); 4854 if (Val.isInvalid()) 4855 return true; 4856 NewStep = Val.get(); 4857 4858 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4859 // If test-expr is of form var relational-op b and relational-op is < or 4860 // <= then incr-expr must cause var to increase on each iteration of the 4861 // loop. If test-expr is of form var relational-op b and relational-op is 4862 // > or >= then incr-expr must cause var to decrease on each iteration of 4863 // the loop. 4864 // If test-expr is of form b relational-op var and relational-op is < or 4865 // <= then incr-expr must cause var to decrease on each iteration of the 4866 // loop. If test-expr is of form b relational-op var and relational-op is 4867 // > or >= then incr-expr must cause var to increase on each iteration of 4868 // the loop. 4869 llvm::APSInt Result; 4870 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4871 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4872 bool IsConstNeg = 4873 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4874 bool IsConstPos = 4875 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4876 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4877 4878 // != with increment is treated as <; != with decrement is treated as > 4879 if (!TestIsLessOp.hasValue()) 4880 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4881 if (UB && (IsConstZero || 4882 (TestIsLessOp.getValue() ? 4883 (IsConstNeg || (IsUnsigned && Subtract)) : 4884 (IsConstPos || (IsUnsigned && !Subtract))))) { 4885 SemaRef.Diag(NewStep->getExprLoc(), 4886 diag::err_omp_loop_incr_not_compatible) 4887 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4888 SemaRef.Diag(ConditionLoc, 4889 diag::note_omp_loop_cond_requres_compatible_incr) 4890 << TestIsLessOp.getValue() << ConditionSrcRange; 4891 return true; 4892 } 4893 if (TestIsLessOp.getValue() == Subtract) { 4894 NewStep = 4895 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4896 .get(); 4897 Subtract = !Subtract; 4898 } 4899 } 4900 4901 Step = NewStep; 4902 SubtractStep = Subtract; 4903 return false; 4904 } 4905 4906 namespace { 4907 /// Checker for the non-rectangular loops. Checks if the initializer or 4908 /// condition expression references loop counter variable. 4909 class LoopCounterRefChecker final 4910 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 4911 Sema &SemaRef; 4912 DSAStackTy &Stack; 4913 const ValueDecl *CurLCDecl = nullptr; 4914 const ValueDecl *DepDecl = nullptr; 4915 const ValueDecl *PrevDepDecl = nullptr; 4916 bool IsInitializer = true; 4917 unsigned BaseLoopId = 0; 4918 bool checkDecl(const Expr *E, const ValueDecl *VD) { 4919 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 4920 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 4921 << (IsInitializer ? 0 : 1); 4922 return false; 4923 } 4924 const auto &&Data = Stack.isLoopControlVariable(VD); 4925 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 4926 // The type of the loop iterator on which we depend may not have a random 4927 // access iterator type. 4928 if (Data.first && VD->getType()->isRecordType()) { 4929 SmallString<128> Name; 4930 llvm::raw_svector_ostream OS(Name); 4931 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4932 /*Qualified=*/true); 4933 SemaRef.Diag(E->getExprLoc(), 4934 diag::err_omp_wrong_dependency_iterator_type) 4935 << OS.str(); 4936 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 4937 return false; 4938 } 4939 if (Data.first && 4940 (DepDecl || (PrevDepDecl && 4941 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 4942 if (!DepDecl && PrevDepDecl) 4943 DepDecl = PrevDepDecl; 4944 SmallString<128> Name; 4945 llvm::raw_svector_ostream OS(Name); 4946 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 4947 /*Qualified=*/true); 4948 SemaRef.Diag(E->getExprLoc(), 4949 diag::err_omp_invariant_or_linear_dependency) 4950 << OS.str(); 4951 return false; 4952 } 4953 if (Data.first) { 4954 DepDecl = VD; 4955 BaseLoopId = Data.first; 4956 } 4957 return Data.first; 4958 } 4959 4960 public: 4961 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4962 const ValueDecl *VD = E->getDecl(); 4963 if (isa<VarDecl>(VD)) 4964 return checkDecl(E, VD); 4965 return false; 4966 } 4967 bool VisitMemberExpr(const MemberExpr *E) { 4968 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 4969 const ValueDecl *VD = E->getMemberDecl(); 4970 return checkDecl(E, VD); 4971 } 4972 return false; 4973 } 4974 bool VisitStmt(const Stmt *S) { 4975 bool Res = true; 4976 for (const Stmt *Child : S->children()) 4977 Res = Child && Visit(Child) && Res; 4978 return Res; 4979 } 4980 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 4981 const ValueDecl *CurLCDecl, bool IsInitializer, 4982 const ValueDecl *PrevDepDecl = nullptr) 4983 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 4984 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 4985 unsigned getBaseLoopId() const { 4986 assert(CurLCDecl && "Expected loop dependency."); 4987 return BaseLoopId; 4988 } 4989 const ValueDecl *getDepDecl() const { 4990 assert(CurLCDecl && "Expected loop dependency."); 4991 return DepDecl; 4992 } 4993 }; 4994 } // namespace 4995 4996 Optional<unsigned> 4997 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 4998 bool IsInitializer) { 4999 // Check for the non-rectangular loops. 5000 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5001 DepDecl); 5002 if (LoopStmtChecker.Visit(S)) { 5003 DepDecl = LoopStmtChecker.getDepDecl(); 5004 return LoopStmtChecker.getBaseLoopId(); 5005 } 5006 return llvm::None; 5007 } 5008 5009 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5010 // Check init-expr for canonical loop form and save loop counter 5011 // variable - #Var and its initialization value - #LB. 5012 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5013 // var = lb 5014 // integer-type var = lb 5015 // random-access-iterator-type var = lb 5016 // pointer-type var = lb 5017 // 5018 if (!S) { 5019 if (EmitDiags) { 5020 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5021 } 5022 return true; 5023 } 5024 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5025 if (!ExprTemp->cleanupsHaveSideEffects()) 5026 S = ExprTemp->getSubExpr(); 5027 5028 InitSrcRange = S->getSourceRange(); 5029 if (Expr *E = dyn_cast<Expr>(S)) 5030 S = E->IgnoreParens(); 5031 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5032 if (BO->getOpcode() == BO_Assign) { 5033 Expr *LHS = BO->getLHS()->IgnoreParens(); 5034 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5035 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5036 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5037 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5038 EmitDiags); 5039 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5040 } 5041 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5042 if (ME->isArrow() && 5043 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5044 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5045 EmitDiags); 5046 } 5047 } 5048 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5049 if (DS->isSingleDecl()) { 5050 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5051 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5052 // Accept non-canonical init form here but emit ext. warning. 5053 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5054 SemaRef.Diag(S->getBeginLoc(), 5055 diag::ext_omp_loop_not_canonical_init) 5056 << S->getSourceRange(); 5057 return setLCDeclAndLB( 5058 Var, 5059 buildDeclRefExpr(SemaRef, Var, 5060 Var->getType().getNonReferenceType(), 5061 DS->getBeginLoc()), 5062 Var->getInit(), EmitDiags); 5063 } 5064 } 5065 } 5066 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5067 if (CE->getOperator() == OO_Equal) { 5068 Expr *LHS = CE->getArg(0); 5069 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5070 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5071 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5072 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5073 EmitDiags); 5074 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5075 } 5076 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5077 if (ME->isArrow() && 5078 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5079 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5080 EmitDiags); 5081 } 5082 } 5083 } 5084 5085 if (dependent() || SemaRef.CurContext->isDependentContext()) 5086 return false; 5087 if (EmitDiags) { 5088 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5089 << S->getSourceRange(); 5090 } 5091 return true; 5092 } 5093 5094 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5095 /// variable (which may be the loop variable) if possible. 5096 static const ValueDecl *getInitLCDecl(const Expr *E) { 5097 if (!E) 5098 return nullptr; 5099 E = getExprAsWritten(E); 5100 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5101 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5102 if ((Ctor->isCopyOrMoveConstructor() || 5103 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5104 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5105 E = CE->getArg(0)->IgnoreParenImpCasts(); 5106 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5107 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5108 return getCanonicalDecl(VD); 5109 } 5110 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5111 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5112 return getCanonicalDecl(ME->getMemberDecl()); 5113 return nullptr; 5114 } 5115 5116 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5117 // Check test-expr for canonical form, save upper-bound UB, flags for 5118 // less/greater and for strict/non-strict comparison. 5119 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5120 // var relational-op b 5121 // b relational-op var 5122 // 5123 if (!S) { 5124 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 5125 return true; 5126 } 5127 S = getExprAsWritten(S); 5128 SourceLocation CondLoc = S->getBeginLoc(); 5129 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5130 if (BO->isRelationalOp()) { 5131 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5132 return setUB(BO->getRHS(), 5133 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5134 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5135 BO->getSourceRange(), BO->getOperatorLoc()); 5136 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5137 return setUB(BO->getLHS(), 5138 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5139 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5140 BO->getSourceRange(), BO->getOperatorLoc()); 5141 } else if (BO->getOpcode() == BO_NE) 5142 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 5143 BO->getRHS() : BO->getLHS(), 5144 /*LessOp=*/llvm::None, 5145 /*StrictOp=*/true, 5146 BO->getSourceRange(), BO->getOperatorLoc()); 5147 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5148 if (CE->getNumArgs() == 2) { 5149 auto Op = CE->getOperator(); 5150 switch (Op) { 5151 case OO_Greater: 5152 case OO_GreaterEqual: 5153 case OO_Less: 5154 case OO_LessEqual: 5155 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5156 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5157 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5158 CE->getOperatorLoc()); 5159 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5160 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5161 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5162 CE->getOperatorLoc()); 5163 break; 5164 case OO_ExclaimEqual: 5165 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 5166 CE->getArg(1) : CE->getArg(0), 5167 /*LessOp=*/llvm::None, 5168 /*StrictOp=*/true, 5169 CE->getSourceRange(), 5170 CE->getOperatorLoc()); 5171 break; 5172 default: 5173 break; 5174 } 5175 } 5176 } 5177 if (dependent() || SemaRef.CurContext->isDependentContext()) 5178 return false; 5179 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5180 << S->getSourceRange() << LCDecl; 5181 return true; 5182 } 5183 5184 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5185 // RHS of canonical loop form increment can be: 5186 // var + incr 5187 // incr + var 5188 // var - incr 5189 // 5190 RHS = RHS->IgnoreParenImpCasts(); 5191 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5192 if (BO->isAdditiveOp()) { 5193 bool IsAdd = BO->getOpcode() == BO_Add; 5194 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5195 return setStep(BO->getRHS(), !IsAdd); 5196 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5197 return setStep(BO->getLHS(), /*Subtract=*/false); 5198 } 5199 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5200 bool IsAdd = CE->getOperator() == OO_Plus; 5201 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5202 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5203 return setStep(CE->getArg(1), !IsAdd); 5204 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5205 return setStep(CE->getArg(0), /*Subtract=*/false); 5206 } 5207 } 5208 if (dependent() || SemaRef.CurContext->isDependentContext()) 5209 return false; 5210 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5211 << RHS->getSourceRange() << LCDecl; 5212 return true; 5213 } 5214 5215 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5216 // Check incr-expr for canonical loop form and return true if it 5217 // does not conform. 5218 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5219 // ++var 5220 // var++ 5221 // --var 5222 // var-- 5223 // var += incr 5224 // var -= incr 5225 // var = var + incr 5226 // var = incr + var 5227 // var = var - incr 5228 // 5229 if (!S) { 5230 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5231 return true; 5232 } 5233 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5234 if (!ExprTemp->cleanupsHaveSideEffects()) 5235 S = ExprTemp->getSubExpr(); 5236 5237 IncrementSrcRange = S->getSourceRange(); 5238 S = S->IgnoreParens(); 5239 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5240 if (UO->isIncrementDecrementOp() && 5241 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5242 return setStep(SemaRef 5243 .ActOnIntegerConstant(UO->getBeginLoc(), 5244 (UO->isDecrementOp() ? -1 : 1)) 5245 .get(), 5246 /*Subtract=*/false); 5247 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5248 switch (BO->getOpcode()) { 5249 case BO_AddAssign: 5250 case BO_SubAssign: 5251 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5252 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5253 break; 5254 case BO_Assign: 5255 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5256 return checkAndSetIncRHS(BO->getRHS()); 5257 break; 5258 default: 5259 break; 5260 } 5261 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5262 switch (CE->getOperator()) { 5263 case OO_PlusPlus: 5264 case OO_MinusMinus: 5265 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5266 return setStep(SemaRef 5267 .ActOnIntegerConstant( 5268 CE->getBeginLoc(), 5269 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5270 .get(), 5271 /*Subtract=*/false); 5272 break; 5273 case OO_PlusEqual: 5274 case OO_MinusEqual: 5275 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5276 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5277 break; 5278 case OO_Equal: 5279 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5280 return checkAndSetIncRHS(CE->getArg(1)); 5281 break; 5282 default: 5283 break; 5284 } 5285 } 5286 if (dependent() || SemaRef.CurContext->isDependentContext()) 5287 return false; 5288 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5289 << S->getSourceRange() << LCDecl; 5290 return true; 5291 } 5292 5293 static ExprResult 5294 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5295 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5296 if (SemaRef.CurContext->isDependentContext()) 5297 return ExprResult(Capture); 5298 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5299 return SemaRef.PerformImplicitConversion( 5300 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5301 /*AllowExplicit=*/true); 5302 auto I = Captures.find(Capture); 5303 if (I != Captures.end()) 5304 return buildCapture(SemaRef, Capture, I->second); 5305 DeclRefExpr *Ref = nullptr; 5306 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5307 Captures[Capture] = Ref; 5308 return Res; 5309 } 5310 5311 /// Build the expression to calculate the number of iterations. 5312 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5313 Scope *S, const bool LimitedType, 5314 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5315 ExprResult Diff; 5316 QualType VarType = LCDecl->getType().getNonReferenceType(); 5317 if (VarType->isIntegerType() || VarType->isPointerType() || 5318 SemaRef.getLangOpts().CPlusPlus) { 5319 // Upper - Lower 5320 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 5321 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 5322 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 5323 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 5324 if (!Upper || !Lower) 5325 return nullptr; 5326 5327 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5328 5329 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5330 // BuildBinOp already emitted error, this one is to point user to upper 5331 // and lower bound, and to tell what is passed to 'operator-'. 5332 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5333 << Upper->getSourceRange() << Lower->getSourceRange(); 5334 return nullptr; 5335 } 5336 } 5337 5338 if (!Diff.isUsable()) 5339 return nullptr; 5340 5341 // Upper - Lower [- 1] 5342 if (TestIsStrictOp) 5343 Diff = SemaRef.BuildBinOp( 5344 S, DefaultLoc, BO_Sub, Diff.get(), 5345 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5346 if (!Diff.isUsable()) 5347 return nullptr; 5348 5349 // Upper - Lower [- 1] + Step 5350 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5351 if (!NewStep.isUsable()) 5352 return nullptr; 5353 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 5354 if (!Diff.isUsable()) 5355 return nullptr; 5356 5357 // Parentheses (for dumping/debugging purposes only). 5358 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5359 if (!Diff.isUsable()) 5360 return nullptr; 5361 5362 // (Upper - Lower [- 1] + Step) / Step 5363 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5364 if (!Diff.isUsable()) 5365 return nullptr; 5366 5367 // OpenMP runtime requires 32-bit or 64-bit loop variables. 5368 QualType Type = Diff.get()->getType(); 5369 ASTContext &C = SemaRef.Context; 5370 bool UseVarType = VarType->hasIntegerRepresentation() && 5371 C.getTypeSize(Type) > C.getTypeSize(VarType); 5372 if (!Type->isIntegerType() || UseVarType) { 5373 unsigned NewSize = 5374 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 5375 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 5376 : Type->hasSignedIntegerRepresentation(); 5377 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 5378 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 5379 Diff = SemaRef.PerformImplicitConversion( 5380 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 5381 if (!Diff.isUsable()) 5382 return nullptr; 5383 } 5384 } 5385 if (LimitedType) { 5386 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 5387 if (NewSize != C.getTypeSize(Type)) { 5388 if (NewSize < C.getTypeSize(Type)) { 5389 assert(NewSize == 64 && "incorrect loop var size"); 5390 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 5391 << InitSrcRange << ConditionSrcRange; 5392 } 5393 QualType NewType = C.getIntTypeForBitwidth( 5394 NewSize, Type->hasSignedIntegerRepresentation() || 5395 C.getTypeSize(Type) < NewSize); 5396 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 5397 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 5398 Sema::AA_Converting, true); 5399 if (!Diff.isUsable()) 5400 return nullptr; 5401 } 5402 } 5403 } 5404 5405 return Diff.get(); 5406 } 5407 5408 Expr *OpenMPIterationSpaceChecker::buildPreCond( 5409 Scope *S, Expr *Cond, 5410 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5411 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 5412 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5413 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5414 5415 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 5416 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 5417 if (!NewLB.isUsable() || !NewUB.isUsable()) 5418 return nullptr; 5419 5420 ExprResult CondExpr = 5421 SemaRef.BuildBinOp(S, DefaultLoc, 5422 TestIsLessOp.getValue() ? 5423 (TestIsStrictOp ? BO_LT : BO_LE) : 5424 (TestIsStrictOp ? BO_GT : BO_GE), 5425 NewLB.get(), NewUB.get()); 5426 if (CondExpr.isUsable()) { 5427 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 5428 SemaRef.Context.BoolTy)) 5429 CondExpr = SemaRef.PerformImplicitConversion( 5430 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 5431 /*AllowExplicit=*/true); 5432 } 5433 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5434 // Otherwise use original loop condition and evaluate it in runtime. 5435 return CondExpr.isUsable() ? CondExpr.get() : Cond; 5436 } 5437 5438 /// Build reference expression to the counter be used for codegen. 5439 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 5440 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5441 DSAStackTy &DSA) const { 5442 auto *VD = dyn_cast<VarDecl>(LCDecl); 5443 if (!VD) { 5444 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 5445 DeclRefExpr *Ref = buildDeclRefExpr( 5446 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 5447 const DSAStackTy::DSAVarData Data = 5448 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 5449 // If the loop control decl is explicitly marked as private, do not mark it 5450 // as captured again. 5451 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 5452 Captures.insert(std::make_pair(LCRef, Ref)); 5453 return Ref; 5454 } 5455 return cast<DeclRefExpr>(LCRef); 5456 } 5457 5458 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 5459 if (LCDecl && !LCDecl->isInvalidDecl()) { 5460 QualType Type = LCDecl->getType().getNonReferenceType(); 5461 VarDecl *PrivateVar = buildVarDecl( 5462 SemaRef, DefaultLoc, Type, LCDecl->getName(), 5463 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 5464 isa<VarDecl>(LCDecl) 5465 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 5466 : nullptr); 5467 if (PrivateVar->isInvalidDecl()) 5468 return nullptr; 5469 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 5470 } 5471 return nullptr; 5472 } 5473 5474 /// Build initialization of the counter to be used for codegen. 5475 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 5476 5477 /// Build step of the counter be used for codegen. 5478 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 5479 5480 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 5481 Scope *S, Expr *Counter, 5482 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 5483 Expr *Inc, OverloadedOperatorKind OOK) { 5484 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 5485 if (!Cnt) 5486 return nullptr; 5487 if (Inc) { 5488 assert((OOK == OO_Plus || OOK == OO_Minus) && 5489 "Expected only + or - operations for depend clauses."); 5490 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 5491 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 5492 if (!Cnt) 5493 return nullptr; 5494 } 5495 ExprResult Diff; 5496 QualType VarType = LCDecl->getType().getNonReferenceType(); 5497 if (VarType->isIntegerType() || VarType->isPointerType() || 5498 SemaRef.getLangOpts().CPlusPlus) { 5499 // Upper - Lower 5500 Expr *Upper = TestIsLessOp.getValue() 5501 ? Cnt 5502 : tryBuildCapture(SemaRef, UB, Captures).get(); 5503 Expr *Lower = TestIsLessOp.getValue() 5504 ? tryBuildCapture(SemaRef, LB, Captures).get() 5505 : Cnt; 5506 if (!Upper || !Lower) 5507 return nullptr; 5508 5509 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 5510 5511 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 5512 // BuildBinOp already emitted error, this one is to point user to upper 5513 // and lower bound, and to tell what is passed to 'operator-'. 5514 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 5515 << Upper->getSourceRange() << Lower->getSourceRange(); 5516 return nullptr; 5517 } 5518 } 5519 5520 if (!Diff.isUsable()) 5521 return nullptr; 5522 5523 // Parentheses (for dumping/debugging purposes only). 5524 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 5525 if (!Diff.isUsable()) 5526 return nullptr; 5527 5528 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 5529 if (!NewStep.isUsable()) 5530 return nullptr; 5531 // (Upper - Lower) / Step 5532 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 5533 if (!Diff.isUsable()) 5534 return nullptr; 5535 5536 return Diff.get(); 5537 } 5538 5539 /// Iteration space of a single for loop. 5540 struct LoopIterationSpace final { 5541 /// True if the condition operator is the strict compare operator (<, > or 5542 /// !=). 5543 bool IsStrictCompare = false; 5544 /// Condition of the loop. 5545 Expr *PreCond = nullptr; 5546 /// This expression calculates the number of iterations in the loop. 5547 /// It is always possible to calculate it before starting the loop. 5548 Expr *NumIterations = nullptr; 5549 /// The loop counter variable. 5550 Expr *CounterVar = nullptr; 5551 /// Private loop counter variable. 5552 Expr *PrivateCounterVar = nullptr; 5553 /// This is initializer for the initial value of #CounterVar. 5554 Expr *CounterInit = nullptr; 5555 /// This is step for the #CounterVar used to generate its update: 5556 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5557 Expr *CounterStep = nullptr; 5558 /// Should step be subtracted? 5559 bool Subtract = false; 5560 /// Source range of the loop init. 5561 SourceRange InitSrcRange; 5562 /// Source range of the loop condition. 5563 SourceRange CondSrcRange; 5564 /// Source range of the loop increment. 5565 SourceRange IncSrcRange; 5566 }; 5567 5568 } // namespace 5569 5570 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5571 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5572 assert(Init && "Expected loop in canonical form."); 5573 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5574 if (AssociatedLoops > 0 && 5575 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5576 DSAStack->loopStart(); 5577 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 5578 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5579 if (ValueDecl *D = ISC.getLoopDecl()) { 5580 auto *VD = dyn_cast<VarDecl>(D); 5581 if (!VD) { 5582 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5583 VD = Private; 5584 } else { 5585 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5586 /*WithInit=*/false); 5587 VD = cast<VarDecl>(Ref->getDecl()); 5588 } 5589 } 5590 DSAStack->addLoopControlVariable(D, VD); 5591 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5592 if (LD != D->getCanonicalDecl()) { 5593 DSAStack->resetPossibleLoopCounter(); 5594 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5595 MarkDeclarationsReferencedInExpr( 5596 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5597 Var->getType().getNonLValueExprType(Context), 5598 ForLoc, /*RefersToCapture=*/true)); 5599 } 5600 } 5601 } 5602 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 5603 } 5604 } 5605 5606 /// Called on a for stmt to check and extract its iteration space 5607 /// for further processing (such as collapsing). 5608 static bool checkOpenMPIterationSpace( 5609 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 5610 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 5611 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 5612 Expr *OrderedLoopCountExpr, 5613 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5614 LoopIterationSpace &ResultIterSpace, 5615 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5616 // OpenMP [2.6, Canonical Loop Form] 5617 // for (init-expr; test-expr; incr-expr) structured-block 5618 auto *For = dyn_cast_or_null<ForStmt>(S); 5619 if (!For) { 5620 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 5621 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 5622 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 5623 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 5624 if (TotalNestedLoopCount > 1) { 5625 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 5626 SemaRef.Diag(DSA.getConstructLoc(), 5627 diag::note_omp_collapse_ordered_expr) 5628 << 2 << CollapseLoopCountExpr->getSourceRange() 5629 << OrderedLoopCountExpr->getSourceRange(); 5630 else if (CollapseLoopCountExpr) 5631 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5632 diag::note_omp_collapse_ordered_expr) 5633 << 0 << CollapseLoopCountExpr->getSourceRange(); 5634 else 5635 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5636 diag::note_omp_collapse_ordered_expr) 5637 << 1 << OrderedLoopCountExpr->getSourceRange(); 5638 } 5639 return true; 5640 } 5641 assert(For->getBody()); 5642 5643 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); 5644 5645 // Check init. 5646 Stmt *Init = For->getInit(); 5647 if (ISC.checkAndSetInit(Init)) 5648 return true; 5649 5650 bool HasErrors = false; 5651 5652 // Check loop variable's type. 5653 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 5654 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5655 5656 // OpenMP [2.6, Canonical Loop Form] 5657 // Var is one of the following: 5658 // A variable of signed or unsigned integer type. 5659 // For C++, a variable of a random access iterator type. 5660 // For C, a variable of a pointer type. 5661 QualType VarType = LCDecl->getType().getNonReferenceType(); 5662 if (!VarType->isDependentType() && !VarType->isIntegerType() && 5663 !VarType->isPointerType() && 5664 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 5665 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 5666 << SemaRef.getLangOpts().CPlusPlus; 5667 HasErrors = true; 5668 } 5669 5670 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 5671 // a Construct 5672 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5673 // parallel for construct is (are) private. 5674 // The loop iteration variable in the associated for-loop of a simd 5675 // construct with just one associated for-loop is linear with a 5676 // constant-linear-step that is the increment of the associated for-loop. 5677 // Exclude loop var from the list of variables with implicitly defined data 5678 // sharing attributes. 5679 VarsWithImplicitDSA.erase(LCDecl); 5680 5681 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5682 // in a Construct, C/C++]. 5683 // The loop iteration variable in the associated for-loop of a simd 5684 // construct with just one associated for-loop may be listed in a linear 5685 // clause with a constant-linear-step that is the increment of the 5686 // associated for-loop. 5687 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5688 // parallel for construct may be listed in a private or lastprivate clause. 5689 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 5690 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 5691 // declared in the loop and it is predetermined as a private. 5692 OpenMPClauseKind PredeterminedCKind = 5693 isOpenMPSimdDirective(DKind) 5694 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5695 : OMPC_private; 5696 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5697 DVar.CKind != PredeterminedCKind) || 5698 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5699 isOpenMPDistributeDirective(DKind)) && 5700 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5701 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5702 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5703 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5704 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5705 << getOpenMPClauseName(PredeterminedCKind); 5706 if (DVar.RefExpr == nullptr) 5707 DVar.CKind = PredeterminedCKind; 5708 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5709 HasErrors = true; 5710 } else if (LoopDeclRefExpr != nullptr) { 5711 // Make the loop iteration variable private (for worksharing constructs), 5712 // linear (for simd directives with the only one associated loop) or 5713 // lastprivate (for simd directives with several collapsed or ordered 5714 // loops). 5715 if (DVar.CKind == OMPC_unknown) 5716 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5717 } 5718 5719 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5720 5721 // Check test-expr. 5722 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5723 5724 // Check incr-expr. 5725 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5726 } 5727 5728 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5729 return HasErrors; 5730 5731 // Build the loop's iteration space representation. 5732 ResultIterSpace.PreCond = 5733 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5734 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5735 DSA.getCurScope(), 5736 (isOpenMPWorksharingDirective(DKind) || 5737 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5738 Captures); 5739 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5740 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5741 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5742 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5743 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5744 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5745 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5746 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5747 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5748 5749 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5750 ResultIterSpace.NumIterations == nullptr || 5751 ResultIterSpace.CounterVar == nullptr || 5752 ResultIterSpace.PrivateCounterVar == nullptr || 5753 ResultIterSpace.CounterInit == nullptr || 5754 ResultIterSpace.CounterStep == nullptr); 5755 if (!HasErrors && DSA.isOrderedRegion()) { 5756 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5757 if (CurrentNestedLoopCount < 5758 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5759 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5760 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5761 DSA.getOrderedRegionParam().second->setLoopCounter( 5762 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5763 } 5764 } 5765 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5766 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5767 // Erroneous case - clause has some problems. 5768 continue; 5769 } 5770 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5771 Pair.second.size() <= CurrentNestedLoopCount) { 5772 // Erroneous case - clause has some problems. 5773 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5774 continue; 5775 } 5776 Expr *CntValue; 5777 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5778 CntValue = ISC.buildOrderedLoopData( 5779 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5780 Pair.first->getDependencyLoc()); 5781 else 5782 CntValue = ISC.buildOrderedLoopData( 5783 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5784 Pair.first->getDependencyLoc(), 5785 Pair.second[CurrentNestedLoopCount].first, 5786 Pair.second[CurrentNestedLoopCount].second); 5787 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5788 } 5789 } 5790 5791 return HasErrors; 5792 } 5793 5794 /// Build 'VarRef = Start. 5795 static ExprResult 5796 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5797 ExprResult Start, 5798 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5799 // Build 'VarRef = Start. 5800 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5801 if (!NewStart.isUsable()) 5802 return ExprError(); 5803 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5804 VarRef.get()->getType())) { 5805 NewStart = SemaRef.PerformImplicitConversion( 5806 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5807 /*AllowExplicit=*/true); 5808 if (!NewStart.isUsable()) 5809 return ExprError(); 5810 } 5811 5812 ExprResult Init = 5813 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5814 return Init; 5815 } 5816 5817 /// Build 'VarRef = Start + Iter * Step'. 5818 static ExprResult buildCounterUpdate( 5819 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5820 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5821 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5822 // Add parentheses (for debugging purposes only). 5823 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5824 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5825 !Step.isUsable()) 5826 return ExprError(); 5827 5828 ExprResult NewStep = Step; 5829 if (Captures) 5830 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5831 if (NewStep.isInvalid()) 5832 return ExprError(); 5833 ExprResult Update = 5834 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5835 if (!Update.isUsable()) 5836 return ExprError(); 5837 5838 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5839 // 'VarRef = Start (+|-) Iter * Step'. 5840 ExprResult NewStart = Start; 5841 if (Captures) 5842 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5843 if (NewStart.isInvalid()) 5844 return ExprError(); 5845 5846 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5847 ExprResult SavedUpdate = Update; 5848 ExprResult UpdateVal; 5849 if (VarRef.get()->getType()->isOverloadableType() || 5850 NewStart.get()->getType()->isOverloadableType() || 5851 Update.get()->getType()->isOverloadableType()) { 5852 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5853 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5854 Update = 5855 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5856 if (Update.isUsable()) { 5857 UpdateVal = 5858 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5859 VarRef.get(), SavedUpdate.get()); 5860 if (UpdateVal.isUsable()) { 5861 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5862 UpdateVal.get()); 5863 } 5864 } 5865 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5866 } 5867 5868 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5869 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5870 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5871 NewStart.get(), SavedUpdate.get()); 5872 if (!Update.isUsable()) 5873 return ExprError(); 5874 5875 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5876 VarRef.get()->getType())) { 5877 Update = SemaRef.PerformImplicitConversion( 5878 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5879 if (!Update.isUsable()) 5880 return ExprError(); 5881 } 5882 5883 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5884 } 5885 return Update; 5886 } 5887 5888 /// Convert integer expression \a E to make it have at least \a Bits 5889 /// bits. 5890 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5891 if (E == nullptr) 5892 return ExprError(); 5893 ASTContext &C = SemaRef.Context; 5894 QualType OldType = E->getType(); 5895 unsigned HasBits = C.getTypeSize(OldType); 5896 if (HasBits >= Bits) 5897 return ExprResult(E); 5898 // OK to convert to signed, because new type has more bits than old. 5899 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5900 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5901 true); 5902 } 5903 5904 /// Check if the given expression \a E is a constant integer that fits 5905 /// into \a Bits bits. 5906 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5907 if (E == nullptr) 5908 return false; 5909 llvm::APSInt Result; 5910 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5911 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5912 return false; 5913 } 5914 5915 /// Build preinits statement for the given declarations. 5916 static Stmt *buildPreInits(ASTContext &Context, 5917 MutableArrayRef<Decl *> PreInits) { 5918 if (!PreInits.empty()) { 5919 return new (Context) DeclStmt( 5920 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5921 SourceLocation(), SourceLocation()); 5922 } 5923 return nullptr; 5924 } 5925 5926 /// Build preinits statement for the given declarations. 5927 static Stmt * 5928 buildPreInits(ASTContext &Context, 5929 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5930 if (!Captures.empty()) { 5931 SmallVector<Decl *, 16> PreInits; 5932 for (const auto &Pair : Captures) 5933 PreInits.push_back(Pair.second->getDecl()); 5934 return buildPreInits(Context, PreInits); 5935 } 5936 return nullptr; 5937 } 5938 5939 /// Build postupdate expression for the given list of postupdates expressions. 5940 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5941 Expr *PostUpdate = nullptr; 5942 if (!PostUpdates.empty()) { 5943 for (Expr *E : PostUpdates) { 5944 Expr *ConvE = S.BuildCStyleCastExpr( 5945 E->getExprLoc(), 5946 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5947 E->getExprLoc(), E) 5948 .get(); 5949 PostUpdate = PostUpdate 5950 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5951 PostUpdate, ConvE) 5952 .get() 5953 : ConvE; 5954 } 5955 } 5956 return PostUpdate; 5957 } 5958 5959 /// Called on a for stmt to check itself and nested loops (if any). 5960 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5961 /// number of collapsed loops otherwise. 5962 static unsigned 5963 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5964 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5965 DSAStackTy &DSA, 5966 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5967 OMPLoopDirective::HelperExprs &Built) { 5968 unsigned NestedLoopCount = 1; 5969 if (CollapseLoopCountExpr) { 5970 // Found 'collapse' clause - calculate collapse number. 5971 Expr::EvalResult Result; 5972 if (!CollapseLoopCountExpr->isValueDependent() && 5973 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 5974 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5975 } else { 5976 Built.clear(/*size=*/1); 5977 return 1; 5978 } 5979 } 5980 unsigned OrderedLoopCount = 1; 5981 if (OrderedLoopCountExpr) { 5982 // Found 'ordered' clause - calculate collapse number. 5983 Expr::EvalResult EVResult; 5984 if (!OrderedLoopCountExpr->isValueDependent() && 5985 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 5986 SemaRef.getASTContext())) { 5987 llvm::APSInt Result = EVResult.Val.getInt(); 5988 if (Result.getLimitedValue() < NestedLoopCount) { 5989 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5990 diag::err_omp_wrong_ordered_loop_count) 5991 << OrderedLoopCountExpr->getSourceRange(); 5992 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5993 diag::note_collapse_loop_count) 5994 << CollapseLoopCountExpr->getSourceRange(); 5995 } 5996 OrderedLoopCount = Result.getLimitedValue(); 5997 } else { 5998 Built.clear(/*size=*/1); 5999 return 1; 6000 } 6001 } 6002 // This is helper routine for loop directives (e.g., 'for', 'simd', 6003 // 'for simd', etc.). 6004 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6005 SmallVector<LoopIterationSpace, 4> IterSpaces( 6006 std::max(OrderedLoopCount, NestedLoopCount)); 6007 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6008 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6009 if (checkOpenMPIterationSpace( 6010 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6011 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6012 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 6013 Captures)) 6014 return 0; 6015 // Move on to the next nested for loop, or to the loop body. 6016 // OpenMP [2.8.1, simd construct, Restrictions] 6017 // All loops associated with the construct must be perfectly nested; that 6018 // is, there must be no intervening code nor any OpenMP directive between 6019 // any two loops. 6020 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6021 } 6022 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6023 if (checkOpenMPIterationSpace( 6024 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6025 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6026 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 6027 Captures)) 6028 return 0; 6029 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6030 // Handle initialization of captured loop iterator variables. 6031 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6032 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6033 Captures[DRE] = DRE; 6034 } 6035 } 6036 // Move on to the next nested for loop, or to the loop body. 6037 // OpenMP [2.8.1, simd construct, Restrictions] 6038 // All loops associated with the construct must be perfectly nested; that 6039 // is, there must be no intervening code nor any OpenMP directive between 6040 // any two loops. 6041 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 6042 } 6043 6044 Built.clear(/* size */ NestedLoopCount); 6045 6046 if (SemaRef.CurContext->isDependentContext()) 6047 return NestedLoopCount; 6048 6049 // An example of what is generated for the following code: 6050 // 6051 // #pragma omp simd collapse(2) ordered(2) 6052 // for (i = 0; i < NI; ++i) 6053 // for (k = 0; k < NK; ++k) 6054 // for (j = J0; j < NJ; j+=2) { 6055 // <loop body> 6056 // } 6057 // 6058 // We generate the code below. 6059 // Note: the loop body may be outlined in CodeGen. 6060 // Note: some counters may be C++ classes, operator- is used to find number of 6061 // iterations and operator+= to calculate counter value. 6062 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6063 // or i64 is currently supported). 6064 // 6065 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6066 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6067 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6068 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6069 // // similar updates for vars in clauses (e.g. 'linear') 6070 // <loop body (using local i and j)> 6071 // } 6072 // i = NI; // assign final values of counters 6073 // j = NJ; 6074 // 6075 6076 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6077 // the iteration counts of the collapsed for loops. 6078 // Precondition tests if there is at least one iteration (all conditions are 6079 // true). 6080 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6081 Expr *N0 = IterSpaces[0].NumIterations; 6082 ExprResult LastIteration32 = 6083 widenIterationCount(/*Bits=*/32, 6084 SemaRef 6085 .PerformImplicitConversion( 6086 N0->IgnoreImpCasts(), N0->getType(), 6087 Sema::AA_Converting, /*AllowExplicit=*/true) 6088 .get(), 6089 SemaRef); 6090 ExprResult LastIteration64 = widenIterationCount( 6091 /*Bits=*/64, 6092 SemaRef 6093 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6094 Sema::AA_Converting, 6095 /*AllowExplicit=*/true) 6096 .get(), 6097 SemaRef); 6098 6099 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6100 return NestedLoopCount; 6101 6102 ASTContext &C = SemaRef.Context; 6103 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6104 6105 Scope *CurScope = DSA.getCurScope(); 6106 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6107 if (PreCond.isUsable()) { 6108 PreCond = 6109 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6110 PreCond.get(), IterSpaces[Cnt].PreCond); 6111 } 6112 Expr *N = IterSpaces[Cnt].NumIterations; 6113 SourceLocation Loc = N->getExprLoc(); 6114 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6115 if (LastIteration32.isUsable()) 6116 LastIteration32 = SemaRef.BuildBinOp( 6117 CurScope, Loc, BO_Mul, LastIteration32.get(), 6118 SemaRef 6119 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6120 Sema::AA_Converting, 6121 /*AllowExplicit=*/true) 6122 .get()); 6123 if (LastIteration64.isUsable()) 6124 LastIteration64 = SemaRef.BuildBinOp( 6125 CurScope, Loc, BO_Mul, LastIteration64.get(), 6126 SemaRef 6127 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6128 Sema::AA_Converting, 6129 /*AllowExplicit=*/true) 6130 .get()); 6131 } 6132 6133 // Choose either the 32-bit or 64-bit version. 6134 ExprResult LastIteration = LastIteration64; 6135 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 6136 (LastIteration32.isUsable() && 6137 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 6138 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 6139 fitsInto( 6140 /*Bits=*/32, 6141 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 6142 LastIteration64.get(), SemaRef)))) 6143 LastIteration = LastIteration32; 6144 QualType VType = LastIteration.get()->getType(); 6145 QualType RealVType = VType; 6146 QualType StrideVType = VType; 6147 if (isOpenMPTaskLoopDirective(DKind)) { 6148 VType = 6149 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 6150 StrideVType = 6151 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 6152 } 6153 6154 if (!LastIteration.isUsable()) 6155 return 0; 6156 6157 // Save the number of iterations. 6158 ExprResult NumIterations = LastIteration; 6159 { 6160 LastIteration = SemaRef.BuildBinOp( 6161 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 6162 LastIteration.get(), 6163 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6164 if (!LastIteration.isUsable()) 6165 return 0; 6166 } 6167 6168 // Calculate the last iteration number beforehand instead of doing this on 6169 // each iteration. Do not do this if the number of iterations may be kfold-ed. 6170 llvm::APSInt Result; 6171 bool IsConstant = 6172 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 6173 ExprResult CalcLastIteration; 6174 if (!IsConstant) { 6175 ExprResult SaveRef = 6176 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 6177 LastIteration = SaveRef; 6178 6179 // Prepare SaveRef + 1. 6180 NumIterations = SemaRef.BuildBinOp( 6181 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 6182 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6183 if (!NumIterations.isUsable()) 6184 return 0; 6185 } 6186 6187 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 6188 6189 // Build variables passed into runtime, necessary for worksharing directives. 6190 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 6191 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6192 isOpenMPDistributeDirective(DKind)) { 6193 // Lower bound variable, initialized with zero. 6194 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 6195 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 6196 SemaRef.AddInitializerToDecl(LBDecl, 6197 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6198 /*DirectInit*/ false); 6199 6200 // Upper bound variable, initialized with last iteration number. 6201 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 6202 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 6203 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 6204 /*DirectInit*/ false); 6205 6206 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 6207 // This will be used to implement clause 'lastprivate'. 6208 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 6209 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 6210 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 6211 SemaRef.AddInitializerToDecl(ILDecl, 6212 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6213 /*DirectInit*/ false); 6214 6215 // Stride variable returned by runtime (we initialize it to 1 by default). 6216 VarDecl *STDecl = 6217 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 6218 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 6219 SemaRef.AddInitializerToDecl(STDecl, 6220 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 6221 /*DirectInit*/ false); 6222 6223 // Build expression: UB = min(UB, LastIteration) 6224 // It is necessary for CodeGen of directives with static scheduling. 6225 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 6226 UB.get(), LastIteration.get()); 6227 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6228 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 6229 LastIteration.get(), UB.get()); 6230 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 6231 CondOp.get()); 6232 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 6233 6234 // If we have a combined directive that combines 'distribute', 'for' or 6235 // 'simd' we need to be able to access the bounds of the schedule of the 6236 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 6237 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 6238 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6239 // Lower bound variable, initialized with zero. 6240 VarDecl *CombLBDecl = 6241 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 6242 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 6243 SemaRef.AddInitializerToDecl( 6244 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 6245 /*DirectInit*/ false); 6246 6247 // Upper bound variable, initialized with last iteration number. 6248 VarDecl *CombUBDecl = 6249 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 6250 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 6251 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 6252 /*DirectInit*/ false); 6253 6254 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 6255 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 6256 ExprResult CombCondOp = 6257 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 6258 LastIteration.get(), CombUB.get()); 6259 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 6260 CombCondOp.get()); 6261 CombEUB = 6262 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 6263 6264 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 6265 // We expect to have at least 2 more parameters than the 'parallel' 6266 // directive does - the lower and upper bounds of the previous schedule. 6267 assert(CD->getNumParams() >= 4 && 6268 "Unexpected number of parameters in loop combined directive"); 6269 6270 // Set the proper type for the bounds given what we learned from the 6271 // enclosed loops. 6272 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 6273 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 6274 6275 // Previous lower and upper bounds are obtained from the region 6276 // parameters. 6277 PrevLB = 6278 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 6279 PrevUB = 6280 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 6281 } 6282 } 6283 6284 // Build the iteration variable and its initialization before loop. 6285 ExprResult IV; 6286 ExprResult Init, CombInit; 6287 { 6288 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 6289 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 6290 Expr *RHS = 6291 (isOpenMPWorksharingDirective(DKind) || 6292 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6293 ? LB.get() 6294 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6295 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 6296 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 6297 6298 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6299 Expr *CombRHS = 6300 (isOpenMPWorksharingDirective(DKind) || 6301 isOpenMPTaskLoopDirective(DKind) || 6302 isOpenMPDistributeDirective(DKind)) 6303 ? CombLB.get() 6304 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 6305 CombInit = 6306 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 6307 CombInit = 6308 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 6309 } 6310 } 6311 6312 bool UseStrictCompare = 6313 RealVType->hasUnsignedIntegerRepresentation() && 6314 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 6315 return LIS.IsStrictCompare; 6316 }); 6317 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 6318 // unsigned IV)) for worksharing loops. 6319 SourceLocation CondLoc = AStmt->getBeginLoc(); 6320 Expr *BoundUB = UB.get(); 6321 if (UseStrictCompare) { 6322 BoundUB = 6323 SemaRef 6324 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 6325 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6326 .get(); 6327 BoundUB = 6328 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 6329 } 6330 ExprResult Cond = 6331 (isOpenMPWorksharingDirective(DKind) || 6332 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 6333 ? SemaRef.BuildBinOp(CurScope, CondLoc, 6334 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 6335 BoundUB) 6336 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6337 NumIterations.get()); 6338 ExprResult CombDistCond; 6339 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6340 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 6341 NumIterations.get()); 6342 } 6343 6344 ExprResult CombCond; 6345 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6346 Expr *BoundCombUB = CombUB.get(); 6347 if (UseStrictCompare) { 6348 BoundCombUB = 6349 SemaRef 6350 .BuildBinOp( 6351 CurScope, CondLoc, BO_Add, BoundCombUB, 6352 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6353 .get(); 6354 BoundCombUB = 6355 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 6356 .get(); 6357 } 6358 CombCond = 6359 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6360 IV.get(), BoundCombUB); 6361 } 6362 // Loop increment (IV = IV + 1) 6363 SourceLocation IncLoc = AStmt->getBeginLoc(); 6364 ExprResult Inc = 6365 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 6366 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 6367 if (!Inc.isUsable()) 6368 return 0; 6369 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 6370 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 6371 if (!Inc.isUsable()) 6372 return 0; 6373 6374 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 6375 // Used for directives with static scheduling. 6376 // In combined construct, add combined version that use CombLB and CombUB 6377 // base variables for the update 6378 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 6379 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 6380 isOpenMPDistributeDirective(DKind)) { 6381 // LB + ST 6382 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 6383 if (!NextLB.isUsable()) 6384 return 0; 6385 // LB = LB + ST 6386 NextLB = 6387 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 6388 NextLB = 6389 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 6390 if (!NextLB.isUsable()) 6391 return 0; 6392 // UB + ST 6393 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 6394 if (!NextUB.isUsable()) 6395 return 0; 6396 // UB = UB + ST 6397 NextUB = 6398 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 6399 NextUB = 6400 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 6401 if (!NextUB.isUsable()) 6402 return 0; 6403 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6404 CombNextLB = 6405 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 6406 if (!NextLB.isUsable()) 6407 return 0; 6408 // LB = LB + ST 6409 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 6410 CombNextLB.get()); 6411 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 6412 /*DiscardedValue*/ false); 6413 if (!CombNextLB.isUsable()) 6414 return 0; 6415 // UB + ST 6416 CombNextUB = 6417 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 6418 if (!CombNextUB.isUsable()) 6419 return 0; 6420 // UB = UB + ST 6421 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 6422 CombNextUB.get()); 6423 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 6424 /*DiscardedValue*/ false); 6425 if (!CombNextUB.isUsable()) 6426 return 0; 6427 } 6428 } 6429 6430 // Create increment expression for distribute loop when combined in a same 6431 // directive with for as IV = IV + ST; ensure upper bound expression based 6432 // on PrevUB instead of NumIterations - used to implement 'for' when found 6433 // in combination with 'distribute', like in 'distribute parallel for' 6434 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 6435 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 6436 if (isOpenMPLoopBoundSharingDirective(DKind)) { 6437 DistCond = SemaRef.BuildBinOp( 6438 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 6439 assert(DistCond.isUsable() && "distribute cond expr was not built"); 6440 6441 DistInc = 6442 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 6443 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6444 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 6445 DistInc.get()); 6446 DistInc = 6447 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 6448 assert(DistInc.isUsable() && "distribute inc expr was not built"); 6449 6450 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 6451 // construct 6452 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 6453 ExprResult IsUBGreater = 6454 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 6455 ExprResult CondOp = SemaRef.ActOnConditionalOp( 6456 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 6457 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 6458 CondOp.get()); 6459 PrevEUB = 6460 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 6461 6462 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 6463 // parallel for is in combination with a distribute directive with 6464 // schedule(static, 1) 6465 Expr *BoundPrevUB = PrevUB.get(); 6466 if (UseStrictCompare) { 6467 BoundPrevUB = 6468 SemaRef 6469 .BuildBinOp( 6470 CurScope, CondLoc, BO_Add, BoundPrevUB, 6471 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 6472 .get(); 6473 BoundPrevUB = 6474 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 6475 .get(); 6476 } 6477 ParForInDistCond = 6478 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 6479 IV.get(), BoundPrevUB); 6480 } 6481 6482 // Build updates and final values of the loop counters. 6483 bool HasErrors = false; 6484 Built.Counters.resize(NestedLoopCount); 6485 Built.Inits.resize(NestedLoopCount); 6486 Built.Updates.resize(NestedLoopCount); 6487 Built.Finals.resize(NestedLoopCount); 6488 { 6489 // We implement the following algorithm for obtaining the 6490 // original loop iteration variable values based on the 6491 // value of the collapsed loop iteration variable IV. 6492 // 6493 // Let n+1 be the number of collapsed loops in the nest. 6494 // Iteration variables (I0, I1, .... In) 6495 // Iteration counts (N0, N1, ... Nn) 6496 // 6497 // Acc = IV; 6498 // 6499 // To compute Ik for loop k, 0 <= k <= n, generate: 6500 // Prod = N(k+1) * N(k+2) * ... * Nn; 6501 // Ik = Acc / Prod; 6502 // Acc -= Ik * Prod; 6503 // 6504 ExprResult Acc = IV; 6505 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6506 LoopIterationSpace &IS = IterSpaces[Cnt]; 6507 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 6508 ExprResult Iter; 6509 6510 // Compute prod 6511 ExprResult Prod = 6512 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6513 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 6514 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 6515 IterSpaces[K].NumIterations); 6516 6517 // Iter = Acc / Prod 6518 // If there is at least one more inner loop to avoid 6519 // multiplication by 1. 6520 if (Cnt + 1 < NestedLoopCount) 6521 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 6522 Acc.get(), Prod.get()); 6523 else 6524 Iter = Acc; 6525 if (!Iter.isUsable()) { 6526 HasErrors = true; 6527 break; 6528 } 6529 6530 // Update Acc: 6531 // Acc -= Iter * Prod 6532 // Check if there is at least one more inner loop to avoid 6533 // multiplication by 1. 6534 if (Cnt + 1 < NestedLoopCount) 6535 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 6536 Iter.get(), Prod.get()); 6537 else 6538 Prod = Iter; 6539 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 6540 Acc.get(), Prod.get()); 6541 6542 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 6543 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 6544 DeclRefExpr *CounterVar = buildDeclRefExpr( 6545 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 6546 /*RefersToCapture=*/true); 6547 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 6548 IS.CounterInit, Captures); 6549 if (!Init.isUsable()) { 6550 HasErrors = true; 6551 break; 6552 } 6553 ExprResult Update = buildCounterUpdate( 6554 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 6555 IS.CounterStep, IS.Subtract, &Captures); 6556 if (!Update.isUsable()) { 6557 HasErrors = true; 6558 break; 6559 } 6560 6561 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6562 ExprResult Final = buildCounterUpdate( 6563 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 6564 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 6565 if (!Final.isUsable()) { 6566 HasErrors = true; 6567 break; 6568 } 6569 6570 if (!Update.isUsable() || !Final.isUsable()) { 6571 HasErrors = true; 6572 break; 6573 } 6574 // Save results 6575 Built.Counters[Cnt] = IS.CounterVar; 6576 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6577 Built.Inits[Cnt] = Init.get(); 6578 Built.Updates[Cnt] = Update.get(); 6579 Built.Finals[Cnt] = Final.get(); 6580 } 6581 } 6582 6583 if (HasErrors) 6584 return 0; 6585 6586 // Save results 6587 Built.IterationVarRef = IV.get(); 6588 Built.LastIteration = LastIteration.get(); 6589 Built.NumIterations = NumIterations.get(); 6590 Built.CalcLastIteration = SemaRef 6591 .ActOnFinishFullExpr(CalcLastIteration.get(), 6592 /*DiscardedValue*/ false) 6593 .get(); 6594 Built.PreCond = PreCond.get(); 6595 Built.PreInits = buildPreInits(C, Captures); 6596 Built.Cond = Cond.get(); 6597 Built.Init = Init.get(); 6598 Built.Inc = Inc.get(); 6599 Built.LB = LB.get(); 6600 Built.UB = UB.get(); 6601 Built.IL = IL.get(); 6602 Built.ST = ST.get(); 6603 Built.EUB = EUB.get(); 6604 Built.NLB = NextLB.get(); 6605 Built.NUB = NextUB.get(); 6606 Built.PrevLB = PrevLB.get(); 6607 Built.PrevUB = PrevUB.get(); 6608 Built.DistInc = DistInc.get(); 6609 Built.PrevEUB = PrevEUB.get(); 6610 Built.DistCombinedFields.LB = CombLB.get(); 6611 Built.DistCombinedFields.UB = CombUB.get(); 6612 Built.DistCombinedFields.EUB = CombEUB.get(); 6613 Built.DistCombinedFields.Init = CombInit.get(); 6614 Built.DistCombinedFields.Cond = CombCond.get(); 6615 Built.DistCombinedFields.NLB = CombNextLB.get(); 6616 Built.DistCombinedFields.NUB = CombNextUB.get(); 6617 Built.DistCombinedFields.DistCond = CombDistCond.get(); 6618 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 6619 6620 return NestedLoopCount; 6621 } 6622 6623 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 6624 auto CollapseClauses = 6625 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 6626 if (CollapseClauses.begin() != CollapseClauses.end()) 6627 return (*CollapseClauses.begin())->getNumForLoops(); 6628 return nullptr; 6629 } 6630 6631 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 6632 auto OrderedClauses = 6633 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 6634 if (OrderedClauses.begin() != OrderedClauses.end()) 6635 return (*OrderedClauses.begin())->getNumForLoops(); 6636 return nullptr; 6637 } 6638 6639 static bool checkSimdlenSafelenSpecified(Sema &S, 6640 const ArrayRef<OMPClause *> Clauses) { 6641 const OMPSafelenClause *Safelen = nullptr; 6642 const OMPSimdlenClause *Simdlen = nullptr; 6643 6644 for (const OMPClause *Clause : Clauses) { 6645 if (Clause->getClauseKind() == OMPC_safelen) 6646 Safelen = cast<OMPSafelenClause>(Clause); 6647 else if (Clause->getClauseKind() == OMPC_simdlen) 6648 Simdlen = cast<OMPSimdlenClause>(Clause); 6649 if (Safelen && Simdlen) 6650 break; 6651 } 6652 6653 if (Simdlen && Safelen) { 6654 const Expr *SimdlenLength = Simdlen->getSimdlen(); 6655 const Expr *SafelenLength = Safelen->getSafelen(); 6656 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 6657 SimdlenLength->isInstantiationDependent() || 6658 SimdlenLength->containsUnexpandedParameterPack()) 6659 return false; 6660 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 6661 SafelenLength->isInstantiationDependent() || 6662 SafelenLength->containsUnexpandedParameterPack()) 6663 return false; 6664 Expr::EvalResult SimdlenResult, SafelenResult; 6665 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 6666 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 6667 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 6668 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 6669 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 6670 // If both simdlen and safelen clauses are specified, the value of the 6671 // simdlen parameter must be less than or equal to the value of the safelen 6672 // parameter. 6673 if (SimdlenRes > SafelenRes) { 6674 S.Diag(SimdlenLength->getExprLoc(), 6675 diag::err_omp_wrong_simdlen_safelen_values) 6676 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 6677 return true; 6678 } 6679 } 6680 return false; 6681 } 6682 6683 StmtResult 6684 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6685 SourceLocation StartLoc, SourceLocation EndLoc, 6686 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6687 if (!AStmt) 6688 return StmtError(); 6689 6690 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6691 OMPLoopDirective::HelperExprs B; 6692 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6693 // define the nested loops number. 6694 unsigned NestedLoopCount = checkOpenMPLoop( 6695 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6696 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6697 if (NestedLoopCount == 0) 6698 return StmtError(); 6699 6700 assert((CurContext->isDependentContext() || B.builtAll()) && 6701 "omp simd loop exprs were not built"); 6702 6703 if (!CurContext->isDependentContext()) { 6704 // Finalize the clauses that need pre-built expressions for CodeGen. 6705 for (OMPClause *C : Clauses) { 6706 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6707 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6708 B.NumIterations, *this, CurScope, 6709 DSAStack)) 6710 return StmtError(); 6711 } 6712 } 6713 6714 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6715 return StmtError(); 6716 6717 setFunctionHasBranchProtectedScope(); 6718 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6719 Clauses, AStmt, B); 6720 } 6721 6722 StmtResult 6723 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6724 SourceLocation StartLoc, SourceLocation EndLoc, 6725 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6726 if (!AStmt) 6727 return StmtError(); 6728 6729 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6730 OMPLoopDirective::HelperExprs B; 6731 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6732 // define the nested loops number. 6733 unsigned NestedLoopCount = checkOpenMPLoop( 6734 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6735 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6736 if (NestedLoopCount == 0) 6737 return StmtError(); 6738 6739 assert((CurContext->isDependentContext() || B.builtAll()) && 6740 "omp for loop exprs were not built"); 6741 6742 if (!CurContext->isDependentContext()) { 6743 // Finalize the clauses that need pre-built expressions for CodeGen. 6744 for (OMPClause *C : Clauses) { 6745 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6746 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6747 B.NumIterations, *this, CurScope, 6748 DSAStack)) 6749 return StmtError(); 6750 } 6751 } 6752 6753 setFunctionHasBranchProtectedScope(); 6754 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6755 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6756 } 6757 6758 StmtResult Sema::ActOnOpenMPForSimdDirective( 6759 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6760 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6761 if (!AStmt) 6762 return StmtError(); 6763 6764 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6765 OMPLoopDirective::HelperExprs B; 6766 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6767 // define the nested loops number. 6768 unsigned NestedLoopCount = 6769 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6770 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6771 VarsWithImplicitDSA, B); 6772 if (NestedLoopCount == 0) 6773 return StmtError(); 6774 6775 assert((CurContext->isDependentContext() || B.builtAll()) && 6776 "omp for simd loop exprs were not built"); 6777 6778 if (!CurContext->isDependentContext()) { 6779 // Finalize the clauses that need pre-built expressions for CodeGen. 6780 for (OMPClause *C : Clauses) { 6781 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6782 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6783 B.NumIterations, *this, CurScope, 6784 DSAStack)) 6785 return StmtError(); 6786 } 6787 } 6788 6789 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6790 return StmtError(); 6791 6792 setFunctionHasBranchProtectedScope(); 6793 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6794 Clauses, AStmt, B); 6795 } 6796 6797 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6798 Stmt *AStmt, 6799 SourceLocation StartLoc, 6800 SourceLocation EndLoc) { 6801 if (!AStmt) 6802 return StmtError(); 6803 6804 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6805 auto BaseStmt = AStmt; 6806 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6807 BaseStmt = CS->getCapturedStmt(); 6808 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6809 auto S = C->children(); 6810 if (S.begin() == S.end()) 6811 return StmtError(); 6812 // All associated statements must be '#pragma omp section' except for 6813 // the first one. 6814 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6815 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6816 if (SectionStmt) 6817 Diag(SectionStmt->getBeginLoc(), 6818 diag::err_omp_sections_substmt_not_section); 6819 return StmtError(); 6820 } 6821 cast<OMPSectionDirective>(SectionStmt) 6822 ->setHasCancel(DSAStack->isCancelRegion()); 6823 } 6824 } else { 6825 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6826 return StmtError(); 6827 } 6828 6829 setFunctionHasBranchProtectedScope(); 6830 6831 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6832 DSAStack->isCancelRegion()); 6833 } 6834 6835 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6836 SourceLocation StartLoc, 6837 SourceLocation EndLoc) { 6838 if (!AStmt) 6839 return StmtError(); 6840 6841 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6842 6843 setFunctionHasBranchProtectedScope(); 6844 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6845 6846 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6847 DSAStack->isCancelRegion()); 6848 } 6849 6850 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6851 Stmt *AStmt, 6852 SourceLocation StartLoc, 6853 SourceLocation EndLoc) { 6854 if (!AStmt) 6855 return StmtError(); 6856 6857 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6858 6859 setFunctionHasBranchProtectedScope(); 6860 6861 // OpenMP [2.7.3, single Construct, Restrictions] 6862 // The copyprivate clause must not be used with the nowait clause. 6863 const OMPClause *Nowait = nullptr; 6864 const OMPClause *Copyprivate = nullptr; 6865 for (const OMPClause *Clause : Clauses) { 6866 if (Clause->getClauseKind() == OMPC_nowait) 6867 Nowait = Clause; 6868 else if (Clause->getClauseKind() == OMPC_copyprivate) 6869 Copyprivate = Clause; 6870 if (Copyprivate && Nowait) { 6871 Diag(Copyprivate->getBeginLoc(), 6872 diag::err_omp_single_copyprivate_with_nowait); 6873 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6874 return StmtError(); 6875 } 6876 } 6877 6878 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6879 } 6880 6881 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6882 SourceLocation StartLoc, 6883 SourceLocation EndLoc) { 6884 if (!AStmt) 6885 return StmtError(); 6886 6887 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6888 6889 setFunctionHasBranchProtectedScope(); 6890 6891 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6892 } 6893 6894 StmtResult Sema::ActOnOpenMPCriticalDirective( 6895 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6896 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6897 if (!AStmt) 6898 return StmtError(); 6899 6900 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6901 6902 bool ErrorFound = false; 6903 llvm::APSInt Hint; 6904 SourceLocation HintLoc; 6905 bool DependentHint = false; 6906 for (const OMPClause *C : Clauses) { 6907 if (C->getClauseKind() == OMPC_hint) { 6908 if (!DirName.getName()) { 6909 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6910 ErrorFound = true; 6911 } 6912 Expr *E = cast<OMPHintClause>(C)->getHint(); 6913 if (E->isTypeDependent() || E->isValueDependent() || 6914 E->isInstantiationDependent()) { 6915 DependentHint = true; 6916 } else { 6917 Hint = E->EvaluateKnownConstInt(Context); 6918 HintLoc = C->getBeginLoc(); 6919 } 6920 } 6921 } 6922 if (ErrorFound) 6923 return StmtError(); 6924 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6925 if (Pair.first && DirName.getName() && !DependentHint) { 6926 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6927 Diag(StartLoc, diag::err_omp_critical_with_hint); 6928 if (HintLoc.isValid()) 6929 Diag(HintLoc, diag::note_omp_critical_hint_here) 6930 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6931 else 6932 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6933 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6934 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6935 << 1 6936 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6937 /*Radix=*/10, /*Signed=*/false); 6938 } else { 6939 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6940 } 6941 } 6942 } 6943 6944 setFunctionHasBranchProtectedScope(); 6945 6946 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6947 Clauses, AStmt); 6948 if (!Pair.first && DirName.getName() && !DependentHint) 6949 DSAStack->addCriticalWithHint(Dir, Hint); 6950 return Dir; 6951 } 6952 6953 StmtResult Sema::ActOnOpenMPParallelForDirective( 6954 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6955 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6956 if (!AStmt) 6957 return StmtError(); 6958 6959 auto *CS = cast<CapturedStmt>(AStmt); 6960 // 1.2.2 OpenMP Language Terminology 6961 // Structured block - An executable statement with a single entry at the 6962 // top and a single exit at the bottom. 6963 // The point of exit cannot be a branch out of the structured block. 6964 // longjmp() and throw() must not violate the entry/exit criteria. 6965 CS->getCapturedDecl()->setNothrow(); 6966 6967 OMPLoopDirective::HelperExprs B; 6968 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6969 // define the nested loops number. 6970 unsigned NestedLoopCount = 6971 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6972 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6973 VarsWithImplicitDSA, B); 6974 if (NestedLoopCount == 0) 6975 return StmtError(); 6976 6977 assert((CurContext->isDependentContext() || B.builtAll()) && 6978 "omp parallel for loop exprs were not built"); 6979 6980 if (!CurContext->isDependentContext()) { 6981 // Finalize the clauses that need pre-built expressions for CodeGen. 6982 for (OMPClause *C : Clauses) { 6983 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6984 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6985 B.NumIterations, *this, CurScope, 6986 DSAStack)) 6987 return StmtError(); 6988 } 6989 } 6990 6991 setFunctionHasBranchProtectedScope(); 6992 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6993 NestedLoopCount, Clauses, AStmt, B, 6994 DSAStack->isCancelRegion()); 6995 } 6996 6997 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6998 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6999 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7000 if (!AStmt) 7001 return StmtError(); 7002 7003 auto *CS = cast<CapturedStmt>(AStmt); 7004 // 1.2.2 OpenMP Language Terminology 7005 // Structured block - An executable statement with a single entry at the 7006 // top and a single exit at the bottom. 7007 // The point of exit cannot be a branch out of the structured block. 7008 // longjmp() and throw() must not violate the entry/exit criteria. 7009 CS->getCapturedDecl()->setNothrow(); 7010 7011 OMPLoopDirective::HelperExprs B; 7012 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7013 // define the nested loops number. 7014 unsigned NestedLoopCount = 7015 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7016 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7017 VarsWithImplicitDSA, B); 7018 if (NestedLoopCount == 0) 7019 return StmtError(); 7020 7021 if (!CurContext->isDependentContext()) { 7022 // Finalize the clauses that need pre-built expressions for CodeGen. 7023 for (OMPClause *C : Clauses) { 7024 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7025 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7026 B.NumIterations, *this, CurScope, 7027 DSAStack)) 7028 return StmtError(); 7029 } 7030 } 7031 7032 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7033 return StmtError(); 7034 7035 setFunctionHasBranchProtectedScope(); 7036 return OMPParallelForSimdDirective::Create( 7037 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7038 } 7039 7040 StmtResult 7041 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7042 Stmt *AStmt, SourceLocation StartLoc, 7043 SourceLocation EndLoc) { 7044 if (!AStmt) 7045 return StmtError(); 7046 7047 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7048 auto BaseStmt = AStmt; 7049 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7050 BaseStmt = CS->getCapturedStmt(); 7051 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7052 auto S = C->children(); 7053 if (S.begin() == S.end()) 7054 return StmtError(); 7055 // All associated statements must be '#pragma omp section' except for 7056 // the first one. 7057 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7058 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7059 if (SectionStmt) 7060 Diag(SectionStmt->getBeginLoc(), 7061 diag::err_omp_parallel_sections_substmt_not_section); 7062 return StmtError(); 7063 } 7064 cast<OMPSectionDirective>(SectionStmt) 7065 ->setHasCancel(DSAStack->isCancelRegion()); 7066 } 7067 } else { 7068 Diag(AStmt->getBeginLoc(), 7069 diag::err_omp_parallel_sections_not_compound_stmt); 7070 return StmtError(); 7071 } 7072 7073 setFunctionHasBranchProtectedScope(); 7074 7075 return OMPParallelSectionsDirective::Create( 7076 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7077 } 7078 7079 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7080 Stmt *AStmt, SourceLocation StartLoc, 7081 SourceLocation EndLoc) { 7082 if (!AStmt) 7083 return StmtError(); 7084 7085 auto *CS = cast<CapturedStmt>(AStmt); 7086 // 1.2.2 OpenMP Language Terminology 7087 // Structured block - An executable statement with a single entry at the 7088 // top and a single exit at the bottom. 7089 // The point of exit cannot be a branch out of the structured block. 7090 // longjmp() and throw() must not violate the entry/exit criteria. 7091 CS->getCapturedDecl()->setNothrow(); 7092 7093 setFunctionHasBranchProtectedScope(); 7094 7095 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7096 DSAStack->isCancelRegion()); 7097 } 7098 7099 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7100 SourceLocation EndLoc) { 7101 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7102 } 7103 7104 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7105 SourceLocation EndLoc) { 7106 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7107 } 7108 7109 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7110 SourceLocation EndLoc) { 7111 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7112 } 7113 7114 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 7115 Stmt *AStmt, 7116 SourceLocation StartLoc, 7117 SourceLocation EndLoc) { 7118 if (!AStmt) 7119 return StmtError(); 7120 7121 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7122 7123 setFunctionHasBranchProtectedScope(); 7124 7125 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 7126 AStmt, 7127 DSAStack->getTaskgroupReductionRef()); 7128 } 7129 7130 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 7131 SourceLocation StartLoc, 7132 SourceLocation EndLoc) { 7133 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 7134 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 7135 } 7136 7137 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 7138 Stmt *AStmt, 7139 SourceLocation StartLoc, 7140 SourceLocation EndLoc) { 7141 const OMPClause *DependFound = nullptr; 7142 const OMPClause *DependSourceClause = nullptr; 7143 const OMPClause *DependSinkClause = nullptr; 7144 bool ErrorFound = false; 7145 const OMPThreadsClause *TC = nullptr; 7146 const OMPSIMDClause *SC = nullptr; 7147 for (const OMPClause *C : Clauses) { 7148 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 7149 DependFound = C; 7150 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 7151 if (DependSourceClause) { 7152 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 7153 << getOpenMPDirectiveName(OMPD_ordered) 7154 << getOpenMPClauseName(OMPC_depend) << 2; 7155 ErrorFound = true; 7156 } else { 7157 DependSourceClause = C; 7158 } 7159 if (DependSinkClause) { 7160 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7161 << 0; 7162 ErrorFound = true; 7163 } 7164 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 7165 if (DependSourceClause) { 7166 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 7167 << 1; 7168 ErrorFound = true; 7169 } 7170 DependSinkClause = C; 7171 } 7172 } else if (C->getClauseKind() == OMPC_threads) { 7173 TC = cast<OMPThreadsClause>(C); 7174 } else if (C->getClauseKind() == OMPC_simd) { 7175 SC = cast<OMPSIMDClause>(C); 7176 } 7177 } 7178 if (!ErrorFound && !SC && 7179 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 7180 // OpenMP [2.8.1,simd Construct, Restrictions] 7181 // An ordered construct with the simd clause is the only OpenMP construct 7182 // that can appear in the simd region. 7183 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 7184 ErrorFound = true; 7185 } else if (DependFound && (TC || SC)) { 7186 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 7187 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 7188 ErrorFound = true; 7189 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 7190 Diag(DependFound->getBeginLoc(), 7191 diag::err_omp_ordered_directive_without_param); 7192 ErrorFound = true; 7193 } else if (TC || Clauses.empty()) { 7194 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 7195 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 7196 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 7197 << (TC != nullptr); 7198 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 7199 ErrorFound = true; 7200 } 7201 } 7202 if ((!AStmt && !DependFound) || ErrorFound) 7203 return StmtError(); 7204 7205 if (AStmt) { 7206 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7207 7208 setFunctionHasBranchProtectedScope(); 7209 } 7210 7211 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7212 } 7213 7214 namespace { 7215 /// Helper class for checking expression in 'omp atomic [update]' 7216 /// construct. 7217 class OpenMPAtomicUpdateChecker { 7218 /// Error results for atomic update expressions. 7219 enum ExprAnalysisErrorCode { 7220 /// A statement is not an expression statement. 7221 NotAnExpression, 7222 /// Expression is not builtin binary or unary operation. 7223 NotABinaryOrUnaryExpression, 7224 /// Unary operation is not post-/pre- increment/decrement operation. 7225 NotAnUnaryIncDecExpression, 7226 /// An expression is not of scalar type. 7227 NotAScalarType, 7228 /// A binary operation is not an assignment operation. 7229 NotAnAssignmentOp, 7230 /// RHS part of the binary operation is not a binary expression. 7231 NotABinaryExpression, 7232 /// RHS part is not additive/multiplicative/shift/biwise binary 7233 /// expression. 7234 NotABinaryOperator, 7235 /// RHS binary operation does not have reference to the updated LHS 7236 /// part. 7237 NotAnUpdateExpression, 7238 /// No errors is found. 7239 NoError 7240 }; 7241 /// Reference to Sema. 7242 Sema &SemaRef; 7243 /// A location for note diagnostics (when error is found). 7244 SourceLocation NoteLoc; 7245 /// 'x' lvalue part of the source atomic expression. 7246 Expr *X; 7247 /// 'expr' rvalue part of the source atomic expression. 7248 Expr *E; 7249 /// Helper expression of the form 7250 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7251 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7252 Expr *UpdateExpr; 7253 /// Is 'x' a LHS in a RHS part of full update expression. It is 7254 /// important for non-associative operations. 7255 bool IsXLHSInRHSPart; 7256 BinaryOperatorKind Op; 7257 SourceLocation OpLoc; 7258 /// true if the source expression is a postfix unary operation, false 7259 /// if it is a prefix unary operation. 7260 bool IsPostfixUpdate; 7261 7262 public: 7263 OpenMPAtomicUpdateChecker(Sema &SemaRef) 7264 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 7265 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 7266 /// Check specified statement that it is suitable for 'atomic update' 7267 /// constructs and extract 'x', 'expr' and Operation from the original 7268 /// expression. If DiagId and NoteId == 0, then only check is performed 7269 /// without error notification. 7270 /// \param DiagId Diagnostic which should be emitted if error is found. 7271 /// \param NoteId Diagnostic note for the main error message. 7272 /// \return true if statement is not an update expression, false otherwise. 7273 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 7274 /// Return the 'x' lvalue part of the source atomic expression. 7275 Expr *getX() const { return X; } 7276 /// Return the 'expr' rvalue part of the source atomic expression. 7277 Expr *getExpr() const { return E; } 7278 /// Return the update expression used in calculation of the updated 7279 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 7280 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 7281 Expr *getUpdateExpr() const { return UpdateExpr; } 7282 /// Return true if 'x' is LHS in RHS part of full update expression, 7283 /// false otherwise. 7284 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 7285 7286 /// true if the source expression is a postfix unary operation, false 7287 /// if it is a prefix unary operation. 7288 bool isPostfixUpdate() const { return IsPostfixUpdate; } 7289 7290 private: 7291 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 7292 unsigned NoteId = 0); 7293 }; 7294 } // namespace 7295 7296 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 7297 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 7298 ExprAnalysisErrorCode ErrorFound = NoError; 7299 SourceLocation ErrorLoc, NoteLoc; 7300 SourceRange ErrorRange, NoteRange; 7301 // Allowed constructs are: 7302 // x = x binop expr; 7303 // x = expr binop x; 7304 if (AtomicBinOp->getOpcode() == BO_Assign) { 7305 X = AtomicBinOp->getLHS(); 7306 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 7307 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 7308 if (AtomicInnerBinOp->isMultiplicativeOp() || 7309 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 7310 AtomicInnerBinOp->isBitwiseOp()) { 7311 Op = AtomicInnerBinOp->getOpcode(); 7312 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 7313 Expr *LHS = AtomicInnerBinOp->getLHS(); 7314 Expr *RHS = AtomicInnerBinOp->getRHS(); 7315 llvm::FoldingSetNodeID XId, LHSId, RHSId; 7316 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 7317 /*Canonical=*/true); 7318 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 7319 /*Canonical=*/true); 7320 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 7321 /*Canonical=*/true); 7322 if (XId == LHSId) { 7323 E = RHS; 7324 IsXLHSInRHSPart = true; 7325 } else if (XId == RHSId) { 7326 E = LHS; 7327 IsXLHSInRHSPart = false; 7328 } else { 7329 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7330 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7331 NoteLoc = X->getExprLoc(); 7332 NoteRange = X->getSourceRange(); 7333 ErrorFound = NotAnUpdateExpression; 7334 } 7335 } else { 7336 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 7337 ErrorRange = AtomicInnerBinOp->getSourceRange(); 7338 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 7339 NoteRange = SourceRange(NoteLoc, NoteLoc); 7340 ErrorFound = NotABinaryOperator; 7341 } 7342 } else { 7343 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 7344 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 7345 ErrorFound = NotABinaryExpression; 7346 } 7347 } else { 7348 ErrorLoc = AtomicBinOp->getExprLoc(); 7349 ErrorRange = AtomicBinOp->getSourceRange(); 7350 NoteLoc = AtomicBinOp->getOperatorLoc(); 7351 NoteRange = SourceRange(NoteLoc, NoteLoc); 7352 ErrorFound = NotAnAssignmentOp; 7353 } 7354 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7355 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7356 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7357 return true; 7358 } 7359 if (SemaRef.CurContext->isDependentContext()) 7360 E = X = UpdateExpr = nullptr; 7361 return ErrorFound != NoError; 7362 } 7363 7364 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 7365 unsigned NoteId) { 7366 ExprAnalysisErrorCode ErrorFound = NoError; 7367 SourceLocation ErrorLoc, NoteLoc; 7368 SourceRange ErrorRange, NoteRange; 7369 // Allowed constructs are: 7370 // x++; 7371 // x--; 7372 // ++x; 7373 // --x; 7374 // x binop= expr; 7375 // x = x binop expr; 7376 // x = expr binop x; 7377 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 7378 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 7379 if (AtomicBody->getType()->isScalarType() || 7380 AtomicBody->isInstantiationDependent()) { 7381 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 7382 AtomicBody->IgnoreParenImpCasts())) { 7383 // Check for Compound Assignment Operation 7384 Op = BinaryOperator::getOpForCompoundAssignment( 7385 AtomicCompAssignOp->getOpcode()); 7386 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 7387 E = AtomicCompAssignOp->getRHS(); 7388 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 7389 IsXLHSInRHSPart = true; 7390 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 7391 AtomicBody->IgnoreParenImpCasts())) { 7392 // Check for Binary Operation 7393 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 7394 return true; 7395 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 7396 AtomicBody->IgnoreParenImpCasts())) { 7397 // Check for Unary Operation 7398 if (AtomicUnaryOp->isIncrementDecrementOp()) { 7399 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 7400 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 7401 OpLoc = AtomicUnaryOp->getOperatorLoc(); 7402 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 7403 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 7404 IsXLHSInRHSPart = true; 7405 } else { 7406 ErrorFound = NotAnUnaryIncDecExpression; 7407 ErrorLoc = AtomicUnaryOp->getExprLoc(); 7408 ErrorRange = AtomicUnaryOp->getSourceRange(); 7409 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 7410 NoteRange = SourceRange(NoteLoc, NoteLoc); 7411 } 7412 } else if (!AtomicBody->isInstantiationDependent()) { 7413 ErrorFound = NotABinaryOrUnaryExpression; 7414 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 7415 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 7416 } 7417 } else { 7418 ErrorFound = NotAScalarType; 7419 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 7420 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7421 } 7422 } else { 7423 ErrorFound = NotAnExpression; 7424 NoteLoc = ErrorLoc = S->getBeginLoc(); 7425 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7426 } 7427 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 7428 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 7429 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 7430 return true; 7431 } 7432 if (SemaRef.CurContext->isDependentContext()) 7433 E = X = UpdateExpr = nullptr; 7434 if (ErrorFound == NoError && E && X) { 7435 // Build an update expression of form 'OpaqueValueExpr(x) binop 7436 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 7437 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 7438 auto *OVEX = new (SemaRef.getASTContext()) 7439 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 7440 auto *OVEExpr = new (SemaRef.getASTContext()) 7441 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 7442 ExprResult Update = 7443 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 7444 IsXLHSInRHSPart ? OVEExpr : OVEX); 7445 if (Update.isInvalid()) 7446 return true; 7447 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 7448 Sema::AA_Casting); 7449 if (Update.isInvalid()) 7450 return true; 7451 UpdateExpr = Update.get(); 7452 } 7453 return ErrorFound != NoError; 7454 } 7455 7456 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 7457 Stmt *AStmt, 7458 SourceLocation StartLoc, 7459 SourceLocation EndLoc) { 7460 if (!AStmt) 7461 return StmtError(); 7462 7463 auto *CS = cast<CapturedStmt>(AStmt); 7464 // 1.2.2 OpenMP Language Terminology 7465 // Structured block - An executable statement with a single entry at the 7466 // top and a single exit at the bottom. 7467 // The point of exit cannot be a branch out of the structured block. 7468 // longjmp() and throw() must not violate the entry/exit criteria. 7469 OpenMPClauseKind AtomicKind = OMPC_unknown; 7470 SourceLocation AtomicKindLoc; 7471 for (const OMPClause *C : Clauses) { 7472 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 7473 C->getClauseKind() == OMPC_update || 7474 C->getClauseKind() == OMPC_capture) { 7475 if (AtomicKind != OMPC_unknown) { 7476 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 7477 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 7478 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 7479 << getOpenMPClauseName(AtomicKind); 7480 } else { 7481 AtomicKind = C->getClauseKind(); 7482 AtomicKindLoc = C->getBeginLoc(); 7483 } 7484 } 7485 } 7486 7487 Stmt *Body = CS->getCapturedStmt(); 7488 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 7489 Body = EWC->getSubExpr(); 7490 7491 Expr *X = nullptr; 7492 Expr *V = nullptr; 7493 Expr *E = nullptr; 7494 Expr *UE = nullptr; 7495 bool IsXLHSInRHSPart = false; 7496 bool IsPostfixUpdate = false; 7497 // OpenMP [2.12.6, atomic Construct] 7498 // In the next expressions: 7499 // * x and v (as applicable) are both l-value expressions with scalar type. 7500 // * During the execution of an atomic region, multiple syntactic 7501 // occurrences of x must designate the same storage location. 7502 // * Neither of v and expr (as applicable) may access the storage location 7503 // designated by x. 7504 // * Neither of x and expr (as applicable) may access the storage location 7505 // designated by v. 7506 // * expr is an expression with scalar type. 7507 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 7508 // * binop, binop=, ++, and -- are not overloaded operators. 7509 // * The expression x binop expr must be numerically equivalent to x binop 7510 // (expr). This requirement is satisfied if the operators in expr have 7511 // precedence greater than binop, or by using parentheses around expr or 7512 // subexpressions of expr. 7513 // * The expression expr binop x must be numerically equivalent to (expr) 7514 // binop x. This requirement is satisfied if the operators in expr have 7515 // precedence equal to or greater than binop, or by using parentheses around 7516 // expr or subexpressions of expr. 7517 // * For forms that allow multiple occurrences of x, the number of times 7518 // that x is evaluated is unspecified. 7519 if (AtomicKind == OMPC_read) { 7520 enum { 7521 NotAnExpression, 7522 NotAnAssignmentOp, 7523 NotAScalarType, 7524 NotAnLValue, 7525 NoError 7526 } ErrorFound = NoError; 7527 SourceLocation ErrorLoc, NoteLoc; 7528 SourceRange ErrorRange, NoteRange; 7529 // If clause is read: 7530 // v = x; 7531 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7532 const auto *AtomicBinOp = 7533 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7534 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7535 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7536 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 7537 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7538 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 7539 if (!X->isLValue() || !V->isLValue()) { 7540 const Expr *NotLValueExpr = X->isLValue() ? V : X; 7541 ErrorFound = NotAnLValue; 7542 ErrorLoc = AtomicBinOp->getExprLoc(); 7543 ErrorRange = AtomicBinOp->getSourceRange(); 7544 NoteLoc = NotLValueExpr->getExprLoc(); 7545 NoteRange = NotLValueExpr->getSourceRange(); 7546 } 7547 } else if (!X->isInstantiationDependent() || 7548 !V->isInstantiationDependent()) { 7549 const Expr *NotScalarExpr = 7550 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7551 ? V 7552 : X; 7553 ErrorFound = NotAScalarType; 7554 ErrorLoc = AtomicBinOp->getExprLoc(); 7555 ErrorRange = AtomicBinOp->getSourceRange(); 7556 NoteLoc = NotScalarExpr->getExprLoc(); 7557 NoteRange = NotScalarExpr->getSourceRange(); 7558 } 7559 } else if (!AtomicBody->isInstantiationDependent()) { 7560 ErrorFound = NotAnAssignmentOp; 7561 ErrorLoc = AtomicBody->getExprLoc(); 7562 ErrorRange = AtomicBody->getSourceRange(); 7563 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7564 : AtomicBody->getExprLoc(); 7565 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7566 : AtomicBody->getSourceRange(); 7567 } 7568 } else { 7569 ErrorFound = NotAnExpression; 7570 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7571 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7572 } 7573 if (ErrorFound != NoError) { 7574 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7575 << ErrorRange; 7576 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7577 << NoteRange; 7578 return StmtError(); 7579 } 7580 if (CurContext->isDependentContext()) 7581 V = X = nullptr; 7582 } else if (AtomicKind == OMPC_write) { 7583 enum { 7584 NotAnExpression, 7585 NotAnAssignmentOp, 7586 NotAScalarType, 7587 NotAnLValue, 7588 NoError 7589 } ErrorFound = NoError; 7590 SourceLocation ErrorLoc, NoteLoc; 7591 SourceRange ErrorRange, NoteRange; 7592 // If clause is write: 7593 // x = expr; 7594 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7595 const auto *AtomicBinOp = 7596 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7597 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7598 X = AtomicBinOp->getLHS(); 7599 E = AtomicBinOp->getRHS(); 7600 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7601 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 7602 if (!X->isLValue()) { 7603 ErrorFound = NotAnLValue; 7604 ErrorLoc = AtomicBinOp->getExprLoc(); 7605 ErrorRange = AtomicBinOp->getSourceRange(); 7606 NoteLoc = X->getExprLoc(); 7607 NoteRange = X->getSourceRange(); 7608 } 7609 } else if (!X->isInstantiationDependent() || 7610 !E->isInstantiationDependent()) { 7611 const Expr *NotScalarExpr = 7612 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7613 ? E 7614 : X; 7615 ErrorFound = NotAScalarType; 7616 ErrorLoc = AtomicBinOp->getExprLoc(); 7617 ErrorRange = AtomicBinOp->getSourceRange(); 7618 NoteLoc = NotScalarExpr->getExprLoc(); 7619 NoteRange = NotScalarExpr->getSourceRange(); 7620 } 7621 } else if (!AtomicBody->isInstantiationDependent()) { 7622 ErrorFound = NotAnAssignmentOp; 7623 ErrorLoc = AtomicBody->getExprLoc(); 7624 ErrorRange = AtomicBody->getSourceRange(); 7625 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7626 : AtomicBody->getExprLoc(); 7627 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7628 : AtomicBody->getSourceRange(); 7629 } 7630 } else { 7631 ErrorFound = NotAnExpression; 7632 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7633 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7634 } 7635 if (ErrorFound != NoError) { 7636 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 7637 << ErrorRange; 7638 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7639 << NoteRange; 7640 return StmtError(); 7641 } 7642 if (CurContext->isDependentContext()) 7643 E = X = nullptr; 7644 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 7645 // If clause is update: 7646 // x++; 7647 // x--; 7648 // ++x; 7649 // --x; 7650 // x binop= expr; 7651 // x = x binop expr; 7652 // x = expr binop x; 7653 OpenMPAtomicUpdateChecker Checker(*this); 7654 if (Checker.checkStatement( 7655 Body, (AtomicKind == OMPC_update) 7656 ? diag::err_omp_atomic_update_not_expression_statement 7657 : diag::err_omp_atomic_not_expression_statement, 7658 diag::note_omp_atomic_update)) 7659 return StmtError(); 7660 if (!CurContext->isDependentContext()) { 7661 E = Checker.getExpr(); 7662 X = Checker.getX(); 7663 UE = Checker.getUpdateExpr(); 7664 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7665 } 7666 } else if (AtomicKind == OMPC_capture) { 7667 enum { 7668 NotAnAssignmentOp, 7669 NotACompoundStatement, 7670 NotTwoSubstatements, 7671 NotASpecificExpression, 7672 NoError 7673 } ErrorFound = NoError; 7674 SourceLocation ErrorLoc, NoteLoc; 7675 SourceRange ErrorRange, NoteRange; 7676 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7677 // If clause is a capture: 7678 // v = x++; 7679 // v = x--; 7680 // v = ++x; 7681 // v = --x; 7682 // v = x binop= expr; 7683 // v = x = x binop expr; 7684 // v = x = expr binop x; 7685 const auto *AtomicBinOp = 7686 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7687 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7688 V = AtomicBinOp->getLHS(); 7689 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7690 OpenMPAtomicUpdateChecker Checker(*this); 7691 if (Checker.checkStatement( 7692 Body, diag::err_omp_atomic_capture_not_expression_statement, 7693 diag::note_omp_atomic_update)) 7694 return StmtError(); 7695 E = Checker.getExpr(); 7696 X = Checker.getX(); 7697 UE = Checker.getUpdateExpr(); 7698 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7699 IsPostfixUpdate = Checker.isPostfixUpdate(); 7700 } else if (!AtomicBody->isInstantiationDependent()) { 7701 ErrorLoc = AtomicBody->getExprLoc(); 7702 ErrorRange = AtomicBody->getSourceRange(); 7703 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7704 : AtomicBody->getExprLoc(); 7705 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7706 : AtomicBody->getSourceRange(); 7707 ErrorFound = NotAnAssignmentOp; 7708 } 7709 if (ErrorFound != NoError) { 7710 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7711 << ErrorRange; 7712 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7713 return StmtError(); 7714 } 7715 if (CurContext->isDependentContext()) 7716 UE = V = E = X = nullptr; 7717 } else { 7718 // If clause is a capture: 7719 // { v = x; x = expr; } 7720 // { v = x; x++; } 7721 // { v = x; x--; } 7722 // { v = x; ++x; } 7723 // { v = x; --x; } 7724 // { v = x; x binop= expr; } 7725 // { v = x; x = x binop expr; } 7726 // { v = x; x = expr binop x; } 7727 // { x++; v = x; } 7728 // { x--; v = x; } 7729 // { ++x; v = x; } 7730 // { --x; v = x; } 7731 // { x binop= expr; v = x; } 7732 // { x = x binop expr; v = x; } 7733 // { x = expr binop x; v = x; } 7734 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7735 // Check that this is { expr1; expr2; } 7736 if (CS->size() == 2) { 7737 Stmt *First = CS->body_front(); 7738 Stmt *Second = CS->body_back(); 7739 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7740 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7741 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7742 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7743 // Need to find what subexpression is 'v' and what is 'x'. 7744 OpenMPAtomicUpdateChecker Checker(*this); 7745 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7746 BinaryOperator *BinOp = nullptr; 7747 if (IsUpdateExprFound) { 7748 BinOp = dyn_cast<BinaryOperator>(First); 7749 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7750 } 7751 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7752 // { v = x; x++; } 7753 // { v = x; x--; } 7754 // { v = x; ++x; } 7755 // { v = x; --x; } 7756 // { v = x; x binop= expr; } 7757 // { v = x; x = x binop expr; } 7758 // { v = x; x = expr binop x; } 7759 // Check that the first expression has form v = x. 7760 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7761 llvm::FoldingSetNodeID XId, PossibleXId; 7762 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7763 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7764 IsUpdateExprFound = XId == PossibleXId; 7765 if (IsUpdateExprFound) { 7766 V = BinOp->getLHS(); 7767 X = Checker.getX(); 7768 E = Checker.getExpr(); 7769 UE = Checker.getUpdateExpr(); 7770 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7771 IsPostfixUpdate = true; 7772 } 7773 } 7774 if (!IsUpdateExprFound) { 7775 IsUpdateExprFound = !Checker.checkStatement(First); 7776 BinOp = nullptr; 7777 if (IsUpdateExprFound) { 7778 BinOp = dyn_cast<BinaryOperator>(Second); 7779 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7780 } 7781 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7782 // { x++; v = x; } 7783 // { x--; v = x; } 7784 // { ++x; v = x; } 7785 // { --x; v = x; } 7786 // { x binop= expr; v = x; } 7787 // { x = x binop expr; v = x; } 7788 // { x = expr binop x; v = x; } 7789 // Check that the second expression has form v = x. 7790 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7791 llvm::FoldingSetNodeID XId, PossibleXId; 7792 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7793 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7794 IsUpdateExprFound = XId == PossibleXId; 7795 if (IsUpdateExprFound) { 7796 V = BinOp->getLHS(); 7797 X = Checker.getX(); 7798 E = Checker.getExpr(); 7799 UE = Checker.getUpdateExpr(); 7800 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7801 IsPostfixUpdate = false; 7802 } 7803 } 7804 } 7805 if (!IsUpdateExprFound) { 7806 // { v = x; x = expr; } 7807 auto *FirstExpr = dyn_cast<Expr>(First); 7808 auto *SecondExpr = dyn_cast<Expr>(Second); 7809 if (!FirstExpr || !SecondExpr || 7810 !(FirstExpr->isInstantiationDependent() || 7811 SecondExpr->isInstantiationDependent())) { 7812 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7813 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7814 ErrorFound = NotAnAssignmentOp; 7815 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7816 : First->getBeginLoc(); 7817 NoteRange = ErrorRange = FirstBinOp 7818 ? FirstBinOp->getSourceRange() 7819 : SourceRange(ErrorLoc, ErrorLoc); 7820 } else { 7821 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7822 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7823 ErrorFound = NotAnAssignmentOp; 7824 NoteLoc = ErrorLoc = SecondBinOp 7825 ? SecondBinOp->getOperatorLoc() 7826 : Second->getBeginLoc(); 7827 NoteRange = ErrorRange = 7828 SecondBinOp ? SecondBinOp->getSourceRange() 7829 : SourceRange(ErrorLoc, ErrorLoc); 7830 } else { 7831 Expr *PossibleXRHSInFirst = 7832 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7833 Expr *PossibleXLHSInSecond = 7834 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7835 llvm::FoldingSetNodeID X1Id, X2Id; 7836 PossibleXRHSInFirst->Profile(X1Id, Context, 7837 /*Canonical=*/true); 7838 PossibleXLHSInSecond->Profile(X2Id, Context, 7839 /*Canonical=*/true); 7840 IsUpdateExprFound = X1Id == X2Id; 7841 if (IsUpdateExprFound) { 7842 V = FirstBinOp->getLHS(); 7843 X = SecondBinOp->getLHS(); 7844 E = SecondBinOp->getRHS(); 7845 UE = nullptr; 7846 IsXLHSInRHSPart = false; 7847 IsPostfixUpdate = true; 7848 } else { 7849 ErrorFound = NotASpecificExpression; 7850 ErrorLoc = FirstBinOp->getExprLoc(); 7851 ErrorRange = FirstBinOp->getSourceRange(); 7852 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7853 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7854 } 7855 } 7856 } 7857 } 7858 } 7859 } else { 7860 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7861 NoteRange = ErrorRange = 7862 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7863 ErrorFound = NotTwoSubstatements; 7864 } 7865 } else { 7866 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7867 NoteRange = ErrorRange = 7868 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7869 ErrorFound = NotACompoundStatement; 7870 } 7871 if (ErrorFound != NoError) { 7872 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7873 << ErrorRange; 7874 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7875 return StmtError(); 7876 } 7877 if (CurContext->isDependentContext()) 7878 UE = V = E = X = nullptr; 7879 } 7880 } 7881 7882 setFunctionHasBranchProtectedScope(); 7883 7884 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7885 X, V, E, UE, IsXLHSInRHSPart, 7886 IsPostfixUpdate); 7887 } 7888 7889 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7890 Stmt *AStmt, 7891 SourceLocation StartLoc, 7892 SourceLocation EndLoc) { 7893 if (!AStmt) 7894 return StmtError(); 7895 7896 auto *CS = cast<CapturedStmt>(AStmt); 7897 // 1.2.2 OpenMP Language Terminology 7898 // Structured block - An executable statement with a single entry at the 7899 // top and a single exit at the bottom. 7900 // The point of exit cannot be a branch out of the structured block. 7901 // longjmp() and throw() must not violate the entry/exit criteria. 7902 CS->getCapturedDecl()->setNothrow(); 7903 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7904 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7905 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7906 // 1.2.2 OpenMP Language Terminology 7907 // Structured block - An executable statement with a single entry at the 7908 // top and a single exit at the bottom. 7909 // The point of exit cannot be a branch out of the structured block. 7910 // longjmp() and throw() must not violate the entry/exit criteria. 7911 CS->getCapturedDecl()->setNothrow(); 7912 } 7913 7914 // OpenMP [2.16, Nesting of Regions] 7915 // If specified, a teams construct must be contained within a target 7916 // construct. That target construct must contain no statements or directives 7917 // outside of the teams construct. 7918 if (DSAStack->hasInnerTeamsRegion()) { 7919 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7920 bool OMPTeamsFound = true; 7921 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7922 auto I = CS->body_begin(); 7923 while (I != CS->body_end()) { 7924 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7925 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7926 OMPTeamsFound) { 7927 7928 OMPTeamsFound = false; 7929 break; 7930 } 7931 ++I; 7932 } 7933 assert(I != CS->body_end() && "Not found statement"); 7934 S = *I; 7935 } else { 7936 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7937 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7938 } 7939 if (!OMPTeamsFound) { 7940 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7941 Diag(DSAStack->getInnerTeamsRegionLoc(), 7942 diag::note_omp_nested_teams_construct_here); 7943 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7944 << isa<OMPExecutableDirective>(S); 7945 return StmtError(); 7946 } 7947 } 7948 7949 setFunctionHasBranchProtectedScope(); 7950 7951 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7952 } 7953 7954 StmtResult 7955 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7956 Stmt *AStmt, SourceLocation StartLoc, 7957 SourceLocation EndLoc) { 7958 if (!AStmt) 7959 return StmtError(); 7960 7961 auto *CS = cast<CapturedStmt>(AStmt); 7962 // 1.2.2 OpenMP Language Terminology 7963 // Structured block - An executable statement with a single entry at the 7964 // top and a single exit at the bottom. 7965 // The point of exit cannot be a branch out of the structured block. 7966 // longjmp() and throw() must not violate the entry/exit criteria. 7967 CS->getCapturedDecl()->setNothrow(); 7968 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7969 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7970 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7971 // 1.2.2 OpenMP Language Terminology 7972 // Structured block - An executable statement with a single entry at the 7973 // top and a single exit at the bottom. 7974 // The point of exit cannot be a branch out of the structured block. 7975 // longjmp() and throw() must not violate the entry/exit criteria. 7976 CS->getCapturedDecl()->setNothrow(); 7977 } 7978 7979 setFunctionHasBranchProtectedScope(); 7980 7981 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7982 AStmt); 7983 } 7984 7985 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7986 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7987 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7988 if (!AStmt) 7989 return StmtError(); 7990 7991 auto *CS = cast<CapturedStmt>(AStmt); 7992 // 1.2.2 OpenMP Language Terminology 7993 // Structured block - An executable statement with a single entry at the 7994 // top and a single exit at the bottom. 7995 // The point of exit cannot be a branch out of the structured block. 7996 // longjmp() and throw() must not violate the entry/exit criteria. 7997 CS->getCapturedDecl()->setNothrow(); 7998 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7999 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8000 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8001 // 1.2.2 OpenMP Language Terminology 8002 // Structured block - An executable statement with a single entry at the 8003 // top and a single exit at the bottom. 8004 // The point of exit cannot be a branch out of the structured block. 8005 // longjmp() and throw() must not violate the entry/exit criteria. 8006 CS->getCapturedDecl()->setNothrow(); 8007 } 8008 8009 OMPLoopDirective::HelperExprs B; 8010 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8011 // define the nested loops number. 8012 unsigned NestedLoopCount = 8013 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8014 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8015 VarsWithImplicitDSA, B); 8016 if (NestedLoopCount == 0) 8017 return StmtError(); 8018 8019 assert((CurContext->isDependentContext() || B.builtAll()) && 8020 "omp target parallel for loop exprs were not built"); 8021 8022 if (!CurContext->isDependentContext()) { 8023 // Finalize the clauses that need pre-built expressions for CodeGen. 8024 for (OMPClause *C : Clauses) { 8025 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8026 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8027 B.NumIterations, *this, CurScope, 8028 DSAStack)) 8029 return StmtError(); 8030 } 8031 } 8032 8033 setFunctionHasBranchProtectedScope(); 8034 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8035 NestedLoopCount, Clauses, AStmt, 8036 B, DSAStack->isCancelRegion()); 8037 } 8038 8039 /// Check for existence of a map clause in the list of clauses. 8040 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8041 const OpenMPClauseKind K) { 8042 return llvm::any_of( 8043 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8044 } 8045 8046 template <typename... Params> 8047 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8048 const Params... ClauseTypes) { 8049 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8050 } 8051 8052 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8053 Stmt *AStmt, 8054 SourceLocation StartLoc, 8055 SourceLocation EndLoc) { 8056 if (!AStmt) 8057 return StmtError(); 8058 8059 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8060 8061 // OpenMP [2.10.1, Restrictions, p. 97] 8062 // At least one map clause must appear on the directive. 8063 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8064 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8065 << "'map' or 'use_device_ptr'" 8066 << getOpenMPDirectiveName(OMPD_target_data); 8067 return StmtError(); 8068 } 8069 8070 setFunctionHasBranchProtectedScope(); 8071 8072 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8073 AStmt); 8074 } 8075 8076 StmtResult 8077 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8078 SourceLocation StartLoc, 8079 SourceLocation EndLoc, Stmt *AStmt) { 8080 if (!AStmt) 8081 return StmtError(); 8082 8083 auto *CS = cast<CapturedStmt>(AStmt); 8084 // 1.2.2 OpenMP Language Terminology 8085 // Structured block - An executable statement with a single entry at the 8086 // top and a single exit at the bottom. 8087 // The point of exit cannot be a branch out of the structured block. 8088 // longjmp() and throw() must not violate the entry/exit criteria. 8089 CS->getCapturedDecl()->setNothrow(); 8090 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8091 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8092 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8093 // 1.2.2 OpenMP Language Terminology 8094 // Structured block - An executable statement with a single entry at the 8095 // top and a single exit at the bottom. 8096 // The point of exit cannot be a branch out of the structured block. 8097 // longjmp() and throw() must not violate the entry/exit criteria. 8098 CS->getCapturedDecl()->setNothrow(); 8099 } 8100 8101 // OpenMP [2.10.2, Restrictions, p. 99] 8102 // At least one map clause must appear on the directive. 8103 if (!hasClauses(Clauses, OMPC_map)) { 8104 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8105 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8106 return StmtError(); 8107 } 8108 8109 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8110 AStmt); 8111 } 8112 8113 StmtResult 8114 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 8115 SourceLocation StartLoc, 8116 SourceLocation EndLoc, Stmt *AStmt) { 8117 if (!AStmt) 8118 return StmtError(); 8119 8120 auto *CS = cast<CapturedStmt>(AStmt); 8121 // 1.2.2 OpenMP Language Terminology 8122 // Structured block - An executable statement with a single entry at the 8123 // top and a single exit at the bottom. 8124 // The point of exit cannot be a branch out of the structured block. 8125 // longjmp() and throw() must not violate the entry/exit criteria. 8126 CS->getCapturedDecl()->setNothrow(); 8127 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 8128 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8129 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8130 // 1.2.2 OpenMP Language Terminology 8131 // Structured block - An executable statement with a single entry at the 8132 // top and a single exit at the bottom. 8133 // The point of exit cannot be a branch out of the structured block. 8134 // longjmp() and throw() must not violate the entry/exit criteria. 8135 CS->getCapturedDecl()->setNothrow(); 8136 } 8137 8138 // OpenMP [2.10.3, Restrictions, p. 102] 8139 // At least one map clause must appear on the directive. 8140 if (!hasClauses(Clauses, OMPC_map)) { 8141 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8142 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 8143 return StmtError(); 8144 } 8145 8146 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8147 AStmt); 8148 } 8149 8150 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 8151 SourceLocation StartLoc, 8152 SourceLocation EndLoc, 8153 Stmt *AStmt) { 8154 if (!AStmt) 8155 return StmtError(); 8156 8157 auto *CS = cast<CapturedStmt>(AStmt); 8158 // 1.2.2 OpenMP Language Terminology 8159 // Structured block - An executable statement with a single entry at the 8160 // top and a single exit at the bottom. 8161 // The point of exit cannot be a branch out of the structured block. 8162 // longjmp() and throw() must not violate the entry/exit criteria. 8163 CS->getCapturedDecl()->setNothrow(); 8164 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 8165 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8166 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8167 // 1.2.2 OpenMP Language Terminology 8168 // Structured block - An executable statement with a single entry at the 8169 // top and a single exit at the bottom. 8170 // The point of exit cannot be a branch out of the structured block. 8171 // longjmp() and throw() must not violate the entry/exit criteria. 8172 CS->getCapturedDecl()->setNothrow(); 8173 } 8174 8175 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 8176 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 8177 return StmtError(); 8178 } 8179 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 8180 AStmt); 8181 } 8182 8183 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 8184 Stmt *AStmt, SourceLocation StartLoc, 8185 SourceLocation EndLoc) { 8186 if (!AStmt) 8187 return StmtError(); 8188 8189 auto *CS = cast<CapturedStmt>(AStmt); 8190 // 1.2.2 OpenMP Language Terminology 8191 // Structured block - An executable statement with a single entry at the 8192 // top and a single exit at the bottom. 8193 // The point of exit cannot be a branch out of the structured block. 8194 // longjmp() and throw() must not violate the entry/exit criteria. 8195 CS->getCapturedDecl()->setNothrow(); 8196 8197 setFunctionHasBranchProtectedScope(); 8198 8199 DSAStack->setParentTeamsRegionLoc(StartLoc); 8200 8201 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8202 } 8203 8204 StmtResult 8205 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 8206 SourceLocation EndLoc, 8207 OpenMPDirectiveKind CancelRegion) { 8208 if (DSAStack->isParentNowaitRegion()) { 8209 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 8210 return StmtError(); 8211 } 8212 if (DSAStack->isParentOrderedRegion()) { 8213 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 8214 return StmtError(); 8215 } 8216 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 8217 CancelRegion); 8218 } 8219 8220 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 8221 SourceLocation StartLoc, 8222 SourceLocation EndLoc, 8223 OpenMPDirectiveKind CancelRegion) { 8224 if (DSAStack->isParentNowaitRegion()) { 8225 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 8226 return StmtError(); 8227 } 8228 if (DSAStack->isParentOrderedRegion()) { 8229 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 8230 return StmtError(); 8231 } 8232 DSAStack->setParentCancelRegion(/*Cancel=*/true); 8233 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8234 CancelRegion); 8235 } 8236 8237 static bool checkGrainsizeNumTasksClauses(Sema &S, 8238 ArrayRef<OMPClause *> Clauses) { 8239 const OMPClause *PrevClause = nullptr; 8240 bool ErrorFound = false; 8241 for (const OMPClause *C : Clauses) { 8242 if (C->getClauseKind() == OMPC_grainsize || 8243 C->getClauseKind() == OMPC_num_tasks) { 8244 if (!PrevClause) 8245 PrevClause = C; 8246 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8247 S.Diag(C->getBeginLoc(), 8248 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 8249 << getOpenMPClauseName(C->getClauseKind()) 8250 << getOpenMPClauseName(PrevClause->getClauseKind()); 8251 S.Diag(PrevClause->getBeginLoc(), 8252 diag::note_omp_previous_grainsize_num_tasks) 8253 << getOpenMPClauseName(PrevClause->getClauseKind()); 8254 ErrorFound = true; 8255 } 8256 } 8257 } 8258 return ErrorFound; 8259 } 8260 8261 static bool checkReductionClauseWithNogroup(Sema &S, 8262 ArrayRef<OMPClause *> Clauses) { 8263 const OMPClause *ReductionClause = nullptr; 8264 const OMPClause *NogroupClause = nullptr; 8265 for (const OMPClause *C : Clauses) { 8266 if (C->getClauseKind() == OMPC_reduction) { 8267 ReductionClause = C; 8268 if (NogroupClause) 8269 break; 8270 continue; 8271 } 8272 if (C->getClauseKind() == OMPC_nogroup) { 8273 NogroupClause = C; 8274 if (ReductionClause) 8275 break; 8276 continue; 8277 } 8278 } 8279 if (ReductionClause && NogroupClause) { 8280 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 8281 << SourceRange(NogroupClause->getBeginLoc(), 8282 NogroupClause->getEndLoc()); 8283 return true; 8284 } 8285 return false; 8286 } 8287 8288 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 8289 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8290 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8291 if (!AStmt) 8292 return StmtError(); 8293 8294 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8295 OMPLoopDirective::HelperExprs B; 8296 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8297 // define the nested loops number. 8298 unsigned NestedLoopCount = 8299 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 8300 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8301 VarsWithImplicitDSA, B); 8302 if (NestedLoopCount == 0) 8303 return StmtError(); 8304 8305 assert((CurContext->isDependentContext() || B.builtAll()) && 8306 "omp for loop exprs were not built"); 8307 8308 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8309 // The grainsize clause and num_tasks clause are mutually exclusive and may 8310 // not appear on the same taskloop directive. 8311 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8312 return StmtError(); 8313 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8314 // If a reduction clause is present on the taskloop directive, the nogroup 8315 // clause must not be specified. 8316 if (checkReductionClauseWithNogroup(*this, Clauses)) 8317 return StmtError(); 8318 8319 setFunctionHasBranchProtectedScope(); 8320 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 8321 NestedLoopCount, Clauses, AStmt, B); 8322 } 8323 8324 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 8325 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8326 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8327 if (!AStmt) 8328 return StmtError(); 8329 8330 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8331 OMPLoopDirective::HelperExprs B; 8332 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8333 // define the nested loops number. 8334 unsigned NestedLoopCount = 8335 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 8336 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 8337 VarsWithImplicitDSA, B); 8338 if (NestedLoopCount == 0) 8339 return StmtError(); 8340 8341 assert((CurContext->isDependentContext() || B.builtAll()) && 8342 "omp for loop exprs were not built"); 8343 8344 if (!CurContext->isDependentContext()) { 8345 // Finalize the clauses that need pre-built expressions for CodeGen. 8346 for (OMPClause *C : Clauses) { 8347 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8348 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8349 B.NumIterations, *this, CurScope, 8350 DSAStack)) 8351 return StmtError(); 8352 } 8353 } 8354 8355 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8356 // The grainsize clause and num_tasks clause are mutually exclusive and may 8357 // not appear on the same taskloop directive. 8358 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 8359 return StmtError(); 8360 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 8361 // If a reduction clause is present on the taskloop directive, the nogroup 8362 // clause must not be specified. 8363 if (checkReductionClauseWithNogroup(*this, Clauses)) 8364 return StmtError(); 8365 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8366 return StmtError(); 8367 8368 setFunctionHasBranchProtectedScope(); 8369 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 8370 NestedLoopCount, Clauses, AStmt, B); 8371 } 8372 8373 StmtResult Sema::ActOnOpenMPDistributeDirective( 8374 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8375 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8376 if (!AStmt) 8377 return StmtError(); 8378 8379 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8380 OMPLoopDirective::HelperExprs B; 8381 // In presence of clause 'collapse' with number of loops, it will 8382 // define the nested loops number. 8383 unsigned NestedLoopCount = 8384 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 8385 nullptr /*ordered not a clause on distribute*/, AStmt, 8386 *this, *DSAStack, VarsWithImplicitDSA, B); 8387 if (NestedLoopCount == 0) 8388 return StmtError(); 8389 8390 assert((CurContext->isDependentContext() || B.builtAll()) && 8391 "omp for loop exprs were not built"); 8392 8393 setFunctionHasBranchProtectedScope(); 8394 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 8395 NestedLoopCount, Clauses, AStmt, B); 8396 } 8397 8398 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 8399 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8400 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8401 if (!AStmt) 8402 return StmtError(); 8403 8404 auto *CS = cast<CapturedStmt>(AStmt); 8405 // 1.2.2 OpenMP Language Terminology 8406 // Structured block - An executable statement with a single entry at the 8407 // top and a single exit at the bottom. 8408 // The point of exit cannot be a branch out of the structured block. 8409 // longjmp() and throw() must not violate the entry/exit criteria. 8410 CS->getCapturedDecl()->setNothrow(); 8411 for (int ThisCaptureLevel = 8412 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 8413 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8414 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8415 // 1.2.2 OpenMP Language Terminology 8416 // Structured block - An executable statement with a single entry at the 8417 // top and a single exit at the bottom. 8418 // The point of exit cannot be a branch out of the structured block. 8419 // longjmp() and throw() must not violate the entry/exit criteria. 8420 CS->getCapturedDecl()->setNothrow(); 8421 } 8422 8423 OMPLoopDirective::HelperExprs B; 8424 // In presence of clause 'collapse' with number of loops, it will 8425 // define the nested loops number. 8426 unsigned NestedLoopCount = checkOpenMPLoop( 8427 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8428 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8429 VarsWithImplicitDSA, B); 8430 if (NestedLoopCount == 0) 8431 return StmtError(); 8432 8433 assert((CurContext->isDependentContext() || B.builtAll()) && 8434 "omp for loop exprs were not built"); 8435 8436 setFunctionHasBranchProtectedScope(); 8437 return OMPDistributeParallelForDirective::Create( 8438 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8439 DSAStack->isCancelRegion()); 8440 } 8441 8442 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 8443 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8444 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8445 if (!AStmt) 8446 return StmtError(); 8447 8448 auto *CS = cast<CapturedStmt>(AStmt); 8449 // 1.2.2 OpenMP Language Terminology 8450 // Structured block - An executable statement with a single entry at the 8451 // top and a single exit at the bottom. 8452 // The point of exit cannot be a branch out of the structured block. 8453 // longjmp() and throw() must not violate the entry/exit criteria. 8454 CS->getCapturedDecl()->setNothrow(); 8455 for (int ThisCaptureLevel = 8456 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 8457 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8458 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8459 // 1.2.2 OpenMP Language Terminology 8460 // Structured block - An executable statement with a single entry at the 8461 // top and a single exit at the bottom. 8462 // The point of exit cannot be a branch out of the structured block. 8463 // longjmp() and throw() must not violate the entry/exit criteria. 8464 CS->getCapturedDecl()->setNothrow(); 8465 } 8466 8467 OMPLoopDirective::HelperExprs B; 8468 // In presence of clause 'collapse' with number of loops, it will 8469 // define the nested loops number. 8470 unsigned NestedLoopCount = checkOpenMPLoop( 8471 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8472 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8473 VarsWithImplicitDSA, B); 8474 if (NestedLoopCount == 0) 8475 return StmtError(); 8476 8477 assert((CurContext->isDependentContext() || B.builtAll()) && 8478 "omp for loop exprs were not built"); 8479 8480 if (!CurContext->isDependentContext()) { 8481 // Finalize the clauses that need pre-built expressions for CodeGen. 8482 for (OMPClause *C : Clauses) { 8483 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8484 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8485 B.NumIterations, *this, CurScope, 8486 DSAStack)) 8487 return StmtError(); 8488 } 8489 } 8490 8491 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8492 return StmtError(); 8493 8494 setFunctionHasBranchProtectedScope(); 8495 return OMPDistributeParallelForSimdDirective::Create( 8496 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8497 } 8498 8499 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 8500 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8501 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8502 if (!AStmt) 8503 return StmtError(); 8504 8505 auto *CS = cast<CapturedStmt>(AStmt); 8506 // 1.2.2 OpenMP Language Terminology 8507 // Structured block - An executable statement with a single entry at the 8508 // top and a single exit at the bottom. 8509 // The point of exit cannot be a branch out of the structured block. 8510 // longjmp() and throw() must not violate the entry/exit criteria. 8511 CS->getCapturedDecl()->setNothrow(); 8512 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 8513 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8514 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8515 // 1.2.2 OpenMP Language Terminology 8516 // Structured block - An executable statement with a single entry at the 8517 // top and a single exit at the bottom. 8518 // The point of exit cannot be a branch out of the structured block. 8519 // longjmp() and throw() must not violate the entry/exit criteria. 8520 CS->getCapturedDecl()->setNothrow(); 8521 } 8522 8523 OMPLoopDirective::HelperExprs B; 8524 // In presence of clause 'collapse' with number of loops, it will 8525 // define the nested loops number. 8526 unsigned NestedLoopCount = 8527 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 8528 nullptr /*ordered not a clause on distribute*/, CS, *this, 8529 *DSAStack, VarsWithImplicitDSA, B); 8530 if (NestedLoopCount == 0) 8531 return StmtError(); 8532 8533 assert((CurContext->isDependentContext() || B.builtAll()) && 8534 "omp for loop exprs were not built"); 8535 8536 if (!CurContext->isDependentContext()) { 8537 // Finalize the clauses that need pre-built expressions for CodeGen. 8538 for (OMPClause *C : Clauses) { 8539 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8540 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8541 B.NumIterations, *this, CurScope, 8542 DSAStack)) 8543 return StmtError(); 8544 } 8545 } 8546 8547 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8548 return StmtError(); 8549 8550 setFunctionHasBranchProtectedScope(); 8551 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 8552 NestedLoopCount, Clauses, AStmt, B); 8553 } 8554 8555 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 8556 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8557 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8558 if (!AStmt) 8559 return StmtError(); 8560 8561 auto *CS = cast<CapturedStmt>(AStmt); 8562 // 1.2.2 OpenMP Language Terminology 8563 // Structured block - An executable statement with a single entry at the 8564 // top and a single exit at the bottom. 8565 // The point of exit cannot be a branch out of the structured block. 8566 // longjmp() and throw() must not violate the entry/exit criteria. 8567 CS->getCapturedDecl()->setNothrow(); 8568 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8569 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8570 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8571 // 1.2.2 OpenMP Language Terminology 8572 // Structured block - An executable statement with a single entry at the 8573 // top and a single exit at the bottom. 8574 // The point of exit cannot be a branch out of the structured block. 8575 // longjmp() and throw() must not violate the entry/exit criteria. 8576 CS->getCapturedDecl()->setNothrow(); 8577 } 8578 8579 OMPLoopDirective::HelperExprs B; 8580 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8581 // define the nested loops number. 8582 unsigned NestedLoopCount = checkOpenMPLoop( 8583 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8584 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8585 VarsWithImplicitDSA, B); 8586 if (NestedLoopCount == 0) 8587 return StmtError(); 8588 8589 assert((CurContext->isDependentContext() || B.builtAll()) && 8590 "omp target parallel for simd loop exprs were not built"); 8591 8592 if (!CurContext->isDependentContext()) { 8593 // Finalize the clauses that need pre-built expressions for CodeGen. 8594 for (OMPClause *C : Clauses) { 8595 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8596 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8597 B.NumIterations, *this, CurScope, 8598 DSAStack)) 8599 return StmtError(); 8600 } 8601 } 8602 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8603 return StmtError(); 8604 8605 setFunctionHasBranchProtectedScope(); 8606 return OMPTargetParallelForSimdDirective::Create( 8607 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8608 } 8609 8610 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 8611 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8612 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8613 if (!AStmt) 8614 return StmtError(); 8615 8616 auto *CS = cast<CapturedStmt>(AStmt); 8617 // 1.2.2 OpenMP Language Terminology 8618 // Structured block - An executable statement with a single entry at the 8619 // top and a single exit at the bottom. 8620 // The point of exit cannot be a branch out of the structured block. 8621 // longjmp() and throw() must not violate the entry/exit criteria. 8622 CS->getCapturedDecl()->setNothrow(); 8623 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 8624 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8625 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8626 // 1.2.2 OpenMP Language Terminology 8627 // Structured block - An executable statement with a single entry at the 8628 // top and a single exit at the bottom. 8629 // The point of exit cannot be a branch out of the structured block. 8630 // longjmp() and throw() must not violate the entry/exit criteria. 8631 CS->getCapturedDecl()->setNothrow(); 8632 } 8633 8634 OMPLoopDirective::HelperExprs B; 8635 // In presence of clause 'collapse' with number of loops, it will define the 8636 // nested loops number. 8637 unsigned NestedLoopCount = 8638 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 8639 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8640 VarsWithImplicitDSA, B); 8641 if (NestedLoopCount == 0) 8642 return StmtError(); 8643 8644 assert((CurContext->isDependentContext() || B.builtAll()) && 8645 "omp target simd loop exprs were not built"); 8646 8647 if (!CurContext->isDependentContext()) { 8648 // Finalize the clauses that need pre-built expressions for CodeGen. 8649 for (OMPClause *C : Clauses) { 8650 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8651 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8652 B.NumIterations, *this, CurScope, 8653 DSAStack)) 8654 return StmtError(); 8655 } 8656 } 8657 8658 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8659 return StmtError(); 8660 8661 setFunctionHasBranchProtectedScope(); 8662 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 8663 NestedLoopCount, Clauses, AStmt, B); 8664 } 8665 8666 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 8667 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8668 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8669 if (!AStmt) 8670 return StmtError(); 8671 8672 auto *CS = cast<CapturedStmt>(AStmt); 8673 // 1.2.2 OpenMP Language Terminology 8674 // Structured block - An executable statement with a single entry at the 8675 // top and a single exit at the bottom. 8676 // The point of exit cannot be a branch out of the structured block. 8677 // longjmp() and throw() must not violate the entry/exit criteria. 8678 CS->getCapturedDecl()->setNothrow(); 8679 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 8680 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8681 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8682 // 1.2.2 OpenMP Language Terminology 8683 // Structured block - An executable statement with a single entry at the 8684 // top and a single exit at the bottom. 8685 // The point of exit cannot be a branch out of the structured block. 8686 // longjmp() and throw() must not violate the entry/exit criteria. 8687 CS->getCapturedDecl()->setNothrow(); 8688 } 8689 8690 OMPLoopDirective::HelperExprs B; 8691 // In presence of clause 'collapse' with number of loops, it will 8692 // define the nested loops number. 8693 unsigned NestedLoopCount = 8694 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 8695 nullptr /*ordered not a clause on distribute*/, CS, *this, 8696 *DSAStack, VarsWithImplicitDSA, B); 8697 if (NestedLoopCount == 0) 8698 return StmtError(); 8699 8700 assert((CurContext->isDependentContext() || B.builtAll()) && 8701 "omp teams distribute loop exprs were not built"); 8702 8703 setFunctionHasBranchProtectedScope(); 8704 8705 DSAStack->setParentTeamsRegionLoc(StartLoc); 8706 8707 return OMPTeamsDistributeDirective::Create( 8708 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8709 } 8710 8711 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 8712 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8713 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8714 if (!AStmt) 8715 return StmtError(); 8716 8717 auto *CS = cast<CapturedStmt>(AStmt); 8718 // 1.2.2 OpenMP Language Terminology 8719 // Structured block - An executable statement with a single entry at the 8720 // top and a single exit at the bottom. 8721 // The point of exit cannot be a branch out of the structured block. 8722 // longjmp() and throw() must not violate the entry/exit criteria. 8723 CS->getCapturedDecl()->setNothrow(); 8724 for (int ThisCaptureLevel = 8725 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8726 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8727 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8728 // 1.2.2 OpenMP Language Terminology 8729 // Structured block - An executable statement with a single entry at the 8730 // top and a single exit at the bottom. 8731 // The point of exit cannot be a branch out of the structured block. 8732 // longjmp() and throw() must not violate the entry/exit criteria. 8733 CS->getCapturedDecl()->setNothrow(); 8734 } 8735 8736 8737 OMPLoopDirective::HelperExprs B; 8738 // In presence of clause 'collapse' with number of loops, it will 8739 // define the nested loops number. 8740 unsigned NestedLoopCount = checkOpenMPLoop( 8741 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8742 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8743 VarsWithImplicitDSA, B); 8744 8745 if (NestedLoopCount == 0) 8746 return StmtError(); 8747 8748 assert((CurContext->isDependentContext() || B.builtAll()) && 8749 "omp teams distribute simd loop exprs were not built"); 8750 8751 if (!CurContext->isDependentContext()) { 8752 // Finalize the clauses that need pre-built expressions for CodeGen. 8753 for (OMPClause *C : Clauses) { 8754 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8755 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8756 B.NumIterations, *this, CurScope, 8757 DSAStack)) 8758 return StmtError(); 8759 } 8760 } 8761 8762 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8763 return StmtError(); 8764 8765 setFunctionHasBranchProtectedScope(); 8766 8767 DSAStack->setParentTeamsRegionLoc(StartLoc); 8768 8769 return OMPTeamsDistributeSimdDirective::Create( 8770 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8771 } 8772 8773 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8774 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8775 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8776 if (!AStmt) 8777 return StmtError(); 8778 8779 auto *CS = cast<CapturedStmt>(AStmt); 8780 // 1.2.2 OpenMP Language Terminology 8781 // Structured block - An executable statement with a single entry at the 8782 // top and a single exit at the bottom. 8783 // The point of exit cannot be a branch out of the structured block. 8784 // longjmp() and throw() must not violate the entry/exit criteria. 8785 CS->getCapturedDecl()->setNothrow(); 8786 8787 for (int ThisCaptureLevel = 8788 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8789 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8790 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8791 // 1.2.2 OpenMP Language Terminology 8792 // Structured block - An executable statement with a single entry at the 8793 // top and a single exit at the bottom. 8794 // The point of exit cannot be a branch out of the structured block. 8795 // longjmp() and throw() must not violate the entry/exit criteria. 8796 CS->getCapturedDecl()->setNothrow(); 8797 } 8798 8799 OMPLoopDirective::HelperExprs B; 8800 // In presence of clause 'collapse' with number of loops, it will 8801 // define the nested loops number. 8802 unsigned NestedLoopCount = checkOpenMPLoop( 8803 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8804 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8805 VarsWithImplicitDSA, B); 8806 8807 if (NestedLoopCount == 0) 8808 return StmtError(); 8809 8810 assert((CurContext->isDependentContext() || B.builtAll()) && 8811 "omp for loop exprs were not built"); 8812 8813 if (!CurContext->isDependentContext()) { 8814 // Finalize the clauses that need pre-built expressions for CodeGen. 8815 for (OMPClause *C : Clauses) { 8816 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8817 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8818 B.NumIterations, *this, CurScope, 8819 DSAStack)) 8820 return StmtError(); 8821 } 8822 } 8823 8824 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8825 return StmtError(); 8826 8827 setFunctionHasBranchProtectedScope(); 8828 8829 DSAStack->setParentTeamsRegionLoc(StartLoc); 8830 8831 return OMPTeamsDistributeParallelForSimdDirective::Create( 8832 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8833 } 8834 8835 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 8836 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8837 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8838 if (!AStmt) 8839 return StmtError(); 8840 8841 auto *CS = cast<CapturedStmt>(AStmt); 8842 // 1.2.2 OpenMP Language Terminology 8843 // Structured block - An executable statement with a single entry at the 8844 // top and a single exit at the bottom. 8845 // The point of exit cannot be a branch out of the structured block. 8846 // longjmp() and throw() must not violate the entry/exit criteria. 8847 CS->getCapturedDecl()->setNothrow(); 8848 8849 for (int ThisCaptureLevel = 8850 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8851 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8852 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8853 // 1.2.2 OpenMP Language Terminology 8854 // Structured block - An executable statement with a single entry at the 8855 // top and a single exit at the bottom. 8856 // The point of exit cannot be a branch out of the structured block. 8857 // longjmp() and throw() must not violate the entry/exit criteria. 8858 CS->getCapturedDecl()->setNothrow(); 8859 } 8860 8861 OMPLoopDirective::HelperExprs B; 8862 // In presence of clause 'collapse' with number of loops, it will 8863 // define the nested loops number. 8864 unsigned NestedLoopCount = checkOpenMPLoop( 8865 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8866 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8867 VarsWithImplicitDSA, B); 8868 8869 if (NestedLoopCount == 0) 8870 return StmtError(); 8871 8872 assert((CurContext->isDependentContext() || B.builtAll()) && 8873 "omp for loop exprs were not built"); 8874 8875 setFunctionHasBranchProtectedScope(); 8876 8877 DSAStack->setParentTeamsRegionLoc(StartLoc); 8878 8879 return OMPTeamsDistributeParallelForDirective::Create( 8880 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8881 DSAStack->isCancelRegion()); 8882 } 8883 8884 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8885 Stmt *AStmt, 8886 SourceLocation StartLoc, 8887 SourceLocation EndLoc) { 8888 if (!AStmt) 8889 return StmtError(); 8890 8891 auto *CS = cast<CapturedStmt>(AStmt); 8892 // 1.2.2 OpenMP Language Terminology 8893 // Structured block - An executable statement with a single entry at the 8894 // top and a single exit at the bottom. 8895 // The point of exit cannot be a branch out of the structured block. 8896 // longjmp() and throw() must not violate the entry/exit criteria. 8897 CS->getCapturedDecl()->setNothrow(); 8898 8899 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8900 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8901 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8902 // 1.2.2 OpenMP Language Terminology 8903 // Structured block - An executable statement with a single entry at the 8904 // top and a single exit at the bottom. 8905 // The point of exit cannot be a branch out of the structured block. 8906 // longjmp() and throw() must not violate the entry/exit criteria. 8907 CS->getCapturedDecl()->setNothrow(); 8908 } 8909 setFunctionHasBranchProtectedScope(); 8910 8911 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8912 AStmt); 8913 } 8914 8915 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8916 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8917 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8918 if (!AStmt) 8919 return StmtError(); 8920 8921 auto *CS = cast<CapturedStmt>(AStmt); 8922 // 1.2.2 OpenMP Language Terminology 8923 // Structured block - An executable statement with a single entry at the 8924 // top and a single exit at the bottom. 8925 // The point of exit cannot be a branch out of the structured block. 8926 // longjmp() and throw() must not violate the entry/exit criteria. 8927 CS->getCapturedDecl()->setNothrow(); 8928 for (int ThisCaptureLevel = 8929 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8930 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8931 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8932 // 1.2.2 OpenMP Language Terminology 8933 // Structured block - An executable statement with a single entry at the 8934 // top and a single exit at the bottom. 8935 // The point of exit cannot be a branch out of the structured block. 8936 // longjmp() and throw() must not violate the entry/exit criteria. 8937 CS->getCapturedDecl()->setNothrow(); 8938 } 8939 8940 OMPLoopDirective::HelperExprs B; 8941 // In presence of clause 'collapse' with number of loops, it will 8942 // define the nested loops number. 8943 unsigned NestedLoopCount = checkOpenMPLoop( 8944 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8945 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8946 VarsWithImplicitDSA, B); 8947 if (NestedLoopCount == 0) 8948 return StmtError(); 8949 8950 assert((CurContext->isDependentContext() || B.builtAll()) && 8951 "omp target teams distribute loop exprs were not built"); 8952 8953 setFunctionHasBranchProtectedScope(); 8954 return OMPTargetTeamsDistributeDirective::Create( 8955 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8956 } 8957 8958 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8959 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8960 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8961 if (!AStmt) 8962 return StmtError(); 8963 8964 auto *CS = cast<CapturedStmt>(AStmt); 8965 // 1.2.2 OpenMP Language Terminology 8966 // Structured block - An executable statement with a single entry at the 8967 // top and a single exit at the bottom. 8968 // The point of exit cannot be a branch out of the structured block. 8969 // longjmp() and throw() must not violate the entry/exit criteria. 8970 CS->getCapturedDecl()->setNothrow(); 8971 for (int ThisCaptureLevel = 8972 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 8973 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8974 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8975 // 1.2.2 OpenMP Language Terminology 8976 // Structured block - An executable statement with a single entry at the 8977 // top and a single exit at the bottom. 8978 // The point of exit cannot be a branch out of the structured block. 8979 // longjmp() and throw() must not violate the entry/exit criteria. 8980 CS->getCapturedDecl()->setNothrow(); 8981 } 8982 8983 OMPLoopDirective::HelperExprs B; 8984 // In presence of clause 'collapse' with number of loops, it will 8985 // define the nested loops number. 8986 unsigned NestedLoopCount = checkOpenMPLoop( 8987 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8988 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8989 VarsWithImplicitDSA, B); 8990 if (NestedLoopCount == 0) 8991 return StmtError(); 8992 8993 assert((CurContext->isDependentContext() || B.builtAll()) && 8994 "omp target teams distribute parallel for loop exprs were not built"); 8995 8996 if (!CurContext->isDependentContext()) { 8997 // Finalize the clauses that need pre-built expressions for CodeGen. 8998 for (OMPClause *C : Clauses) { 8999 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9000 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9001 B.NumIterations, *this, CurScope, 9002 DSAStack)) 9003 return StmtError(); 9004 } 9005 } 9006 9007 setFunctionHasBranchProtectedScope(); 9008 return OMPTargetTeamsDistributeParallelForDirective::Create( 9009 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9010 DSAStack->isCancelRegion()); 9011 } 9012 9013 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9014 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9015 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9016 if (!AStmt) 9017 return StmtError(); 9018 9019 auto *CS = cast<CapturedStmt>(AStmt); 9020 // 1.2.2 OpenMP Language Terminology 9021 // Structured block - An executable statement with a single entry at the 9022 // top and a single exit at the bottom. 9023 // The point of exit cannot be a branch out of the structured block. 9024 // longjmp() and throw() must not violate the entry/exit criteria. 9025 CS->getCapturedDecl()->setNothrow(); 9026 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9027 OMPD_target_teams_distribute_parallel_for_simd); 9028 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9029 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9030 // 1.2.2 OpenMP Language Terminology 9031 // Structured block - An executable statement with a single entry at the 9032 // top and a single exit at the bottom. 9033 // The point of exit cannot be a branch out of the structured block. 9034 // longjmp() and throw() must not violate the entry/exit criteria. 9035 CS->getCapturedDecl()->setNothrow(); 9036 } 9037 9038 OMPLoopDirective::HelperExprs B; 9039 // In presence of clause 'collapse' with number of loops, it will 9040 // define the nested loops number. 9041 unsigned NestedLoopCount = 9042 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9043 getCollapseNumberExpr(Clauses), 9044 nullptr /*ordered not a clause on distribute*/, CS, *this, 9045 *DSAStack, VarsWithImplicitDSA, B); 9046 if (NestedLoopCount == 0) 9047 return StmtError(); 9048 9049 assert((CurContext->isDependentContext() || B.builtAll()) && 9050 "omp target teams distribute parallel for simd loop exprs were not " 9051 "built"); 9052 9053 if (!CurContext->isDependentContext()) { 9054 // Finalize the clauses that need pre-built expressions for CodeGen. 9055 for (OMPClause *C : Clauses) { 9056 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9057 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9058 B.NumIterations, *this, CurScope, 9059 DSAStack)) 9060 return StmtError(); 9061 } 9062 } 9063 9064 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9065 return StmtError(); 9066 9067 setFunctionHasBranchProtectedScope(); 9068 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9069 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9070 } 9071 9072 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9073 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9074 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9075 if (!AStmt) 9076 return StmtError(); 9077 9078 auto *CS = cast<CapturedStmt>(AStmt); 9079 // 1.2.2 OpenMP Language Terminology 9080 // Structured block - An executable statement with a single entry at the 9081 // top and a single exit at the bottom. 9082 // The point of exit cannot be a branch out of the structured block. 9083 // longjmp() and throw() must not violate the entry/exit criteria. 9084 CS->getCapturedDecl()->setNothrow(); 9085 for (int ThisCaptureLevel = 9086 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 9087 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9088 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9089 // 1.2.2 OpenMP Language Terminology 9090 // Structured block - An executable statement with a single entry at the 9091 // top and a single exit at the bottom. 9092 // The point of exit cannot be a branch out of the structured block. 9093 // longjmp() and throw() must not violate the entry/exit criteria. 9094 CS->getCapturedDecl()->setNothrow(); 9095 } 9096 9097 OMPLoopDirective::HelperExprs B; 9098 // In presence of clause 'collapse' with number of loops, it will 9099 // define the nested loops number. 9100 unsigned NestedLoopCount = checkOpenMPLoop( 9101 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9102 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9103 VarsWithImplicitDSA, B); 9104 if (NestedLoopCount == 0) 9105 return StmtError(); 9106 9107 assert((CurContext->isDependentContext() || B.builtAll()) && 9108 "omp target teams distribute simd loop exprs were not built"); 9109 9110 if (!CurContext->isDependentContext()) { 9111 // Finalize the clauses that need pre-built expressions for CodeGen. 9112 for (OMPClause *C : Clauses) { 9113 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9114 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9115 B.NumIterations, *this, CurScope, 9116 DSAStack)) 9117 return StmtError(); 9118 } 9119 } 9120 9121 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9122 return StmtError(); 9123 9124 setFunctionHasBranchProtectedScope(); 9125 return OMPTargetTeamsDistributeSimdDirective::Create( 9126 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9127 } 9128 9129 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 9130 SourceLocation StartLoc, 9131 SourceLocation LParenLoc, 9132 SourceLocation EndLoc) { 9133 OMPClause *Res = nullptr; 9134 switch (Kind) { 9135 case OMPC_final: 9136 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 9137 break; 9138 case OMPC_num_threads: 9139 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 9140 break; 9141 case OMPC_safelen: 9142 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 9143 break; 9144 case OMPC_simdlen: 9145 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 9146 break; 9147 case OMPC_allocator: 9148 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 9149 break; 9150 case OMPC_collapse: 9151 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 9152 break; 9153 case OMPC_ordered: 9154 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 9155 break; 9156 case OMPC_device: 9157 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 9158 break; 9159 case OMPC_num_teams: 9160 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 9161 break; 9162 case OMPC_thread_limit: 9163 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 9164 break; 9165 case OMPC_priority: 9166 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 9167 break; 9168 case OMPC_grainsize: 9169 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 9170 break; 9171 case OMPC_num_tasks: 9172 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 9173 break; 9174 case OMPC_hint: 9175 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 9176 break; 9177 case OMPC_if: 9178 case OMPC_default: 9179 case OMPC_proc_bind: 9180 case OMPC_schedule: 9181 case OMPC_private: 9182 case OMPC_firstprivate: 9183 case OMPC_lastprivate: 9184 case OMPC_shared: 9185 case OMPC_reduction: 9186 case OMPC_task_reduction: 9187 case OMPC_in_reduction: 9188 case OMPC_linear: 9189 case OMPC_aligned: 9190 case OMPC_copyin: 9191 case OMPC_copyprivate: 9192 case OMPC_nowait: 9193 case OMPC_untied: 9194 case OMPC_mergeable: 9195 case OMPC_threadprivate: 9196 case OMPC_allocate: 9197 case OMPC_flush: 9198 case OMPC_read: 9199 case OMPC_write: 9200 case OMPC_update: 9201 case OMPC_capture: 9202 case OMPC_seq_cst: 9203 case OMPC_depend: 9204 case OMPC_threads: 9205 case OMPC_simd: 9206 case OMPC_map: 9207 case OMPC_nogroup: 9208 case OMPC_dist_schedule: 9209 case OMPC_defaultmap: 9210 case OMPC_unknown: 9211 case OMPC_uniform: 9212 case OMPC_to: 9213 case OMPC_from: 9214 case OMPC_use_device_ptr: 9215 case OMPC_is_device_ptr: 9216 case OMPC_unified_address: 9217 case OMPC_unified_shared_memory: 9218 case OMPC_reverse_offload: 9219 case OMPC_dynamic_allocators: 9220 case OMPC_atomic_default_mem_order: 9221 llvm_unreachable("Clause is not allowed."); 9222 } 9223 return Res; 9224 } 9225 9226 // An OpenMP directive such as 'target parallel' has two captured regions: 9227 // for the 'target' and 'parallel' respectively. This function returns 9228 // the region in which to capture expressions associated with a clause. 9229 // A return value of OMPD_unknown signifies that the expression should not 9230 // be captured. 9231 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 9232 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 9233 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 9234 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9235 switch (CKind) { 9236 case OMPC_if: 9237 switch (DKind) { 9238 case OMPD_target_parallel: 9239 case OMPD_target_parallel_for: 9240 case OMPD_target_parallel_for_simd: 9241 // If this clause applies to the nested 'parallel' region, capture within 9242 // the 'target' region, otherwise do not capture. 9243 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9244 CaptureRegion = OMPD_target; 9245 break; 9246 case OMPD_target_teams_distribute_parallel_for: 9247 case OMPD_target_teams_distribute_parallel_for_simd: 9248 // If this clause applies to the nested 'parallel' region, capture within 9249 // the 'teams' region, otherwise do not capture. 9250 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 9251 CaptureRegion = OMPD_teams; 9252 break; 9253 case OMPD_teams_distribute_parallel_for: 9254 case OMPD_teams_distribute_parallel_for_simd: 9255 CaptureRegion = OMPD_teams; 9256 break; 9257 case OMPD_target_update: 9258 case OMPD_target_enter_data: 9259 case OMPD_target_exit_data: 9260 CaptureRegion = OMPD_task; 9261 break; 9262 case OMPD_cancel: 9263 case OMPD_parallel: 9264 case OMPD_parallel_sections: 9265 case OMPD_parallel_for: 9266 case OMPD_parallel_for_simd: 9267 case OMPD_target: 9268 case OMPD_target_simd: 9269 case OMPD_target_teams: 9270 case OMPD_target_teams_distribute: 9271 case OMPD_target_teams_distribute_simd: 9272 case OMPD_distribute_parallel_for: 9273 case OMPD_distribute_parallel_for_simd: 9274 case OMPD_task: 9275 case OMPD_taskloop: 9276 case OMPD_taskloop_simd: 9277 case OMPD_target_data: 9278 // Do not capture if-clause expressions. 9279 break; 9280 case OMPD_threadprivate: 9281 case OMPD_allocate: 9282 case OMPD_taskyield: 9283 case OMPD_barrier: 9284 case OMPD_taskwait: 9285 case OMPD_cancellation_point: 9286 case OMPD_flush: 9287 case OMPD_declare_reduction: 9288 case OMPD_declare_mapper: 9289 case OMPD_declare_simd: 9290 case OMPD_declare_target: 9291 case OMPD_end_declare_target: 9292 case OMPD_teams: 9293 case OMPD_simd: 9294 case OMPD_for: 9295 case OMPD_for_simd: 9296 case OMPD_sections: 9297 case OMPD_section: 9298 case OMPD_single: 9299 case OMPD_master: 9300 case OMPD_critical: 9301 case OMPD_taskgroup: 9302 case OMPD_distribute: 9303 case OMPD_ordered: 9304 case OMPD_atomic: 9305 case OMPD_distribute_simd: 9306 case OMPD_teams_distribute: 9307 case OMPD_teams_distribute_simd: 9308 case OMPD_requires: 9309 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 9310 case OMPD_unknown: 9311 llvm_unreachable("Unknown OpenMP directive"); 9312 } 9313 break; 9314 case OMPC_num_threads: 9315 switch (DKind) { 9316 case OMPD_target_parallel: 9317 case OMPD_target_parallel_for: 9318 case OMPD_target_parallel_for_simd: 9319 CaptureRegion = OMPD_target; 9320 break; 9321 case OMPD_teams_distribute_parallel_for: 9322 case OMPD_teams_distribute_parallel_for_simd: 9323 case OMPD_target_teams_distribute_parallel_for: 9324 case OMPD_target_teams_distribute_parallel_for_simd: 9325 CaptureRegion = OMPD_teams; 9326 break; 9327 case OMPD_parallel: 9328 case OMPD_parallel_sections: 9329 case OMPD_parallel_for: 9330 case OMPD_parallel_for_simd: 9331 case OMPD_distribute_parallel_for: 9332 case OMPD_distribute_parallel_for_simd: 9333 // Do not capture num_threads-clause expressions. 9334 break; 9335 case OMPD_target_data: 9336 case OMPD_target_enter_data: 9337 case OMPD_target_exit_data: 9338 case OMPD_target_update: 9339 case OMPD_target: 9340 case OMPD_target_simd: 9341 case OMPD_target_teams: 9342 case OMPD_target_teams_distribute: 9343 case OMPD_target_teams_distribute_simd: 9344 case OMPD_cancel: 9345 case OMPD_task: 9346 case OMPD_taskloop: 9347 case OMPD_taskloop_simd: 9348 case OMPD_threadprivate: 9349 case OMPD_allocate: 9350 case OMPD_taskyield: 9351 case OMPD_barrier: 9352 case OMPD_taskwait: 9353 case OMPD_cancellation_point: 9354 case OMPD_flush: 9355 case OMPD_declare_reduction: 9356 case OMPD_declare_mapper: 9357 case OMPD_declare_simd: 9358 case OMPD_declare_target: 9359 case OMPD_end_declare_target: 9360 case OMPD_teams: 9361 case OMPD_simd: 9362 case OMPD_for: 9363 case OMPD_for_simd: 9364 case OMPD_sections: 9365 case OMPD_section: 9366 case OMPD_single: 9367 case OMPD_master: 9368 case OMPD_critical: 9369 case OMPD_taskgroup: 9370 case OMPD_distribute: 9371 case OMPD_ordered: 9372 case OMPD_atomic: 9373 case OMPD_distribute_simd: 9374 case OMPD_teams_distribute: 9375 case OMPD_teams_distribute_simd: 9376 case OMPD_requires: 9377 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 9378 case OMPD_unknown: 9379 llvm_unreachable("Unknown OpenMP directive"); 9380 } 9381 break; 9382 case OMPC_num_teams: 9383 switch (DKind) { 9384 case OMPD_target_teams: 9385 case OMPD_target_teams_distribute: 9386 case OMPD_target_teams_distribute_simd: 9387 case OMPD_target_teams_distribute_parallel_for: 9388 case OMPD_target_teams_distribute_parallel_for_simd: 9389 CaptureRegion = OMPD_target; 9390 break; 9391 case OMPD_teams_distribute_parallel_for: 9392 case OMPD_teams_distribute_parallel_for_simd: 9393 case OMPD_teams: 9394 case OMPD_teams_distribute: 9395 case OMPD_teams_distribute_simd: 9396 // Do not capture num_teams-clause expressions. 9397 break; 9398 case OMPD_distribute_parallel_for: 9399 case OMPD_distribute_parallel_for_simd: 9400 case OMPD_task: 9401 case OMPD_taskloop: 9402 case OMPD_taskloop_simd: 9403 case OMPD_target_data: 9404 case OMPD_target_enter_data: 9405 case OMPD_target_exit_data: 9406 case OMPD_target_update: 9407 case OMPD_cancel: 9408 case OMPD_parallel: 9409 case OMPD_parallel_sections: 9410 case OMPD_parallel_for: 9411 case OMPD_parallel_for_simd: 9412 case OMPD_target: 9413 case OMPD_target_simd: 9414 case OMPD_target_parallel: 9415 case OMPD_target_parallel_for: 9416 case OMPD_target_parallel_for_simd: 9417 case OMPD_threadprivate: 9418 case OMPD_allocate: 9419 case OMPD_taskyield: 9420 case OMPD_barrier: 9421 case OMPD_taskwait: 9422 case OMPD_cancellation_point: 9423 case OMPD_flush: 9424 case OMPD_declare_reduction: 9425 case OMPD_declare_mapper: 9426 case OMPD_declare_simd: 9427 case OMPD_declare_target: 9428 case OMPD_end_declare_target: 9429 case OMPD_simd: 9430 case OMPD_for: 9431 case OMPD_for_simd: 9432 case OMPD_sections: 9433 case OMPD_section: 9434 case OMPD_single: 9435 case OMPD_master: 9436 case OMPD_critical: 9437 case OMPD_taskgroup: 9438 case OMPD_distribute: 9439 case OMPD_ordered: 9440 case OMPD_atomic: 9441 case OMPD_distribute_simd: 9442 case OMPD_requires: 9443 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9444 case OMPD_unknown: 9445 llvm_unreachable("Unknown OpenMP directive"); 9446 } 9447 break; 9448 case OMPC_thread_limit: 9449 switch (DKind) { 9450 case OMPD_target_teams: 9451 case OMPD_target_teams_distribute: 9452 case OMPD_target_teams_distribute_simd: 9453 case OMPD_target_teams_distribute_parallel_for: 9454 case OMPD_target_teams_distribute_parallel_for_simd: 9455 CaptureRegion = OMPD_target; 9456 break; 9457 case OMPD_teams_distribute_parallel_for: 9458 case OMPD_teams_distribute_parallel_for_simd: 9459 case OMPD_teams: 9460 case OMPD_teams_distribute: 9461 case OMPD_teams_distribute_simd: 9462 // Do not capture thread_limit-clause expressions. 9463 break; 9464 case OMPD_distribute_parallel_for: 9465 case OMPD_distribute_parallel_for_simd: 9466 case OMPD_task: 9467 case OMPD_taskloop: 9468 case OMPD_taskloop_simd: 9469 case OMPD_target_data: 9470 case OMPD_target_enter_data: 9471 case OMPD_target_exit_data: 9472 case OMPD_target_update: 9473 case OMPD_cancel: 9474 case OMPD_parallel: 9475 case OMPD_parallel_sections: 9476 case OMPD_parallel_for: 9477 case OMPD_parallel_for_simd: 9478 case OMPD_target: 9479 case OMPD_target_simd: 9480 case OMPD_target_parallel: 9481 case OMPD_target_parallel_for: 9482 case OMPD_target_parallel_for_simd: 9483 case OMPD_threadprivate: 9484 case OMPD_allocate: 9485 case OMPD_taskyield: 9486 case OMPD_barrier: 9487 case OMPD_taskwait: 9488 case OMPD_cancellation_point: 9489 case OMPD_flush: 9490 case OMPD_declare_reduction: 9491 case OMPD_declare_mapper: 9492 case OMPD_declare_simd: 9493 case OMPD_declare_target: 9494 case OMPD_end_declare_target: 9495 case OMPD_simd: 9496 case OMPD_for: 9497 case OMPD_for_simd: 9498 case OMPD_sections: 9499 case OMPD_section: 9500 case OMPD_single: 9501 case OMPD_master: 9502 case OMPD_critical: 9503 case OMPD_taskgroup: 9504 case OMPD_distribute: 9505 case OMPD_ordered: 9506 case OMPD_atomic: 9507 case OMPD_distribute_simd: 9508 case OMPD_requires: 9509 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 9510 case OMPD_unknown: 9511 llvm_unreachable("Unknown OpenMP directive"); 9512 } 9513 break; 9514 case OMPC_schedule: 9515 switch (DKind) { 9516 case OMPD_parallel_for: 9517 case OMPD_parallel_for_simd: 9518 case OMPD_distribute_parallel_for: 9519 case OMPD_distribute_parallel_for_simd: 9520 case OMPD_teams_distribute_parallel_for: 9521 case OMPD_teams_distribute_parallel_for_simd: 9522 case OMPD_target_parallel_for: 9523 case OMPD_target_parallel_for_simd: 9524 case OMPD_target_teams_distribute_parallel_for: 9525 case OMPD_target_teams_distribute_parallel_for_simd: 9526 CaptureRegion = OMPD_parallel; 9527 break; 9528 case OMPD_for: 9529 case OMPD_for_simd: 9530 // Do not capture schedule-clause expressions. 9531 break; 9532 case OMPD_task: 9533 case OMPD_taskloop: 9534 case OMPD_taskloop_simd: 9535 case OMPD_target_data: 9536 case OMPD_target_enter_data: 9537 case OMPD_target_exit_data: 9538 case OMPD_target_update: 9539 case OMPD_teams: 9540 case OMPD_teams_distribute: 9541 case OMPD_teams_distribute_simd: 9542 case OMPD_target_teams_distribute: 9543 case OMPD_target_teams_distribute_simd: 9544 case OMPD_target: 9545 case OMPD_target_simd: 9546 case OMPD_target_parallel: 9547 case OMPD_cancel: 9548 case OMPD_parallel: 9549 case OMPD_parallel_sections: 9550 case OMPD_threadprivate: 9551 case OMPD_allocate: 9552 case OMPD_taskyield: 9553 case OMPD_barrier: 9554 case OMPD_taskwait: 9555 case OMPD_cancellation_point: 9556 case OMPD_flush: 9557 case OMPD_declare_reduction: 9558 case OMPD_declare_mapper: 9559 case OMPD_declare_simd: 9560 case OMPD_declare_target: 9561 case OMPD_end_declare_target: 9562 case OMPD_simd: 9563 case OMPD_sections: 9564 case OMPD_section: 9565 case OMPD_single: 9566 case OMPD_master: 9567 case OMPD_critical: 9568 case OMPD_taskgroup: 9569 case OMPD_distribute: 9570 case OMPD_ordered: 9571 case OMPD_atomic: 9572 case OMPD_distribute_simd: 9573 case OMPD_target_teams: 9574 case OMPD_requires: 9575 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9576 case OMPD_unknown: 9577 llvm_unreachable("Unknown OpenMP directive"); 9578 } 9579 break; 9580 case OMPC_dist_schedule: 9581 switch (DKind) { 9582 case OMPD_teams_distribute_parallel_for: 9583 case OMPD_teams_distribute_parallel_for_simd: 9584 case OMPD_teams_distribute: 9585 case OMPD_teams_distribute_simd: 9586 case OMPD_target_teams_distribute_parallel_for: 9587 case OMPD_target_teams_distribute_parallel_for_simd: 9588 case OMPD_target_teams_distribute: 9589 case OMPD_target_teams_distribute_simd: 9590 CaptureRegion = OMPD_teams; 9591 break; 9592 case OMPD_distribute_parallel_for: 9593 case OMPD_distribute_parallel_for_simd: 9594 case OMPD_distribute: 9595 case OMPD_distribute_simd: 9596 // Do not capture thread_limit-clause expressions. 9597 break; 9598 case OMPD_parallel_for: 9599 case OMPD_parallel_for_simd: 9600 case OMPD_target_parallel_for_simd: 9601 case OMPD_target_parallel_for: 9602 case OMPD_task: 9603 case OMPD_taskloop: 9604 case OMPD_taskloop_simd: 9605 case OMPD_target_data: 9606 case OMPD_target_enter_data: 9607 case OMPD_target_exit_data: 9608 case OMPD_target_update: 9609 case OMPD_teams: 9610 case OMPD_target: 9611 case OMPD_target_simd: 9612 case OMPD_target_parallel: 9613 case OMPD_cancel: 9614 case OMPD_parallel: 9615 case OMPD_parallel_sections: 9616 case OMPD_threadprivate: 9617 case OMPD_allocate: 9618 case OMPD_taskyield: 9619 case OMPD_barrier: 9620 case OMPD_taskwait: 9621 case OMPD_cancellation_point: 9622 case OMPD_flush: 9623 case OMPD_declare_reduction: 9624 case OMPD_declare_mapper: 9625 case OMPD_declare_simd: 9626 case OMPD_declare_target: 9627 case OMPD_end_declare_target: 9628 case OMPD_simd: 9629 case OMPD_for: 9630 case OMPD_for_simd: 9631 case OMPD_sections: 9632 case OMPD_section: 9633 case OMPD_single: 9634 case OMPD_master: 9635 case OMPD_critical: 9636 case OMPD_taskgroup: 9637 case OMPD_ordered: 9638 case OMPD_atomic: 9639 case OMPD_target_teams: 9640 case OMPD_requires: 9641 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9642 case OMPD_unknown: 9643 llvm_unreachable("Unknown OpenMP directive"); 9644 } 9645 break; 9646 case OMPC_device: 9647 switch (DKind) { 9648 case OMPD_target_update: 9649 case OMPD_target_enter_data: 9650 case OMPD_target_exit_data: 9651 case OMPD_target: 9652 case OMPD_target_simd: 9653 case OMPD_target_teams: 9654 case OMPD_target_parallel: 9655 case OMPD_target_teams_distribute: 9656 case OMPD_target_teams_distribute_simd: 9657 case OMPD_target_parallel_for: 9658 case OMPD_target_parallel_for_simd: 9659 case OMPD_target_teams_distribute_parallel_for: 9660 case OMPD_target_teams_distribute_parallel_for_simd: 9661 CaptureRegion = OMPD_task; 9662 break; 9663 case OMPD_target_data: 9664 // Do not capture device-clause expressions. 9665 break; 9666 case OMPD_teams_distribute_parallel_for: 9667 case OMPD_teams_distribute_parallel_for_simd: 9668 case OMPD_teams: 9669 case OMPD_teams_distribute: 9670 case OMPD_teams_distribute_simd: 9671 case OMPD_distribute_parallel_for: 9672 case OMPD_distribute_parallel_for_simd: 9673 case OMPD_task: 9674 case OMPD_taskloop: 9675 case OMPD_taskloop_simd: 9676 case OMPD_cancel: 9677 case OMPD_parallel: 9678 case OMPD_parallel_sections: 9679 case OMPD_parallel_for: 9680 case OMPD_parallel_for_simd: 9681 case OMPD_threadprivate: 9682 case OMPD_allocate: 9683 case OMPD_taskyield: 9684 case OMPD_barrier: 9685 case OMPD_taskwait: 9686 case OMPD_cancellation_point: 9687 case OMPD_flush: 9688 case OMPD_declare_reduction: 9689 case OMPD_declare_mapper: 9690 case OMPD_declare_simd: 9691 case OMPD_declare_target: 9692 case OMPD_end_declare_target: 9693 case OMPD_simd: 9694 case OMPD_for: 9695 case OMPD_for_simd: 9696 case OMPD_sections: 9697 case OMPD_section: 9698 case OMPD_single: 9699 case OMPD_master: 9700 case OMPD_critical: 9701 case OMPD_taskgroup: 9702 case OMPD_distribute: 9703 case OMPD_ordered: 9704 case OMPD_atomic: 9705 case OMPD_distribute_simd: 9706 case OMPD_requires: 9707 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9708 case OMPD_unknown: 9709 llvm_unreachable("Unknown OpenMP directive"); 9710 } 9711 break; 9712 case OMPC_firstprivate: 9713 case OMPC_lastprivate: 9714 case OMPC_reduction: 9715 case OMPC_task_reduction: 9716 case OMPC_in_reduction: 9717 case OMPC_linear: 9718 case OMPC_default: 9719 case OMPC_proc_bind: 9720 case OMPC_final: 9721 case OMPC_safelen: 9722 case OMPC_simdlen: 9723 case OMPC_allocator: 9724 case OMPC_collapse: 9725 case OMPC_private: 9726 case OMPC_shared: 9727 case OMPC_aligned: 9728 case OMPC_copyin: 9729 case OMPC_copyprivate: 9730 case OMPC_ordered: 9731 case OMPC_nowait: 9732 case OMPC_untied: 9733 case OMPC_mergeable: 9734 case OMPC_threadprivate: 9735 case OMPC_allocate: 9736 case OMPC_flush: 9737 case OMPC_read: 9738 case OMPC_write: 9739 case OMPC_update: 9740 case OMPC_capture: 9741 case OMPC_seq_cst: 9742 case OMPC_depend: 9743 case OMPC_threads: 9744 case OMPC_simd: 9745 case OMPC_map: 9746 case OMPC_priority: 9747 case OMPC_grainsize: 9748 case OMPC_nogroup: 9749 case OMPC_num_tasks: 9750 case OMPC_hint: 9751 case OMPC_defaultmap: 9752 case OMPC_unknown: 9753 case OMPC_uniform: 9754 case OMPC_to: 9755 case OMPC_from: 9756 case OMPC_use_device_ptr: 9757 case OMPC_is_device_ptr: 9758 case OMPC_unified_address: 9759 case OMPC_unified_shared_memory: 9760 case OMPC_reverse_offload: 9761 case OMPC_dynamic_allocators: 9762 case OMPC_atomic_default_mem_order: 9763 llvm_unreachable("Unexpected OpenMP clause."); 9764 } 9765 return CaptureRegion; 9766 } 9767 9768 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9769 Expr *Condition, SourceLocation StartLoc, 9770 SourceLocation LParenLoc, 9771 SourceLocation NameModifierLoc, 9772 SourceLocation ColonLoc, 9773 SourceLocation EndLoc) { 9774 Expr *ValExpr = Condition; 9775 Stmt *HelperValStmt = nullptr; 9776 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9777 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9778 !Condition->isInstantiationDependent() && 9779 !Condition->containsUnexpandedParameterPack()) { 9780 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9781 if (Val.isInvalid()) 9782 return nullptr; 9783 9784 ValExpr = Val.get(); 9785 9786 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9787 CaptureRegion = 9788 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9789 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9790 ValExpr = MakeFullExpr(ValExpr).get(); 9791 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9792 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9793 HelperValStmt = buildPreInits(Context, Captures); 9794 } 9795 } 9796 9797 return new (Context) 9798 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9799 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9800 } 9801 9802 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9803 SourceLocation StartLoc, 9804 SourceLocation LParenLoc, 9805 SourceLocation EndLoc) { 9806 Expr *ValExpr = Condition; 9807 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9808 !Condition->isInstantiationDependent() && 9809 !Condition->containsUnexpandedParameterPack()) { 9810 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9811 if (Val.isInvalid()) 9812 return nullptr; 9813 9814 ValExpr = MakeFullExpr(Val.get()).get(); 9815 } 9816 9817 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9818 } 9819 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9820 Expr *Op) { 9821 if (!Op) 9822 return ExprError(); 9823 9824 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9825 public: 9826 IntConvertDiagnoser() 9827 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9828 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9829 QualType T) override { 9830 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9831 } 9832 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9833 QualType T) override { 9834 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9835 } 9836 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9837 QualType T, 9838 QualType ConvTy) override { 9839 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9840 } 9841 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9842 QualType ConvTy) override { 9843 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9844 << ConvTy->isEnumeralType() << ConvTy; 9845 } 9846 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9847 QualType T) override { 9848 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9849 } 9850 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9851 QualType ConvTy) override { 9852 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9853 << ConvTy->isEnumeralType() << ConvTy; 9854 } 9855 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9856 QualType) override { 9857 llvm_unreachable("conversion functions are permitted"); 9858 } 9859 } ConvertDiagnoser; 9860 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9861 } 9862 9863 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9864 OpenMPClauseKind CKind, 9865 bool StrictlyPositive) { 9866 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9867 !ValExpr->isInstantiationDependent()) { 9868 SourceLocation Loc = ValExpr->getExprLoc(); 9869 ExprResult Value = 9870 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9871 if (Value.isInvalid()) 9872 return false; 9873 9874 ValExpr = Value.get(); 9875 // The expression must evaluate to a non-negative integer value. 9876 llvm::APSInt Result; 9877 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9878 Result.isSigned() && 9879 !((!StrictlyPositive && Result.isNonNegative()) || 9880 (StrictlyPositive && Result.isStrictlyPositive()))) { 9881 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9882 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9883 << ValExpr->getSourceRange(); 9884 return false; 9885 } 9886 } 9887 return true; 9888 } 9889 9890 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9891 SourceLocation StartLoc, 9892 SourceLocation LParenLoc, 9893 SourceLocation EndLoc) { 9894 Expr *ValExpr = NumThreads; 9895 Stmt *HelperValStmt = nullptr; 9896 9897 // OpenMP [2.5, Restrictions] 9898 // The num_threads expression must evaluate to a positive integer value. 9899 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9900 /*StrictlyPositive=*/true)) 9901 return nullptr; 9902 9903 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9904 OpenMPDirectiveKind CaptureRegion = 9905 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9906 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9907 ValExpr = MakeFullExpr(ValExpr).get(); 9908 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9909 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9910 HelperValStmt = buildPreInits(Context, Captures); 9911 } 9912 9913 return new (Context) OMPNumThreadsClause( 9914 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9915 } 9916 9917 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9918 OpenMPClauseKind CKind, 9919 bool StrictlyPositive) { 9920 if (!E) 9921 return ExprError(); 9922 if (E->isValueDependent() || E->isTypeDependent() || 9923 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9924 return E; 9925 llvm::APSInt Result; 9926 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9927 if (ICE.isInvalid()) 9928 return ExprError(); 9929 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9930 (!StrictlyPositive && !Result.isNonNegative())) { 9931 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9932 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9933 << E->getSourceRange(); 9934 return ExprError(); 9935 } 9936 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9937 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9938 << E->getSourceRange(); 9939 return ExprError(); 9940 } 9941 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9942 DSAStack->setAssociatedLoops(Result.getExtValue()); 9943 else if (CKind == OMPC_ordered) 9944 DSAStack->setAssociatedLoops(Result.getExtValue()); 9945 return ICE; 9946 } 9947 9948 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9949 SourceLocation LParenLoc, 9950 SourceLocation EndLoc) { 9951 // OpenMP [2.8.1, simd construct, Description] 9952 // The parameter of the safelen clause must be a constant 9953 // positive integer expression. 9954 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9955 if (Safelen.isInvalid()) 9956 return nullptr; 9957 return new (Context) 9958 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9959 } 9960 9961 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9962 SourceLocation LParenLoc, 9963 SourceLocation EndLoc) { 9964 // OpenMP [2.8.1, simd construct, Description] 9965 // The parameter of the simdlen clause must be a constant 9966 // positive integer expression. 9967 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9968 if (Simdlen.isInvalid()) 9969 return nullptr; 9970 return new (Context) 9971 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9972 } 9973 9974 /// Tries to find omp_allocator_handle_t type. 9975 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 9976 DSAStackTy *Stack) { 9977 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 9978 if (!OMPAllocatorHandleT.isNull()) 9979 return true; 9980 // Build the predefined allocator expressions. 9981 bool ErrorFound = false; 9982 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 9983 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 9984 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 9985 StringRef Allocator = 9986 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 9987 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 9988 auto *VD = dyn_cast_or_null<ValueDecl>( 9989 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 9990 if (!VD) { 9991 ErrorFound = true; 9992 break; 9993 } 9994 QualType AllocatorType = 9995 VD->getType().getNonLValueExprType(S.getASTContext()); 9996 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 9997 if (!Res.isUsable()) { 9998 ErrorFound = true; 9999 break; 10000 } 10001 if (OMPAllocatorHandleT.isNull()) 10002 OMPAllocatorHandleT = AllocatorType; 10003 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10004 ErrorFound = true; 10005 break; 10006 } 10007 Stack->setAllocator(AllocatorKind, Res.get()); 10008 } 10009 if (ErrorFound) { 10010 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10011 return false; 10012 } 10013 OMPAllocatorHandleT.addConst(); 10014 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10015 return true; 10016 } 10017 10018 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10019 SourceLocation LParenLoc, 10020 SourceLocation EndLoc) { 10021 // OpenMP [2.11.3, allocate Directive, Description] 10022 // allocator is an expression of omp_allocator_handle_t type. 10023 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10024 return nullptr; 10025 10026 ExprResult Allocator = DefaultLvalueConversion(A); 10027 if (Allocator.isInvalid()) 10028 return nullptr; 10029 Allocator = PerformImplicitConversion(Allocator.get(), 10030 DSAStack->getOMPAllocatorHandleT(), 10031 Sema::AA_Initializing, 10032 /*AllowExplicit=*/true); 10033 if (Allocator.isInvalid()) 10034 return nullptr; 10035 return new (Context) 10036 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10037 } 10038 10039 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10040 SourceLocation StartLoc, 10041 SourceLocation LParenLoc, 10042 SourceLocation EndLoc) { 10043 // OpenMP [2.7.1, loop construct, Description] 10044 // OpenMP [2.8.1, simd construct, Description] 10045 // OpenMP [2.9.6, distribute construct, Description] 10046 // The parameter of the collapse clause must be a constant 10047 // positive integer expression. 10048 ExprResult NumForLoopsResult = 10049 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10050 if (NumForLoopsResult.isInvalid()) 10051 return nullptr; 10052 return new (Context) 10053 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10054 } 10055 10056 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10057 SourceLocation EndLoc, 10058 SourceLocation LParenLoc, 10059 Expr *NumForLoops) { 10060 // OpenMP [2.7.1, loop construct, Description] 10061 // OpenMP [2.8.1, simd construct, Description] 10062 // OpenMP [2.9.6, distribute construct, Description] 10063 // The parameter of the ordered clause must be a constant 10064 // positive integer expression if any. 10065 if (NumForLoops && LParenLoc.isValid()) { 10066 ExprResult NumForLoopsResult = 10067 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 10068 if (NumForLoopsResult.isInvalid()) 10069 return nullptr; 10070 NumForLoops = NumForLoopsResult.get(); 10071 } else { 10072 NumForLoops = nullptr; 10073 } 10074 auto *Clause = OMPOrderedClause::Create( 10075 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 10076 StartLoc, LParenLoc, EndLoc); 10077 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 10078 return Clause; 10079 } 10080 10081 OMPClause *Sema::ActOnOpenMPSimpleClause( 10082 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 10083 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10084 OMPClause *Res = nullptr; 10085 switch (Kind) { 10086 case OMPC_default: 10087 Res = 10088 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 10089 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10090 break; 10091 case OMPC_proc_bind: 10092 Res = ActOnOpenMPProcBindClause( 10093 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 10094 LParenLoc, EndLoc); 10095 break; 10096 case OMPC_atomic_default_mem_order: 10097 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 10098 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 10099 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 10100 break; 10101 case OMPC_if: 10102 case OMPC_final: 10103 case OMPC_num_threads: 10104 case OMPC_safelen: 10105 case OMPC_simdlen: 10106 case OMPC_allocator: 10107 case OMPC_collapse: 10108 case OMPC_schedule: 10109 case OMPC_private: 10110 case OMPC_firstprivate: 10111 case OMPC_lastprivate: 10112 case OMPC_shared: 10113 case OMPC_reduction: 10114 case OMPC_task_reduction: 10115 case OMPC_in_reduction: 10116 case OMPC_linear: 10117 case OMPC_aligned: 10118 case OMPC_copyin: 10119 case OMPC_copyprivate: 10120 case OMPC_ordered: 10121 case OMPC_nowait: 10122 case OMPC_untied: 10123 case OMPC_mergeable: 10124 case OMPC_threadprivate: 10125 case OMPC_allocate: 10126 case OMPC_flush: 10127 case OMPC_read: 10128 case OMPC_write: 10129 case OMPC_update: 10130 case OMPC_capture: 10131 case OMPC_seq_cst: 10132 case OMPC_depend: 10133 case OMPC_device: 10134 case OMPC_threads: 10135 case OMPC_simd: 10136 case OMPC_map: 10137 case OMPC_num_teams: 10138 case OMPC_thread_limit: 10139 case OMPC_priority: 10140 case OMPC_grainsize: 10141 case OMPC_nogroup: 10142 case OMPC_num_tasks: 10143 case OMPC_hint: 10144 case OMPC_dist_schedule: 10145 case OMPC_defaultmap: 10146 case OMPC_unknown: 10147 case OMPC_uniform: 10148 case OMPC_to: 10149 case OMPC_from: 10150 case OMPC_use_device_ptr: 10151 case OMPC_is_device_ptr: 10152 case OMPC_unified_address: 10153 case OMPC_unified_shared_memory: 10154 case OMPC_reverse_offload: 10155 case OMPC_dynamic_allocators: 10156 llvm_unreachable("Clause is not allowed."); 10157 } 10158 return Res; 10159 } 10160 10161 static std::string 10162 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 10163 ArrayRef<unsigned> Exclude = llvm::None) { 10164 SmallString<256> Buffer; 10165 llvm::raw_svector_ostream Out(Buffer); 10166 unsigned Bound = Last >= 2 ? Last - 2 : 0; 10167 unsigned Skipped = Exclude.size(); 10168 auto S = Exclude.begin(), E = Exclude.end(); 10169 for (unsigned I = First; I < Last; ++I) { 10170 if (std::find(S, E, I) != E) { 10171 --Skipped; 10172 continue; 10173 } 10174 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 10175 if (I == Bound - Skipped) 10176 Out << " or "; 10177 else if (I != Bound + 1 - Skipped) 10178 Out << ", "; 10179 } 10180 return Out.str(); 10181 } 10182 10183 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 10184 SourceLocation KindKwLoc, 10185 SourceLocation StartLoc, 10186 SourceLocation LParenLoc, 10187 SourceLocation EndLoc) { 10188 if (Kind == OMPC_DEFAULT_unknown) { 10189 static_assert(OMPC_DEFAULT_unknown > 0, 10190 "OMPC_DEFAULT_unknown not greater than 0"); 10191 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10192 << getListOfPossibleValues(OMPC_default, /*First=*/0, 10193 /*Last=*/OMPC_DEFAULT_unknown) 10194 << getOpenMPClauseName(OMPC_default); 10195 return nullptr; 10196 } 10197 switch (Kind) { 10198 case OMPC_DEFAULT_none: 10199 DSAStack->setDefaultDSANone(KindKwLoc); 10200 break; 10201 case OMPC_DEFAULT_shared: 10202 DSAStack->setDefaultDSAShared(KindKwLoc); 10203 break; 10204 case OMPC_DEFAULT_unknown: 10205 llvm_unreachable("Clause kind is not allowed."); 10206 break; 10207 } 10208 return new (Context) 10209 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10210 } 10211 10212 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 10213 SourceLocation KindKwLoc, 10214 SourceLocation StartLoc, 10215 SourceLocation LParenLoc, 10216 SourceLocation EndLoc) { 10217 if (Kind == OMPC_PROC_BIND_unknown) { 10218 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10219 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 10220 /*Last=*/OMPC_PROC_BIND_unknown) 10221 << getOpenMPClauseName(OMPC_proc_bind); 10222 return nullptr; 10223 } 10224 return new (Context) 10225 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 10226 } 10227 10228 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 10229 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 10230 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 10231 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 10232 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 10233 << getListOfPossibleValues( 10234 OMPC_atomic_default_mem_order, /*First=*/0, 10235 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 10236 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 10237 return nullptr; 10238 } 10239 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 10240 LParenLoc, EndLoc); 10241 } 10242 10243 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 10244 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 10245 SourceLocation StartLoc, SourceLocation LParenLoc, 10246 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 10247 SourceLocation EndLoc) { 10248 OMPClause *Res = nullptr; 10249 switch (Kind) { 10250 case OMPC_schedule: 10251 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 10252 assert(Argument.size() == NumberOfElements && 10253 ArgumentLoc.size() == NumberOfElements); 10254 Res = ActOnOpenMPScheduleClause( 10255 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 10256 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 10257 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 10258 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 10259 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 10260 break; 10261 case OMPC_if: 10262 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 10263 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 10264 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 10265 DelimLoc, EndLoc); 10266 break; 10267 case OMPC_dist_schedule: 10268 Res = ActOnOpenMPDistScheduleClause( 10269 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 10270 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 10271 break; 10272 case OMPC_defaultmap: 10273 enum { Modifier, DefaultmapKind }; 10274 Res = ActOnOpenMPDefaultmapClause( 10275 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 10276 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 10277 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 10278 EndLoc); 10279 break; 10280 case OMPC_final: 10281 case OMPC_num_threads: 10282 case OMPC_safelen: 10283 case OMPC_simdlen: 10284 case OMPC_allocator: 10285 case OMPC_collapse: 10286 case OMPC_default: 10287 case OMPC_proc_bind: 10288 case OMPC_private: 10289 case OMPC_firstprivate: 10290 case OMPC_lastprivate: 10291 case OMPC_shared: 10292 case OMPC_reduction: 10293 case OMPC_task_reduction: 10294 case OMPC_in_reduction: 10295 case OMPC_linear: 10296 case OMPC_aligned: 10297 case OMPC_copyin: 10298 case OMPC_copyprivate: 10299 case OMPC_ordered: 10300 case OMPC_nowait: 10301 case OMPC_untied: 10302 case OMPC_mergeable: 10303 case OMPC_threadprivate: 10304 case OMPC_allocate: 10305 case OMPC_flush: 10306 case OMPC_read: 10307 case OMPC_write: 10308 case OMPC_update: 10309 case OMPC_capture: 10310 case OMPC_seq_cst: 10311 case OMPC_depend: 10312 case OMPC_device: 10313 case OMPC_threads: 10314 case OMPC_simd: 10315 case OMPC_map: 10316 case OMPC_num_teams: 10317 case OMPC_thread_limit: 10318 case OMPC_priority: 10319 case OMPC_grainsize: 10320 case OMPC_nogroup: 10321 case OMPC_num_tasks: 10322 case OMPC_hint: 10323 case OMPC_unknown: 10324 case OMPC_uniform: 10325 case OMPC_to: 10326 case OMPC_from: 10327 case OMPC_use_device_ptr: 10328 case OMPC_is_device_ptr: 10329 case OMPC_unified_address: 10330 case OMPC_unified_shared_memory: 10331 case OMPC_reverse_offload: 10332 case OMPC_dynamic_allocators: 10333 case OMPC_atomic_default_mem_order: 10334 llvm_unreachable("Clause is not allowed."); 10335 } 10336 return Res; 10337 } 10338 10339 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 10340 OpenMPScheduleClauseModifier M2, 10341 SourceLocation M1Loc, SourceLocation M2Loc) { 10342 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 10343 SmallVector<unsigned, 2> Excluded; 10344 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 10345 Excluded.push_back(M2); 10346 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 10347 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 10348 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 10349 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 10350 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 10351 << getListOfPossibleValues(OMPC_schedule, 10352 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 10353 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10354 Excluded) 10355 << getOpenMPClauseName(OMPC_schedule); 10356 return true; 10357 } 10358 return false; 10359 } 10360 10361 OMPClause *Sema::ActOnOpenMPScheduleClause( 10362 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 10363 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10364 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 10365 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 10366 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 10367 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 10368 return nullptr; 10369 // OpenMP, 2.7.1, Loop Construct, Restrictions 10370 // Either the monotonic modifier or the nonmonotonic modifier can be specified 10371 // but not both. 10372 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 10373 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 10374 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 10375 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 10376 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 10377 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 10378 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 10379 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 10380 return nullptr; 10381 } 10382 if (Kind == OMPC_SCHEDULE_unknown) { 10383 std::string Values; 10384 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 10385 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 10386 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10387 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 10388 Exclude); 10389 } else { 10390 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 10391 /*Last=*/OMPC_SCHEDULE_unknown); 10392 } 10393 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10394 << Values << getOpenMPClauseName(OMPC_schedule); 10395 return nullptr; 10396 } 10397 // OpenMP, 2.7.1, Loop Construct, Restrictions 10398 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 10399 // schedule(guided). 10400 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 10401 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 10402 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 10403 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 10404 diag::err_omp_schedule_nonmonotonic_static); 10405 return nullptr; 10406 } 10407 Expr *ValExpr = ChunkSize; 10408 Stmt *HelperValStmt = nullptr; 10409 if (ChunkSize) { 10410 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10411 !ChunkSize->isInstantiationDependent() && 10412 !ChunkSize->containsUnexpandedParameterPack()) { 10413 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 10414 ExprResult Val = 10415 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10416 if (Val.isInvalid()) 10417 return nullptr; 10418 10419 ValExpr = Val.get(); 10420 10421 // OpenMP [2.7.1, Restrictions] 10422 // chunk_size must be a loop invariant integer expression with a positive 10423 // value. 10424 llvm::APSInt Result; 10425 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10426 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10427 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10428 << "schedule" << 1 << ChunkSize->getSourceRange(); 10429 return nullptr; 10430 } 10431 } else if (getOpenMPCaptureRegionForClause( 10432 DSAStack->getCurrentDirective(), OMPC_schedule) != 10433 OMPD_unknown && 10434 !CurContext->isDependentContext()) { 10435 ValExpr = MakeFullExpr(ValExpr).get(); 10436 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10437 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10438 HelperValStmt = buildPreInits(Context, Captures); 10439 } 10440 } 10441 } 10442 10443 return new (Context) 10444 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 10445 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 10446 } 10447 10448 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 10449 SourceLocation StartLoc, 10450 SourceLocation EndLoc) { 10451 OMPClause *Res = nullptr; 10452 switch (Kind) { 10453 case OMPC_ordered: 10454 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 10455 break; 10456 case OMPC_nowait: 10457 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 10458 break; 10459 case OMPC_untied: 10460 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 10461 break; 10462 case OMPC_mergeable: 10463 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 10464 break; 10465 case OMPC_read: 10466 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 10467 break; 10468 case OMPC_write: 10469 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 10470 break; 10471 case OMPC_update: 10472 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 10473 break; 10474 case OMPC_capture: 10475 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 10476 break; 10477 case OMPC_seq_cst: 10478 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 10479 break; 10480 case OMPC_threads: 10481 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 10482 break; 10483 case OMPC_simd: 10484 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 10485 break; 10486 case OMPC_nogroup: 10487 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 10488 break; 10489 case OMPC_unified_address: 10490 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 10491 break; 10492 case OMPC_unified_shared_memory: 10493 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10494 break; 10495 case OMPC_reverse_offload: 10496 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 10497 break; 10498 case OMPC_dynamic_allocators: 10499 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 10500 break; 10501 case OMPC_if: 10502 case OMPC_final: 10503 case OMPC_num_threads: 10504 case OMPC_safelen: 10505 case OMPC_simdlen: 10506 case OMPC_allocator: 10507 case OMPC_collapse: 10508 case OMPC_schedule: 10509 case OMPC_private: 10510 case OMPC_firstprivate: 10511 case OMPC_lastprivate: 10512 case OMPC_shared: 10513 case OMPC_reduction: 10514 case OMPC_task_reduction: 10515 case OMPC_in_reduction: 10516 case OMPC_linear: 10517 case OMPC_aligned: 10518 case OMPC_copyin: 10519 case OMPC_copyprivate: 10520 case OMPC_default: 10521 case OMPC_proc_bind: 10522 case OMPC_threadprivate: 10523 case OMPC_allocate: 10524 case OMPC_flush: 10525 case OMPC_depend: 10526 case OMPC_device: 10527 case OMPC_map: 10528 case OMPC_num_teams: 10529 case OMPC_thread_limit: 10530 case OMPC_priority: 10531 case OMPC_grainsize: 10532 case OMPC_num_tasks: 10533 case OMPC_hint: 10534 case OMPC_dist_schedule: 10535 case OMPC_defaultmap: 10536 case OMPC_unknown: 10537 case OMPC_uniform: 10538 case OMPC_to: 10539 case OMPC_from: 10540 case OMPC_use_device_ptr: 10541 case OMPC_is_device_ptr: 10542 case OMPC_atomic_default_mem_order: 10543 llvm_unreachable("Clause is not allowed."); 10544 } 10545 return Res; 10546 } 10547 10548 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 10549 SourceLocation EndLoc) { 10550 DSAStack->setNowaitRegion(); 10551 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 10552 } 10553 10554 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 10555 SourceLocation EndLoc) { 10556 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 10557 } 10558 10559 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 10560 SourceLocation EndLoc) { 10561 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10562 } 10563 10564 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10565 SourceLocation EndLoc) { 10566 return new (Context) OMPReadClause(StartLoc, EndLoc); 10567 } 10568 10569 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10570 SourceLocation EndLoc) { 10571 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10572 } 10573 10574 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10575 SourceLocation EndLoc) { 10576 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10577 } 10578 10579 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10580 SourceLocation EndLoc) { 10581 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10582 } 10583 10584 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10585 SourceLocation EndLoc) { 10586 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10587 } 10588 10589 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10590 SourceLocation EndLoc) { 10591 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10592 } 10593 10594 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 10595 SourceLocation EndLoc) { 10596 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 10597 } 10598 10599 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 10600 SourceLocation EndLoc) { 10601 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 10602 } 10603 10604 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 10605 SourceLocation EndLoc) { 10606 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 10607 } 10608 10609 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 10610 SourceLocation EndLoc) { 10611 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10612 } 10613 10614 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 10615 SourceLocation EndLoc) { 10616 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 10617 } 10618 10619 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 10620 SourceLocation EndLoc) { 10621 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 10622 } 10623 10624 OMPClause *Sema::ActOnOpenMPVarListClause( 10625 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 10626 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 10627 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 10628 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 10629 OpenMPLinearClauseKind LinKind, 10630 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 10631 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 10632 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 10633 SourceLocation StartLoc = Locs.StartLoc; 10634 SourceLocation LParenLoc = Locs.LParenLoc; 10635 SourceLocation EndLoc = Locs.EndLoc; 10636 OMPClause *Res = nullptr; 10637 switch (Kind) { 10638 case OMPC_private: 10639 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10640 break; 10641 case OMPC_firstprivate: 10642 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10643 break; 10644 case OMPC_lastprivate: 10645 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10646 break; 10647 case OMPC_shared: 10648 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 10649 break; 10650 case OMPC_reduction: 10651 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10652 EndLoc, ReductionOrMapperIdScopeSpec, 10653 ReductionOrMapperId); 10654 break; 10655 case OMPC_task_reduction: 10656 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10657 EndLoc, ReductionOrMapperIdScopeSpec, 10658 ReductionOrMapperId); 10659 break; 10660 case OMPC_in_reduction: 10661 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10662 EndLoc, ReductionOrMapperIdScopeSpec, 10663 ReductionOrMapperId); 10664 break; 10665 case OMPC_linear: 10666 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 10667 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 10668 break; 10669 case OMPC_aligned: 10670 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 10671 ColonLoc, EndLoc); 10672 break; 10673 case OMPC_copyin: 10674 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 10675 break; 10676 case OMPC_copyprivate: 10677 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10678 break; 10679 case OMPC_flush: 10680 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 10681 break; 10682 case OMPC_depend: 10683 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 10684 StartLoc, LParenLoc, EndLoc); 10685 break; 10686 case OMPC_map: 10687 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 10688 ReductionOrMapperIdScopeSpec, 10689 ReductionOrMapperId, MapType, IsMapTypeImplicit, 10690 DepLinMapLoc, ColonLoc, VarList, Locs); 10691 break; 10692 case OMPC_to: 10693 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 10694 ReductionOrMapperId, Locs); 10695 break; 10696 case OMPC_from: 10697 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 10698 ReductionOrMapperId, Locs); 10699 break; 10700 case OMPC_use_device_ptr: 10701 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 10702 break; 10703 case OMPC_is_device_ptr: 10704 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 10705 break; 10706 case OMPC_allocate: 10707 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 10708 ColonLoc, EndLoc); 10709 break; 10710 case OMPC_if: 10711 case OMPC_final: 10712 case OMPC_num_threads: 10713 case OMPC_safelen: 10714 case OMPC_simdlen: 10715 case OMPC_allocator: 10716 case OMPC_collapse: 10717 case OMPC_default: 10718 case OMPC_proc_bind: 10719 case OMPC_schedule: 10720 case OMPC_ordered: 10721 case OMPC_nowait: 10722 case OMPC_untied: 10723 case OMPC_mergeable: 10724 case OMPC_threadprivate: 10725 case OMPC_read: 10726 case OMPC_write: 10727 case OMPC_update: 10728 case OMPC_capture: 10729 case OMPC_seq_cst: 10730 case OMPC_device: 10731 case OMPC_threads: 10732 case OMPC_simd: 10733 case OMPC_num_teams: 10734 case OMPC_thread_limit: 10735 case OMPC_priority: 10736 case OMPC_grainsize: 10737 case OMPC_nogroup: 10738 case OMPC_num_tasks: 10739 case OMPC_hint: 10740 case OMPC_dist_schedule: 10741 case OMPC_defaultmap: 10742 case OMPC_unknown: 10743 case OMPC_uniform: 10744 case OMPC_unified_address: 10745 case OMPC_unified_shared_memory: 10746 case OMPC_reverse_offload: 10747 case OMPC_dynamic_allocators: 10748 case OMPC_atomic_default_mem_order: 10749 llvm_unreachable("Clause is not allowed."); 10750 } 10751 return Res; 10752 } 10753 10754 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10755 ExprObjectKind OK, SourceLocation Loc) { 10756 ExprResult Res = BuildDeclRefExpr( 10757 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10758 if (!Res.isUsable()) 10759 return ExprError(); 10760 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10761 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10762 if (!Res.isUsable()) 10763 return ExprError(); 10764 } 10765 if (VK != VK_LValue && Res.get()->isGLValue()) { 10766 Res = DefaultLvalueConversion(Res.get()); 10767 if (!Res.isUsable()) 10768 return ExprError(); 10769 } 10770 return Res; 10771 } 10772 10773 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10774 SourceLocation StartLoc, 10775 SourceLocation LParenLoc, 10776 SourceLocation EndLoc) { 10777 SmallVector<Expr *, 8> Vars; 10778 SmallVector<Expr *, 8> PrivateCopies; 10779 for (Expr *RefExpr : VarList) { 10780 assert(RefExpr && "NULL expr in OpenMP private clause."); 10781 SourceLocation ELoc; 10782 SourceRange ERange; 10783 Expr *SimpleRefExpr = RefExpr; 10784 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10785 if (Res.second) { 10786 // It will be analyzed later. 10787 Vars.push_back(RefExpr); 10788 PrivateCopies.push_back(nullptr); 10789 } 10790 ValueDecl *D = Res.first; 10791 if (!D) 10792 continue; 10793 10794 QualType Type = D->getType(); 10795 auto *VD = dyn_cast<VarDecl>(D); 10796 10797 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10798 // A variable that appears in a private clause must not have an incomplete 10799 // type or a reference type. 10800 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10801 continue; 10802 Type = Type.getNonReferenceType(); 10803 10804 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10805 // A variable that is privatized must not have a const-qualified type 10806 // unless it is of class type with a mutable member. This restriction does 10807 // not apply to the firstprivate clause. 10808 // 10809 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10810 // A variable that appears in a private clause must not have a 10811 // const-qualified type unless it is of class type with a mutable member. 10812 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10813 continue; 10814 10815 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10816 // in a Construct] 10817 // Variables with the predetermined data-sharing attributes may not be 10818 // listed in data-sharing attributes clauses, except for the cases 10819 // listed below. For these exceptions only, listing a predetermined 10820 // variable in a data-sharing attribute clause is allowed and overrides 10821 // the variable's predetermined data-sharing attributes. 10822 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10823 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10824 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10825 << getOpenMPClauseName(OMPC_private); 10826 reportOriginalDsa(*this, DSAStack, D, DVar); 10827 continue; 10828 } 10829 10830 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10831 // Variably modified types are not supported for tasks. 10832 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10833 isOpenMPTaskingDirective(CurrDir)) { 10834 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10835 << getOpenMPClauseName(OMPC_private) << Type 10836 << getOpenMPDirectiveName(CurrDir); 10837 bool IsDecl = 10838 !VD || 10839 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10840 Diag(D->getLocation(), 10841 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10842 << D; 10843 continue; 10844 } 10845 10846 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10847 // A list item cannot appear in both a map clause and a data-sharing 10848 // attribute clause on the same construct 10849 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10850 OpenMPClauseKind ConflictKind; 10851 if (DSAStack->checkMappableExprComponentListsForDecl( 10852 VD, /*CurrentRegionOnly=*/true, 10853 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10854 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10855 ConflictKind = WhereFoundClauseKind; 10856 return true; 10857 })) { 10858 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10859 << getOpenMPClauseName(OMPC_private) 10860 << getOpenMPClauseName(ConflictKind) 10861 << getOpenMPDirectiveName(CurrDir); 10862 reportOriginalDsa(*this, DSAStack, D, DVar); 10863 continue; 10864 } 10865 } 10866 10867 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10868 // A variable of class type (or array thereof) that appears in a private 10869 // clause requires an accessible, unambiguous default constructor for the 10870 // class type. 10871 // Generate helper private variable and initialize it with the default 10872 // value. The address of the original variable is replaced by the address of 10873 // the new private variable in CodeGen. This new variable is not added to 10874 // IdResolver, so the code in the OpenMP region uses original variable for 10875 // proper diagnostics. 10876 Type = Type.getUnqualifiedType(); 10877 VarDecl *VDPrivate = 10878 buildVarDecl(*this, ELoc, Type, D->getName(), 10879 D->hasAttrs() ? &D->getAttrs() : nullptr, 10880 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10881 ActOnUninitializedDecl(VDPrivate); 10882 if (VDPrivate->isInvalidDecl()) 10883 continue; 10884 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10885 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10886 10887 DeclRefExpr *Ref = nullptr; 10888 if (!VD && !CurContext->isDependentContext()) 10889 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10890 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10891 Vars.push_back((VD || CurContext->isDependentContext()) 10892 ? RefExpr->IgnoreParens() 10893 : Ref); 10894 PrivateCopies.push_back(VDPrivateRefExpr); 10895 } 10896 10897 if (Vars.empty()) 10898 return nullptr; 10899 10900 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10901 PrivateCopies); 10902 } 10903 10904 namespace { 10905 class DiagsUninitializedSeveretyRAII { 10906 private: 10907 DiagnosticsEngine &Diags; 10908 SourceLocation SavedLoc; 10909 bool IsIgnored = false; 10910 10911 public: 10912 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10913 bool IsIgnored) 10914 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10915 if (!IsIgnored) { 10916 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10917 /*Map*/ diag::Severity::Ignored, Loc); 10918 } 10919 } 10920 ~DiagsUninitializedSeveretyRAII() { 10921 if (!IsIgnored) 10922 Diags.popMappings(SavedLoc); 10923 } 10924 }; 10925 } 10926 10927 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10928 SourceLocation StartLoc, 10929 SourceLocation LParenLoc, 10930 SourceLocation EndLoc) { 10931 SmallVector<Expr *, 8> Vars; 10932 SmallVector<Expr *, 8> PrivateCopies; 10933 SmallVector<Expr *, 8> Inits; 10934 SmallVector<Decl *, 4> ExprCaptures; 10935 bool IsImplicitClause = 10936 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10937 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10938 10939 for (Expr *RefExpr : VarList) { 10940 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10941 SourceLocation ELoc; 10942 SourceRange ERange; 10943 Expr *SimpleRefExpr = RefExpr; 10944 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10945 if (Res.second) { 10946 // It will be analyzed later. 10947 Vars.push_back(RefExpr); 10948 PrivateCopies.push_back(nullptr); 10949 Inits.push_back(nullptr); 10950 } 10951 ValueDecl *D = Res.first; 10952 if (!D) 10953 continue; 10954 10955 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 10956 QualType Type = D->getType(); 10957 auto *VD = dyn_cast<VarDecl>(D); 10958 10959 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10960 // A variable that appears in a private clause must not have an incomplete 10961 // type or a reference type. 10962 if (RequireCompleteType(ELoc, Type, 10963 diag::err_omp_firstprivate_incomplete_type)) 10964 continue; 10965 Type = Type.getNonReferenceType(); 10966 10967 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10968 // A variable of class type (or array thereof) that appears in a private 10969 // clause requires an accessible, unambiguous copy constructor for the 10970 // class type. 10971 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10972 10973 // If an implicit firstprivate variable found it was checked already. 10974 DSAStackTy::DSAVarData TopDVar; 10975 if (!IsImplicitClause) { 10976 DSAStackTy::DSAVarData DVar = 10977 DSAStack->getTopDSA(D, /*FromParent=*/false); 10978 TopDVar = DVar; 10979 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10980 bool IsConstant = ElemType.isConstant(Context); 10981 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10982 // A list item that specifies a given variable may not appear in more 10983 // than one clause on the same directive, except that a variable may be 10984 // specified in both firstprivate and lastprivate clauses. 10985 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10986 // A list item may appear in a firstprivate or lastprivate clause but not 10987 // both. 10988 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10989 (isOpenMPDistributeDirective(CurrDir) || 10990 DVar.CKind != OMPC_lastprivate) && 10991 DVar.RefExpr) { 10992 Diag(ELoc, diag::err_omp_wrong_dsa) 10993 << getOpenMPClauseName(DVar.CKind) 10994 << getOpenMPClauseName(OMPC_firstprivate); 10995 reportOriginalDsa(*this, DSAStack, D, DVar); 10996 continue; 10997 } 10998 10999 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11000 // in a Construct] 11001 // Variables with the predetermined data-sharing attributes may not be 11002 // listed in data-sharing attributes clauses, except for the cases 11003 // listed below. For these exceptions only, listing a predetermined 11004 // variable in a data-sharing attribute clause is allowed and overrides 11005 // the variable's predetermined data-sharing attributes. 11006 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11007 // in a Construct, C/C++, p.2] 11008 // Variables with const-qualified type having no mutable member may be 11009 // listed in a firstprivate clause, even if they are static data members. 11010 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11011 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11012 Diag(ELoc, diag::err_omp_wrong_dsa) 11013 << getOpenMPClauseName(DVar.CKind) 11014 << getOpenMPClauseName(OMPC_firstprivate); 11015 reportOriginalDsa(*this, DSAStack, D, DVar); 11016 continue; 11017 } 11018 11019 // OpenMP [2.9.3.4, Restrictions, p.2] 11020 // A list item that is private within a parallel region must not appear 11021 // in a firstprivate clause on a worksharing construct if any of the 11022 // worksharing regions arising from the worksharing construct ever bind 11023 // to any of the parallel regions arising from the parallel construct. 11024 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11025 // A list item that is private within a teams region must not appear in a 11026 // firstprivate clause on a distribute construct if any of the distribute 11027 // regions arising from the distribute construct ever bind to any of the 11028 // teams regions arising from the teams construct. 11029 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11030 // A list item that appears in a reduction clause of a teams construct 11031 // must not appear in a firstprivate clause on a distribute construct if 11032 // any of the distribute regions arising from the distribute construct 11033 // ever bind to any of the teams regions arising from the teams construct. 11034 if ((isOpenMPWorksharingDirective(CurrDir) || 11035 isOpenMPDistributeDirective(CurrDir)) && 11036 !isOpenMPParallelDirective(CurrDir) && 11037 !isOpenMPTeamsDirective(CurrDir)) { 11038 DVar = DSAStack->getImplicitDSA(D, true); 11039 if (DVar.CKind != OMPC_shared && 11040 (isOpenMPParallelDirective(DVar.DKind) || 11041 isOpenMPTeamsDirective(DVar.DKind) || 11042 DVar.DKind == OMPD_unknown)) { 11043 Diag(ELoc, diag::err_omp_required_access) 11044 << getOpenMPClauseName(OMPC_firstprivate) 11045 << getOpenMPClauseName(OMPC_shared); 11046 reportOriginalDsa(*this, DSAStack, D, DVar); 11047 continue; 11048 } 11049 } 11050 // OpenMP [2.9.3.4, Restrictions, p.3] 11051 // A list item that appears in a reduction clause of a parallel construct 11052 // must not appear in a firstprivate clause on a worksharing or task 11053 // construct if any of the worksharing or task regions arising from the 11054 // worksharing or task construct ever bind to any of the parallel regions 11055 // arising from the parallel construct. 11056 // OpenMP [2.9.3.4, Restrictions, p.4] 11057 // A list item that appears in a reduction clause in worksharing 11058 // construct must not appear in a firstprivate clause in a task construct 11059 // encountered during execution of any of the worksharing regions arising 11060 // from the worksharing construct. 11061 if (isOpenMPTaskingDirective(CurrDir)) { 11062 DVar = DSAStack->hasInnermostDSA( 11063 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 11064 [](OpenMPDirectiveKind K) { 11065 return isOpenMPParallelDirective(K) || 11066 isOpenMPWorksharingDirective(K) || 11067 isOpenMPTeamsDirective(K); 11068 }, 11069 /*FromParent=*/true); 11070 if (DVar.CKind == OMPC_reduction && 11071 (isOpenMPParallelDirective(DVar.DKind) || 11072 isOpenMPWorksharingDirective(DVar.DKind) || 11073 isOpenMPTeamsDirective(DVar.DKind))) { 11074 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 11075 << getOpenMPDirectiveName(DVar.DKind); 11076 reportOriginalDsa(*this, DSAStack, D, DVar); 11077 continue; 11078 } 11079 } 11080 11081 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11082 // A list item cannot appear in both a map clause and a data-sharing 11083 // attribute clause on the same construct 11084 if (isOpenMPTargetExecutionDirective(CurrDir)) { 11085 OpenMPClauseKind ConflictKind; 11086 if (DSAStack->checkMappableExprComponentListsForDecl( 11087 VD, /*CurrentRegionOnly=*/true, 11088 [&ConflictKind]( 11089 OMPClauseMappableExprCommon::MappableExprComponentListRef, 11090 OpenMPClauseKind WhereFoundClauseKind) { 11091 ConflictKind = WhereFoundClauseKind; 11092 return true; 11093 })) { 11094 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11095 << getOpenMPClauseName(OMPC_firstprivate) 11096 << getOpenMPClauseName(ConflictKind) 11097 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11098 reportOriginalDsa(*this, DSAStack, D, DVar); 11099 continue; 11100 } 11101 } 11102 } 11103 11104 // Variably modified types are not supported for tasks. 11105 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11106 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 11107 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11108 << getOpenMPClauseName(OMPC_firstprivate) << Type 11109 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11110 bool IsDecl = 11111 !VD || 11112 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11113 Diag(D->getLocation(), 11114 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11115 << D; 11116 continue; 11117 } 11118 11119 Type = Type.getUnqualifiedType(); 11120 VarDecl *VDPrivate = 11121 buildVarDecl(*this, ELoc, Type, D->getName(), 11122 D->hasAttrs() ? &D->getAttrs() : nullptr, 11123 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11124 // Generate helper private variable and initialize it with the value of the 11125 // original variable. The address of the original variable is replaced by 11126 // the address of the new private variable in the CodeGen. This new variable 11127 // is not added to IdResolver, so the code in the OpenMP region uses 11128 // original variable for proper diagnostics and variable capturing. 11129 Expr *VDInitRefExpr = nullptr; 11130 // For arrays generate initializer for single element and replace it by the 11131 // original array element in CodeGen. 11132 if (Type->isArrayType()) { 11133 VarDecl *VDInit = 11134 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 11135 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 11136 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 11137 ElemType = ElemType.getUnqualifiedType(); 11138 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 11139 ".firstprivate.temp"); 11140 InitializedEntity Entity = 11141 InitializedEntity::InitializeVariable(VDInitTemp); 11142 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 11143 11144 InitializationSequence InitSeq(*this, Entity, Kind, Init); 11145 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 11146 if (Result.isInvalid()) 11147 VDPrivate->setInvalidDecl(); 11148 else 11149 VDPrivate->setInit(Result.getAs<Expr>()); 11150 // Remove temp variable declaration. 11151 Context.Deallocate(VDInitTemp); 11152 } else { 11153 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 11154 ".firstprivate.temp"); 11155 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11156 RefExpr->getExprLoc()); 11157 AddInitializerToDecl(VDPrivate, 11158 DefaultLvalueConversion(VDInitRefExpr).get(), 11159 /*DirectInit=*/false); 11160 } 11161 if (VDPrivate->isInvalidDecl()) { 11162 if (IsImplicitClause) { 11163 Diag(RefExpr->getExprLoc(), 11164 diag::note_omp_task_predetermined_firstprivate_here); 11165 } 11166 continue; 11167 } 11168 CurContext->addDecl(VDPrivate); 11169 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11170 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 11171 RefExpr->getExprLoc()); 11172 DeclRefExpr *Ref = nullptr; 11173 if (!VD && !CurContext->isDependentContext()) { 11174 if (TopDVar.CKind == OMPC_lastprivate) { 11175 Ref = TopDVar.PrivateCopy; 11176 } else { 11177 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11178 if (!isOpenMPCapturedDecl(D)) 11179 ExprCaptures.push_back(Ref->getDecl()); 11180 } 11181 } 11182 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11183 Vars.push_back((VD || CurContext->isDependentContext()) 11184 ? RefExpr->IgnoreParens() 11185 : Ref); 11186 PrivateCopies.push_back(VDPrivateRefExpr); 11187 Inits.push_back(VDInitRefExpr); 11188 } 11189 11190 if (Vars.empty()) 11191 return nullptr; 11192 11193 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11194 Vars, PrivateCopies, Inits, 11195 buildPreInits(Context, ExprCaptures)); 11196 } 11197 11198 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 11199 SourceLocation StartLoc, 11200 SourceLocation LParenLoc, 11201 SourceLocation EndLoc) { 11202 SmallVector<Expr *, 8> Vars; 11203 SmallVector<Expr *, 8> SrcExprs; 11204 SmallVector<Expr *, 8> DstExprs; 11205 SmallVector<Expr *, 8> AssignmentOps; 11206 SmallVector<Decl *, 4> ExprCaptures; 11207 SmallVector<Expr *, 4> ExprPostUpdates; 11208 for (Expr *RefExpr : VarList) { 11209 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11210 SourceLocation ELoc; 11211 SourceRange ERange; 11212 Expr *SimpleRefExpr = RefExpr; 11213 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11214 if (Res.second) { 11215 // It will be analyzed later. 11216 Vars.push_back(RefExpr); 11217 SrcExprs.push_back(nullptr); 11218 DstExprs.push_back(nullptr); 11219 AssignmentOps.push_back(nullptr); 11220 } 11221 ValueDecl *D = Res.first; 11222 if (!D) 11223 continue; 11224 11225 QualType Type = D->getType(); 11226 auto *VD = dyn_cast<VarDecl>(D); 11227 11228 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 11229 // A variable that appears in a lastprivate clause must not have an 11230 // incomplete type or a reference type. 11231 if (RequireCompleteType(ELoc, Type, 11232 diag::err_omp_lastprivate_incomplete_type)) 11233 continue; 11234 Type = Type.getNonReferenceType(); 11235 11236 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11237 // A variable that is privatized must not have a const-qualified type 11238 // unless it is of class type with a mutable member. This restriction does 11239 // not apply to the firstprivate clause. 11240 // 11241 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 11242 // A variable that appears in a lastprivate clause must not have a 11243 // const-qualified type unless it is of class type with a mutable member. 11244 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 11245 continue; 11246 11247 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11248 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11249 // in a Construct] 11250 // Variables with the predetermined data-sharing attributes may not be 11251 // listed in data-sharing attributes clauses, except for the cases 11252 // listed below. 11253 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11254 // A list item may appear in a firstprivate or lastprivate clause but not 11255 // both. 11256 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11257 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 11258 (isOpenMPDistributeDirective(CurrDir) || 11259 DVar.CKind != OMPC_firstprivate) && 11260 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 11261 Diag(ELoc, diag::err_omp_wrong_dsa) 11262 << getOpenMPClauseName(DVar.CKind) 11263 << getOpenMPClauseName(OMPC_lastprivate); 11264 reportOriginalDsa(*this, DSAStack, D, DVar); 11265 continue; 11266 } 11267 11268 // OpenMP [2.14.3.5, Restrictions, p.2] 11269 // A list item that is private within a parallel region, or that appears in 11270 // the reduction clause of a parallel construct, must not appear in a 11271 // lastprivate clause on a worksharing construct if any of the corresponding 11272 // worksharing regions ever binds to any of the corresponding parallel 11273 // regions. 11274 DSAStackTy::DSAVarData TopDVar = DVar; 11275 if (isOpenMPWorksharingDirective(CurrDir) && 11276 !isOpenMPParallelDirective(CurrDir) && 11277 !isOpenMPTeamsDirective(CurrDir)) { 11278 DVar = DSAStack->getImplicitDSA(D, true); 11279 if (DVar.CKind != OMPC_shared) { 11280 Diag(ELoc, diag::err_omp_required_access) 11281 << getOpenMPClauseName(OMPC_lastprivate) 11282 << getOpenMPClauseName(OMPC_shared); 11283 reportOriginalDsa(*this, DSAStack, D, DVar); 11284 continue; 11285 } 11286 } 11287 11288 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 11289 // A variable of class type (or array thereof) that appears in a 11290 // lastprivate clause requires an accessible, unambiguous default 11291 // constructor for the class type, unless the list item is also specified 11292 // in a firstprivate clause. 11293 // A variable of class type (or array thereof) that appears in a 11294 // lastprivate clause requires an accessible, unambiguous copy assignment 11295 // operator for the class type. 11296 Type = Context.getBaseElementType(Type).getNonReferenceType(); 11297 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 11298 Type.getUnqualifiedType(), ".lastprivate.src", 11299 D->hasAttrs() ? &D->getAttrs() : nullptr); 11300 DeclRefExpr *PseudoSrcExpr = 11301 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 11302 VarDecl *DstVD = 11303 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 11304 D->hasAttrs() ? &D->getAttrs() : nullptr); 11305 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11306 // For arrays generate assignment operation for single element and replace 11307 // it by the original array element in CodeGen. 11308 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 11309 PseudoDstExpr, PseudoSrcExpr); 11310 if (AssignmentOp.isInvalid()) 11311 continue; 11312 AssignmentOp = 11313 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 11314 if (AssignmentOp.isInvalid()) 11315 continue; 11316 11317 DeclRefExpr *Ref = nullptr; 11318 if (!VD && !CurContext->isDependentContext()) { 11319 if (TopDVar.CKind == OMPC_firstprivate) { 11320 Ref = TopDVar.PrivateCopy; 11321 } else { 11322 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11323 if (!isOpenMPCapturedDecl(D)) 11324 ExprCaptures.push_back(Ref->getDecl()); 11325 } 11326 if (TopDVar.CKind == OMPC_firstprivate || 11327 (!isOpenMPCapturedDecl(D) && 11328 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 11329 ExprResult RefRes = DefaultLvalueConversion(Ref); 11330 if (!RefRes.isUsable()) 11331 continue; 11332 ExprResult PostUpdateRes = 11333 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11334 RefRes.get()); 11335 if (!PostUpdateRes.isUsable()) 11336 continue; 11337 ExprPostUpdates.push_back( 11338 IgnoredValueConversions(PostUpdateRes.get()).get()); 11339 } 11340 } 11341 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 11342 Vars.push_back((VD || CurContext->isDependentContext()) 11343 ? RefExpr->IgnoreParens() 11344 : Ref); 11345 SrcExprs.push_back(PseudoSrcExpr); 11346 DstExprs.push_back(PseudoDstExpr); 11347 AssignmentOps.push_back(AssignmentOp.get()); 11348 } 11349 11350 if (Vars.empty()) 11351 return nullptr; 11352 11353 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11354 Vars, SrcExprs, DstExprs, AssignmentOps, 11355 buildPreInits(Context, ExprCaptures), 11356 buildPostUpdate(*this, ExprPostUpdates)); 11357 } 11358 11359 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 11360 SourceLocation StartLoc, 11361 SourceLocation LParenLoc, 11362 SourceLocation EndLoc) { 11363 SmallVector<Expr *, 8> Vars; 11364 for (Expr *RefExpr : VarList) { 11365 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 11366 SourceLocation ELoc; 11367 SourceRange ERange; 11368 Expr *SimpleRefExpr = RefExpr; 11369 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11370 if (Res.second) { 11371 // It will be analyzed later. 11372 Vars.push_back(RefExpr); 11373 } 11374 ValueDecl *D = Res.first; 11375 if (!D) 11376 continue; 11377 11378 auto *VD = dyn_cast<VarDecl>(D); 11379 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11380 // in a Construct] 11381 // Variables with the predetermined data-sharing attributes may not be 11382 // listed in data-sharing attributes clauses, except for the cases 11383 // listed below. For these exceptions only, listing a predetermined 11384 // variable in a data-sharing attribute clause is allowed and overrides 11385 // the variable's predetermined data-sharing attributes. 11386 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11387 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 11388 DVar.RefExpr) { 11389 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11390 << getOpenMPClauseName(OMPC_shared); 11391 reportOriginalDsa(*this, DSAStack, D, DVar); 11392 continue; 11393 } 11394 11395 DeclRefExpr *Ref = nullptr; 11396 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 11397 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11398 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 11399 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 11400 ? RefExpr->IgnoreParens() 11401 : Ref); 11402 } 11403 11404 if (Vars.empty()) 11405 return nullptr; 11406 11407 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 11408 } 11409 11410 namespace { 11411 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 11412 DSAStackTy *Stack; 11413 11414 public: 11415 bool VisitDeclRefExpr(DeclRefExpr *E) { 11416 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 11417 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 11418 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 11419 return false; 11420 if (DVar.CKind != OMPC_unknown) 11421 return true; 11422 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 11423 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 11424 /*FromParent=*/true); 11425 return DVarPrivate.CKind != OMPC_unknown; 11426 } 11427 return false; 11428 } 11429 bool VisitStmt(Stmt *S) { 11430 for (Stmt *Child : S->children()) { 11431 if (Child && Visit(Child)) 11432 return true; 11433 } 11434 return false; 11435 } 11436 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 11437 }; 11438 } // namespace 11439 11440 namespace { 11441 // Transform MemberExpression for specified FieldDecl of current class to 11442 // DeclRefExpr to specified OMPCapturedExprDecl. 11443 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 11444 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 11445 ValueDecl *Field = nullptr; 11446 DeclRefExpr *CapturedExpr = nullptr; 11447 11448 public: 11449 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 11450 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 11451 11452 ExprResult TransformMemberExpr(MemberExpr *E) { 11453 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 11454 E->getMemberDecl() == Field) { 11455 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 11456 return CapturedExpr; 11457 } 11458 return BaseTransform::TransformMemberExpr(E); 11459 } 11460 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 11461 }; 11462 } // namespace 11463 11464 template <typename T, typename U> 11465 static T filterLookupForUDReductionAndMapper( 11466 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 11467 for (U &Set : Lookups) { 11468 for (auto *D : Set) { 11469 if (T Res = Gen(cast<ValueDecl>(D))) 11470 return Res; 11471 } 11472 } 11473 return T(); 11474 } 11475 11476 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 11477 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 11478 11479 for (auto RD : D->redecls()) { 11480 // Don't bother with extra checks if we already know this one isn't visible. 11481 if (RD == D) 11482 continue; 11483 11484 auto ND = cast<NamedDecl>(RD); 11485 if (LookupResult::isVisible(SemaRef, ND)) 11486 return ND; 11487 } 11488 11489 return nullptr; 11490 } 11491 11492 static void 11493 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 11494 SourceLocation Loc, QualType Ty, 11495 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 11496 // Find all of the associated namespaces and classes based on the 11497 // arguments we have. 11498 Sema::AssociatedNamespaceSet AssociatedNamespaces; 11499 Sema::AssociatedClassSet AssociatedClasses; 11500 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 11501 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 11502 AssociatedClasses); 11503 11504 // C++ [basic.lookup.argdep]p3: 11505 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11506 // and let Y be the lookup set produced by argument dependent 11507 // lookup (defined as follows). If X contains [...] then Y is 11508 // empty. Otherwise Y is the set of declarations found in the 11509 // namespaces associated with the argument types as described 11510 // below. The set of declarations found by the lookup of the name 11511 // is the union of X and Y. 11512 // 11513 // Here, we compute Y and add its members to the overloaded 11514 // candidate set. 11515 for (auto *NS : AssociatedNamespaces) { 11516 // When considering an associated namespace, the lookup is the 11517 // same as the lookup performed when the associated namespace is 11518 // used as a qualifier (3.4.3.2) except that: 11519 // 11520 // -- Any using-directives in the associated namespace are 11521 // ignored. 11522 // 11523 // -- Any namespace-scope friend functions declared in 11524 // associated classes are visible within their respective 11525 // namespaces even if they are not visible during an ordinary 11526 // lookup (11.4). 11527 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11528 for (auto *D : R) { 11529 auto *Underlying = D; 11530 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11531 Underlying = USD->getTargetDecl(); 11532 11533 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11534 !isa<OMPDeclareMapperDecl>(Underlying)) 11535 continue; 11536 11537 if (!SemaRef.isVisible(D)) { 11538 D = findAcceptableDecl(SemaRef, D); 11539 if (!D) 11540 continue; 11541 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11542 Underlying = USD->getTargetDecl(); 11543 } 11544 Lookups.emplace_back(); 11545 Lookups.back().addDecl(Underlying); 11546 } 11547 } 11548 } 11549 11550 static ExprResult 11551 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11552 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11553 const DeclarationNameInfo &ReductionId, QualType Ty, 11554 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11555 if (ReductionIdScopeSpec.isInvalid()) 11556 return ExprError(); 11557 SmallVector<UnresolvedSet<8>, 4> Lookups; 11558 if (S) { 11559 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11560 Lookup.suppressDiagnostics(); 11561 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11562 NamedDecl *D = Lookup.getRepresentativeDecl(); 11563 do { 11564 S = S->getParent(); 11565 } while (S && !S->isDeclScope(D)); 11566 if (S) 11567 S = S->getParent(); 11568 Lookups.emplace_back(); 11569 Lookups.back().append(Lookup.begin(), Lookup.end()); 11570 Lookup.clear(); 11571 } 11572 } else if (auto *ULE = 11573 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11574 Lookups.push_back(UnresolvedSet<8>()); 11575 Decl *PrevD = nullptr; 11576 for (NamedDecl *D : ULE->decls()) { 11577 if (D == PrevD) 11578 Lookups.push_back(UnresolvedSet<8>()); 11579 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11580 Lookups.back().addDecl(DRD); 11581 PrevD = D; 11582 } 11583 } 11584 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11585 Ty->isInstantiationDependentType() || 11586 Ty->containsUnexpandedParameterPack() || 11587 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11588 return !D->isInvalidDecl() && 11589 (D->getType()->isDependentType() || 11590 D->getType()->isInstantiationDependentType() || 11591 D->getType()->containsUnexpandedParameterPack()); 11592 })) { 11593 UnresolvedSet<8> ResSet; 11594 for (const UnresolvedSet<8> &Set : Lookups) { 11595 if (Set.empty()) 11596 continue; 11597 ResSet.append(Set.begin(), Set.end()); 11598 // The last item marks the end of all declarations at the specified scope. 11599 ResSet.addDecl(Set[Set.size() - 1]); 11600 } 11601 return UnresolvedLookupExpr::Create( 11602 SemaRef.Context, /*NamingClass=*/nullptr, 11603 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 11604 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 11605 } 11606 // Lookup inside the classes. 11607 // C++ [over.match.oper]p3: 11608 // For a unary operator @ with an operand of a type whose 11609 // cv-unqualified version is T1, and for a binary operator @ with 11610 // a left operand of a type whose cv-unqualified version is T1 and 11611 // a right operand of a type whose cv-unqualified version is T2, 11612 // three sets of candidate functions, designated member 11613 // candidates, non-member candidates and built-in candidates, are 11614 // constructed as follows: 11615 // -- If T1 is a complete class type or a class currently being 11616 // defined, the set of member candidates is the result of the 11617 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 11618 // the set of member candidates is empty. 11619 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11620 Lookup.suppressDiagnostics(); 11621 if (const auto *TyRec = Ty->getAs<RecordType>()) { 11622 // Complete the type if it can be completed. 11623 // If the type is neither complete nor being defined, bail out now. 11624 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 11625 TyRec->getDecl()->getDefinition()) { 11626 Lookup.clear(); 11627 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 11628 if (Lookup.empty()) { 11629 Lookups.emplace_back(); 11630 Lookups.back().append(Lookup.begin(), Lookup.end()); 11631 } 11632 } 11633 } 11634 // Perform ADL. 11635 if (SemaRef.getLangOpts().CPlusPlus) 11636 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 11637 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11638 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 11639 if (!D->isInvalidDecl() && 11640 SemaRef.Context.hasSameType(D->getType(), Ty)) 11641 return D; 11642 return nullptr; 11643 })) 11644 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 11645 VK_LValue, Loc); 11646 if (SemaRef.getLangOpts().CPlusPlus) { 11647 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11648 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 11649 if (!D->isInvalidDecl() && 11650 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 11651 !Ty.isMoreQualifiedThan(D->getType())) 11652 return D; 11653 return nullptr; 11654 })) { 11655 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 11656 /*DetectVirtual=*/false); 11657 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 11658 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 11659 VD->getType().getUnqualifiedType()))) { 11660 if (SemaRef.CheckBaseClassAccess( 11661 Loc, VD->getType(), Ty, Paths.front(), 11662 /*DiagID=*/0) != Sema::AR_inaccessible) { 11663 SemaRef.BuildBasePathArray(Paths, BasePath); 11664 return SemaRef.BuildDeclRefExpr( 11665 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 11666 } 11667 } 11668 } 11669 } 11670 } 11671 if (ReductionIdScopeSpec.isSet()) { 11672 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 11673 return ExprError(); 11674 } 11675 return ExprEmpty(); 11676 } 11677 11678 namespace { 11679 /// Data for the reduction-based clauses. 11680 struct ReductionData { 11681 /// List of original reduction items. 11682 SmallVector<Expr *, 8> Vars; 11683 /// List of private copies of the reduction items. 11684 SmallVector<Expr *, 8> Privates; 11685 /// LHS expressions for the reduction_op expressions. 11686 SmallVector<Expr *, 8> LHSs; 11687 /// RHS expressions for the reduction_op expressions. 11688 SmallVector<Expr *, 8> RHSs; 11689 /// Reduction operation expression. 11690 SmallVector<Expr *, 8> ReductionOps; 11691 /// Taskgroup descriptors for the corresponding reduction items in 11692 /// in_reduction clauses. 11693 SmallVector<Expr *, 8> TaskgroupDescriptors; 11694 /// List of captures for clause. 11695 SmallVector<Decl *, 4> ExprCaptures; 11696 /// List of postupdate expressions. 11697 SmallVector<Expr *, 4> ExprPostUpdates; 11698 ReductionData() = delete; 11699 /// Reserves required memory for the reduction data. 11700 ReductionData(unsigned Size) { 11701 Vars.reserve(Size); 11702 Privates.reserve(Size); 11703 LHSs.reserve(Size); 11704 RHSs.reserve(Size); 11705 ReductionOps.reserve(Size); 11706 TaskgroupDescriptors.reserve(Size); 11707 ExprCaptures.reserve(Size); 11708 ExprPostUpdates.reserve(Size); 11709 } 11710 /// Stores reduction item and reduction operation only (required for dependent 11711 /// reduction item). 11712 void push(Expr *Item, Expr *ReductionOp) { 11713 Vars.emplace_back(Item); 11714 Privates.emplace_back(nullptr); 11715 LHSs.emplace_back(nullptr); 11716 RHSs.emplace_back(nullptr); 11717 ReductionOps.emplace_back(ReductionOp); 11718 TaskgroupDescriptors.emplace_back(nullptr); 11719 } 11720 /// Stores reduction data. 11721 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11722 Expr *TaskgroupDescriptor) { 11723 Vars.emplace_back(Item); 11724 Privates.emplace_back(Private); 11725 LHSs.emplace_back(LHS); 11726 RHSs.emplace_back(RHS); 11727 ReductionOps.emplace_back(ReductionOp); 11728 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11729 } 11730 }; 11731 } // namespace 11732 11733 static bool checkOMPArraySectionConstantForReduction( 11734 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11735 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11736 const Expr *Length = OASE->getLength(); 11737 if (Length == nullptr) { 11738 // For array sections of the form [1:] or [:], we would need to analyze 11739 // the lower bound... 11740 if (OASE->getColonLoc().isValid()) 11741 return false; 11742 11743 // This is an array subscript which has implicit length 1! 11744 SingleElement = true; 11745 ArraySizes.push_back(llvm::APSInt::get(1)); 11746 } else { 11747 Expr::EvalResult Result; 11748 if (!Length->EvaluateAsInt(Result, Context)) 11749 return false; 11750 11751 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11752 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11753 ArraySizes.push_back(ConstantLengthValue); 11754 } 11755 11756 // Get the base of this array section and walk up from there. 11757 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11758 11759 // We require length = 1 for all array sections except the right-most to 11760 // guarantee that the memory region is contiguous and has no holes in it. 11761 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11762 Length = TempOASE->getLength(); 11763 if (Length == nullptr) { 11764 // For array sections of the form [1:] or [:], we would need to analyze 11765 // the lower bound... 11766 if (OASE->getColonLoc().isValid()) 11767 return false; 11768 11769 // This is an array subscript which has implicit length 1! 11770 ArraySizes.push_back(llvm::APSInt::get(1)); 11771 } else { 11772 Expr::EvalResult Result; 11773 if (!Length->EvaluateAsInt(Result, Context)) 11774 return false; 11775 11776 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11777 if (ConstantLengthValue.getSExtValue() != 1) 11778 return false; 11779 11780 ArraySizes.push_back(ConstantLengthValue); 11781 } 11782 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11783 } 11784 11785 // If we have a single element, we don't need to add the implicit lengths. 11786 if (!SingleElement) { 11787 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11788 // Has implicit length 1! 11789 ArraySizes.push_back(llvm::APSInt::get(1)); 11790 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11791 } 11792 } 11793 11794 // This array section can be privatized as a single value or as a constant 11795 // sized array. 11796 return true; 11797 } 11798 11799 static bool actOnOMPReductionKindClause( 11800 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11801 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11802 SourceLocation ColonLoc, SourceLocation EndLoc, 11803 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11804 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11805 DeclarationName DN = ReductionId.getName(); 11806 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11807 BinaryOperatorKind BOK = BO_Comma; 11808 11809 ASTContext &Context = S.Context; 11810 // OpenMP [2.14.3.6, reduction clause] 11811 // C 11812 // reduction-identifier is either an identifier or one of the following 11813 // operators: +, -, *, &, |, ^, && and || 11814 // C++ 11815 // reduction-identifier is either an id-expression or one of the following 11816 // operators: +, -, *, &, |, ^, && and || 11817 switch (OOK) { 11818 case OO_Plus: 11819 case OO_Minus: 11820 BOK = BO_Add; 11821 break; 11822 case OO_Star: 11823 BOK = BO_Mul; 11824 break; 11825 case OO_Amp: 11826 BOK = BO_And; 11827 break; 11828 case OO_Pipe: 11829 BOK = BO_Or; 11830 break; 11831 case OO_Caret: 11832 BOK = BO_Xor; 11833 break; 11834 case OO_AmpAmp: 11835 BOK = BO_LAnd; 11836 break; 11837 case OO_PipePipe: 11838 BOK = BO_LOr; 11839 break; 11840 case OO_New: 11841 case OO_Delete: 11842 case OO_Array_New: 11843 case OO_Array_Delete: 11844 case OO_Slash: 11845 case OO_Percent: 11846 case OO_Tilde: 11847 case OO_Exclaim: 11848 case OO_Equal: 11849 case OO_Less: 11850 case OO_Greater: 11851 case OO_LessEqual: 11852 case OO_GreaterEqual: 11853 case OO_PlusEqual: 11854 case OO_MinusEqual: 11855 case OO_StarEqual: 11856 case OO_SlashEqual: 11857 case OO_PercentEqual: 11858 case OO_CaretEqual: 11859 case OO_AmpEqual: 11860 case OO_PipeEqual: 11861 case OO_LessLess: 11862 case OO_GreaterGreater: 11863 case OO_LessLessEqual: 11864 case OO_GreaterGreaterEqual: 11865 case OO_EqualEqual: 11866 case OO_ExclaimEqual: 11867 case OO_Spaceship: 11868 case OO_PlusPlus: 11869 case OO_MinusMinus: 11870 case OO_Comma: 11871 case OO_ArrowStar: 11872 case OO_Arrow: 11873 case OO_Call: 11874 case OO_Subscript: 11875 case OO_Conditional: 11876 case OO_Coawait: 11877 case NUM_OVERLOADED_OPERATORS: 11878 llvm_unreachable("Unexpected reduction identifier"); 11879 case OO_None: 11880 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11881 if (II->isStr("max")) 11882 BOK = BO_GT; 11883 else if (II->isStr("min")) 11884 BOK = BO_LT; 11885 } 11886 break; 11887 } 11888 SourceRange ReductionIdRange; 11889 if (ReductionIdScopeSpec.isValid()) 11890 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11891 else 11892 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11893 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11894 11895 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11896 bool FirstIter = true; 11897 for (Expr *RefExpr : VarList) { 11898 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11899 // OpenMP [2.1, C/C++] 11900 // A list item is a variable or array section, subject to the restrictions 11901 // specified in Section 2.4 on page 42 and in each of the sections 11902 // describing clauses and directives for which a list appears. 11903 // OpenMP [2.14.3.3, Restrictions, p.1] 11904 // A variable that is part of another variable (as an array or 11905 // structure element) cannot appear in a private clause. 11906 if (!FirstIter && IR != ER) 11907 ++IR; 11908 FirstIter = false; 11909 SourceLocation ELoc; 11910 SourceRange ERange; 11911 Expr *SimpleRefExpr = RefExpr; 11912 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11913 /*AllowArraySection=*/true); 11914 if (Res.second) { 11915 // Try to find 'declare reduction' corresponding construct before using 11916 // builtin/overloaded operators. 11917 QualType Type = Context.DependentTy; 11918 CXXCastPath BasePath; 11919 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11920 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11921 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11922 Expr *ReductionOp = nullptr; 11923 if (S.CurContext->isDependentContext() && 11924 (DeclareReductionRef.isUnset() || 11925 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11926 ReductionOp = DeclareReductionRef.get(); 11927 // It will be analyzed later. 11928 RD.push(RefExpr, ReductionOp); 11929 } 11930 ValueDecl *D = Res.first; 11931 if (!D) 11932 continue; 11933 11934 Expr *TaskgroupDescriptor = nullptr; 11935 QualType Type; 11936 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11937 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11938 if (ASE) { 11939 Type = ASE->getType().getNonReferenceType(); 11940 } else if (OASE) { 11941 QualType BaseType = 11942 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11943 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11944 Type = ATy->getElementType(); 11945 else 11946 Type = BaseType->getPointeeType(); 11947 Type = Type.getNonReferenceType(); 11948 } else { 11949 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11950 } 11951 auto *VD = dyn_cast<VarDecl>(D); 11952 11953 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11954 // A variable that appears in a private clause must not have an incomplete 11955 // type or a reference type. 11956 if (S.RequireCompleteType(ELoc, D->getType(), 11957 diag::err_omp_reduction_incomplete_type)) 11958 continue; 11959 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11960 // A list item that appears in a reduction clause must not be 11961 // const-qualified. 11962 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 11963 /*AcceptIfMutable*/ false, ASE || OASE)) 11964 continue; 11965 11966 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 11967 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 11968 // If a list-item is a reference type then it must bind to the same object 11969 // for all threads of the team. 11970 if (!ASE && !OASE) { 11971 if (VD) { 11972 VarDecl *VDDef = VD->getDefinition(); 11973 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11974 DSARefChecker Check(Stack); 11975 if (Check.Visit(VDDef->getInit())) { 11976 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11977 << getOpenMPClauseName(ClauseKind) << ERange; 11978 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11979 continue; 11980 } 11981 } 11982 } 11983 11984 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11985 // in a Construct] 11986 // Variables with the predetermined data-sharing attributes may not be 11987 // listed in data-sharing attributes clauses, except for the cases 11988 // listed below. For these exceptions only, listing a predetermined 11989 // variable in a data-sharing attribute clause is allowed and overrides 11990 // the variable's predetermined data-sharing attributes. 11991 // OpenMP [2.14.3.6, Restrictions, p.3] 11992 // Any number of reduction clauses can be specified on the directive, 11993 // but a list item can appear only once in the reduction clauses for that 11994 // directive. 11995 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11996 if (DVar.CKind == OMPC_reduction) { 11997 S.Diag(ELoc, diag::err_omp_once_referenced) 11998 << getOpenMPClauseName(ClauseKind); 11999 if (DVar.RefExpr) 12000 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12001 continue; 12002 } 12003 if (DVar.CKind != OMPC_unknown) { 12004 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12005 << getOpenMPClauseName(DVar.CKind) 12006 << getOpenMPClauseName(OMPC_reduction); 12007 reportOriginalDsa(S, Stack, D, DVar); 12008 continue; 12009 } 12010 12011 // OpenMP [2.14.3.6, Restrictions, p.1] 12012 // A list item that appears in a reduction clause of a worksharing 12013 // construct must be shared in the parallel regions to which any of the 12014 // worksharing regions arising from the worksharing construct bind. 12015 if (isOpenMPWorksharingDirective(CurrDir) && 12016 !isOpenMPParallelDirective(CurrDir) && 12017 !isOpenMPTeamsDirective(CurrDir)) { 12018 DVar = Stack->getImplicitDSA(D, true); 12019 if (DVar.CKind != OMPC_shared) { 12020 S.Diag(ELoc, diag::err_omp_required_access) 12021 << getOpenMPClauseName(OMPC_reduction) 12022 << getOpenMPClauseName(OMPC_shared); 12023 reportOriginalDsa(S, Stack, D, DVar); 12024 continue; 12025 } 12026 } 12027 } 12028 12029 // Try to find 'declare reduction' corresponding construct before using 12030 // builtin/overloaded operators. 12031 CXXCastPath BasePath; 12032 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12033 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12034 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12035 if (DeclareReductionRef.isInvalid()) 12036 continue; 12037 if (S.CurContext->isDependentContext() && 12038 (DeclareReductionRef.isUnset() || 12039 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 12040 RD.push(RefExpr, DeclareReductionRef.get()); 12041 continue; 12042 } 12043 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 12044 // Not allowed reduction identifier is found. 12045 S.Diag(ReductionId.getBeginLoc(), 12046 diag::err_omp_unknown_reduction_identifier) 12047 << Type << ReductionIdRange; 12048 continue; 12049 } 12050 12051 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12052 // The type of a list item that appears in a reduction clause must be valid 12053 // for the reduction-identifier. For a max or min reduction in C, the type 12054 // of the list item must be an allowed arithmetic data type: char, int, 12055 // float, double, or _Bool, possibly modified with long, short, signed, or 12056 // unsigned. For a max or min reduction in C++, the type of the list item 12057 // must be an allowed arithmetic data type: char, wchar_t, int, float, 12058 // double, or bool, possibly modified with long, short, signed, or unsigned. 12059 if (DeclareReductionRef.isUnset()) { 12060 if ((BOK == BO_GT || BOK == BO_LT) && 12061 !(Type->isScalarType() || 12062 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 12063 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 12064 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 12065 if (!ASE && !OASE) { 12066 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12067 VarDecl::DeclarationOnly; 12068 S.Diag(D->getLocation(), 12069 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12070 << D; 12071 } 12072 continue; 12073 } 12074 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 12075 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 12076 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 12077 << getOpenMPClauseName(ClauseKind); 12078 if (!ASE && !OASE) { 12079 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12080 VarDecl::DeclarationOnly; 12081 S.Diag(D->getLocation(), 12082 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12083 << D; 12084 } 12085 continue; 12086 } 12087 } 12088 12089 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 12090 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 12091 D->hasAttrs() ? &D->getAttrs() : nullptr); 12092 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 12093 D->hasAttrs() ? &D->getAttrs() : nullptr); 12094 QualType PrivateTy = Type; 12095 12096 // Try if we can determine constant lengths for all array sections and avoid 12097 // the VLA. 12098 bool ConstantLengthOASE = false; 12099 if (OASE) { 12100 bool SingleElement; 12101 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 12102 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 12103 Context, OASE, SingleElement, ArraySizes); 12104 12105 // If we don't have a single element, we must emit a constant array type. 12106 if (ConstantLengthOASE && !SingleElement) { 12107 for (llvm::APSInt &Size : ArraySizes) 12108 PrivateTy = Context.getConstantArrayType( 12109 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 12110 } 12111 } 12112 12113 if ((OASE && !ConstantLengthOASE) || 12114 (!OASE && !ASE && 12115 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 12116 if (!Context.getTargetInfo().isVLASupported() && 12117 S.shouldDiagnoseTargetSupportFromOpenMP()) { 12118 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 12119 S.Diag(ELoc, diag::note_vla_unsupported); 12120 continue; 12121 } 12122 // For arrays/array sections only: 12123 // Create pseudo array type for private copy. The size for this array will 12124 // be generated during codegen. 12125 // For array subscripts or single variables Private Ty is the same as Type 12126 // (type of the variable or single array element). 12127 PrivateTy = Context.getVariableArrayType( 12128 Type, 12129 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 12130 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 12131 } else if (!ASE && !OASE && 12132 Context.getAsArrayType(D->getType().getNonReferenceType())) { 12133 PrivateTy = D->getType().getNonReferenceType(); 12134 } 12135 // Private copy. 12136 VarDecl *PrivateVD = 12137 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 12138 D->hasAttrs() ? &D->getAttrs() : nullptr, 12139 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12140 // Add initializer for private variable. 12141 Expr *Init = nullptr; 12142 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 12143 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 12144 if (DeclareReductionRef.isUsable()) { 12145 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 12146 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 12147 if (DRD->getInitializer()) { 12148 Init = DRDRef; 12149 RHSVD->setInit(DRDRef); 12150 RHSVD->setInitStyle(VarDecl::CallInit); 12151 } 12152 } else { 12153 switch (BOK) { 12154 case BO_Add: 12155 case BO_Xor: 12156 case BO_Or: 12157 case BO_LOr: 12158 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 12159 if (Type->isScalarType() || Type->isAnyComplexType()) 12160 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 12161 break; 12162 case BO_Mul: 12163 case BO_LAnd: 12164 if (Type->isScalarType() || Type->isAnyComplexType()) { 12165 // '*' and '&&' reduction ops - initializer is '1'. 12166 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 12167 } 12168 break; 12169 case BO_And: { 12170 // '&' reduction op - initializer is '~0'. 12171 QualType OrigType = Type; 12172 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 12173 Type = ComplexTy->getElementType(); 12174 if (Type->isRealFloatingType()) { 12175 llvm::APFloat InitValue = 12176 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 12177 /*isIEEE=*/true); 12178 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12179 Type, ELoc); 12180 } else if (Type->isScalarType()) { 12181 uint64_t Size = Context.getTypeSize(Type); 12182 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 12183 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 12184 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12185 } 12186 if (Init && OrigType->isAnyComplexType()) { 12187 // Init = 0xFFFF + 0xFFFFi; 12188 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 12189 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 12190 } 12191 Type = OrigType; 12192 break; 12193 } 12194 case BO_LT: 12195 case BO_GT: { 12196 // 'min' reduction op - initializer is 'Largest representable number in 12197 // the reduction list item type'. 12198 // 'max' reduction op - initializer is 'Least representable number in 12199 // the reduction list item type'. 12200 if (Type->isIntegerType() || Type->isPointerType()) { 12201 bool IsSigned = Type->hasSignedIntegerRepresentation(); 12202 uint64_t Size = Context.getTypeSize(Type); 12203 QualType IntTy = 12204 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 12205 llvm::APInt InitValue = 12206 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 12207 : llvm::APInt::getMinValue(Size) 12208 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 12209 : llvm::APInt::getMaxValue(Size); 12210 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 12211 if (Type->isPointerType()) { 12212 // Cast to pointer type. 12213 ExprResult CastExpr = S.BuildCStyleCastExpr( 12214 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 12215 if (CastExpr.isInvalid()) 12216 continue; 12217 Init = CastExpr.get(); 12218 } 12219 } else if (Type->isRealFloatingType()) { 12220 llvm::APFloat InitValue = llvm::APFloat::getLargest( 12221 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 12222 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 12223 Type, ELoc); 12224 } 12225 break; 12226 } 12227 case BO_PtrMemD: 12228 case BO_PtrMemI: 12229 case BO_MulAssign: 12230 case BO_Div: 12231 case BO_Rem: 12232 case BO_Sub: 12233 case BO_Shl: 12234 case BO_Shr: 12235 case BO_LE: 12236 case BO_GE: 12237 case BO_EQ: 12238 case BO_NE: 12239 case BO_Cmp: 12240 case BO_AndAssign: 12241 case BO_XorAssign: 12242 case BO_OrAssign: 12243 case BO_Assign: 12244 case BO_AddAssign: 12245 case BO_SubAssign: 12246 case BO_DivAssign: 12247 case BO_RemAssign: 12248 case BO_ShlAssign: 12249 case BO_ShrAssign: 12250 case BO_Comma: 12251 llvm_unreachable("Unexpected reduction operation"); 12252 } 12253 } 12254 if (Init && DeclareReductionRef.isUnset()) 12255 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 12256 else if (!Init) 12257 S.ActOnUninitializedDecl(RHSVD); 12258 if (RHSVD->isInvalidDecl()) 12259 continue; 12260 if (!RHSVD->hasInit() && 12261 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 12262 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 12263 << Type << ReductionIdRange; 12264 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 12265 VarDecl::DeclarationOnly; 12266 S.Diag(D->getLocation(), 12267 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12268 << D; 12269 continue; 12270 } 12271 // Store initializer for single element in private copy. Will be used during 12272 // codegen. 12273 PrivateVD->setInit(RHSVD->getInit()); 12274 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 12275 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 12276 ExprResult ReductionOp; 12277 if (DeclareReductionRef.isUsable()) { 12278 QualType RedTy = DeclareReductionRef.get()->getType(); 12279 QualType PtrRedTy = Context.getPointerType(RedTy); 12280 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 12281 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 12282 if (!BasePath.empty()) { 12283 LHS = S.DefaultLvalueConversion(LHS.get()); 12284 RHS = S.DefaultLvalueConversion(RHS.get()); 12285 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12286 CK_UncheckedDerivedToBase, LHS.get(), 12287 &BasePath, LHS.get()->getValueKind()); 12288 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 12289 CK_UncheckedDerivedToBase, RHS.get(), 12290 &BasePath, RHS.get()->getValueKind()); 12291 } 12292 FunctionProtoType::ExtProtoInfo EPI; 12293 QualType Params[] = {PtrRedTy, PtrRedTy}; 12294 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 12295 auto *OVE = new (Context) OpaqueValueExpr( 12296 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 12297 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 12298 Expr *Args[] = {LHS.get(), RHS.get()}; 12299 ReductionOp = 12300 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 12301 } else { 12302 ReductionOp = S.BuildBinOp( 12303 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 12304 if (ReductionOp.isUsable()) { 12305 if (BOK != BO_LT && BOK != BO_GT) { 12306 ReductionOp = 12307 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12308 BO_Assign, LHSDRE, ReductionOp.get()); 12309 } else { 12310 auto *ConditionalOp = new (Context) 12311 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 12312 Type, VK_LValue, OK_Ordinary); 12313 ReductionOp = 12314 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 12315 BO_Assign, LHSDRE, ConditionalOp); 12316 } 12317 if (ReductionOp.isUsable()) 12318 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 12319 /*DiscardedValue*/ false); 12320 } 12321 if (!ReductionOp.isUsable()) 12322 continue; 12323 } 12324 12325 // OpenMP [2.15.4.6, Restrictions, p.2] 12326 // A list item that appears in an in_reduction clause of a task construct 12327 // must appear in a task_reduction clause of a construct associated with a 12328 // taskgroup region that includes the participating task in its taskgroup 12329 // set. The construct associated with the innermost region that meets this 12330 // condition must specify the same reduction-identifier as the in_reduction 12331 // clause. 12332 if (ClauseKind == OMPC_in_reduction) { 12333 SourceRange ParentSR; 12334 BinaryOperatorKind ParentBOK; 12335 const Expr *ParentReductionOp; 12336 Expr *ParentBOKTD, *ParentReductionOpTD; 12337 DSAStackTy::DSAVarData ParentBOKDSA = 12338 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 12339 ParentBOKTD); 12340 DSAStackTy::DSAVarData ParentReductionOpDSA = 12341 Stack->getTopMostTaskgroupReductionData( 12342 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 12343 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 12344 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 12345 if (!IsParentBOK && !IsParentReductionOp) { 12346 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 12347 continue; 12348 } 12349 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 12350 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 12351 IsParentReductionOp) { 12352 bool EmitError = true; 12353 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 12354 llvm::FoldingSetNodeID RedId, ParentRedId; 12355 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 12356 DeclareReductionRef.get()->Profile(RedId, Context, 12357 /*Canonical=*/true); 12358 EmitError = RedId != ParentRedId; 12359 } 12360 if (EmitError) { 12361 S.Diag(ReductionId.getBeginLoc(), 12362 diag::err_omp_reduction_identifier_mismatch) 12363 << ReductionIdRange << RefExpr->getSourceRange(); 12364 S.Diag(ParentSR.getBegin(), 12365 diag::note_omp_previous_reduction_identifier) 12366 << ParentSR 12367 << (IsParentBOK ? ParentBOKDSA.RefExpr 12368 : ParentReductionOpDSA.RefExpr) 12369 ->getSourceRange(); 12370 continue; 12371 } 12372 } 12373 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 12374 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 12375 } 12376 12377 DeclRefExpr *Ref = nullptr; 12378 Expr *VarsExpr = RefExpr->IgnoreParens(); 12379 if (!VD && !S.CurContext->isDependentContext()) { 12380 if (ASE || OASE) { 12381 TransformExprToCaptures RebuildToCapture(S, D); 12382 VarsExpr = 12383 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 12384 Ref = RebuildToCapture.getCapturedExpr(); 12385 } else { 12386 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 12387 } 12388 if (!S.isOpenMPCapturedDecl(D)) { 12389 RD.ExprCaptures.emplace_back(Ref->getDecl()); 12390 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12391 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 12392 if (!RefRes.isUsable()) 12393 continue; 12394 ExprResult PostUpdateRes = 12395 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12396 RefRes.get()); 12397 if (!PostUpdateRes.isUsable()) 12398 continue; 12399 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 12400 Stack->getCurrentDirective() == OMPD_taskgroup) { 12401 S.Diag(RefExpr->getExprLoc(), 12402 diag::err_omp_reduction_non_addressable_expression) 12403 << RefExpr->getSourceRange(); 12404 continue; 12405 } 12406 RD.ExprPostUpdates.emplace_back( 12407 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 12408 } 12409 } 12410 } 12411 // All reduction items are still marked as reduction (to do not increase 12412 // code base size). 12413 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 12414 if (CurrDir == OMPD_taskgroup) { 12415 if (DeclareReductionRef.isUsable()) 12416 Stack->addTaskgroupReductionData(D, ReductionIdRange, 12417 DeclareReductionRef.get()); 12418 else 12419 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 12420 } 12421 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 12422 TaskgroupDescriptor); 12423 } 12424 return RD.Vars.empty(); 12425 } 12426 12427 OMPClause *Sema::ActOnOpenMPReductionClause( 12428 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12429 SourceLocation ColonLoc, SourceLocation EndLoc, 12430 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12431 ArrayRef<Expr *> UnresolvedReductions) { 12432 ReductionData RD(VarList.size()); 12433 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 12434 StartLoc, LParenLoc, ColonLoc, EndLoc, 12435 ReductionIdScopeSpec, ReductionId, 12436 UnresolvedReductions, RD)) 12437 return nullptr; 12438 12439 return OMPReductionClause::Create( 12440 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12441 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12442 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12443 buildPreInits(Context, RD.ExprCaptures), 12444 buildPostUpdate(*this, RD.ExprPostUpdates)); 12445 } 12446 12447 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 12448 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12449 SourceLocation ColonLoc, SourceLocation EndLoc, 12450 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12451 ArrayRef<Expr *> UnresolvedReductions) { 12452 ReductionData RD(VarList.size()); 12453 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 12454 StartLoc, LParenLoc, ColonLoc, EndLoc, 12455 ReductionIdScopeSpec, ReductionId, 12456 UnresolvedReductions, RD)) 12457 return nullptr; 12458 12459 return OMPTaskReductionClause::Create( 12460 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12461 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12462 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 12463 buildPreInits(Context, RD.ExprCaptures), 12464 buildPostUpdate(*this, RD.ExprPostUpdates)); 12465 } 12466 12467 OMPClause *Sema::ActOnOpenMPInReductionClause( 12468 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12469 SourceLocation ColonLoc, SourceLocation EndLoc, 12470 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12471 ArrayRef<Expr *> UnresolvedReductions) { 12472 ReductionData RD(VarList.size()); 12473 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 12474 StartLoc, LParenLoc, ColonLoc, EndLoc, 12475 ReductionIdScopeSpec, ReductionId, 12476 UnresolvedReductions, RD)) 12477 return nullptr; 12478 12479 return OMPInReductionClause::Create( 12480 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 12481 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 12482 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 12483 buildPreInits(Context, RD.ExprCaptures), 12484 buildPostUpdate(*this, RD.ExprPostUpdates)); 12485 } 12486 12487 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 12488 SourceLocation LinLoc) { 12489 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 12490 LinKind == OMPC_LINEAR_unknown) { 12491 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 12492 return true; 12493 } 12494 return false; 12495 } 12496 12497 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 12498 OpenMPLinearClauseKind LinKind, 12499 QualType Type) { 12500 const auto *VD = dyn_cast_or_null<VarDecl>(D); 12501 // A variable must not have an incomplete type or a reference type. 12502 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 12503 return true; 12504 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 12505 !Type->isReferenceType()) { 12506 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12507 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12508 return true; 12509 } 12510 Type = Type.getNonReferenceType(); 12511 12512 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12513 // A variable that is privatized must not have a const-qualified type 12514 // unless it is of class type with a mutable member. This restriction does 12515 // not apply to the firstprivate clause. 12516 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12517 return true; 12518 12519 // A list item must be of integral or pointer type. 12520 Type = Type.getUnqualifiedType().getCanonicalType(); 12521 const auto *Ty = Type.getTypePtrOrNull(); 12522 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12523 !Ty->isPointerType())) { 12524 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12525 if (D) { 12526 bool IsDecl = 12527 !VD || 12528 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12529 Diag(D->getLocation(), 12530 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12531 << D; 12532 } 12533 return true; 12534 } 12535 return false; 12536 } 12537 12538 OMPClause *Sema::ActOnOpenMPLinearClause( 12539 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12540 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12541 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12542 SmallVector<Expr *, 8> Vars; 12543 SmallVector<Expr *, 8> Privates; 12544 SmallVector<Expr *, 8> Inits; 12545 SmallVector<Decl *, 4> ExprCaptures; 12546 SmallVector<Expr *, 4> ExprPostUpdates; 12547 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12548 LinKind = OMPC_LINEAR_val; 12549 for (Expr *RefExpr : VarList) { 12550 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12551 SourceLocation ELoc; 12552 SourceRange ERange; 12553 Expr *SimpleRefExpr = RefExpr; 12554 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12555 if (Res.second) { 12556 // It will be analyzed later. 12557 Vars.push_back(RefExpr); 12558 Privates.push_back(nullptr); 12559 Inits.push_back(nullptr); 12560 } 12561 ValueDecl *D = Res.first; 12562 if (!D) 12563 continue; 12564 12565 QualType Type = D->getType(); 12566 auto *VD = dyn_cast<VarDecl>(D); 12567 12568 // OpenMP [2.14.3.7, linear clause] 12569 // A list-item cannot appear in more than one linear clause. 12570 // A list-item that appears in a linear clause cannot appear in any 12571 // other data-sharing attribute clause. 12572 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12573 if (DVar.RefExpr) { 12574 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12575 << getOpenMPClauseName(OMPC_linear); 12576 reportOriginalDsa(*this, DSAStack, D, DVar); 12577 continue; 12578 } 12579 12580 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12581 continue; 12582 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12583 12584 // Build private copy of original var. 12585 VarDecl *Private = 12586 buildVarDecl(*this, ELoc, Type, D->getName(), 12587 D->hasAttrs() ? &D->getAttrs() : nullptr, 12588 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12589 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 12590 // Build var to save initial value. 12591 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 12592 Expr *InitExpr; 12593 DeclRefExpr *Ref = nullptr; 12594 if (!VD && !CurContext->isDependentContext()) { 12595 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12596 if (!isOpenMPCapturedDecl(D)) { 12597 ExprCaptures.push_back(Ref->getDecl()); 12598 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12599 ExprResult RefRes = DefaultLvalueConversion(Ref); 12600 if (!RefRes.isUsable()) 12601 continue; 12602 ExprResult PostUpdateRes = 12603 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 12604 SimpleRefExpr, RefRes.get()); 12605 if (!PostUpdateRes.isUsable()) 12606 continue; 12607 ExprPostUpdates.push_back( 12608 IgnoredValueConversions(PostUpdateRes.get()).get()); 12609 } 12610 } 12611 } 12612 if (LinKind == OMPC_LINEAR_uval) 12613 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 12614 else 12615 InitExpr = VD ? SimpleRefExpr : Ref; 12616 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 12617 /*DirectInit=*/false); 12618 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 12619 12620 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 12621 Vars.push_back((VD || CurContext->isDependentContext()) 12622 ? RefExpr->IgnoreParens() 12623 : Ref); 12624 Privates.push_back(PrivateRef); 12625 Inits.push_back(InitRef); 12626 } 12627 12628 if (Vars.empty()) 12629 return nullptr; 12630 12631 Expr *StepExpr = Step; 12632 Expr *CalcStepExpr = nullptr; 12633 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 12634 !Step->isInstantiationDependent() && 12635 !Step->containsUnexpandedParameterPack()) { 12636 SourceLocation StepLoc = Step->getBeginLoc(); 12637 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 12638 if (Val.isInvalid()) 12639 return nullptr; 12640 StepExpr = Val.get(); 12641 12642 // Build var to save the step value. 12643 VarDecl *SaveVar = 12644 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 12645 ExprResult SaveRef = 12646 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 12647 ExprResult CalcStep = 12648 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 12649 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 12650 12651 // Warn about zero linear step (it would be probably better specified as 12652 // making corresponding variables 'const'). 12653 llvm::APSInt Result; 12654 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 12655 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 12656 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 12657 << (Vars.size() > 1); 12658 if (!IsConstant && CalcStep.isUsable()) { 12659 // Calculate the step beforehand instead of doing this on each iteration. 12660 // (This is not used if the number of iterations may be kfold-ed). 12661 CalcStepExpr = CalcStep.get(); 12662 } 12663 } 12664 12665 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 12666 ColonLoc, EndLoc, Vars, Privates, Inits, 12667 StepExpr, CalcStepExpr, 12668 buildPreInits(Context, ExprCaptures), 12669 buildPostUpdate(*this, ExprPostUpdates)); 12670 } 12671 12672 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 12673 Expr *NumIterations, Sema &SemaRef, 12674 Scope *S, DSAStackTy *Stack) { 12675 // Walk the vars and build update/final expressions for the CodeGen. 12676 SmallVector<Expr *, 8> Updates; 12677 SmallVector<Expr *, 8> Finals; 12678 Expr *Step = Clause.getStep(); 12679 Expr *CalcStep = Clause.getCalcStep(); 12680 // OpenMP [2.14.3.7, linear clause] 12681 // If linear-step is not specified it is assumed to be 1. 12682 if (!Step) 12683 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12684 else if (CalcStep) 12685 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12686 bool HasErrors = false; 12687 auto CurInit = Clause.inits().begin(); 12688 auto CurPrivate = Clause.privates().begin(); 12689 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12690 for (Expr *RefExpr : Clause.varlists()) { 12691 SourceLocation ELoc; 12692 SourceRange ERange; 12693 Expr *SimpleRefExpr = RefExpr; 12694 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12695 ValueDecl *D = Res.first; 12696 if (Res.second || !D) { 12697 Updates.push_back(nullptr); 12698 Finals.push_back(nullptr); 12699 HasErrors = true; 12700 continue; 12701 } 12702 auto &&Info = Stack->isLoopControlVariable(D); 12703 // OpenMP [2.15.11, distribute simd Construct] 12704 // A list item may not appear in a linear clause, unless it is the loop 12705 // iteration variable. 12706 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12707 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12708 SemaRef.Diag(ELoc, 12709 diag::err_omp_linear_distribute_var_non_loop_iteration); 12710 Updates.push_back(nullptr); 12711 Finals.push_back(nullptr); 12712 HasErrors = true; 12713 continue; 12714 } 12715 Expr *InitExpr = *CurInit; 12716 12717 // Build privatized reference to the current linear var. 12718 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12719 Expr *CapturedRef; 12720 if (LinKind == OMPC_LINEAR_uval) 12721 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12722 else 12723 CapturedRef = 12724 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12725 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12726 /*RefersToCapture=*/true); 12727 12728 // Build update: Var = InitExpr + IV * Step 12729 ExprResult Update; 12730 if (!Info.first) 12731 Update = 12732 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12733 InitExpr, IV, Step, /* Subtract */ false); 12734 else 12735 Update = *CurPrivate; 12736 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12737 /*DiscardedValue*/ false); 12738 12739 // Build final: Var = InitExpr + NumIterations * Step 12740 ExprResult Final; 12741 if (!Info.first) 12742 Final = 12743 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12744 InitExpr, NumIterations, Step, /*Subtract=*/false); 12745 else 12746 Final = *CurPrivate; 12747 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12748 /*DiscardedValue*/ false); 12749 12750 if (!Update.isUsable() || !Final.isUsable()) { 12751 Updates.push_back(nullptr); 12752 Finals.push_back(nullptr); 12753 HasErrors = true; 12754 } else { 12755 Updates.push_back(Update.get()); 12756 Finals.push_back(Final.get()); 12757 } 12758 ++CurInit; 12759 ++CurPrivate; 12760 } 12761 Clause.setUpdates(Updates); 12762 Clause.setFinals(Finals); 12763 return HasErrors; 12764 } 12765 12766 OMPClause *Sema::ActOnOpenMPAlignedClause( 12767 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12768 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12769 SmallVector<Expr *, 8> Vars; 12770 for (Expr *RefExpr : VarList) { 12771 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12772 SourceLocation ELoc; 12773 SourceRange ERange; 12774 Expr *SimpleRefExpr = RefExpr; 12775 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12776 if (Res.second) { 12777 // It will be analyzed later. 12778 Vars.push_back(RefExpr); 12779 } 12780 ValueDecl *D = Res.first; 12781 if (!D) 12782 continue; 12783 12784 QualType QType = D->getType(); 12785 auto *VD = dyn_cast<VarDecl>(D); 12786 12787 // OpenMP [2.8.1, simd construct, Restrictions] 12788 // The type of list items appearing in the aligned clause must be 12789 // array, pointer, reference to array, or reference to pointer. 12790 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12791 const Type *Ty = QType.getTypePtrOrNull(); 12792 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12793 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12794 << QType << getLangOpts().CPlusPlus << ERange; 12795 bool IsDecl = 12796 !VD || 12797 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12798 Diag(D->getLocation(), 12799 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12800 << D; 12801 continue; 12802 } 12803 12804 // OpenMP [2.8.1, simd construct, Restrictions] 12805 // A list-item cannot appear in more than one aligned clause. 12806 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12807 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12808 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12809 << getOpenMPClauseName(OMPC_aligned); 12810 continue; 12811 } 12812 12813 DeclRefExpr *Ref = nullptr; 12814 if (!VD && isOpenMPCapturedDecl(D)) 12815 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12816 Vars.push_back(DefaultFunctionArrayConversion( 12817 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12818 .get()); 12819 } 12820 12821 // OpenMP [2.8.1, simd construct, Description] 12822 // The parameter of the aligned clause, alignment, must be a constant 12823 // positive integer expression. 12824 // If no optional parameter is specified, implementation-defined default 12825 // alignments for SIMD instructions on the target platforms are assumed. 12826 if (Alignment != nullptr) { 12827 ExprResult AlignResult = 12828 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12829 if (AlignResult.isInvalid()) 12830 return nullptr; 12831 Alignment = AlignResult.get(); 12832 } 12833 if (Vars.empty()) 12834 return nullptr; 12835 12836 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12837 EndLoc, Vars, Alignment); 12838 } 12839 12840 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12841 SourceLocation StartLoc, 12842 SourceLocation LParenLoc, 12843 SourceLocation EndLoc) { 12844 SmallVector<Expr *, 8> Vars; 12845 SmallVector<Expr *, 8> SrcExprs; 12846 SmallVector<Expr *, 8> DstExprs; 12847 SmallVector<Expr *, 8> AssignmentOps; 12848 for (Expr *RefExpr : VarList) { 12849 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12850 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12851 // It will be analyzed later. 12852 Vars.push_back(RefExpr); 12853 SrcExprs.push_back(nullptr); 12854 DstExprs.push_back(nullptr); 12855 AssignmentOps.push_back(nullptr); 12856 continue; 12857 } 12858 12859 SourceLocation ELoc = RefExpr->getExprLoc(); 12860 // OpenMP [2.1, C/C++] 12861 // A list item is a variable name. 12862 // OpenMP [2.14.4.1, Restrictions, p.1] 12863 // A list item that appears in a copyin clause must be threadprivate. 12864 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12865 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12866 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12867 << 0 << RefExpr->getSourceRange(); 12868 continue; 12869 } 12870 12871 Decl *D = DE->getDecl(); 12872 auto *VD = cast<VarDecl>(D); 12873 12874 QualType Type = VD->getType(); 12875 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12876 // It will be analyzed later. 12877 Vars.push_back(DE); 12878 SrcExprs.push_back(nullptr); 12879 DstExprs.push_back(nullptr); 12880 AssignmentOps.push_back(nullptr); 12881 continue; 12882 } 12883 12884 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12885 // A list item that appears in a copyin clause must be threadprivate. 12886 if (!DSAStack->isThreadPrivate(VD)) { 12887 Diag(ELoc, diag::err_omp_required_access) 12888 << getOpenMPClauseName(OMPC_copyin) 12889 << getOpenMPDirectiveName(OMPD_threadprivate); 12890 continue; 12891 } 12892 12893 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12894 // A variable of class type (or array thereof) that appears in a 12895 // copyin clause requires an accessible, unambiguous copy assignment 12896 // operator for the class type. 12897 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12898 VarDecl *SrcVD = 12899 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12900 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12901 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12902 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12903 VarDecl *DstVD = 12904 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12905 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12906 DeclRefExpr *PseudoDstExpr = 12907 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12908 // For arrays generate assignment operation for single element and replace 12909 // it by the original array element in CodeGen. 12910 ExprResult AssignmentOp = 12911 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12912 PseudoSrcExpr); 12913 if (AssignmentOp.isInvalid()) 12914 continue; 12915 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12916 /*DiscardedValue*/ false); 12917 if (AssignmentOp.isInvalid()) 12918 continue; 12919 12920 DSAStack->addDSA(VD, DE, OMPC_copyin); 12921 Vars.push_back(DE); 12922 SrcExprs.push_back(PseudoSrcExpr); 12923 DstExprs.push_back(PseudoDstExpr); 12924 AssignmentOps.push_back(AssignmentOp.get()); 12925 } 12926 12927 if (Vars.empty()) 12928 return nullptr; 12929 12930 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12931 SrcExprs, DstExprs, AssignmentOps); 12932 } 12933 12934 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12935 SourceLocation StartLoc, 12936 SourceLocation LParenLoc, 12937 SourceLocation EndLoc) { 12938 SmallVector<Expr *, 8> Vars; 12939 SmallVector<Expr *, 8> SrcExprs; 12940 SmallVector<Expr *, 8> DstExprs; 12941 SmallVector<Expr *, 8> AssignmentOps; 12942 for (Expr *RefExpr : VarList) { 12943 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12944 SourceLocation ELoc; 12945 SourceRange ERange; 12946 Expr *SimpleRefExpr = RefExpr; 12947 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12948 if (Res.second) { 12949 // It will be analyzed later. 12950 Vars.push_back(RefExpr); 12951 SrcExprs.push_back(nullptr); 12952 DstExprs.push_back(nullptr); 12953 AssignmentOps.push_back(nullptr); 12954 } 12955 ValueDecl *D = Res.first; 12956 if (!D) 12957 continue; 12958 12959 QualType Type = D->getType(); 12960 auto *VD = dyn_cast<VarDecl>(D); 12961 12962 // OpenMP [2.14.4.2, Restrictions, p.2] 12963 // A list item that appears in a copyprivate clause may not appear in a 12964 // private or firstprivate clause on the single construct. 12965 if (!VD || !DSAStack->isThreadPrivate(VD)) { 12966 DSAStackTy::DSAVarData DVar = 12967 DSAStack->getTopDSA(D, /*FromParent=*/false); 12968 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 12969 DVar.RefExpr) { 12970 Diag(ELoc, diag::err_omp_wrong_dsa) 12971 << getOpenMPClauseName(DVar.CKind) 12972 << getOpenMPClauseName(OMPC_copyprivate); 12973 reportOriginalDsa(*this, DSAStack, D, DVar); 12974 continue; 12975 } 12976 12977 // OpenMP [2.11.4.2, Restrictions, p.1] 12978 // All list items that appear in a copyprivate clause must be either 12979 // threadprivate or private in the enclosing context. 12980 if (DVar.CKind == OMPC_unknown) { 12981 DVar = DSAStack->getImplicitDSA(D, false); 12982 if (DVar.CKind == OMPC_shared) { 12983 Diag(ELoc, diag::err_omp_required_access) 12984 << getOpenMPClauseName(OMPC_copyprivate) 12985 << "threadprivate or private in the enclosing context"; 12986 reportOriginalDsa(*this, DSAStack, D, DVar); 12987 continue; 12988 } 12989 } 12990 } 12991 12992 // Variably modified types are not supported. 12993 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12994 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12995 << getOpenMPClauseName(OMPC_copyprivate) << Type 12996 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12997 bool IsDecl = 12998 !VD || 12999 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13000 Diag(D->getLocation(), 13001 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13002 << D; 13003 continue; 13004 } 13005 13006 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13007 // A variable of class type (or array thereof) that appears in a 13008 // copyin clause requires an accessible, unambiguous copy assignment 13009 // operator for the class type. 13010 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13011 .getUnqualifiedType(); 13012 VarDecl *SrcVD = 13013 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13014 D->hasAttrs() ? &D->getAttrs() : nullptr); 13015 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13016 VarDecl *DstVD = 13017 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13018 D->hasAttrs() ? &D->getAttrs() : nullptr); 13019 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13020 ExprResult AssignmentOp = BuildBinOp( 13021 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13022 if (AssignmentOp.isInvalid()) 13023 continue; 13024 AssignmentOp = 13025 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13026 if (AssignmentOp.isInvalid()) 13027 continue; 13028 13029 // No need to mark vars as copyprivate, they are already threadprivate or 13030 // implicitly private. 13031 assert(VD || isOpenMPCapturedDecl(D)); 13032 Vars.push_back( 13033 VD ? RefExpr->IgnoreParens() 13034 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 13035 SrcExprs.push_back(PseudoSrcExpr); 13036 DstExprs.push_back(PseudoDstExpr); 13037 AssignmentOps.push_back(AssignmentOp.get()); 13038 } 13039 13040 if (Vars.empty()) 13041 return nullptr; 13042 13043 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13044 Vars, SrcExprs, DstExprs, AssignmentOps); 13045 } 13046 13047 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 13048 SourceLocation StartLoc, 13049 SourceLocation LParenLoc, 13050 SourceLocation EndLoc) { 13051 if (VarList.empty()) 13052 return nullptr; 13053 13054 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 13055 } 13056 13057 OMPClause * 13058 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 13059 SourceLocation DepLoc, SourceLocation ColonLoc, 13060 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 13061 SourceLocation LParenLoc, SourceLocation EndLoc) { 13062 if (DSAStack->getCurrentDirective() == OMPD_ordered && 13063 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 13064 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13065 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 13066 return nullptr; 13067 } 13068 if (DSAStack->getCurrentDirective() != OMPD_ordered && 13069 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 13070 DepKind == OMPC_DEPEND_sink)) { 13071 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 13072 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 13073 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13074 /*Last=*/OMPC_DEPEND_unknown, Except) 13075 << getOpenMPClauseName(OMPC_depend); 13076 return nullptr; 13077 } 13078 SmallVector<Expr *, 8> Vars; 13079 DSAStackTy::OperatorOffsetTy OpsOffs; 13080 llvm::APSInt DepCounter(/*BitWidth=*/32); 13081 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 13082 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 13083 if (const Expr *OrderedCountExpr = 13084 DSAStack->getParentOrderedRegionParam().first) { 13085 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 13086 TotalDepCount.setIsUnsigned(/*Val=*/true); 13087 } 13088 } 13089 for (Expr *RefExpr : VarList) { 13090 assert(RefExpr && "NULL expr in OpenMP shared clause."); 13091 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13092 // It will be analyzed later. 13093 Vars.push_back(RefExpr); 13094 continue; 13095 } 13096 13097 SourceLocation ELoc = RefExpr->getExprLoc(); 13098 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 13099 if (DepKind == OMPC_DEPEND_sink) { 13100 if (DSAStack->getParentOrderedRegionParam().first && 13101 DepCounter >= TotalDepCount) { 13102 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 13103 continue; 13104 } 13105 ++DepCounter; 13106 // OpenMP [2.13.9, Summary] 13107 // depend(dependence-type : vec), where dependence-type is: 13108 // 'sink' and where vec is the iteration vector, which has the form: 13109 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 13110 // where n is the value specified by the ordered clause in the loop 13111 // directive, xi denotes the loop iteration variable of the i-th nested 13112 // loop associated with the loop directive, and di is a constant 13113 // non-negative integer. 13114 if (CurContext->isDependentContext()) { 13115 // It will be analyzed later. 13116 Vars.push_back(RefExpr); 13117 continue; 13118 } 13119 SimpleExpr = SimpleExpr->IgnoreImplicit(); 13120 OverloadedOperatorKind OOK = OO_None; 13121 SourceLocation OOLoc; 13122 Expr *LHS = SimpleExpr; 13123 Expr *RHS = nullptr; 13124 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 13125 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 13126 OOLoc = BO->getOperatorLoc(); 13127 LHS = BO->getLHS()->IgnoreParenImpCasts(); 13128 RHS = BO->getRHS()->IgnoreParenImpCasts(); 13129 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 13130 OOK = OCE->getOperator(); 13131 OOLoc = OCE->getOperatorLoc(); 13132 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13133 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 13134 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 13135 OOK = MCE->getMethodDecl() 13136 ->getNameInfo() 13137 .getName() 13138 .getCXXOverloadedOperator(); 13139 OOLoc = MCE->getCallee()->getExprLoc(); 13140 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 13141 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 13142 } 13143 SourceLocation ELoc; 13144 SourceRange ERange; 13145 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 13146 if (Res.second) { 13147 // It will be analyzed later. 13148 Vars.push_back(RefExpr); 13149 } 13150 ValueDecl *D = Res.first; 13151 if (!D) 13152 continue; 13153 13154 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 13155 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 13156 continue; 13157 } 13158 if (RHS) { 13159 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 13160 RHS, OMPC_depend, /*StrictlyPositive=*/false); 13161 if (RHSRes.isInvalid()) 13162 continue; 13163 } 13164 if (!CurContext->isDependentContext() && 13165 DSAStack->getParentOrderedRegionParam().first && 13166 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 13167 const ValueDecl *VD = 13168 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 13169 if (VD) 13170 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 13171 << 1 << VD; 13172 else 13173 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 13174 continue; 13175 } 13176 OpsOffs.emplace_back(RHS, OOK); 13177 } else { 13178 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 13179 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 13180 (ASE && 13181 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 13182 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 13183 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13184 << RefExpr->getSourceRange(); 13185 continue; 13186 } 13187 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 13188 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 13189 ExprResult Res = 13190 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 13191 getDiagnostics().setSuppressAllDiagnostics(Suppress); 13192 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 13193 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 13194 << RefExpr->getSourceRange(); 13195 continue; 13196 } 13197 } 13198 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 13199 } 13200 13201 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 13202 TotalDepCount > VarList.size() && 13203 DSAStack->getParentOrderedRegionParam().first && 13204 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 13205 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 13206 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 13207 } 13208 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 13209 Vars.empty()) 13210 return nullptr; 13211 13212 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13213 DepKind, DepLoc, ColonLoc, Vars, 13214 TotalDepCount.getZExtValue()); 13215 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 13216 DSAStack->isParentOrderedRegion()) 13217 DSAStack->addDoacrossDependClause(C, OpsOffs); 13218 return C; 13219 } 13220 13221 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 13222 SourceLocation LParenLoc, 13223 SourceLocation EndLoc) { 13224 Expr *ValExpr = Device; 13225 Stmt *HelperValStmt = nullptr; 13226 13227 // OpenMP [2.9.1, Restrictions] 13228 // The device expression must evaluate to a non-negative integer value. 13229 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 13230 /*StrictlyPositive=*/false)) 13231 return nullptr; 13232 13233 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13234 OpenMPDirectiveKind CaptureRegion = 13235 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 13236 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13237 ValExpr = MakeFullExpr(ValExpr).get(); 13238 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13239 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13240 HelperValStmt = buildPreInits(Context, Captures); 13241 } 13242 13243 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 13244 StartLoc, LParenLoc, EndLoc); 13245 } 13246 13247 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 13248 DSAStackTy *Stack, QualType QTy, 13249 bool FullCheck = true) { 13250 NamedDecl *ND; 13251 if (QTy->isIncompleteType(&ND)) { 13252 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 13253 return false; 13254 } 13255 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 13256 !QTy.isTrivialType(SemaRef.Context)) 13257 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 13258 return true; 13259 } 13260 13261 /// Return true if it can be proven that the provided array expression 13262 /// (array section or array subscript) does NOT specify the whole size of the 13263 /// array whose base type is \a BaseQTy. 13264 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 13265 const Expr *E, 13266 QualType BaseQTy) { 13267 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13268 13269 // If this is an array subscript, it refers to the whole size if the size of 13270 // the dimension is constant and equals 1. Also, an array section assumes the 13271 // format of an array subscript if no colon is used. 13272 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 13273 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13274 return ATy->getSize().getSExtValue() != 1; 13275 // Size can't be evaluated statically. 13276 return false; 13277 } 13278 13279 assert(OASE && "Expecting array section if not an array subscript."); 13280 const Expr *LowerBound = OASE->getLowerBound(); 13281 const Expr *Length = OASE->getLength(); 13282 13283 // If there is a lower bound that does not evaluates to zero, we are not 13284 // covering the whole dimension. 13285 if (LowerBound) { 13286 Expr::EvalResult Result; 13287 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 13288 return false; // Can't get the integer value as a constant. 13289 13290 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 13291 if (ConstLowerBound.getSExtValue()) 13292 return true; 13293 } 13294 13295 // If we don't have a length we covering the whole dimension. 13296 if (!Length) 13297 return false; 13298 13299 // If the base is a pointer, we don't have a way to get the size of the 13300 // pointee. 13301 if (BaseQTy->isPointerType()) 13302 return false; 13303 13304 // We can only check if the length is the same as the size of the dimension 13305 // if we have a constant array. 13306 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 13307 if (!CATy) 13308 return false; 13309 13310 Expr::EvalResult Result; 13311 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13312 return false; // Can't get the integer value as a constant. 13313 13314 llvm::APSInt ConstLength = Result.Val.getInt(); 13315 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 13316 } 13317 13318 // Return true if it can be proven that the provided array expression (array 13319 // section or array subscript) does NOT specify a single element of the array 13320 // whose base type is \a BaseQTy. 13321 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 13322 const Expr *E, 13323 QualType BaseQTy) { 13324 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 13325 13326 // An array subscript always refer to a single element. Also, an array section 13327 // assumes the format of an array subscript if no colon is used. 13328 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 13329 return false; 13330 13331 assert(OASE && "Expecting array section if not an array subscript."); 13332 const Expr *Length = OASE->getLength(); 13333 13334 // If we don't have a length we have to check if the array has unitary size 13335 // for this dimension. Also, we should always expect a length if the base type 13336 // is pointer. 13337 if (!Length) { 13338 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 13339 return ATy->getSize().getSExtValue() != 1; 13340 // We cannot assume anything. 13341 return false; 13342 } 13343 13344 // Check if the length evaluates to 1. 13345 Expr::EvalResult Result; 13346 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 13347 return false; // Can't get the integer value as a constant. 13348 13349 llvm::APSInt ConstLength = Result.Val.getInt(); 13350 return ConstLength.getSExtValue() != 1; 13351 } 13352 13353 // Return the expression of the base of the mappable expression or null if it 13354 // cannot be determined and do all the necessary checks to see if the expression 13355 // is valid as a standalone mappable expression. In the process, record all the 13356 // components of the expression. 13357 static const Expr *checkMapClauseExpressionBase( 13358 Sema &SemaRef, Expr *E, 13359 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 13360 OpenMPClauseKind CKind, bool NoDiagnose) { 13361 SourceLocation ELoc = E->getExprLoc(); 13362 SourceRange ERange = E->getSourceRange(); 13363 13364 // The base of elements of list in a map clause have to be either: 13365 // - a reference to variable or field. 13366 // - a member expression. 13367 // - an array expression. 13368 // 13369 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 13370 // reference to 'r'. 13371 // 13372 // If we have: 13373 // 13374 // struct SS { 13375 // Bla S; 13376 // foo() { 13377 // #pragma omp target map (S.Arr[:12]); 13378 // } 13379 // } 13380 // 13381 // We want to retrieve the member expression 'this->S'; 13382 13383 const Expr *RelevantExpr = nullptr; 13384 13385 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 13386 // If a list item is an array section, it must specify contiguous storage. 13387 // 13388 // For this restriction it is sufficient that we make sure only references 13389 // to variables or fields and array expressions, and that no array sections 13390 // exist except in the rightmost expression (unless they cover the whole 13391 // dimension of the array). E.g. these would be invalid: 13392 // 13393 // r.ArrS[3:5].Arr[6:7] 13394 // 13395 // r.ArrS[3:5].x 13396 // 13397 // but these would be valid: 13398 // r.ArrS[3].Arr[6:7] 13399 // 13400 // r.ArrS[3].x 13401 13402 bool AllowUnitySizeArraySection = true; 13403 bool AllowWholeSizeArraySection = true; 13404 13405 while (!RelevantExpr) { 13406 E = E->IgnoreParenImpCasts(); 13407 13408 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 13409 if (!isa<VarDecl>(CurE->getDecl())) 13410 return nullptr; 13411 13412 RelevantExpr = CurE; 13413 13414 // If we got a reference to a declaration, we should not expect any array 13415 // section before that. 13416 AllowUnitySizeArraySection = false; 13417 AllowWholeSizeArraySection = false; 13418 13419 // Record the component. 13420 CurComponents.emplace_back(CurE, CurE->getDecl()); 13421 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 13422 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 13423 13424 if (isa<CXXThisExpr>(BaseE)) 13425 // We found a base expression: this->Val. 13426 RelevantExpr = CurE; 13427 else 13428 E = BaseE; 13429 13430 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 13431 if (!NoDiagnose) { 13432 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 13433 << CurE->getSourceRange(); 13434 return nullptr; 13435 } 13436 if (RelevantExpr) 13437 return nullptr; 13438 continue; 13439 } 13440 13441 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 13442 13443 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 13444 // A bit-field cannot appear in a map clause. 13445 // 13446 if (FD->isBitField()) { 13447 if (!NoDiagnose) { 13448 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 13449 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 13450 return nullptr; 13451 } 13452 if (RelevantExpr) 13453 return nullptr; 13454 continue; 13455 } 13456 13457 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13458 // If the type of a list item is a reference to a type T then the type 13459 // will be considered to be T for all purposes of this clause. 13460 QualType CurType = BaseE->getType().getNonReferenceType(); 13461 13462 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 13463 // A list item cannot be a variable that is a member of a structure with 13464 // a union type. 13465 // 13466 if (CurType->isUnionType()) { 13467 if (!NoDiagnose) { 13468 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 13469 << CurE->getSourceRange(); 13470 return nullptr; 13471 } 13472 continue; 13473 } 13474 13475 // If we got a member expression, we should not expect any array section 13476 // before that: 13477 // 13478 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 13479 // If a list item is an element of a structure, only the rightmost symbol 13480 // of the variable reference can be an array section. 13481 // 13482 AllowUnitySizeArraySection = false; 13483 AllowWholeSizeArraySection = false; 13484 13485 // Record the component. 13486 CurComponents.emplace_back(CurE, FD); 13487 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 13488 E = CurE->getBase()->IgnoreParenImpCasts(); 13489 13490 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 13491 if (!NoDiagnose) { 13492 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13493 << 0 << CurE->getSourceRange(); 13494 return nullptr; 13495 } 13496 continue; 13497 } 13498 13499 // If we got an array subscript that express the whole dimension we 13500 // can have any array expressions before. If it only expressing part of 13501 // the dimension, we can only have unitary-size array expressions. 13502 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 13503 E->getType())) 13504 AllowWholeSizeArraySection = false; 13505 13506 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13507 Expr::EvalResult Result; 13508 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13509 if (!Result.Val.getInt().isNullValue()) { 13510 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13511 diag::err_omp_invalid_map_this_expr); 13512 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13513 diag::note_omp_invalid_subscript_on_this_ptr_map); 13514 } 13515 } 13516 RelevantExpr = TE; 13517 } 13518 13519 // Record the component - we don't have any declaration associated. 13520 CurComponents.emplace_back(CurE, nullptr); 13521 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13522 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13523 E = CurE->getBase()->IgnoreParenImpCasts(); 13524 13525 QualType CurType = 13526 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13527 13528 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13529 // If the type of a list item is a reference to a type T then the type 13530 // will be considered to be T for all purposes of this clause. 13531 if (CurType->isReferenceType()) 13532 CurType = CurType->getPointeeType(); 13533 13534 bool IsPointer = CurType->isAnyPointerType(); 13535 13536 if (!IsPointer && !CurType->isArrayType()) { 13537 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13538 << 0 << CurE->getSourceRange(); 13539 return nullptr; 13540 } 13541 13542 bool NotWhole = 13543 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13544 bool NotUnity = 13545 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13546 13547 if (AllowWholeSizeArraySection) { 13548 // Any array section is currently allowed. Allowing a whole size array 13549 // section implies allowing a unity array section as well. 13550 // 13551 // If this array section refers to the whole dimension we can still 13552 // accept other array sections before this one, except if the base is a 13553 // pointer. Otherwise, only unitary sections are accepted. 13554 if (NotWhole || IsPointer) 13555 AllowWholeSizeArraySection = false; 13556 } else if (AllowUnitySizeArraySection && NotUnity) { 13557 // A unity or whole array section is not allowed and that is not 13558 // compatible with the properties of the current array section. 13559 SemaRef.Diag( 13560 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13561 << CurE->getSourceRange(); 13562 return nullptr; 13563 } 13564 13565 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13566 Expr::EvalResult ResultR; 13567 Expr::EvalResult ResultL; 13568 if (CurE->getLength()->EvaluateAsInt(ResultR, 13569 SemaRef.getASTContext())) { 13570 if (!ResultR.Val.getInt().isOneValue()) { 13571 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13572 diag::err_omp_invalid_map_this_expr); 13573 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13574 diag::note_omp_invalid_length_on_this_ptr_mapping); 13575 } 13576 } 13577 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 13578 ResultL, SemaRef.getASTContext())) { 13579 if (!ResultL.Val.getInt().isNullValue()) { 13580 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13581 diag::err_omp_invalid_map_this_expr); 13582 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13583 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 13584 } 13585 } 13586 RelevantExpr = TE; 13587 } 13588 13589 // Record the component - we don't have any declaration associated. 13590 CurComponents.emplace_back(CurE, nullptr); 13591 } else { 13592 if (!NoDiagnose) { 13593 // If nothing else worked, this is not a valid map clause expression. 13594 SemaRef.Diag( 13595 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 13596 << ERange; 13597 } 13598 return nullptr; 13599 } 13600 } 13601 13602 return RelevantExpr; 13603 } 13604 13605 // Return true if expression E associated with value VD has conflicts with other 13606 // map information. 13607 static bool checkMapConflicts( 13608 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 13609 bool CurrentRegionOnly, 13610 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 13611 OpenMPClauseKind CKind) { 13612 assert(VD && E); 13613 SourceLocation ELoc = E->getExprLoc(); 13614 SourceRange ERange = E->getSourceRange(); 13615 13616 // In order to easily check the conflicts we need to match each component of 13617 // the expression under test with the components of the expressions that are 13618 // already in the stack. 13619 13620 assert(!CurComponents.empty() && "Map clause expression with no components!"); 13621 assert(CurComponents.back().getAssociatedDeclaration() == VD && 13622 "Map clause expression with unexpected base!"); 13623 13624 // Variables to help detecting enclosing problems in data environment nests. 13625 bool IsEnclosedByDataEnvironmentExpr = false; 13626 const Expr *EnclosingExpr = nullptr; 13627 13628 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 13629 VD, CurrentRegionOnly, 13630 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 13631 ERange, CKind, &EnclosingExpr, 13632 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 13633 StackComponents, 13634 OpenMPClauseKind) { 13635 assert(!StackComponents.empty() && 13636 "Map clause expression with no components!"); 13637 assert(StackComponents.back().getAssociatedDeclaration() == VD && 13638 "Map clause expression with unexpected base!"); 13639 (void)VD; 13640 13641 // The whole expression in the stack. 13642 const Expr *RE = StackComponents.front().getAssociatedExpression(); 13643 13644 // Expressions must start from the same base. Here we detect at which 13645 // point both expressions diverge from each other and see if we can 13646 // detect if the memory referred to both expressions is contiguous and 13647 // do not overlap. 13648 auto CI = CurComponents.rbegin(); 13649 auto CE = CurComponents.rend(); 13650 auto SI = StackComponents.rbegin(); 13651 auto SE = StackComponents.rend(); 13652 for (; CI != CE && SI != SE; ++CI, ++SI) { 13653 13654 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 13655 // At most one list item can be an array item derived from a given 13656 // variable in map clauses of the same construct. 13657 if (CurrentRegionOnly && 13658 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 13659 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 13660 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 13661 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 13662 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 13663 diag::err_omp_multiple_array_items_in_map_clause) 13664 << CI->getAssociatedExpression()->getSourceRange(); 13665 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 13666 diag::note_used_here) 13667 << SI->getAssociatedExpression()->getSourceRange(); 13668 return true; 13669 } 13670 13671 // Do both expressions have the same kind? 13672 if (CI->getAssociatedExpression()->getStmtClass() != 13673 SI->getAssociatedExpression()->getStmtClass()) 13674 break; 13675 13676 // Are we dealing with different variables/fields? 13677 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13678 break; 13679 } 13680 // Check if the extra components of the expressions in the enclosing 13681 // data environment are redundant for the current base declaration. 13682 // If they are, the maps completely overlap, which is legal. 13683 for (; SI != SE; ++SI) { 13684 QualType Type; 13685 if (const auto *ASE = 13686 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13687 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13688 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13689 SI->getAssociatedExpression())) { 13690 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13691 Type = 13692 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13693 } 13694 if (Type.isNull() || Type->isAnyPointerType() || 13695 checkArrayExpressionDoesNotReferToWholeSize( 13696 SemaRef, SI->getAssociatedExpression(), Type)) 13697 break; 13698 } 13699 13700 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13701 // List items of map clauses in the same construct must not share 13702 // original storage. 13703 // 13704 // If the expressions are exactly the same or one is a subset of the 13705 // other, it means they are sharing storage. 13706 if (CI == CE && SI == SE) { 13707 if (CurrentRegionOnly) { 13708 if (CKind == OMPC_map) { 13709 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13710 } else { 13711 assert(CKind == OMPC_to || CKind == OMPC_from); 13712 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13713 << ERange; 13714 } 13715 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13716 << RE->getSourceRange(); 13717 return true; 13718 } 13719 // If we find the same expression in the enclosing data environment, 13720 // that is legal. 13721 IsEnclosedByDataEnvironmentExpr = true; 13722 return false; 13723 } 13724 13725 QualType DerivedType = 13726 std::prev(CI)->getAssociatedDeclaration()->getType(); 13727 SourceLocation DerivedLoc = 13728 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13729 13730 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13731 // If the type of a list item is a reference to a type T then the type 13732 // will be considered to be T for all purposes of this clause. 13733 DerivedType = DerivedType.getNonReferenceType(); 13734 13735 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13736 // A variable for which the type is pointer and an array section 13737 // derived from that variable must not appear as list items of map 13738 // clauses of the same construct. 13739 // 13740 // Also, cover one of the cases in: 13741 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13742 // If any part of the original storage of a list item has corresponding 13743 // storage in the device data environment, all of the original storage 13744 // must have corresponding storage in the device data environment. 13745 // 13746 if (DerivedType->isAnyPointerType()) { 13747 if (CI == CE || SI == SE) { 13748 SemaRef.Diag( 13749 DerivedLoc, 13750 diag::err_omp_pointer_mapped_along_with_derived_section) 13751 << DerivedLoc; 13752 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13753 << RE->getSourceRange(); 13754 return true; 13755 } 13756 if (CI->getAssociatedExpression()->getStmtClass() != 13757 SI->getAssociatedExpression()->getStmtClass() || 13758 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13759 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13760 assert(CI != CE && SI != SE); 13761 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13762 << DerivedLoc; 13763 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13764 << RE->getSourceRange(); 13765 return true; 13766 } 13767 } 13768 13769 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13770 // List items of map clauses in the same construct must not share 13771 // original storage. 13772 // 13773 // An expression is a subset of the other. 13774 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13775 if (CKind == OMPC_map) { 13776 if (CI != CE || SI != SE) { 13777 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13778 // a pointer. 13779 auto Begin = 13780 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13781 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13782 auto It = Begin; 13783 while (It != End && !It->getAssociatedDeclaration()) 13784 std::advance(It, 1); 13785 assert(It != End && 13786 "Expected at least one component with the declaration."); 13787 if (It != Begin && It->getAssociatedDeclaration() 13788 ->getType() 13789 .getCanonicalType() 13790 ->isAnyPointerType()) { 13791 IsEnclosedByDataEnvironmentExpr = false; 13792 EnclosingExpr = nullptr; 13793 return false; 13794 } 13795 } 13796 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13797 } else { 13798 assert(CKind == OMPC_to || CKind == OMPC_from); 13799 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13800 << ERange; 13801 } 13802 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13803 << RE->getSourceRange(); 13804 return true; 13805 } 13806 13807 // The current expression uses the same base as other expression in the 13808 // data environment but does not contain it completely. 13809 if (!CurrentRegionOnly && SI != SE) 13810 EnclosingExpr = RE; 13811 13812 // The current expression is a subset of the expression in the data 13813 // environment. 13814 IsEnclosedByDataEnvironmentExpr |= 13815 (!CurrentRegionOnly && CI != CE && SI == SE); 13816 13817 return false; 13818 }); 13819 13820 if (CurrentRegionOnly) 13821 return FoundError; 13822 13823 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13824 // If any part of the original storage of a list item has corresponding 13825 // storage in the device data environment, all of the original storage must 13826 // have corresponding storage in the device data environment. 13827 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13828 // If a list item is an element of a structure, and a different element of 13829 // the structure has a corresponding list item in the device data environment 13830 // prior to a task encountering the construct associated with the map clause, 13831 // then the list item must also have a corresponding list item in the device 13832 // data environment prior to the task encountering the construct. 13833 // 13834 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13835 SemaRef.Diag(ELoc, 13836 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13837 << ERange; 13838 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13839 << EnclosingExpr->getSourceRange(); 13840 return true; 13841 } 13842 13843 return FoundError; 13844 } 13845 13846 // Look up the user-defined mapper given the mapper name and mapped type, and 13847 // build a reference to it. 13848 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13849 CXXScopeSpec &MapperIdScopeSpec, 13850 const DeclarationNameInfo &MapperId, 13851 QualType Type, 13852 Expr *UnresolvedMapper) { 13853 if (MapperIdScopeSpec.isInvalid()) 13854 return ExprError(); 13855 // Find all user-defined mappers with the given MapperId. 13856 SmallVector<UnresolvedSet<8>, 4> Lookups; 13857 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13858 Lookup.suppressDiagnostics(); 13859 if (S) { 13860 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13861 NamedDecl *D = Lookup.getRepresentativeDecl(); 13862 while (S && !S->isDeclScope(D)) 13863 S = S->getParent(); 13864 if (S) 13865 S = S->getParent(); 13866 Lookups.emplace_back(); 13867 Lookups.back().append(Lookup.begin(), Lookup.end()); 13868 Lookup.clear(); 13869 } 13870 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13871 // Extract the user-defined mappers with the given MapperId. 13872 Lookups.push_back(UnresolvedSet<8>()); 13873 for (NamedDecl *D : ULE->decls()) { 13874 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13875 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13876 Lookups.back().addDecl(DMD); 13877 } 13878 } 13879 // Defer the lookup for dependent types. The results will be passed through 13880 // UnresolvedMapper on instantiation. 13881 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13882 Type->isInstantiationDependentType() || 13883 Type->containsUnexpandedParameterPack() || 13884 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13885 return !D->isInvalidDecl() && 13886 (D->getType()->isDependentType() || 13887 D->getType()->isInstantiationDependentType() || 13888 D->getType()->containsUnexpandedParameterPack()); 13889 })) { 13890 UnresolvedSet<8> URS; 13891 for (const UnresolvedSet<8> &Set : Lookups) { 13892 if (Set.empty()) 13893 continue; 13894 URS.append(Set.begin(), Set.end()); 13895 } 13896 return UnresolvedLookupExpr::Create( 13897 SemaRef.Context, /*NamingClass=*/nullptr, 13898 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13899 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13900 } 13901 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13902 // The type must be of struct, union or class type in C and C++ 13903 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13904 return ExprEmpty(); 13905 SourceLocation Loc = MapperId.getLoc(); 13906 // Perform argument dependent lookup. 13907 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13908 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13909 // Return the first user-defined mapper with the desired type. 13910 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13911 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13912 if (!D->isInvalidDecl() && 13913 SemaRef.Context.hasSameType(D->getType(), Type)) 13914 return D; 13915 return nullptr; 13916 })) 13917 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13918 // Find the first user-defined mapper with a type derived from the desired 13919 // type. 13920 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13921 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13922 if (!D->isInvalidDecl() && 13923 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13924 !Type.isMoreQualifiedThan(D->getType())) 13925 return D; 13926 return nullptr; 13927 })) { 13928 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13929 /*DetectVirtual=*/false); 13930 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13931 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13932 VD->getType().getUnqualifiedType()))) { 13933 if (SemaRef.CheckBaseClassAccess( 13934 Loc, VD->getType(), Type, Paths.front(), 13935 /*DiagID=*/0) != Sema::AR_inaccessible) { 13936 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13937 } 13938 } 13939 } 13940 } 13941 // Report error if a mapper is specified, but cannot be found. 13942 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13943 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13944 << Type << MapperId.getName(); 13945 return ExprError(); 13946 } 13947 return ExprEmpty(); 13948 } 13949 13950 namespace { 13951 // Utility struct that gathers all the related lists associated with a mappable 13952 // expression. 13953 struct MappableVarListInfo { 13954 // The list of expressions. 13955 ArrayRef<Expr *> VarList; 13956 // The list of processed expressions. 13957 SmallVector<Expr *, 16> ProcessedVarList; 13958 // The mappble components for each expression. 13959 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 13960 // The base declaration of the variable. 13961 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 13962 // The reference to the user-defined mapper associated with every expression. 13963 SmallVector<Expr *, 16> UDMapperList; 13964 13965 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 13966 // We have a list of components and base declarations for each entry in the 13967 // variable list. 13968 VarComponents.reserve(VarList.size()); 13969 VarBaseDeclarations.reserve(VarList.size()); 13970 } 13971 }; 13972 } 13973 13974 // Check the validity of the provided variable list for the provided clause kind 13975 // \a CKind. In the check process the valid expressions, mappable expression 13976 // components, variables, and user-defined mappers are extracted and used to 13977 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 13978 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 13979 // and \a MapperId are expected to be valid if the clause kind is 'map'. 13980 static void checkMappableExpressionList( 13981 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 13982 MappableVarListInfo &MVLI, SourceLocation StartLoc, 13983 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 13984 ArrayRef<Expr *> UnresolvedMappers, 13985 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 13986 bool IsMapTypeImplicit = false) { 13987 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 13988 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 13989 "Unexpected clause kind with mappable expressions!"); 13990 13991 // If the identifier of user-defined mapper is not specified, it is "default". 13992 // We do not change the actual name in this clause to distinguish whether a 13993 // mapper is specified explicitly, i.e., it is not explicitly specified when 13994 // MapperId.getName() is empty. 13995 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 13996 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 13997 MapperId.setName(DeclNames.getIdentifier( 13998 &SemaRef.getASTContext().Idents.get("default"))); 13999 } 14000 14001 // Iterators to find the current unresolved mapper expression. 14002 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14003 bool UpdateUMIt = false; 14004 Expr *UnresolvedMapper = nullptr; 14005 14006 // Keep track of the mappable components and base declarations in this clause. 14007 // Each entry in the list is going to have a list of components associated. We 14008 // record each set of the components so that we can build the clause later on. 14009 // In the end we should have the same amount of declarations and component 14010 // lists. 14011 14012 for (Expr *RE : MVLI.VarList) { 14013 assert(RE && "Null expr in omp to/from/map clause"); 14014 SourceLocation ELoc = RE->getExprLoc(); 14015 14016 // Find the current unresolved mapper expression. 14017 if (UpdateUMIt && UMIt != UMEnd) { 14018 UMIt++; 14019 assert( 14020 UMIt != UMEnd && 14021 "Expect the size of UnresolvedMappers to match with that of VarList"); 14022 } 14023 UpdateUMIt = true; 14024 if (UMIt != UMEnd) 14025 UnresolvedMapper = *UMIt; 14026 14027 const Expr *VE = RE->IgnoreParenLValueCasts(); 14028 14029 if (VE->isValueDependent() || VE->isTypeDependent() || 14030 VE->isInstantiationDependent() || 14031 VE->containsUnexpandedParameterPack()) { 14032 // Try to find the associated user-defined mapper. 14033 ExprResult ER = buildUserDefinedMapperRef( 14034 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14035 VE->getType().getCanonicalType(), UnresolvedMapper); 14036 if (ER.isInvalid()) 14037 continue; 14038 MVLI.UDMapperList.push_back(ER.get()); 14039 // We can only analyze this information once the missing information is 14040 // resolved. 14041 MVLI.ProcessedVarList.push_back(RE); 14042 continue; 14043 } 14044 14045 Expr *SimpleExpr = RE->IgnoreParenCasts(); 14046 14047 if (!RE->IgnoreParenImpCasts()->isLValue()) { 14048 SemaRef.Diag(ELoc, 14049 diag::err_omp_expected_named_var_member_or_array_expression) 14050 << RE->getSourceRange(); 14051 continue; 14052 } 14053 14054 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 14055 ValueDecl *CurDeclaration = nullptr; 14056 14057 // Obtain the array or member expression bases if required. Also, fill the 14058 // components array with all the components identified in the process. 14059 const Expr *BE = checkMapClauseExpressionBase( 14060 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 14061 if (!BE) 14062 continue; 14063 14064 assert(!CurComponents.empty() && 14065 "Invalid mappable expression information."); 14066 14067 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 14068 // Add store "this" pointer to class in DSAStackTy for future checking 14069 DSAS->addMappedClassesQualTypes(TE->getType()); 14070 // Try to find the associated user-defined mapper. 14071 ExprResult ER = buildUserDefinedMapperRef( 14072 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14073 VE->getType().getCanonicalType(), UnresolvedMapper); 14074 if (ER.isInvalid()) 14075 continue; 14076 MVLI.UDMapperList.push_back(ER.get()); 14077 // Skip restriction checking for variable or field declarations 14078 MVLI.ProcessedVarList.push_back(RE); 14079 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14080 MVLI.VarComponents.back().append(CurComponents.begin(), 14081 CurComponents.end()); 14082 MVLI.VarBaseDeclarations.push_back(nullptr); 14083 continue; 14084 } 14085 14086 // For the following checks, we rely on the base declaration which is 14087 // expected to be associated with the last component. The declaration is 14088 // expected to be a variable or a field (if 'this' is being mapped). 14089 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 14090 assert(CurDeclaration && "Null decl on map clause."); 14091 assert( 14092 CurDeclaration->isCanonicalDecl() && 14093 "Expecting components to have associated only canonical declarations."); 14094 14095 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 14096 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 14097 14098 assert((VD || FD) && "Only variables or fields are expected here!"); 14099 (void)FD; 14100 14101 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 14102 // threadprivate variables cannot appear in a map clause. 14103 // OpenMP 4.5 [2.10.5, target update Construct] 14104 // threadprivate variables cannot appear in a from clause. 14105 if (VD && DSAS->isThreadPrivate(VD)) { 14106 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14107 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 14108 << getOpenMPClauseName(CKind); 14109 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 14110 continue; 14111 } 14112 14113 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14114 // A list item cannot appear in both a map clause and a data-sharing 14115 // attribute clause on the same construct. 14116 14117 // Check conflicts with other map clause expressions. We check the conflicts 14118 // with the current construct separately from the enclosing data 14119 // environment, because the restrictions are different. We only have to 14120 // check conflicts across regions for the map clauses. 14121 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14122 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 14123 break; 14124 if (CKind == OMPC_map && 14125 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 14126 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 14127 break; 14128 14129 // OpenMP 4.5 [2.10.5, target update Construct] 14130 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14131 // If the type of a list item is a reference to a type T then the type will 14132 // be considered to be T for all purposes of this clause. 14133 auto I = llvm::find_if( 14134 CurComponents, 14135 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 14136 return MC.getAssociatedDeclaration(); 14137 }); 14138 assert(I != CurComponents.end() && "Null decl on map clause."); 14139 QualType Type = 14140 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 14141 14142 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 14143 // A list item in a to or from clause must have a mappable type. 14144 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 14145 // A list item must have a mappable type. 14146 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 14147 DSAS, Type)) 14148 continue; 14149 14150 if (CKind == OMPC_map) { 14151 // target enter data 14152 // OpenMP [2.10.2, Restrictions, p. 99] 14153 // A map-type must be specified in all map clauses and must be either 14154 // to or alloc. 14155 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 14156 if (DKind == OMPD_target_enter_data && 14157 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 14158 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14159 << (IsMapTypeImplicit ? 1 : 0) 14160 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14161 << getOpenMPDirectiveName(DKind); 14162 continue; 14163 } 14164 14165 // target exit_data 14166 // OpenMP [2.10.3, Restrictions, p. 102] 14167 // A map-type must be specified in all map clauses and must be either 14168 // from, release, or delete. 14169 if (DKind == OMPD_target_exit_data && 14170 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 14171 MapType == OMPC_MAP_delete)) { 14172 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 14173 << (IsMapTypeImplicit ? 1 : 0) 14174 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 14175 << getOpenMPDirectiveName(DKind); 14176 continue; 14177 } 14178 14179 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14180 // A list item cannot appear in both a map clause and a data-sharing 14181 // attribute clause on the same construct 14182 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 14183 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 14184 if (isOpenMPPrivate(DVar.CKind)) { 14185 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14186 << getOpenMPClauseName(DVar.CKind) 14187 << getOpenMPClauseName(OMPC_map) 14188 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 14189 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 14190 continue; 14191 } 14192 } 14193 } 14194 14195 // Try to find the associated user-defined mapper. 14196 ExprResult ER = buildUserDefinedMapperRef( 14197 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 14198 Type.getCanonicalType(), UnresolvedMapper); 14199 if (ER.isInvalid()) 14200 continue; 14201 MVLI.UDMapperList.push_back(ER.get()); 14202 14203 // Save the current expression. 14204 MVLI.ProcessedVarList.push_back(RE); 14205 14206 // Store the components in the stack so that they can be used to check 14207 // against other clauses later on. 14208 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 14209 /*WhereFoundClauseKind=*/OMPC_map); 14210 14211 // Save the components and declaration to create the clause. For purposes of 14212 // the clause creation, any component list that has has base 'this' uses 14213 // null as base declaration. 14214 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14215 MVLI.VarComponents.back().append(CurComponents.begin(), 14216 CurComponents.end()); 14217 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 14218 : CurDeclaration); 14219 } 14220 } 14221 14222 OMPClause *Sema::ActOnOpenMPMapClause( 14223 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 14224 ArrayRef<SourceLocation> MapTypeModifiersLoc, 14225 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 14226 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 14227 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 14228 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 14229 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 14230 OMPC_MAP_MODIFIER_unknown, 14231 OMPC_MAP_MODIFIER_unknown}; 14232 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 14233 14234 // Process map-type-modifiers, flag errors for duplicate modifiers. 14235 unsigned Count = 0; 14236 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 14237 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 14238 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 14239 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 14240 continue; 14241 } 14242 assert(Count < OMPMapClause::NumberOfModifiers && 14243 "Modifiers exceed the allowed number of map type modifiers"); 14244 Modifiers[Count] = MapTypeModifiers[I]; 14245 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 14246 ++Count; 14247 } 14248 14249 MappableVarListInfo MVLI(VarList); 14250 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 14251 MapperIdScopeSpec, MapperId, UnresolvedMappers, 14252 MapType, IsMapTypeImplicit); 14253 14254 // We need to produce a map clause even if we don't have variables so that 14255 // other diagnostics related with non-existing map clauses are accurate. 14256 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 14257 MVLI.VarBaseDeclarations, MVLI.VarComponents, 14258 MVLI.UDMapperList, Modifiers, ModifiersLoc, 14259 MapperIdScopeSpec.getWithLocInContext(Context), 14260 MapperId, MapType, IsMapTypeImplicit, MapLoc); 14261 } 14262 14263 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 14264 TypeResult ParsedType) { 14265 assert(ParsedType.isUsable()); 14266 14267 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 14268 if (ReductionType.isNull()) 14269 return QualType(); 14270 14271 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 14272 // A type name in a declare reduction directive cannot be a function type, an 14273 // array type, a reference type, or a type qualified with const, volatile or 14274 // restrict. 14275 if (ReductionType.hasQualifiers()) { 14276 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 14277 return QualType(); 14278 } 14279 14280 if (ReductionType->isFunctionType()) { 14281 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 14282 return QualType(); 14283 } 14284 if (ReductionType->isReferenceType()) { 14285 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 14286 return QualType(); 14287 } 14288 if (ReductionType->isArrayType()) { 14289 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 14290 return QualType(); 14291 } 14292 return ReductionType; 14293 } 14294 14295 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 14296 Scope *S, DeclContext *DC, DeclarationName Name, 14297 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 14298 AccessSpecifier AS, Decl *PrevDeclInScope) { 14299 SmallVector<Decl *, 8> Decls; 14300 Decls.reserve(ReductionTypes.size()); 14301 14302 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 14303 forRedeclarationInCurContext()); 14304 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 14305 // A reduction-identifier may not be re-declared in the current scope for the 14306 // same type or for a type that is compatible according to the base language 14307 // rules. 14308 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14309 OMPDeclareReductionDecl *PrevDRD = nullptr; 14310 bool InCompoundScope = true; 14311 if (S != nullptr) { 14312 // Find previous declaration with the same name not referenced in other 14313 // declarations. 14314 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14315 InCompoundScope = 14316 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14317 LookupName(Lookup, S); 14318 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14319 /*AllowInlineNamespace=*/false); 14320 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 14321 LookupResult::Filter Filter = Lookup.makeFilter(); 14322 while (Filter.hasNext()) { 14323 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 14324 if (InCompoundScope) { 14325 auto I = UsedAsPrevious.find(PrevDecl); 14326 if (I == UsedAsPrevious.end()) 14327 UsedAsPrevious[PrevDecl] = false; 14328 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 14329 UsedAsPrevious[D] = true; 14330 } 14331 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14332 PrevDecl->getLocation(); 14333 } 14334 Filter.done(); 14335 if (InCompoundScope) { 14336 for (const auto &PrevData : UsedAsPrevious) { 14337 if (!PrevData.second) { 14338 PrevDRD = PrevData.first; 14339 break; 14340 } 14341 } 14342 } 14343 } else if (PrevDeclInScope != nullptr) { 14344 auto *PrevDRDInScope = PrevDRD = 14345 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 14346 do { 14347 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 14348 PrevDRDInScope->getLocation(); 14349 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 14350 } while (PrevDRDInScope != nullptr); 14351 } 14352 for (const auto &TyData : ReductionTypes) { 14353 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 14354 bool Invalid = false; 14355 if (I != PreviousRedeclTypes.end()) { 14356 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 14357 << TyData.first; 14358 Diag(I->second, diag::note_previous_definition); 14359 Invalid = true; 14360 } 14361 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 14362 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 14363 Name, TyData.first, PrevDRD); 14364 DC->addDecl(DRD); 14365 DRD->setAccess(AS); 14366 Decls.push_back(DRD); 14367 if (Invalid) 14368 DRD->setInvalidDecl(); 14369 else 14370 PrevDRD = DRD; 14371 } 14372 14373 return DeclGroupPtrTy::make( 14374 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 14375 } 14376 14377 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 14378 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14379 14380 // Enter new function scope. 14381 PushFunctionScope(); 14382 setFunctionHasBranchProtectedScope(); 14383 getCurFunction()->setHasOMPDeclareReductionCombiner(); 14384 14385 if (S != nullptr) 14386 PushDeclContext(S, DRD); 14387 else 14388 CurContext = DRD; 14389 14390 PushExpressionEvaluationContext( 14391 ExpressionEvaluationContext::PotentiallyEvaluated); 14392 14393 QualType ReductionType = DRD->getType(); 14394 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 14395 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 14396 // uses semantics of argument handles by value, but it should be passed by 14397 // reference. C lang does not support references, so pass all parameters as 14398 // pointers. 14399 // Create 'T omp_in;' variable. 14400 VarDecl *OmpInParm = 14401 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 14402 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 14403 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 14404 // uses semantics of argument handles by value, but it should be passed by 14405 // reference. C lang does not support references, so pass all parameters as 14406 // pointers. 14407 // Create 'T omp_out;' variable. 14408 VarDecl *OmpOutParm = 14409 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 14410 if (S != nullptr) { 14411 PushOnScopeChains(OmpInParm, S); 14412 PushOnScopeChains(OmpOutParm, S); 14413 } else { 14414 DRD->addDecl(OmpInParm); 14415 DRD->addDecl(OmpOutParm); 14416 } 14417 Expr *InE = 14418 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 14419 Expr *OutE = 14420 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 14421 DRD->setCombinerData(InE, OutE); 14422 } 14423 14424 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 14425 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14426 DiscardCleanupsInEvaluationContext(); 14427 PopExpressionEvaluationContext(); 14428 14429 PopDeclContext(); 14430 PopFunctionScopeInfo(); 14431 14432 if (Combiner != nullptr) 14433 DRD->setCombiner(Combiner); 14434 else 14435 DRD->setInvalidDecl(); 14436 } 14437 14438 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 14439 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14440 14441 // Enter new function scope. 14442 PushFunctionScope(); 14443 setFunctionHasBranchProtectedScope(); 14444 14445 if (S != nullptr) 14446 PushDeclContext(S, DRD); 14447 else 14448 CurContext = DRD; 14449 14450 PushExpressionEvaluationContext( 14451 ExpressionEvaluationContext::PotentiallyEvaluated); 14452 14453 QualType ReductionType = DRD->getType(); 14454 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 14455 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 14456 // uses semantics of argument handles by value, but it should be passed by 14457 // reference. C lang does not support references, so pass all parameters as 14458 // pointers. 14459 // Create 'T omp_priv;' variable. 14460 VarDecl *OmpPrivParm = 14461 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 14462 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 14463 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 14464 // uses semantics of argument handles by value, but it should be passed by 14465 // reference. C lang does not support references, so pass all parameters as 14466 // pointers. 14467 // Create 'T omp_orig;' variable. 14468 VarDecl *OmpOrigParm = 14469 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 14470 if (S != nullptr) { 14471 PushOnScopeChains(OmpPrivParm, S); 14472 PushOnScopeChains(OmpOrigParm, S); 14473 } else { 14474 DRD->addDecl(OmpPrivParm); 14475 DRD->addDecl(OmpOrigParm); 14476 } 14477 Expr *OrigE = 14478 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 14479 Expr *PrivE = 14480 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 14481 DRD->setInitializerData(OrigE, PrivE); 14482 return OmpPrivParm; 14483 } 14484 14485 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 14486 VarDecl *OmpPrivParm) { 14487 auto *DRD = cast<OMPDeclareReductionDecl>(D); 14488 DiscardCleanupsInEvaluationContext(); 14489 PopExpressionEvaluationContext(); 14490 14491 PopDeclContext(); 14492 PopFunctionScopeInfo(); 14493 14494 if (Initializer != nullptr) { 14495 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 14496 } else if (OmpPrivParm->hasInit()) { 14497 DRD->setInitializer(OmpPrivParm->getInit(), 14498 OmpPrivParm->isDirectInit() 14499 ? OMPDeclareReductionDecl::DirectInit 14500 : OMPDeclareReductionDecl::CopyInit); 14501 } else { 14502 DRD->setInvalidDecl(); 14503 } 14504 } 14505 14506 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14507 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14508 for (Decl *D : DeclReductions.get()) { 14509 if (IsValid) { 14510 if (S) 14511 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14512 /*AddToContext=*/false); 14513 } else { 14514 D->setInvalidDecl(); 14515 } 14516 } 14517 return DeclReductions; 14518 } 14519 14520 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14521 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14522 QualType T = TInfo->getType(); 14523 if (D.isInvalidType()) 14524 return true; 14525 14526 if (getLangOpts().CPlusPlus) { 14527 // Check that there are no default arguments (C++ only). 14528 CheckExtraCXXDefaultArguments(D); 14529 } 14530 14531 return CreateParsedType(T, TInfo); 14532 } 14533 14534 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14535 TypeResult ParsedType) { 14536 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14537 14538 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14539 assert(!MapperType.isNull() && "Expect valid mapper type"); 14540 14541 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14542 // The type must be of struct, union or class type in C and C++ 14543 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14544 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14545 return QualType(); 14546 } 14547 return MapperType; 14548 } 14549 14550 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14551 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14552 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14553 Decl *PrevDeclInScope) { 14554 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14555 forRedeclarationInCurContext()); 14556 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14557 // A mapper-identifier may not be redeclared in the current scope for the 14558 // same type or for a type that is compatible according to the base language 14559 // rules. 14560 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14561 OMPDeclareMapperDecl *PrevDMD = nullptr; 14562 bool InCompoundScope = true; 14563 if (S != nullptr) { 14564 // Find previous declaration with the same name not referenced in other 14565 // declarations. 14566 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14567 InCompoundScope = 14568 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14569 LookupName(Lookup, S); 14570 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14571 /*AllowInlineNamespace=*/false); 14572 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14573 LookupResult::Filter Filter = Lookup.makeFilter(); 14574 while (Filter.hasNext()) { 14575 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14576 if (InCompoundScope) { 14577 auto I = UsedAsPrevious.find(PrevDecl); 14578 if (I == UsedAsPrevious.end()) 14579 UsedAsPrevious[PrevDecl] = false; 14580 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 14581 UsedAsPrevious[D] = true; 14582 } 14583 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14584 PrevDecl->getLocation(); 14585 } 14586 Filter.done(); 14587 if (InCompoundScope) { 14588 for (const auto &PrevData : UsedAsPrevious) { 14589 if (!PrevData.second) { 14590 PrevDMD = PrevData.first; 14591 break; 14592 } 14593 } 14594 } 14595 } else if (PrevDeclInScope) { 14596 auto *PrevDMDInScope = PrevDMD = 14597 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 14598 do { 14599 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 14600 PrevDMDInScope->getLocation(); 14601 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 14602 } while (PrevDMDInScope != nullptr); 14603 } 14604 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 14605 bool Invalid = false; 14606 if (I != PreviousRedeclTypes.end()) { 14607 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 14608 << MapperType << Name; 14609 Diag(I->second, diag::note_previous_definition); 14610 Invalid = true; 14611 } 14612 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 14613 MapperType, VN, PrevDMD); 14614 DC->addDecl(DMD); 14615 DMD->setAccess(AS); 14616 if (Invalid) 14617 DMD->setInvalidDecl(); 14618 14619 // Enter new function scope. 14620 PushFunctionScope(); 14621 setFunctionHasBranchProtectedScope(); 14622 14623 CurContext = DMD; 14624 14625 return DMD; 14626 } 14627 14628 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 14629 Scope *S, 14630 QualType MapperType, 14631 SourceLocation StartLoc, 14632 DeclarationName VN) { 14633 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 14634 if (S) 14635 PushOnScopeChains(VD, S); 14636 else 14637 DMD->addDecl(VD); 14638 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 14639 DMD->setMapperVarRef(MapperVarRefExpr); 14640 } 14641 14642 Sema::DeclGroupPtrTy 14643 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 14644 ArrayRef<OMPClause *> ClauseList) { 14645 PopDeclContext(); 14646 PopFunctionScopeInfo(); 14647 14648 if (D) { 14649 if (S) 14650 PushOnScopeChains(D, S, /*AddToContext=*/false); 14651 D->CreateClauses(Context, ClauseList); 14652 } 14653 14654 return DeclGroupPtrTy::make(DeclGroupRef(D)); 14655 } 14656 14657 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 14658 SourceLocation StartLoc, 14659 SourceLocation LParenLoc, 14660 SourceLocation EndLoc) { 14661 Expr *ValExpr = NumTeams; 14662 Stmt *HelperValStmt = nullptr; 14663 14664 // OpenMP [teams Constrcut, Restrictions] 14665 // The num_teams expression must evaluate to a positive integer value. 14666 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 14667 /*StrictlyPositive=*/true)) 14668 return nullptr; 14669 14670 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14671 OpenMPDirectiveKind CaptureRegion = 14672 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 14673 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14674 ValExpr = MakeFullExpr(ValExpr).get(); 14675 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14676 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14677 HelperValStmt = buildPreInits(Context, Captures); 14678 } 14679 14680 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14681 StartLoc, LParenLoc, EndLoc); 14682 } 14683 14684 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14685 SourceLocation StartLoc, 14686 SourceLocation LParenLoc, 14687 SourceLocation EndLoc) { 14688 Expr *ValExpr = ThreadLimit; 14689 Stmt *HelperValStmt = nullptr; 14690 14691 // OpenMP [teams Constrcut, Restrictions] 14692 // The thread_limit expression must evaluate to a positive integer value. 14693 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14694 /*StrictlyPositive=*/true)) 14695 return nullptr; 14696 14697 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14698 OpenMPDirectiveKind CaptureRegion = 14699 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14700 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14701 ValExpr = MakeFullExpr(ValExpr).get(); 14702 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14703 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14704 HelperValStmt = buildPreInits(Context, Captures); 14705 } 14706 14707 return new (Context) OMPThreadLimitClause( 14708 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14709 } 14710 14711 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14712 SourceLocation StartLoc, 14713 SourceLocation LParenLoc, 14714 SourceLocation EndLoc) { 14715 Expr *ValExpr = Priority; 14716 14717 // OpenMP [2.9.1, task Constrcut] 14718 // The priority-value is a non-negative numerical scalar expression. 14719 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14720 /*StrictlyPositive=*/false)) 14721 return nullptr; 14722 14723 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14724 } 14725 14726 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14727 SourceLocation StartLoc, 14728 SourceLocation LParenLoc, 14729 SourceLocation EndLoc) { 14730 Expr *ValExpr = Grainsize; 14731 14732 // OpenMP [2.9.2, taskloop Constrcut] 14733 // The parameter of the grainsize clause must be a positive integer 14734 // expression. 14735 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14736 /*StrictlyPositive=*/true)) 14737 return nullptr; 14738 14739 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14740 } 14741 14742 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14743 SourceLocation StartLoc, 14744 SourceLocation LParenLoc, 14745 SourceLocation EndLoc) { 14746 Expr *ValExpr = NumTasks; 14747 14748 // OpenMP [2.9.2, taskloop Constrcut] 14749 // The parameter of the num_tasks clause must be a positive integer 14750 // expression. 14751 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14752 /*StrictlyPositive=*/true)) 14753 return nullptr; 14754 14755 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14756 } 14757 14758 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14759 SourceLocation LParenLoc, 14760 SourceLocation EndLoc) { 14761 // OpenMP [2.13.2, critical construct, Description] 14762 // ... where hint-expression is an integer constant expression that evaluates 14763 // to a valid lock hint. 14764 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14765 if (HintExpr.isInvalid()) 14766 return nullptr; 14767 return new (Context) 14768 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14769 } 14770 14771 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14772 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14773 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14774 SourceLocation EndLoc) { 14775 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14776 std::string Values; 14777 Values += "'"; 14778 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14779 Values += "'"; 14780 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14781 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14782 return nullptr; 14783 } 14784 Expr *ValExpr = ChunkSize; 14785 Stmt *HelperValStmt = nullptr; 14786 if (ChunkSize) { 14787 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14788 !ChunkSize->isInstantiationDependent() && 14789 !ChunkSize->containsUnexpandedParameterPack()) { 14790 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14791 ExprResult Val = 14792 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14793 if (Val.isInvalid()) 14794 return nullptr; 14795 14796 ValExpr = Val.get(); 14797 14798 // OpenMP [2.7.1, Restrictions] 14799 // chunk_size must be a loop invariant integer expression with a positive 14800 // value. 14801 llvm::APSInt Result; 14802 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14803 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14804 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14805 << "dist_schedule" << ChunkSize->getSourceRange(); 14806 return nullptr; 14807 } 14808 } else if (getOpenMPCaptureRegionForClause( 14809 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14810 OMPD_unknown && 14811 !CurContext->isDependentContext()) { 14812 ValExpr = MakeFullExpr(ValExpr).get(); 14813 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14814 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14815 HelperValStmt = buildPreInits(Context, Captures); 14816 } 14817 } 14818 } 14819 14820 return new (Context) 14821 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14822 Kind, ValExpr, HelperValStmt); 14823 } 14824 14825 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14826 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14827 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14828 SourceLocation KindLoc, SourceLocation EndLoc) { 14829 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14830 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14831 std::string Value; 14832 SourceLocation Loc; 14833 Value += "'"; 14834 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14835 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14836 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14837 Loc = MLoc; 14838 } else { 14839 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14840 OMPC_DEFAULTMAP_scalar); 14841 Loc = KindLoc; 14842 } 14843 Value += "'"; 14844 Diag(Loc, diag::err_omp_unexpected_clause_value) 14845 << Value << getOpenMPClauseName(OMPC_defaultmap); 14846 return nullptr; 14847 } 14848 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14849 14850 return new (Context) 14851 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14852 } 14853 14854 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14855 DeclContext *CurLexicalContext = getCurLexicalContext(); 14856 if (!CurLexicalContext->isFileContext() && 14857 !CurLexicalContext->isExternCContext() && 14858 !CurLexicalContext->isExternCXXContext() && 14859 !isa<CXXRecordDecl>(CurLexicalContext) && 14860 !isa<ClassTemplateDecl>(CurLexicalContext) && 14861 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14862 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14863 Diag(Loc, diag::err_omp_region_not_file_context); 14864 return false; 14865 } 14866 ++DeclareTargetNestingLevel; 14867 return true; 14868 } 14869 14870 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14871 assert(DeclareTargetNestingLevel > 0 && 14872 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14873 --DeclareTargetNestingLevel; 14874 } 14875 14876 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14877 CXXScopeSpec &ScopeSpec, 14878 const DeclarationNameInfo &Id, 14879 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14880 NamedDeclSetType &SameDirectiveDecls) { 14881 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14882 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14883 14884 if (Lookup.isAmbiguous()) 14885 return; 14886 Lookup.suppressDiagnostics(); 14887 14888 if (!Lookup.isSingleResult()) { 14889 VarOrFuncDeclFilterCCC CCC(*this); 14890 if (TypoCorrection Corrected = 14891 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 14892 CTK_ErrorRecovery)) { 14893 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14894 << Id.getName()); 14895 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14896 return; 14897 } 14898 14899 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14900 return; 14901 } 14902 14903 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14904 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14905 isa<FunctionTemplateDecl>(ND)) { 14906 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14907 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14908 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14909 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14910 cast<ValueDecl>(ND)); 14911 if (!Res) { 14912 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14913 ND->addAttr(A); 14914 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14915 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14916 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14917 } else if (*Res != MT) { 14918 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14919 << Id.getName(); 14920 } 14921 } else { 14922 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14923 } 14924 } 14925 14926 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14927 Sema &SemaRef, Decl *D) { 14928 if (!D || !isa<VarDecl>(D)) 14929 return; 14930 auto *VD = cast<VarDecl>(D); 14931 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14932 return; 14933 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14934 SemaRef.Diag(SL, diag::note_used_here) << SR; 14935 } 14936 14937 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14938 Sema &SemaRef, DSAStackTy *Stack, 14939 ValueDecl *VD) { 14940 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14941 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14942 /*FullCheck=*/false); 14943 } 14944 14945 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14946 SourceLocation IdLoc) { 14947 if (!D || D->isInvalidDecl()) 14948 return; 14949 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14950 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 14951 if (auto *VD = dyn_cast<VarDecl>(D)) { 14952 // Only global variables can be marked as declare target. 14953 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 14954 !VD->isStaticDataMember()) 14955 return; 14956 // 2.10.6: threadprivate variable cannot appear in a declare target 14957 // directive. 14958 if (DSAStack->isThreadPrivate(VD)) { 14959 Diag(SL, diag::err_omp_threadprivate_in_target); 14960 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 14961 return; 14962 } 14963 } 14964 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 14965 D = FTD->getTemplatedDecl(); 14966 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 14967 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14968 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 14969 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 14970 assert(IdLoc.isValid() && "Source location is expected"); 14971 Diag(IdLoc, diag::err_omp_function_in_link_clause); 14972 Diag(FD->getLocation(), diag::note_defined_here) << FD; 14973 return; 14974 } 14975 } 14976 if (auto *VD = dyn_cast<ValueDecl>(D)) { 14977 // Problem if any with var declared with incomplete type will be reported 14978 // as normal, so no need to check it here. 14979 if ((E || !VD->getType()->isIncompleteType()) && 14980 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 14981 return; 14982 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 14983 // Checking declaration inside declare target region. 14984 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 14985 isa<FunctionTemplateDecl>(D)) { 14986 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 14987 Context, OMPDeclareTargetDeclAttr::MT_To); 14988 D->addAttr(A); 14989 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14990 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 14991 } 14992 return; 14993 } 14994 } 14995 if (!E) 14996 return; 14997 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 14998 } 14999 15000 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 15001 CXXScopeSpec &MapperIdScopeSpec, 15002 DeclarationNameInfo &MapperId, 15003 const OMPVarListLocTy &Locs, 15004 ArrayRef<Expr *> UnresolvedMappers) { 15005 MappableVarListInfo MVLI(VarList); 15006 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 15007 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15008 if (MVLI.ProcessedVarList.empty()) 15009 return nullptr; 15010 15011 return OMPToClause::Create( 15012 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15013 MVLI.VarComponents, MVLI.UDMapperList, 15014 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15015 } 15016 15017 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 15018 CXXScopeSpec &MapperIdScopeSpec, 15019 DeclarationNameInfo &MapperId, 15020 const OMPVarListLocTy &Locs, 15021 ArrayRef<Expr *> UnresolvedMappers) { 15022 MappableVarListInfo MVLI(VarList); 15023 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 15024 MapperIdScopeSpec, MapperId, UnresolvedMappers); 15025 if (MVLI.ProcessedVarList.empty()) 15026 return nullptr; 15027 15028 return OMPFromClause::Create( 15029 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 15030 MVLI.VarComponents, MVLI.UDMapperList, 15031 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 15032 } 15033 15034 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 15035 const OMPVarListLocTy &Locs) { 15036 MappableVarListInfo MVLI(VarList); 15037 SmallVector<Expr *, 8> PrivateCopies; 15038 SmallVector<Expr *, 8> Inits; 15039 15040 for (Expr *RefExpr : VarList) { 15041 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 15042 SourceLocation ELoc; 15043 SourceRange ERange; 15044 Expr *SimpleRefExpr = RefExpr; 15045 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15046 if (Res.second) { 15047 // It will be analyzed later. 15048 MVLI.ProcessedVarList.push_back(RefExpr); 15049 PrivateCopies.push_back(nullptr); 15050 Inits.push_back(nullptr); 15051 } 15052 ValueDecl *D = Res.first; 15053 if (!D) 15054 continue; 15055 15056 QualType Type = D->getType(); 15057 Type = Type.getNonReferenceType().getUnqualifiedType(); 15058 15059 auto *VD = dyn_cast<VarDecl>(D); 15060 15061 // Item should be a pointer or reference to pointer. 15062 if (!Type->isPointerType()) { 15063 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 15064 << 0 << RefExpr->getSourceRange(); 15065 continue; 15066 } 15067 15068 // Build the private variable and the expression that refers to it. 15069 auto VDPrivate = 15070 buildVarDecl(*this, ELoc, Type, D->getName(), 15071 D->hasAttrs() ? &D->getAttrs() : nullptr, 15072 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15073 if (VDPrivate->isInvalidDecl()) 15074 continue; 15075 15076 CurContext->addDecl(VDPrivate); 15077 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15078 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15079 15080 // Add temporary variable to initialize the private copy of the pointer. 15081 VarDecl *VDInit = 15082 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 15083 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 15084 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 15085 AddInitializerToDecl(VDPrivate, 15086 DefaultLvalueConversion(VDInitRefExpr).get(), 15087 /*DirectInit=*/false); 15088 15089 // If required, build a capture to implement the privatization initialized 15090 // with the current list item value. 15091 DeclRefExpr *Ref = nullptr; 15092 if (!VD) 15093 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15094 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 15095 PrivateCopies.push_back(VDPrivateRefExpr); 15096 Inits.push_back(VDInitRefExpr); 15097 15098 // We need to add a data sharing attribute for this variable to make sure it 15099 // is correctly captured. A variable that shows up in a use_device_ptr has 15100 // similar properties of a first private variable. 15101 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15102 15103 // Create a mappable component for the list item. List items in this clause 15104 // only need a component. 15105 MVLI.VarBaseDeclarations.push_back(D); 15106 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15107 MVLI.VarComponents.back().push_back( 15108 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 15109 } 15110 15111 if (MVLI.ProcessedVarList.empty()) 15112 return nullptr; 15113 15114 return OMPUseDevicePtrClause::Create( 15115 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 15116 MVLI.VarBaseDeclarations, MVLI.VarComponents); 15117 } 15118 15119 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 15120 const OMPVarListLocTy &Locs) { 15121 MappableVarListInfo MVLI(VarList); 15122 for (Expr *RefExpr : VarList) { 15123 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 15124 SourceLocation ELoc; 15125 SourceRange ERange; 15126 Expr *SimpleRefExpr = RefExpr; 15127 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15128 if (Res.second) { 15129 // It will be analyzed later. 15130 MVLI.ProcessedVarList.push_back(RefExpr); 15131 } 15132 ValueDecl *D = Res.first; 15133 if (!D) 15134 continue; 15135 15136 QualType Type = D->getType(); 15137 // item should be a pointer or array or reference to pointer or array 15138 if (!Type.getNonReferenceType()->isPointerType() && 15139 !Type.getNonReferenceType()->isArrayType()) { 15140 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 15141 << 0 << RefExpr->getSourceRange(); 15142 continue; 15143 } 15144 15145 // Check if the declaration in the clause does not show up in any data 15146 // sharing attribute. 15147 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15148 if (isOpenMPPrivate(DVar.CKind)) { 15149 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15150 << getOpenMPClauseName(DVar.CKind) 15151 << getOpenMPClauseName(OMPC_is_device_ptr) 15152 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15153 reportOriginalDsa(*this, DSAStack, D, DVar); 15154 continue; 15155 } 15156 15157 const Expr *ConflictExpr; 15158 if (DSAStack->checkMappableExprComponentListsForDecl( 15159 D, /*CurrentRegionOnly=*/true, 15160 [&ConflictExpr]( 15161 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 15162 OpenMPClauseKind) -> bool { 15163 ConflictExpr = R.front().getAssociatedExpression(); 15164 return true; 15165 })) { 15166 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 15167 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 15168 << ConflictExpr->getSourceRange(); 15169 continue; 15170 } 15171 15172 // Store the components in the stack so that they can be used to check 15173 // against other clauses later on. 15174 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 15175 DSAStack->addMappableExpressionComponents( 15176 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 15177 15178 // Record the expression we've just processed. 15179 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 15180 15181 // Create a mappable component for the list item. List items in this clause 15182 // only need a component. We use a null declaration to signal fields in 15183 // 'this'. 15184 assert((isa<DeclRefExpr>(SimpleRefExpr) || 15185 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 15186 "Unexpected device pointer expression!"); 15187 MVLI.VarBaseDeclarations.push_back( 15188 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 15189 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15190 MVLI.VarComponents.back().push_back(MC); 15191 } 15192 15193 if (MVLI.ProcessedVarList.empty()) 15194 return nullptr; 15195 15196 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 15197 MVLI.VarBaseDeclarations, 15198 MVLI.VarComponents); 15199 } 15200 15201 OMPClause *Sema::ActOnOpenMPAllocateClause( 15202 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15203 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15204 if (Allocator) { 15205 // OpenMP [2.11.4 allocate Clause, Description] 15206 // allocator is an expression of omp_allocator_handle_t type. 15207 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 15208 return nullptr; 15209 15210 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 15211 if (AllocatorRes.isInvalid()) 15212 return nullptr; 15213 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 15214 DSAStack->getOMPAllocatorHandleT(), 15215 Sema::AA_Initializing, 15216 /*AllowExplicit=*/true); 15217 if (AllocatorRes.isInvalid()) 15218 return nullptr; 15219 Allocator = AllocatorRes.get(); 15220 } else { 15221 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 15222 // allocate clauses that appear on a target construct or on constructs in a 15223 // target region must specify an allocator expression unless a requires 15224 // directive with the dynamic_allocators clause is present in the same 15225 // compilation unit. 15226 if (LangOpts.OpenMPIsDevice && 15227 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 15228 targetDiag(StartLoc, diag::err_expected_allocator_expression); 15229 } 15230 // Analyze and build list of variables. 15231 SmallVector<Expr *, 8> Vars; 15232 for (Expr *RefExpr : VarList) { 15233 assert(RefExpr && "NULL expr in OpenMP private clause."); 15234 SourceLocation ELoc; 15235 SourceRange ERange; 15236 Expr *SimpleRefExpr = RefExpr; 15237 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15238 if (Res.second) { 15239 // It will be analyzed later. 15240 Vars.push_back(RefExpr); 15241 } 15242 ValueDecl *D = Res.first; 15243 if (!D) 15244 continue; 15245 15246 auto *VD = dyn_cast<VarDecl>(D); 15247 DeclRefExpr *Ref = nullptr; 15248 if (!VD && !CurContext->isDependentContext()) 15249 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15250 Vars.push_back((VD || CurContext->isDependentContext()) 15251 ? RefExpr->IgnoreParens() 15252 : Ref); 15253 } 15254 15255 if (Vars.empty()) 15256 return nullptr; 15257 15258 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 15259 ColonLoc, EndLoc, Vars); 15260 } 15261