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 /// Stack for tracking declarations used in OpenMP directives and 52 /// clauses and their data-sharing attributes. 53 class DSAStackTy { 54 public: 55 struct DSAVarData { 56 OpenMPDirectiveKind DKind = OMPD_unknown; 57 OpenMPClauseKind CKind = OMPC_unknown; 58 const Expr *RefExpr = nullptr; 59 DeclRefExpr *PrivateCopy = nullptr; 60 SourceLocation ImplicitDSALoc; 61 DSAVarData() = default; 62 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 63 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 64 SourceLocation ImplicitDSALoc) 65 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 66 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 67 }; 68 using OperatorOffsetTy = 69 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 70 using DoacrossDependMapTy = 71 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 72 73 private: 74 struct DSAInfo { 75 OpenMPClauseKind Attributes = OMPC_unknown; 76 /// Pointer to a reference expression and a flag which shows that the 77 /// variable is marked as lastprivate(true) or not (false). 78 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 79 DeclRefExpr *PrivateCopy = nullptr; 80 }; 81 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 82 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 83 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 84 using LoopControlVariablesMapTy = 85 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 86 /// Struct that associates a component with the clause kind where they are 87 /// found. 88 struct MappedExprComponentTy { 89 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 90 OpenMPClauseKind Kind = OMPC_unknown; 91 }; 92 using MappedExprComponentsTy = 93 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 94 using CriticalsWithHintsTy = 95 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 96 struct ReductionData { 97 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 98 SourceRange ReductionRange; 99 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 100 ReductionData() = default; 101 void set(BinaryOperatorKind BO, SourceRange RR) { 102 ReductionRange = RR; 103 ReductionOp = BO; 104 } 105 void set(const Expr *RefExpr, SourceRange RR) { 106 ReductionRange = RR; 107 ReductionOp = RefExpr; 108 } 109 }; 110 using DeclReductionMapTy = 111 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 112 struct DefaultmapInfo { 113 OpenMPDefaultmapClauseModifier ImplicitBehavior = 114 OMPC_DEFAULTMAP_MODIFIER_unknown; 115 SourceLocation SLoc; 116 DefaultmapInfo() = default; 117 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 118 : ImplicitBehavior(M), SLoc(Loc) {} 119 }; 120 121 struct SharingMapTy { 122 DeclSAMapTy SharingMap; 123 DeclReductionMapTy ReductionMap; 124 AlignedMapTy AlignedMap; 125 MappedExprComponentsTy MappedExprComponents; 126 LoopControlVariablesMapTy LCVMap; 127 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 128 SourceLocation DefaultAttrLoc; 129 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 130 OpenMPDirectiveKind Directive = OMPD_unknown; 131 DeclarationNameInfo DirectiveName; 132 Scope *CurScope = nullptr; 133 SourceLocation ConstructLoc; 134 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 135 /// get the data (loop counters etc.) about enclosing loop-based construct. 136 /// This data is required during codegen. 137 DoacrossDependMapTy DoacrossDepends; 138 /// First argument (Expr *) contains optional argument of the 139 /// 'ordered' clause, the second one is true if the regions has 'ordered' 140 /// clause, false otherwise. 141 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 142 unsigned AssociatedLoops = 1; 143 bool HasMutipleLoops = false; 144 const Decl *PossiblyLoopCounter = nullptr; 145 bool NowaitRegion = false; 146 bool CancelRegion = false; 147 bool LoopStart = false; 148 bool BodyComplete = false; 149 SourceLocation InnerTeamsRegionLoc; 150 /// Reference to the taskgroup task_reduction reference expression. 151 Expr *TaskgroupReductionRef = nullptr; 152 llvm::DenseSet<QualType> MappedClassesQualTypes; 153 /// List of globals marked as declare target link in this target region 154 /// (isOpenMPTargetExecutionDirective(Directive) == true). 155 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 156 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 157 Scope *CurScope, SourceLocation Loc) 158 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 159 ConstructLoc(Loc) {} 160 SharingMapTy() = default; 161 }; 162 163 using StackTy = SmallVector<SharingMapTy, 4>; 164 165 /// Stack of used declaration and their data-sharing attributes. 166 DeclSAMapTy Threadprivates; 167 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 168 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 169 /// true, if check for DSA must be from parent directive, false, if 170 /// from current directive. 171 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 172 Sema &SemaRef; 173 bool ForceCapturing = false; 174 /// true if all the variables in the target executable directives must be 175 /// captured by reference. 176 bool ForceCaptureByReferenceInTargetExecutable = false; 177 CriticalsWithHintsTy Criticals; 178 unsigned IgnoredStackElements = 0; 179 180 /// Iterators over the stack iterate in order from innermost to outermost 181 /// directive. 182 using const_iterator = StackTy::const_reverse_iterator; 183 const_iterator begin() const { 184 return Stack.empty() ? const_iterator() 185 : Stack.back().first.rbegin() + IgnoredStackElements; 186 } 187 const_iterator end() const { 188 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 189 } 190 using iterator = StackTy::reverse_iterator; 191 iterator begin() { 192 return Stack.empty() ? iterator() 193 : Stack.back().first.rbegin() + IgnoredStackElements; 194 } 195 iterator end() { 196 return Stack.empty() ? iterator() : Stack.back().first.rend(); 197 } 198 199 // Convenience operations to get at the elements of the stack. 200 201 bool isStackEmpty() const { 202 return Stack.empty() || 203 Stack.back().second != CurrentNonCapturingFunctionScope || 204 Stack.back().first.size() <= IgnoredStackElements; 205 } 206 size_t getStackSize() const { 207 return isStackEmpty() ? 0 208 : Stack.back().first.size() - IgnoredStackElements; 209 } 210 211 SharingMapTy *getTopOfStackOrNull() { 212 size_t Size = getStackSize(); 213 if (Size == 0) 214 return nullptr; 215 return &Stack.back().first[Size - 1]; 216 } 217 const SharingMapTy *getTopOfStackOrNull() const { 218 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 219 } 220 SharingMapTy &getTopOfStack() { 221 assert(!isStackEmpty() && "no current directive"); 222 return *getTopOfStackOrNull(); 223 } 224 const SharingMapTy &getTopOfStack() const { 225 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 226 } 227 228 SharingMapTy *getSecondOnStackOrNull() { 229 size_t Size = getStackSize(); 230 if (Size <= 1) 231 return nullptr; 232 return &Stack.back().first[Size - 2]; 233 } 234 const SharingMapTy *getSecondOnStackOrNull() const { 235 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 236 } 237 238 /// Get the stack element at a certain level (previously returned by 239 /// \c getNestingLevel). 240 /// 241 /// Note that nesting levels count from outermost to innermost, and this is 242 /// the reverse of our iteration order where new inner levels are pushed at 243 /// the front of the stack. 244 SharingMapTy &getStackElemAtLevel(unsigned Level) { 245 assert(Level < getStackSize() && "no such stack element"); 246 return Stack.back().first[Level]; 247 } 248 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 249 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 250 } 251 252 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 253 254 /// Checks if the variable is a local for OpenMP region. 255 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 256 257 /// Vector of previously declared requires directives 258 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 259 /// omp_allocator_handle_t type. 260 QualType OMPAllocatorHandleT; 261 /// Expression for the predefined allocators. 262 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 263 nullptr}; 264 /// Vector of previously encountered target directives 265 SmallVector<SourceLocation, 2> TargetLocations; 266 267 public: 268 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 269 270 /// Sets omp_allocator_handle_t type. 271 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 272 /// Gets omp_allocator_handle_t type. 273 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 274 /// Sets the given default allocator. 275 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 276 Expr *Allocator) { 277 OMPPredefinedAllocators[AllocatorKind] = Allocator; 278 } 279 /// Returns the specified default allocator. 280 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 281 return OMPPredefinedAllocators[AllocatorKind]; 282 } 283 284 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 285 OpenMPClauseKind getClauseParsingMode() const { 286 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 287 return ClauseKindMode; 288 } 289 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 290 291 bool isBodyComplete() const { 292 const SharingMapTy *Top = getTopOfStackOrNull(); 293 return Top && Top->BodyComplete; 294 } 295 void setBodyComplete() { 296 getTopOfStack().BodyComplete = true; 297 } 298 299 bool isForceVarCapturing() const { return ForceCapturing; } 300 void setForceVarCapturing(bool V) { ForceCapturing = V; } 301 302 void setForceCaptureByReferenceInTargetExecutable(bool V) { 303 ForceCaptureByReferenceInTargetExecutable = V; 304 } 305 bool isForceCaptureByReferenceInTargetExecutable() const { 306 return ForceCaptureByReferenceInTargetExecutable; 307 } 308 309 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 310 Scope *CurScope, SourceLocation Loc) { 311 assert(!IgnoredStackElements && 312 "cannot change stack while ignoring elements"); 313 if (Stack.empty() || 314 Stack.back().second != CurrentNonCapturingFunctionScope) 315 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 316 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 317 Stack.back().first.back().DefaultAttrLoc = Loc; 318 } 319 320 void pop() { 321 assert(!IgnoredStackElements && 322 "cannot change stack while ignoring elements"); 323 assert(!Stack.back().first.empty() && 324 "Data-sharing attributes stack is empty!"); 325 Stack.back().first.pop_back(); 326 } 327 328 /// RAII object to temporarily leave the scope of a directive when we want to 329 /// logically operate in its parent. 330 class ParentDirectiveScope { 331 DSAStackTy &Self; 332 bool Active; 333 public: 334 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 335 : Self(Self), Active(false) { 336 if (Activate) 337 enable(); 338 } 339 ~ParentDirectiveScope() { disable(); } 340 void disable() { 341 if (Active) { 342 --Self.IgnoredStackElements; 343 Active = false; 344 } 345 } 346 void enable() { 347 if (!Active) { 348 ++Self.IgnoredStackElements; 349 Active = true; 350 } 351 } 352 }; 353 354 /// Marks that we're started loop parsing. 355 void loopInit() { 356 assert(isOpenMPLoopDirective(getCurrentDirective()) && 357 "Expected loop-based directive."); 358 getTopOfStack().LoopStart = true; 359 } 360 /// Start capturing of the variables in the loop context. 361 void loopStart() { 362 assert(isOpenMPLoopDirective(getCurrentDirective()) && 363 "Expected loop-based directive."); 364 getTopOfStack().LoopStart = false; 365 } 366 /// true, if variables are captured, false otherwise. 367 bool isLoopStarted() const { 368 assert(isOpenMPLoopDirective(getCurrentDirective()) && 369 "Expected loop-based directive."); 370 return !getTopOfStack().LoopStart; 371 } 372 /// Marks (or clears) declaration as possibly loop counter. 373 void resetPossibleLoopCounter(const Decl *D = nullptr) { 374 getTopOfStack().PossiblyLoopCounter = 375 D ? D->getCanonicalDecl() : D; 376 } 377 /// Gets the possible loop counter decl. 378 const Decl *getPossiblyLoopCunter() const { 379 return getTopOfStack().PossiblyLoopCounter; 380 } 381 /// Start new OpenMP region stack in new non-capturing function. 382 void pushFunction() { 383 assert(!IgnoredStackElements && 384 "cannot change stack while ignoring elements"); 385 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 386 assert(!isa<CapturingScopeInfo>(CurFnScope)); 387 CurrentNonCapturingFunctionScope = CurFnScope; 388 } 389 /// Pop region stack for non-capturing function. 390 void popFunction(const FunctionScopeInfo *OldFSI) { 391 assert(!IgnoredStackElements && 392 "cannot change stack while ignoring elements"); 393 if (!Stack.empty() && Stack.back().second == OldFSI) { 394 assert(Stack.back().first.empty()); 395 Stack.pop_back(); 396 } 397 CurrentNonCapturingFunctionScope = nullptr; 398 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 399 if (!isa<CapturingScopeInfo>(FSI)) { 400 CurrentNonCapturingFunctionScope = FSI; 401 break; 402 } 403 } 404 } 405 406 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 407 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 408 } 409 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 410 getCriticalWithHint(const DeclarationNameInfo &Name) const { 411 auto I = Criticals.find(Name.getAsString()); 412 if (I != Criticals.end()) 413 return I->second; 414 return std::make_pair(nullptr, llvm::APSInt()); 415 } 416 /// If 'aligned' declaration for given variable \a D was not seen yet, 417 /// add it and return NULL; otherwise return previous occurrence's expression 418 /// for diagnostics. 419 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 420 421 /// Register specified variable as loop control variable. 422 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 423 /// Check if the specified variable is a loop control variable for 424 /// current region. 425 /// \return The index of the loop control variable in the list of associated 426 /// for-loops (from outer to inner). 427 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 428 /// Check if the specified variable is a loop control variable for 429 /// parent region. 430 /// \return The index of the loop control variable in the list of associated 431 /// for-loops (from outer to inner). 432 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 433 /// Get the loop control variable for the I-th loop (or nullptr) in 434 /// parent directive. 435 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 436 437 /// Adds explicit data sharing attribute to the specified declaration. 438 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 439 DeclRefExpr *PrivateCopy = nullptr); 440 441 /// Adds additional information for the reduction items with the reduction id 442 /// represented as an operator. 443 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 444 BinaryOperatorKind BOK); 445 /// Adds additional information for the reduction items with the reduction id 446 /// represented as reduction identifier. 447 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 448 const Expr *ReductionRef); 449 /// Returns the location and reduction operation from the innermost parent 450 /// region for the given \p D. 451 const DSAVarData 452 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 453 BinaryOperatorKind &BOK, 454 Expr *&TaskgroupDescriptor) const; 455 /// Returns the location and reduction operation from the innermost parent 456 /// region for the given \p D. 457 const DSAVarData 458 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 459 const Expr *&ReductionRef, 460 Expr *&TaskgroupDescriptor) const; 461 /// Return reduction reference expression for the current taskgroup. 462 Expr *getTaskgroupReductionRef() const { 463 assert(getTopOfStack().Directive == OMPD_taskgroup && 464 "taskgroup reference expression requested for non taskgroup " 465 "directive."); 466 return getTopOfStack().TaskgroupReductionRef; 467 } 468 /// Checks if the given \p VD declaration is actually a taskgroup reduction 469 /// descriptor variable at the \p Level of OpenMP regions. 470 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 471 return getStackElemAtLevel(Level).TaskgroupReductionRef && 472 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 473 ->getDecl() == VD; 474 } 475 476 /// Returns data sharing attributes from top of the stack for the 477 /// specified declaration. 478 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 479 /// Returns data-sharing attributes for the specified declaration. 480 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 481 /// Checks if the specified variables has data-sharing attributes which 482 /// match specified \a CPred predicate in any directive which matches \a DPred 483 /// predicate. 484 const DSAVarData 485 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 486 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 487 bool FromParent) const; 488 /// Checks if the specified variables has data-sharing attributes which 489 /// match specified \a CPred predicate in any innermost directive which 490 /// matches \a DPred predicate. 491 const DSAVarData 492 hasInnermostDSA(ValueDecl *D, 493 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 494 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 495 bool FromParent) const; 496 /// Checks if the specified variables has explicit data-sharing 497 /// attributes which match specified \a CPred predicate at the specified 498 /// OpenMP region. 499 bool hasExplicitDSA(const ValueDecl *D, 500 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 501 unsigned Level, bool NotLastprivate = false) const; 502 503 /// Returns true if the directive at level \Level matches in the 504 /// specified \a DPred predicate. 505 bool hasExplicitDirective( 506 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 507 unsigned Level) const; 508 509 /// Finds a directive which matches specified \a DPred predicate. 510 bool hasDirective( 511 const llvm::function_ref<bool( 512 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 513 DPred, 514 bool FromParent) const; 515 516 /// Returns currently analyzed directive. 517 OpenMPDirectiveKind getCurrentDirective() const { 518 const SharingMapTy *Top = getTopOfStackOrNull(); 519 return Top ? Top->Directive : OMPD_unknown; 520 } 521 /// Returns directive kind at specified level. 522 OpenMPDirectiveKind getDirective(unsigned Level) const { 523 assert(!isStackEmpty() && "No directive at specified level."); 524 return getStackElemAtLevel(Level).Directive; 525 } 526 /// Returns the capture region at the specified level. 527 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 528 unsigned OpenMPCaptureLevel) const { 529 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 530 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 531 return CaptureRegions[OpenMPCaptureLevel]; 532 } 533 /// Returns parent directive. 534 OpenMPDirectiveKind getParentDirective() const { 535 const SharingMapTy *Parent = getSecondOnStackOrNull(); 536 return Parent ? Parent->Directive : OMPD_unknown; 537 } 538 539 /// Add requires decl to internal vector 540 void addRequiresDecl(OMPRequiresDecl *RD) { 541 RequiresDecls.push_back(RD); 542 } 543 544 /// Checks if the defined 'requires' directive has specified type of clause. 545 template <typename ClauseType> 546 bool hasRequiresDeclWithClause() { 547 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 548 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 549 return isa<ClauseType>(C); 550 }); 551 }); 552 } 553 554 /// Checks for a duplicate clause amongst previously declared requires 555 /// directives 556 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 557 bool IsDuplicate = false; 558 for (OMPClause *CNew : ClauseList) { 559 for (const OMPRequiresDecl *D : RequiresDecls) { 560 for (const OMPClause *CPrev : D->clauselists()) { 561 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 562 SemaRef.Diag(CNew->getBeginLoc(), 563 diag::err_omp_requires_clause_redeclaration) 564 << getOpenMPClauseName(CNew->getClauseKind()); 565 SemaRef.Diag(CPrev->getBeginLoc(), 566 diag::note_omp_requires_previous_clause) 567 << getOpenMPClauseName(CPrev->getClauseKind()); 568 IsDuplicate = true; 569 } 570 } 571 } 572 } 573 return IsDuplicate; 574 } 575 576 /// Add location of previously encountered target to internal vector 577 void addTargetDirLocation(SourceLocation LocStart) { 578 TargetLocations.push_back(LocStart); 579 } 580 581 // Return previously encountered target region locations. 582 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 583 return TargetLocations; 584 } 585 586 /// Set default data sharing attribute to none. 587 void setDefaultDSANone(SourceLocation Loc) { 588 getTopOfStack().DefaultAttr = DSA_none; 589 getTopOfStack().DefaultAttrLoc = Loc; 590 } 591 /// Set default data sharing attribute to shared. 592 void setDefaultDSAShared(SourceLocation Loc) { 593 getTopOfStack().DefaultAttr = DSA_shared; 594 getTopOfStack().DefaultAttrLoc = Loc; 595 } 596 /// Set default data mapping attribute to Modifier:Kind 597 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 598 OpenMPDefaultmapClauseKind Kind, 599 SourceLocation Loc) { 600 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 601 DMI.ImplicitBehavior = M; 602 DMI.SLoc = Loc; 603 } 604 /// Check whether the implicit-behavior has been set in defaultmap 605 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 606 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 607 OMPC_DEFAULTMAP_MODIFIER_unknown; 608 } 609 610 DefaultDataSharingAttributes getDefaultDSA() const { 611 return isStackEmpty() ? DSA_unspecified 612 : getTopOfStack().DefaultAttr; 613 } 614 SourceLocation getDefaultDSALocation() const { 615 return isStackEmpty() ? SourceLocation() 616 : getTopOfStack().DefaultAttrLoc; 617 } 618 OpenMPDefaultmapClauseModifier 619 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 620 return isStackEmpty() 621 ? OMPC_DEFAULTMAP_MODIFIER_unknown 622 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 623 } 624 OpenMPDefaultmapClauseModifier 625 getDefaultmapModifierAtLevel(unsigned Level, 626 OpenMPDefaultmapClauseKind Kind) const { 627 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 628 } 629 bool isDefaultmapCapturedByRef(unsigned Level, 630 OpenMPDefaultmapClauseKind Kind) const { 631 OpenMPDefaultmapClauseModifier M = 632 getDefaultmapModifierAtLevel(Level, Kind); 633 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 634 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 635 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 636 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 637 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 638 } 639 return true; 640 } 641 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 642 OpenMPDefaultmapClauseKind Kind) { 643 switch (Kind) { 644 case OMPC_DEFAULTMAP_scalar: 645 case OMPC_DEFAULTMAP_pointer: 646 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 647 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 648 (M == OMPC_DEFAULTMAP_MODIFIER_default); 649 case OMPC_DEFAULTMAP_aggregate: 650 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 651 default: 652 break; 653 } 654 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 655 } 656 bool mustBeFirstprivateAtLevel(unsigned Level, 657 OpenMPDefaultmapClauseKind Kind) const { 658 OpenMPDefaultmapClauseModifier M = 659 getDefaultmapModifierAtLevel(Level, Kind); 660 return mustBeFirstprivateBase(M, Kind); 661 } 662 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 663 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 664 return mustBeFirstprivateBase(M, Kind); 665 } 666 667 /// Checks if the specified variable is a threadprivate. 668 bool isThreadPrivate(VarDecl *D) { 669 const DSAVarData DVar = getTopDSA(D, false); 670 return isOpenMPThreadPrivate(DVar.CKind); 671 } 672 673 /// Marks current region as ordered (it has an 'ordered' clause). 674 void setOrderedRegion(bool IsOrdered, const Expr *Param, 675 OMPOrderedClause *Clause) { 676 if (IsOrdered) 677 getTopOfStack().OrderedRegion.emplace(Param, Clause); 678 else 679 getTopOfStack().OrderedRegion.reset(); 680 } 681 /// Returns true, if region is ordered (has associated 'ordered' clause), 682 /// false - otherwise. 683 bool isOrderedRegion() const { 684 if (const SharingMapTy *Top = getTopOfStackOrNull()) 685 return Top->OrderedRegion.hasValue(); 686 return false; 687 } 688 /// Returns optional parameter for the ordered region. 689 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 690 if (const SharingMapTy *Top = getTopOfStackOrNull()) 691 if (Top->OrderedRegion.hasValue()) 692 return Top->OrderedRegion.getValue(); 693 return std::make_pair(nullptr, nullptr); 694 } 695 /// Returns true, if parent region is ordered (has associated 696 /// 'ordered' clause), false - otherwise. 697 bool isParentOrderedRegion() const { 698 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 699 return Parent->OrderedRegion.hasValue(); 700 return false; 701 } 702 /// Returns optional parameter for the ordered region. 703 std::pair<const Expr *, OMPOrderedClause *> 704 getParentOrderedRegionParam() const { 705 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 706 if (Parent->OrderedRegion.hasValue()) 707 return Parent->OrderedRegion.getValue(); 708 return std::make_pair(nullptr, nullptr); 709 } 710 /// Marks current region as nowait (it has a 'nowait' clause). 711 void setNowaitRegion(bool IsNowait = true) { 712 getTopOfStack().NowaitRegion = IsNowait; 713 } 714 /// Returns true, if parent region is nowait (has associated 715 /// 'nowait' clause), false - otherwise. 716 bool isParentNowaitRegion() const { 717 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 718 return Parent->NowaitRegion; 719 return false; 720 } 721 /// Marks parent region as cancel region. 722 void setParentCancelRegion(bool Cancel = true) { 723 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 724 Parent->CancelRegion |= Cancel; 725 } 726 /// Return true if current region has inner cancel construct. 727 bool isCancelRegion() const { 728 const SharingMapTy *Top = getTopOfStackOrNull(); 729 return Top ? Top->CancelRegion : false; 730 } 731 732 /// Set collapse value for the region. 733 void setAssociatedLoops(unsigned Val) { 734 getTopOfStack().AssociatedLoops = Val; 735 if (Val > 1) 736 getTopOfStack().HasMutipleLoops = true; 737 } 738 /// Return collapse value for region. 739 unsigned getAssociatedLoops() const { 740 const SharingMapTy *Top = getTopOfStackOrNull(); 741 return Top ? Top->AssociatedLoops : 0; 742 } 743 /// Returns true if the construct is associated with multiple loops. 744 bool hasMutipleLoops() const { 745 const SharingMapTy *Top = getTopOfStackOrNull(); 746 return Top ? Top->HasMutipleLoops : false; 747 } 748 749 /// Marks current target region as one with closely nested teams 750 /// region. 751 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 752 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 753 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 754 } 755 /// Returns true, if current region has closely nested teams region. 756 bool hasInnerTeamsRegion() const { 757 return getInnerTeamsRegionLoc().isValid(); 758 } 759 /// Returns location of the nested teams region (if any). 760 SourceLocation getInnerTeamsRegionLoc() const { 761 const SharingMapTy *Top = getTopOfStackOrNull(); 762 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 763 } 764 765 Scope *getCurScope() const { 766 const SharingMapTy *Top = getTopOfStackOrNull(); 767 return Top ? Top->CurScope : nullptr; 768 } 769 SourceLocation getConstructLoc() const { 770 const SharingMapTy *Top = getTopOfStackOrNull(); 771 return Top ? Top->ConstructLoc : SourceLocation(); 772 } 773 774 /// Do the check specified in \a Check to all component lists and return true 775 /// if any issue is found. 776 bool checkMappableExprComponentListsForDecl( 777 const ValueDecl *VD, bool CurrentRegionOnly, 778 const llvm::function_ref< 779 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 780 OpenMPClauseKind)> 781 Check) const { 782 if (isStackEmpty()) 783 return false; 784 auto SI = begin(); 785 auto SE = end(); 786 787 if (SI == SE) 788 return false; 789 790 if (CurrentRegionOnly) 791 SE = std::next(SI); 792 else 793 std::advance(SI, 1); 794 795 for (; SI != SE; ++SI) { 796 auto MI = SI->MappedExprComponents.find(VD); 797 if (MI != SI->MappedExprComponents.end()) 798 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 799 MI->second.Components) 800 if (Check(L, MI->second.Kind)) 801 return true; 802 } 803 return false; 804 } 805 806 /// Do the check specified in \a Check to all component lists at a given level 807 /// and return true if any issue is found. 808 bool checkMappableExprComponentListsForDeclAtLevel( 809 const ValueDecl *VD, unsigned Level, 810 const llvm::function_ref< 811 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 812 OpenMPClauseKind)> 813 Check) const { 814 if (getStackSize() <= Level) 815 return false; 816 817 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 818 auto MI = StackElem.MappedExprComponents.find(VD); 819 if (MI != StackElem.MappedExprComponents.end()) 820 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 821 MI->second.Components) 822 if (Check(L, MI->second.Kind)) 823 return true; 824 return false; 825 } 826 827 /// Create a new mappable expression component list associated with a given 828 /// declaration and initialize it with the provided list of components. 829 void addMappableExpressionComponents( 830 const ValueDecl *VD, 831 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 832 OpenMPClauseKind WhereFoundClauseKind) { 833 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 834 // Create new entry and append the new components there. 835 MEC.Components.resize(MEC.Components.size() + 1); 836 MEC.Components.back().append(Components.begin(), Components.end()); 837 MEC.Kind = WhereFoundClauseKind; 838 } 839 840 unsigned getNestingLevel() const { 841 assert(!isStackEmpty()); 842 return getStackSize() - 1; 843 } 844 void addDoacrossDependClause(OMPDependClause *C, 845 const OperatorOffsetTy &OpsOffs) { 846 SharingMapTy *Parent = getSecondOnStackOrNull(); 847 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 848 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 849 } 850 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 851 getDoacrossDependClauses() const { 852 const SharingMapTy &StackElem = getTopOfStack(); 853 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 854 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 855 return llvm::make_range(Ref.begin(), Ref.end()); 856 } 857 return llvm::make_range(StackElem.DoacrossDepends.end(), 858 StackElem.DoacrossDepends.end()); 859 } 860 861 // Store types of classes which have been explicitly mapped 862 void addMappedClassesQualTypes(QualType QT) { 863 SharingMapTy &StackElem = getTopOfStack(); 864 StackElem.MappedClassesQualTypes.insert(QT); 865 } 866 867 // Return set of mapped classes types 868 bool isClassPreviouslyMapped(QualType QT) const { 869 const SharingMapTy &StackElem = getTopOfStack(); 870 return StackElem.MappedClassesQualTypes.count(QT) != 0; 871 } 872 873 /// Adds global declare target to the parent target region. 874 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 875 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 876 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 877 "Expected declare target link global."); 878 for (auto &Elem : *this) { 879 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 880 Elem.DeclareTargetLinkVarDecls.push_back(E); 881 return; 882 } 883 } 884 } 885 886 /// Returns the list of globals with declare target link if current directive 887 /// is target. 888 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 889 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 890 "Expected target executable directive."); 891 return getTopOfStack().DeclareTargetLinkVarDecls; 892 } 893 }; 894 895 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 896 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 897 } 898 899 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 900 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 901 DKind == OMPD_unknown; 902 } 903 904 } // namespace 905 906 static const Expr *getExprAsWritten(const Expr *E) { 907 if (const auto *FE = dyn_cast<FullExpr>(E)) 908 E = FE->getSubExpr(); 909 910 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 911 E = MTE->getSubExpr(); 912 913 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 914 E = Binder->getSubExpr(); 915 916 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 917 E = ICE->getSubExprAsWritten(); 918 return E->IgnoreParens(); 919 } 920 921 static Expr *getExprAsWritten(Expr *E) { 922 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 923 } 924 925 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 926 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 927 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 928 D = ME->getMemberDecl(); 929 const auto *VD = dyn_cast<VarDecl>(D); 930 const auto *FD = dyn_cast<FieldDecl>(D); 931 if (VD != nullptr) { 932 VD = VD->getCanonicalDecl(); 933 D = VD; 934 } else { 935 assert(FD); 936 FD = FD->getCanonicalDecl(); 937 D = FD; 938 } 939 return D; 940 } 941 942 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 943 return const_cast<ValueDecl *>( 944 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 945 } 946 947 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 948 ValueDecl *D) const { 949 D = getCanonicalDecl(D); 950 auto *VD = dyn_cast<VarDecl>(D); 951 const auto *FD = dyn_cast<FieldDecl>(D); 952 DSAVarData DVar; 953 if (Iter == end()) { 954 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 955 // in a region but not in construct] 956 // File-scope or namespace-scope variables referenced in called routines 957 // in the region are shared unless they appear in a threadprivate 958 // directive. 959 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 960 DVar.CKind = OMPC_shared; 961 962 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 963 // in a region but not in construct] 964 // Variables with static storage duration that are declared in called 965 // routines in the region are shared. 966 if (VD && VD->hasGlobalStorage()) 967 DVar.CKind = OMPC_shared; 968 969 // Non-static data members are shared by default. 970 if (FD) 971 DVar.CKind = OMPC_shared; 972 973 return DVar; 974 } 975 976 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 977 // in a Construct, C/C++, predetermined, p.1] 978 // Variables with automatic storage duration that are declared in a scope 979 // inside the construct are private. 980 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 981 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 982 DVar.CKind = OMPC_private; 983 return DVar; 984 } 985 986 DVar.DKind = Iter->Directive; 987 // Explicitly specified attributes and local variables with predetermined 988 // attributes. 989 if (Iter->SharingMap.count(D)) { 990 const DSAInfo &Data = Iter->SharingMap.lookup(D); 991 DVar.RefExpr = Data.RefExpr.getPointer(); 992 DVar.PrivateCopy = Data.PrivateCopy; 993 DVar.CKind = Data.Attributes; 994 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 995 return DVar; 996 } 997 998 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 999 // in a Construct, C/C++, implicitly determined, p.1] 1000 // In a parallel or task construct, the data-sharing attributes of these 1001 // variables are determined by the default clause, if present. 1002 switch (Iter->DefaultAttr) { 1003 case DSA_shared: 1004 DVar.CKind = OMPC_shared; 1005 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1006 return DVar; 1007 case DSA_none: 1008 return DVar; 1009 case DSA_unspecified: 1010 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1011 // in a Construct, implicitly determined, p.2] 1012 // In a parallel construct, if no default clause is present, these 1013 // variables are shared. 1014 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1015 if ((isOpenMPParallelDirective(DVar.DKind) && 1016 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1017 isOpenMPTeamsDirective(DVar.DKind)) { 1018 DVar.CKind = OMPC_shared; 1019 return DVar; 1020 } 1021 1022 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1023 // in a Construct, implicitly determined, p.4] 1024 // In a task construct, if no default clause is present, a variable that in 1025 // the enclosing context is determined to be shared by all implicit tasks 1026 // bound to the current team is shared. 1027 if (isOpenMPTaskingDirective(DVar.DKind)) { 1028 DSAVarData DVarTemp; 1029 const_iterator I = Iter, E = end(); 1030 do { 1031 ++I; 1032 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1033 // Referenced in a Construct, implicitly determined, p.6] 1034 // In a task construct, if no default clause is present, a variable 1035 // whose data-sharing attribute is not determined by the rules above is 1036 // firstprivate. 1037 DVarTemp = getDSA(I, D); 1038 if (DVarTemp.CKind != OMPC_shared) { 1039 DVar.RefExpr = nullptr; 1040 DVar.CKind = OMPC_firstprivate; 1041 return DVar; 1042 } 1043 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1044 DVar.CKind = 1045 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1046 return DVar; 1047 } 1048 } 1049 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1050 // in a Construct, implicitly determined, p.3] 1051 // For constructs other than task, if no default clause is present, these 1052 // variables inherit their data-sharing attributes from the enclosing 1053 // context. 1054 return getDSA(++Iter, D); 1055 } 1056 1057 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1058 const Expr *NewDE) { 1059 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1060 D = getCanonicalDecl(D); 1061 SharingMapTy &StackElem = getTopOfStack(); 1062 auto It = StackElem.AlignedMap.find(D); 1063 if (It == StackElem.AlignedMap.end()) { 1064 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1065 StackElem.AlignedMap[D] = NewDE; 1066 return nullptr; 1067 } 1068 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1069 return It->second; 1070 } 1071 1072 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1073 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1074 D = getCanonicalDecl(D); 1075 SharingMapTy &StackElem = getTopOfStack(); 1076 StackElem.LCVMap.try_emplace( 1077 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1078 } 1079 1080 const DSAStackTy::LCDeclInfo 1081 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1082 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1083 D = getCanonicalDecl(D); 1084 const SharingMapTy &StackElem = getTopOfStack(); 1085 auto It = StackElem.LCVMap.find(D); 1086 if (It != StackElem.LCVMap.end()) 1087 return It->second; 1088 return {0, nullptr}; 1089 } 1090 1091 const DSAStackTy::LCDeclInfo 1092 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1093 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1094 assert(Parent && "Data-sharing attributes stack is empty"); 1095 D = getCanonicalDecl(D); 1096 auto It = Parent->LCVMap.find(D); 1097 if (It != Parent->LCVMap.end()) 1098 return It->second; 1099 return {0, nullptr}; 1100 } 1101 1102 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1103 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1104 assert(Parent && "Data-sharing attributes stack is empty"); 1105 if (Parent->LCVMap.size() < I) 1106 return nullptr; 1107 for (const auto &Pair : Parent->LCVMap) 1108 if (Pair.second.first == I) 1109 return Pair.first; 1110 return nullptr; 1111 } 1112 1113 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1114 DeclRefExpr *PrivateCopy) { 1115 D = getCanonicalDecl(D); 1116 if (A == OMPC_threadprivate) { 1117 DSAInfo &Data = Threadprivates[D]; 1118 Data.Attributes = A; 1119 Data.RefExpr.setPointer(E); 1120 Data.PrivateCopy = nullptr; 1121 } else { 1122 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1123 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1124 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1125 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1126 (isLoopControlVariable(D).first && A == OMPC_private)); 1127 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1128 Data.RefExpr.setInt(/*IntVal=*/true); 1129 return; 1130 } 1131 const bool IsLastprivate = 1132 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1133 Data.Attributes = A; 1134 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1135 Data.PrivateCopy = PrivateCopy; 1136 if (PrivateCopy) { 1137 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1138 Data.Attributes = A; 1139 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1140 Data.PrivateCopy = nullptr; 1141 } 1142 } 1143 } 1144 1145 /// Build a variable declaration for OpenMP loop iteration variable. 1146 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1147 StringRef Name, const AttrVec *Attrs = nullptr, 1148 DeclRefExpr *OrigRef = nullptr) { 1149 DeclContext *DC = SemaRef.CurContext; 1150 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1151 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1152 auto *Decl = 1153 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1154 if (Attrs) { 1155 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1156 I != E; ++I) 1157 Decl->addAttr(*I); 1158 } 1159 Decl->setImplicit(); 1160 if (OrigRef) { 1161 Decl->addAttr( 1162 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1163 } 1164 return Decl; 1165 } 1166 1167 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1168 SourceLocation Loc, 1169 bool RefersToCapture = false) { 1170 D->setReferenced(); 1171 D->markUsed(S.Context); 1172 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1173 SourceLocation(), D, RefersToCapture, Loc, Ty, 1174 VK_LValue); 1175 } 1176 1177 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1178 BinaryOperatorKind BOK) { 1179 D = getCanonicalDecl(D); 1180 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1181 assert( 1182 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1183 "Additional reduction info may be specified only for reduction items."); 1184 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1185 assert(ReductionData.ReductionRange.isInvalid() && 1186 getTopOfStack().Directive == OMPD_taskgroup && 1187 "Additional reduction info may be specified only once for reduction " 1188 "items."); 1189 ReductionData.set(BOK, SR); 1190 Expr *&TaskgroupReductionRef = 1191 getTopOfStack().TaskgroupReductionRef; 1192 if (!TaskgroupReductionRef) { 1193 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1194 SemaRef.Context.VoidPtrTy, ".task_red."); 1195 TaskgroupReductionRef = 1196 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1197 } 1198 } 1199 1200 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1201 const Expr *ReductionRef) { 1202 D = getCanonicalDecl(D); 1203 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1204 assert( 1205 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1206 "Additional reduction info may be specified only for reduction items."); 1207 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1208 assert(ReductionData.ReductionRange.isInvalid() && 1209 getTopOfStack().Directive == OMPD_taskgroup && 1210 "Additional reduction info may be specified only once for reduction " 1211 "items."); 1212 ReductionData.set(ReductionRef, SR); 1213 Expr *&TaskgroupReductionRef = 1214 getTopOfStack().TaskgroupReductionRef; 1215 if (!TaskgroupReductionRef) { 1216 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1217 SemaRef.Context.VoidPtrTy, ".task_red."); 1218 TaskgroupReductionRef = 1219 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1220 } 1221 } 1222 1223 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1224 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1225 Expr *&TaskgroupDescriptor) const { 1226 D = getCanonicalDecl(D); 1227 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1228 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1229 const DSAInfo &Data = I->SharingMap.lookup(D); 1230 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1231 continue; 1232 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1233 if (!ReductionData.ReductionOp || 1234 ReductionData.ReductionOp.is<const Expr *>()) 1235 return DSAVarData(); 1236 SR = ReductionData.ReductionRange; 1237 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1238 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1239 "expression for the descriptor is not " 1240 "set."); 1241 TaskgroupDescriptor = I->TaskgroupReductionRef; 1242 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1243 Data.PrivateCopy, I->DefaultAttrLoc); 1244 } 1245 return DSAVarData(); 1246 } 1247 1248 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1249 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1250 Expr *&TaskgroupDescriptor) const { 1251 D = getCanonicalDecl(D); 1252 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1253 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1254 const DSAInfo &Data = I->SharingMap.lookup(D); 1255 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1256 continue; 1257 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1258 if (!ReductionData.ReductionOp || 1259 !ReductionData.ReductionOp.is<const Expr *>()) 1260 return DSAVarData(); 1261 SR = ReductionData.ReductionRange; 1262 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1263 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1264 "expression for the descriptor is not " 1265 "set."); 1266 TaskgroupDescriptor = I->TaskgroupReductionRef; 1267 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1268 Data.PrivateCopy, I->DefaultAttrLoc); 1269 } 1270 return DSAVarData(); 1271 } 1272 1273 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1274 D = D->getCanonicalDecl(); 1275 for (const_iterator E = end(); I != E; ++I) { 1276 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1277 isOpenMPTargetExecutionDirective(I->Directive)) { 1278 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1279 Scope *CurScope = getCurScope(); 1280 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1281 CurScope = CurScope->getParent(); 1282 return CurScope != TopScope; 1283 } 1284 } 1285 return false; 1286 } 1287 1288 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1289 bool AcceptIfMutable = true, 1290 bool *IsClassType = nullptr) { 1291 ASTContext &Context = SemaRef.getASTContext(); 1292 Type = Type.getNonReferenceType().getCanonicalType(); 1293 bool IsConstant = Type.isConstant(Context); 1294 Type = Context.getBaseElementType(Type); 1295 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1296 ? Type->getAsCXXRecordDecl() 1297 : nullptr; 1298 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1299 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1300 RD = CTD->getTemplatedDecl(); 1301 if (IsClassType) 1302 *IsClassType = RD; 1303 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1304 RD->hasDefinition() && RD->hasMutableFields()); 1305 } 1306 1307 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1308 QualType Type, OpenMPClauseKind CKind, 1309 SourceLocation ELoc, 1310 bool AcceptIfMutable = true, 1311 bool ListItemNotVar = false) { 1312 ASTContext &Context = SemaRef.getASTContext(); 1313 bool IsClassType; 1314 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1315 unsigned Diag = ListItemNotVar 1316 ? diag::err_omp_const_list_item 1317 : IsClassType ? diag::err_omp_const_not_mutable_variable 1318 : diag::err_omp_const_variable; 1319 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1320 if (!ListItemNotVar && D) { 1321 const VarDecl *VD = dyn_cast<VarDecl>(D); 1322 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1323 VarDecl::DeclarationOnly; 1324 SemaRef.Diag(D->getLocation(), 1325 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1326 << D; 1327 } 1328 return true; 1329 } 1330 return false; 1331 } 1332 1333 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1334 bool FromParent) { 1335 D = getCanonicalDecl(D); 1336 DSAVarData DVar; 1337 1338 auto *VD = dyn_cast<VarDecl>(D); 1339 auto TI = Threadprivates.find(D); 1340 if (TI != Threadprivates.end()) { 1341 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1342 DVar.CKind = OMPC_threadprivate; 1343 return DVar; 1344 } 1345 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1346 DVar.RefExpr = buildDeclRefExpr( 1347 SemaRef, VD, D->getType().getNonReferenceType(), 1348 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1349 DVar.CKind = OMPC_threadprivate; 1350 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1351 return DVar; 1352 } 1353 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1354 // in a Construct, C/C++, predetermined, p.1] 1355 // Variables appearing in threadprivate directives are threadprivate. 1356 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1357 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1358 SemaRef.getLangOpts().OpenMPUseTLS && 1359 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1360 (VD && VD->getStorageClass() == SC_Register && 1361 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1362 DVar.RefExpr = buildDeclRefExpr( 1363 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1364 DVar.CKind = OMPC_threadprivate; 1365 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1366 return DVar; 1367 } 1368 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1369 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1370 !isLoopControlVariable(D).first) { 1371 const_iterator IterTarget = 1372 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1373 return isOpenMPTargetExecutionDirective(Data.Directive); 1374 }); 1375 if (IterTarget != end()) { 1376 const_iterator ParentIterTarget = IterTarget + 1; 1377 for (const_iterator Iter = begin(); 1378 Iter != ParentIterTarget; ++Iter) { 1379 if (isOpenMPLocal(VD, Iter)) { 1380 DVar.RefExpr = 1381 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1382 D->getLocation()); 1383 DVar.CKind = OMPC_threadprivate; 1384 return DVar; 1385 } 1386 } 1387 if (!isClauseParsingMode() || IterTarget != begin()) { 1388 auto DSAIter = IterTarget->SharingMap.find(D); 1389 if (DSAIter != IterTarget->SharingMap.end() && 1390 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1391 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1392 DVar.CKind = OMPC_threadprivate; 1393 return DVar; 1394 } 1395 const_iterator End = end(); 1396 if (!SemaRef.isOpenMPCapturedByRef( 1397 D, std::distance(ParentIterTarget, End), 1398 /*OpenMPCaptureLevel=*/0)) { 1399 DVar.RefExpr = 1400 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1401 IterTarget->ConstructLoc); 1402 DVar.CKind = OMPC_threadprivate; 1403 return DVar; 1404 } 1405 } 1406 } 1407 } 1408 1409 if (isStackEmpty()) 1410 // Not in OpenMP execution region and top scope was already checked. 1411 return DVar; 1412 1413 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1414 // in a Construct, C/C++, predetermined, p.4] 1415 // Static data members are shared. 1416 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1417 // in a Construct, C/C++, predetermined, p.7] 1418 // Variables with static storage duration that are declared in a scope 1419 // inside the construct are shared. 1420 if (VD && VD->isStaticDataMember()) { 1421 // Check for explicitly specified attributes. 1422 const_iterator I = begin(); 1423 const_iterator EndI = end(); 1424 if (FromParent && I != EndI) 1425 ++I; 1426 auto It = I->SharingMap.find(D); 1427 if (It != I->SharingMap.end()) { 1428 const DSAInfo &Data = It->getSecond(); 1429 DVar.RefExpr = Data.RefExpr.getPointer(); 1430 DVar.PrivateCopy = Data.PrivateCopy; 1431 DVar.CKind = Data.Attributes; 1432 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1433 DVar.DKind = I->Directive; 1434 return DVar; 1435 } 1436 1437 DVar.CKind = OMPC_shared; 1438 return DVar; 1439 } 1440 1441 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1442 // The predetermined shared attribute for const-qualified types having no 1443 // mutable members was removed after OpenMP 3.1. 1444 if (SemaRef.LangOpts.OpenMP <= 31) { 1445 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1446 // in a Construct, C/C++, predetermined, p.6] 1447 // Variables with const qualified type having no mutable member are 1448 // shared. 1449 if (isConstNotMutableType(SemaRef, D->getType())) { 1450 // Variables with const-qualified type having no mutable member may be 1451 // listed in a firstprivate clause, even if they are static data members. 1452 DSAVarData DVarTemp = hasInnermostDSA( 1453 D, 1454 [](OpenMPClauseKind C) { 1455 return C == OMPC_firstprivate || C == OMPC_shared; 1456 }, 1457 MatchesAlways, FromParent); 1458 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1459 return DVarTemp; 1460 1461 DVar.CKind = OMPC_shared; 1462 return DVar; 1463 } 1464 } 1465 1466 // Explicitly specified attributes and local variables with predetermined 1467 // attributes. 1468 const_iterator I = begin(); 1469 const_iterator EndI = end(); 1470 if (FromParent && I != EndI) 1471 ++I; 1472 auto It = I->SharingMap.find(D); 1473 if (It != I->SharingMap.end()) { 1474 const DSAInfo &Data = It->getSecond(); 1475 DVar.RefExpr = Data.RefExpr.getPointer(); 1476 DVar.PrivateCopy = Data.PrivateCopy; 1477 DVar.CKind = Data.Attributes; 1478 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1479 DVar.DKind = I->Directive; 1480 } 1481 1482 return DVar; 1483 } 1484 1485 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1486 bool FromParent) const { 1487 if (isStackEmpty()) { 1488 const_iterator I; 1489 return getDSA(I, D); 1490 } 1491 D = getCanonicalDecl(D); 1492 const_iterator StartI = begin(); 1493 const_iterator EndI = end(); 1494 if (FromParent && StartI != EndI) 1495 ++StartI; 1496 return getDSA(StartI, D); 1497 } 1498 1499 const DSAStackTy::DSAVarData 1500 DSAStackTy::hasDSA(ValueDecl *D, 1501 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1502 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1503 bool FromParent) const { 1504 if (isStackEmpty()) 1505 return {}; 1506 D = getCanonicalDecl(D); 1507 const_iterator I = begin(); 1508 const_iterator EndI = end(); 1509 if (FromParent && I != EndI) 1510 ++I; 1511 for (; I != EndI; ++I) { 1512 if (!DPred(I->Directive) && 1513 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1514 continue; 1515 const_iterator NewI = I; 1516 DSAVarData DVar = getDSA(NewI, D); 1517 if (I == NewI && CPred(DVar.CKind)) 1518 return DVar; 1519 } 1520 return {}; 1521 } 1522 1523 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1524 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1525 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1526 bool FromParent) const { 1527 if (isStackEmpty()) 1528 return {}; 1529 D = getCanonicalDecl(D); 1530 const_iterator StartI = begin(); 1531 const_iterator EndI = end(); 1532 if (FromParent && StartI != EndI) 1533 ++StartI; 1534 if (StartI == EndI || !DPred(StartI->Directive)) 1535 return {}; 1536 const_iterator NewI = StartI; 1537 DSAVarData DVar = getDSA(NewI, D); 1538 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1539 } 1540 1541 bool DSAStackTy::hasExplicitDSA( 1542 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1543 unsigned Level, bool NotLastprivate) const { 1544 if (getStackSize() <= Level) 1545 return false; 1546 D = getCanonicalDecl(D); 1547 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1548 auto I = StackElem.SharingMap.find(D); 1549 if (I != StackElem.SharingMap.end() && 1550 I->getSecond().RefExpr.getPointer() && 1551 CPred(I->getSecond().Attributes) && 1552 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1553 return true; 1554 // Check predetermined rules for the loop control variables. 1555 auto LI = StackElem.LCVMap.find(D); 1556 if (LI != StackElem.LCVMap.end()) 1557 return CPred(OMPC_private); 1558 return false; 1559 } 1560 1561 bool DSAStackTy::hasExplicitDirective( 1562 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1563 unsigned Level) const { 1564 if (getStackSize() <= Level) 1565 return false; 1566 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1567 return DPred(StackElem.Directive); 1568 } 1569 1570 bool DSAStackTy::hasDirective( 1571 const llvm::function_ref<bool(OpenMPDirectiveKind, 1572 const DeclarationNameInfo &, SourceLocation)> 1573 DPred, 1574 bool FromParent) const { 1575 // We look only in the enclosing region. 1576 size_t Skip = FromParent ? 2 : 1; 1577 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1578 I != E; ++I) { 1579 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1580 return true; 1581 } 1582 return false; 1583 } 1584 1585 void Sema::InitDataSharingAttributesStack() { 1586 VarDataSharingAttributesStack = new DSAStackTy(*this); 1587 } 1588 1589 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1590 1591 void Sema::pushOpenMPFunctionRegion() { 1592 DSAStack->pushFunction(); 1593 } 1594 1595 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1596 DSAStack->popFunction(OldFSI); 1597 } 1598 1599 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1600 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1601 "Expected OpenMP device compilation."); 1602 return !S.isInOpenMPTargetExecutionDirective() && 1603 !S.isInOpenMPDeclareTargetContext(); 1604 } 1605 1606 namespace { 1607 /// Status of the function emission on the host/device. 1608 enum class FunctionEmissionStatus { 1609 Emitted, 1610 Discarded, 1611 Unknown, 1612 }; 1613 } // anonymous namespace 1614 1615 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1616 unsigned DiagID) { 1617 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1618 "Expected OpenMP device compilation."); 1619 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1620 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1621 switch (FES) { 1622 case FunctionEmissionStatus::Emitted: 1623 Kind = DeviceDiagBuilder::K_Immediate; 1624 break; 1625 case FunctionEmissionStatus::Unknown: 1626 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1627 : DeviceDiagBuilder::K_Immediate; 1628 break; 1629 case FunctionEmissionStatus::TemplateDiscarded: 1630 case FunctionEmissionStatus::OMPDiscarded: 1631 Kind = DeviceDiagBuilder::K_Nop; 1632 break; 1633 case FunctionEmissionStatus::CUDADiscarded: 1634 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1635 break; 1636 } 1637 1638 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1639 } 1640 1641 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1642 unsigned DiagID) { 1643 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1644 "Expected OpenMP host compilation."); 1645 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1646 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1647 switch (FES) { 1648 case FunctionEmissionStatus::Emitted: 1649 Kind = DeviceDiagBuilder::K_Immediate; 1650 break; 1651 case FunctionEmissionStatus::Unknown: 1652 Kind = DeviceDiagBuilder::K_Deferred; 1653 break; 1654 case FunctionEmissionStatus::TemplateDiscarded: 1655 case FunctionEmissionStatus::OMPDiscarded: 1656 case FunctionEmissionStatus::CUDADiscarded: 1657 Kind = DeviceDiagBuilder::K_Nop; 1658 break; 1659 } 1660 1661 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1662 } 1663 1664 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1665 bool CheckForDelayedContext) { 1666 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1667 "Expected OpenMP device compilation."); 1668 assert(Callee && "Callee may not be null."); 1669 Callee = Callee->getMostRecentDecl(); 1670 FunctionDecl *Caller = getCurFunctionDecl(); 1671 1672 // host only function are not available on the device. 1673 if (Caller) { 1674 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1675 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1676 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1677 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1678 "CUDADiscarded unexpected in OpenMP device function check"); 1679 if ((CallerS == FunctionEmissionStatus::Emitted || 1680 (!isOpenMPDeviceDelayedContext(*this) && 1681 CallerS == FunctionEmissionStatus::Unknown)) && 1682 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1683 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1684 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1685 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1686 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1687 diag::note_omp_marked_device_type_here) 1688 << HostDevTy; 1689 return; 1690 } 1691 } 1692 // If the caller is known-emitted, mark the callee as known-emitted. 1693 // Otherwise, mark the call in our call graph so we can traverse it later. 1694 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1695 (!Caller && !CheckForDelayedContext) || 1696 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1697 markKnownEmitted(*this, Caller, Callee, Loc, 1698 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1699 return CheckForDelayedContext && 1700 S.getEmissionStatus(FD) == 1701 FunctionEmissionStatus::Emitted; 1702 }); 1703 else if (Caller) 1704 DeviceCallGraph[Caller].insert({Callee, Loc}); 1705 } 1706 1707 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1708 bool CheckCaller) { 1709 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1710 "Expected OpenMP host compilation."); 1711 assert(Callee && "Callee may not be null."); 1712 Callee = Callee->getMostRecentDecl(); 1713 FunctionDecl *Caller = getCurFunctionDecl(); 1714 1715 // device only function are not available on the host. 1716 if (Caller) { 1717 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1718 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1719 assert( 1720 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1721 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1722 "CUDADiscarded unexpected in OpenMP host function check"); 1723 if (CallerS == FunctionEmissionStatus::Emitted && 1724 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1725 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1726 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1727 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1728 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1729 diag::note_omp_marked_device_type_here) 1730 << NoHostDevTy; 1731 return; 1732 } 1733 } 1734 // If the caller is known-emitted, mark the callee as known-emitted. 1735 // Otherwise, mark the call in our call graph so we can traverse it later. 1736 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1737 if ((!CheckCaller && !Caller) || 1738 (Caller && 1739 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1740 markKnownEmitted( 1741 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1742 return CheckCaller && 1743 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1744 }); 1745 else if (Caller) 1746 DeviceCallGraph[Caller].insert({Callee, Loc}); 1747 } 1748 } 1749 1750 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1751 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1752 "OpenMP device compilation mode is expected."); 1753 QualType Ty = E->getType(); 1754 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1755 ((Ty->isFloat128Type() || 1756 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1757 !Context.getTargetInfo().hasFloat128Type()) || 1758 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1759 !Context.getTargetInfo().hasInt128Type())) 1760 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1761 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1762 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1763 } 1764 1765 static OpenMPDefaultmapClauseKind 1766 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1767 if (LO.OpenMP <= 45) { 1768 if (VD->getType().getNonReferenceType()->isScalarType()) 1769 return OMPC_DEFAULTMAP_scalar; 1770 return OMPC_DEFAULTMAP_aggregate; 1771 } 1772 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1773 return OMPC_DEFAULTMAP_pointer; 1774 if (VD->getType().getNonReferenceType()->isScalarType()) 1775 return OMPC_DEFAULTMAP_scalar; 1776 return OMPC_DEFAULTMAP_aggregate; 1777 } 1778 1779 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1780 unsigned OpenMPCaptureLevel) const { 1781 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1782 1783 ASTContext &Ctx = getASTContext(); 1784 bool IsByRef = true; 1785 1786 // Find the directive that is associated with the provided scope. 1787 D = cast<ValueDecl>(D->getCanonicalDecl()); 1788 QualType Ty = D->getType(); 1789 1790 bool IsVariableUsedInMapClause = false; 1791 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1792 // This table summarizes how a given variable should be passed to the device 1793 // given its type and the clauses where it appears. This table is based on 1794 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1795 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1796 // 1797 // ========================================================================= 1798 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1799 // | |(tofrom:scalar)| | pvt | | | | 1800 // ========================================================================= 1801 // | scl | | | | - | | bycopy| 1802 // | scl | | - | x | - | - | bycopy| 1803 // | scl | | x | - | - | - | null | 1804 // | scl | x | | | - | | byref | 1805 // | scl | x | - | x | - | - | bycopy| 1806 // | scl | x | x | - | - | - | null | 1807 // | scl | | - | - | - | x | byref | 1808 // | scl | x | - | - | - | x | byref | 1809 // 1810 // | agg | n.a. | | | - | | byref | 1811 // | agg | n.a. | - | x | - | - | byref | 1812 // | agg | n.a. | x | - | - | - | null | 1813 // | agg | n.a. | - | - | - | x | byref | 1814 // | agg | n.a. | - | - | - | x[] | byref | 1815 // 1816 // | ptr | n.a. | | | - | | bycopy| 1817 // | ptr | n.a. | - | x | - | - | bycopy| 1818 // | ptr | n.a. | x | - | - | - | null | 1819 // | ptr | n.a. | - | - | - | x | byref | 1820 // | ptr | n.a. | - | - | - | x[] | bycopy| 1821 // | ptr | n.a. | - | - | x | | bycopy| 1822 // | ptr | n.a. | - | - | x | x | bycopy| 1823 // | ptr | n.a. | - | - | x | x[] | bycopy| 1824 // ========================================================================= 1825 // Legend: 1826 // scl - scalar 1827 // ptr - pointer 1828 // agg - aggregate 1829 // x - applies 1830 // - - invalid in this combination 1831 // [] - mapped with an array section 1832 // byref - should be mapped by reference 1833 // byval - should be mapped by value 1834 // null - initialize a local variable to null on the device 1835 // 1836 // Observations: 1837 // - All scalar declarations that show up in a map clause have to be passed 1838 // by reference, because they may have been mapped in the enclosing data 1839 // environment. 1840 // - If the scalar value does not fit the size of uintptr, it has to be 1841 // passed by reference, regardless the result in the table above. 1842 // - For pointers mapped by value that have either an implicit map or an 1843 // array section, the runtime library may pass the NULL value to the 1844 // device instead of the value passed to it by the compiler. 1845 1846 if (Ty->isReferenceType()) 1847 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1848 1849 // Locate map clauses and see if the variable being captured is referred to 1850 // in any of those clauses. Here we only care about variables, not fields, 1851 // because fields are part of aggregates. 1852 bool IsVariableAssociatedWithSection = false; 1853 1854 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1855 D, Level, 1856 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1857 OMPClauseMappableExprCommon::MappableExprComponentListRef 1858 MapExprComponents, 1859 OpenMPClauseKind WhereFoundClauseKind) { 1860 // Only the map clause information influences how a variable is 1861 // captured. E.g. is_device_ptr does not require changing the default 1862 // behavior. 1863 if (WhereFoundClauseKind != OMPC_map) 1864 return false; 1865 1866 auto EI = MapExprComponents.rbegin(); 1867 auto EE = MapExprComponents.rend(); 1868 1869 assert(EI != EE && "Invalid map expression!"); 1870 1871 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1872 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1873 1874 ++EI; 1875 if (EI == EE) 1876 return false; 1877 1878 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1879 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1880 isa<MemberExpr>(EI->getAssociatedExpression())) { 1881 IsVariableAssociatedWithSection = true; 1882 // There is nothing more we need to know about this variable. 1883 return true; 1884 } 1885 1886 // Keep looking for more map info. 1887 return false; 1888 }); 1889 1890 if (IsVariableUsedInMapClause) { 1891 // If variable is identified in a map clause it is always captured by 1892 // reference except if it is a pointer that is dereferenced somehow. 1893 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1894 } else { 1895 // By default, all the data that has a scalar type is mapped by copy 1896 // (except for reduction variables). 1897 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1898 IsByRef = 1899 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1900 !Ty->isAnyPointerType()) || 1901 !Ty->isScalarType() || 1902 DSAStack->isDefaultmapCapturedByRef( 1903 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1904 DSAStack->hasExplicitDSA( 1905 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1906 } 1907 } 1908 1909 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1910 IsByRef = 1911 ((IsVariableUsedInMapClause && 1912 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1913 OMPD_target) || 1914 !DSAStack->hasExplicitDSA( 1915 D, 1916 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1917 Level, /*NotLastprivate=*/true)) && 1918 // If the variable is artificial and must be captured by value - try to 1919 // capture by value. 1920 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1921 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1922 } 1923 1924 // When passing data by copy, we need to make sure it fits the uintptr size 1925 // and alignment, because the runtime library only deals with uintptr types. 1926 // If it does not fit the uintptr size, we need to pass the data by reference 1927 // instead. 1928 if (!IsByRef && 1929 (Ctx.getTypeSizeInChars(Ty) > 1930 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1931 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1932 IsByRef = true; 1933 } 1934 1935 return IsByRef; 1936 } 1937 1938 unsigned Sema::getOpenMPNestingLevel() const { 1939 assert(getLangOpts().OpenMP); 1940 return DSAStack->getNestingLevel(); 1941 } 1942 1943 bool Sema::isInOpenMPTargetExecutionDirective() const { 1944 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1945 !DSAStack->isClauseParsingMode()) || 1946 DSAStack->hasDirective( 1947 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1948 SourceLocation) -> bool { 1949 return isOpenMPTargetExecutionDirective(K); 1950 }, 1951 false); 1952 } 1953 1954 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1955 unsigned StopAt) { 1956 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1957 D = getCanonicalDecl(D); 1958 1959 auto *VD = dyn_cast<VarDecl>(D); 1960 // Do not capture constexpr variables. 1961 if (VD && VD->isConstexpr()) 1962 return nullptr; 1963 1964 // If we want to determine whether the variable should be captured from the 1965 // perspective of the current capturing scope, and we've already left all the 1966 // capturing scopes of the top directive on the stack, check from the 1967 // perspective of its parent directive (if any) instead. 1968 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1969 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1970 1971 // If we are attempting to capture a global variable in a directive with 1972 // 'target' we return true so that this global is also mapped to the device. 1973 // 1974 if (VD && !VD->hasLocalStorage() && 1975 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1976 if (isInOpenMPDeclareTargetContext()) { 1977 // Try to mark variable as declare target if it is used in capturing 1978 // regions. 1979 if (LangOpts.OpenMP <= 45 && 1980 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1981 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1982 return nullptr; 1983 } else if (isInOpenMPTargetExecutionDirective()) { 1984 // If the declaration is enclosed in a 'declare target' directive, 1985 // then it should not be captured. 1986 // 1987 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1988 return nullptr; 1989 return VD; 1990 } 1991 } 1992 1993 if (CheckScopeInfo) { 1994 bool OpenMPFound = false; 1995 for (unsigned I = StopAt + 1; I > 0; --I) { 1996 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1997 if(!isa<CapturingScopeInfo>(FSI)) 1998 return nullptr; 1999 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2000 if (RSI->CapRegionKind == CR_OpenMP) { 2001 OpenMPFound = true; 2002 break; 2003 } 2004 } 2005 if (!OpenMPFound) 2006 return nullptr; 2007 } 2008 2009 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2010 (!DSAStack->isClauseParsingMode() || 2011 DSAStack->getParentDirective() != OMPD_unknown)) { 2012 auto &&Info = DSAStack->isLoopControlVariable(D); 2013 if (Info.first || 2014 (VD && VD->hasLocalStorage() && 2015 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2016 (VD && DSAStack->isForceVarCapturing())) 2017 return VD ? VD : Info.second; 2018 DSAStackTy::DSAVarData DVarPrivate = 2019 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2020 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2021 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2022 // Threadprivate variables must not be captured. 2023 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2024 return nullptr; 2025 // The variable is not private or it is the variable in the directive with 2026 // default(none) clause and not used in any clause. 2027 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2028 [](OpenMPDirectiveKind) { return true; }, 2029 DSAStack->isClauseParsingMode()); 2030 if (DVarPrivate.CKind != OMPC_unknown || 2031 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2032 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2033 } 2034 return nullptr; 2035 } 2036 2037 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2038 unsigned Level) const { 2039 SmallVector<OpenMPDirectiveKind, 4> Regions; 2040 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2041 FunctionScopesIndex -= Regions.size(); 2042 } 2043 2044 void Sema::startOpenMPLoop() { 2045 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2046 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2047 DSAStack->loopInit(); 2048 } 2049 2050 void Sema::startOpenMPCXXRangeFor() { 2051 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2052 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2053 DSAStack->resetPossibleLoopCounter(); 2054 DSAStack->loopStart(); 2055 } 2056 } 2057 2058 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2059 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2060 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2061 if (DSAStack->getAssociatedLoops() > 0 && 2062 !DSAStack->isLoopStarted()) { 2063 DSAStack->resetPossibleLoopCounter(D); 2064 DSAStack->loopStart(); 2065 return true; 2066 } 2067 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2068 DSAStack->isLoopControlVariable(D).first) && 2069 !DSAStack->hasExplicitDSA( 2070 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2071 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2072 return true; 2073 } 2074 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2075 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2076 DSAStack->isForceVarCapturing() && 2077 !DSAStack->hasExplicitDSA( 2078 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2079 return true; 2080 } 2081 return DSAStack->hasExplicitDSA( 2082 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2083 (DSAStack->isClauseParsingMode() && 2084 DSAStack->getClauseParsingMode() == OMPC_private) || 2085 // Consider taskgroup reduction descriptor variable a private to avoid 2086 // possible capture in the region. 2087 (DSAStack->hasExplicitDirective( 2088 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2089 Level) && 2090 DSAStack->isTaskgroupReductionRef(D, Level)); 2091 } 2092 2093 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2094 unsigned Level) { 2095 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2096 D = getCanonicalDecl(D); 2097 OpenMPClauseKind OMPC = OMPC_unknown; 2098 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2099 const unsigned NewLevel = I - 1; 2100 if (DSAStack->hasExplicitDSA(D, 2101 [&OMPC](const OpenMPClauseKind K) { 2102 if (isOpenMPPrivate(K)) { 2103 OMPC = K; 2104 return true; 2105 } 2106 return false; 2107 }, 2108 NewLevel)) 2109 break; 2110 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2111 D, NewLevel, 2112 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2113 OpenMPClauseKind) { return true; })) { 2114 OMPC = OMPC_map; 2115 break; 2116 } 2117 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2118 NewLevel)) { 2119 OMPC = OMPC_map; 2120 if (DSAStack->mustBeFirstprivateAtLevel( 2121 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2122 OMPC = OMPC_firstprivate; 2123 break; 2124 } 2125 } 2126 if (OMPC != OMPC_unknown) 2127 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2128 } 2129 2130 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2131 unsigned Level) const { 2132 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2133 // Return true if the current level is no longer enclosed in a target region. 2134 2135 const auto *VD = dyn_cast<VarDecl>(D); 2136 return VD && !VD->hasLocalStorage() && 2137 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2138 Level); 2139 } 2140 2141 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2142 2143 void Sema::finalizeOpenMPDelayedAnalysis() { 2144 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2145 // Diagnose implicit declare target functions and their callees. 2146 for (const auto &CallerCallees : DeviceCallGraph) { 2147 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2148 OMPDeclareTargetDeclAttr::getDeviceType( 2149 CallerCallees.getFirst()->getMostRecentDecl()); 2150 // Ignore host functions during device analyzis. 2151 if (LangOpts.OpenMPIsDevice && DevTy && 2152 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2153 continue; 2154 // Ignore nohost functions during host analyzis. 2155 if (!LangOpts.OpenMPIsDevice && DevTy && 2156 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2157 continue; 2158 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2159 &Callee : CallerCallees.getSecond()) { 2160 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2161 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2162 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2163 if (LangOpts.OpenMPIsDevice && DevTy && 2164 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2165 // Diagnose host function called during device codegen. 2166 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2167 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2168 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2169 << HostDevTy << 0; 2170 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2171 diag::note_omp_marked_device_type_here) 2172 << HostDevTy; 2173 continue; 2174 } 2175 if (!LangOpts.OpenMPIsDevice && DevTy && 2176 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2177 // Diagnose nohost function called during host codegen. 2178 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2179 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2180 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2181 << NoHostDevTy << 1; 2182 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2183 diag::note_omp_marked_device_type_here) 2184 << NoHostDevTy; 2185 continue; 2186 } 2187 } 2188 } 2189 } 2190 2191 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2192 const DeclarationNameInfo &DirName, 2193 Scope *CurScope, SourceLocation Loc) { 2194 DSAStack->push(DKind, DirName, CurScope, Loc); 2195 PushExpressionEvaluationContext( 2196 ExpressionEvaluationContext::PotentiallyEvaluated); 2197 } 2198 2199 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2200 DSAStack->setClauseParsingMode(K); 2201 } 2202 2203 void Sema::EndOpenMPClause() { 2204 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2205 } 2206 2207 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2208 ArrayRef<OMPClause *> Clauses); 2209 2210 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2211 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2212 // A variable of class type (or array thereof) that appears in a lastprivate 2213 // clause requires an accessible, unambiguous default constructor for the 2214 // class type, unless the list item is also specified in a firstprivate 2215 // clause. 2216 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2217 for (OMPClause *C : D->clauses()) { 2218 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2219 SmallVector<Expr *, 8> PrivateCopies; 2220 for (Expr *DE : Clause->varlists()) { 2221 if (DE->isValueDependent() || DE->isTypeDependent()) { 2222 PrivateCopies.push_back(nullptr); 2223 continue; 2224 } 2225 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2226 auto *VD = cast<VarDecl>(DRE->getDecl()); 2227 QualType Type = VD->getType().getNonReferenceType(); 2228 const DSAStackTy::DSAVarData DVar = 2229 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2230 if (DVar.CKind == OMPC_lastprivate) { 2231 // Generate helper private variable and initialize it with the 2232 // default value. The address of the original variable is replaced 2233 // by the address of the new private variable in CodeGen. This new 2234 // variable is not added to IdResolver, so the code in the OpenMP 2235 // region uses original variable for proper diagnostics. 2236 VarDecl *VDPrivate = buildVarDecl( 2237 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2238 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2239 ActOnUninitializedDecl(VDPrivate); 2240 if (VDPrivate->isInvalidDecl()) { 2241 PrivateCopies.push_back(nullptr); 2242 continue; 2243 } 2244 PrivateCopies.push_back(buildDeclRefExpr( 2245 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2246 } else { 2247 // The variable is also a firstprivate, so initialization sequence 2248 // for private copy is generated already. 2249 PrivateCopies.push_back(nullptr); 2250 } 2251 } 2252 Clause->setPrivateCopies(PrivateCopies); 2253 } 2254 } 2255 // Check allocate clauses. 2256 if (!CurContext->isDependentContext()) 2257 checkAllocateClauses(*this, DSAStack, D->clauses()); 2258 } 2259 2260 DSAStack->pop(); 2261 DiscardCleanupsInEvaluationContext(); 2262 PopExpressionEvaluationContext(); 2263 } 2264 2265 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2266 Expr *NumIterations, Sema &SemaRef, 2267 Scope *S, DSAStackTy *Stack); 2268 2269 namespace { 2270 2271 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2272 private: 2273 Sema &SemaRef; 2274 2275 public: 2276 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2277 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2278 NamedDecl *ND = Candidate.getCorrectionDecl(); 2279 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2280 return VD->hasGlobalStorage() && 2281 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2282 SemaRef.getCurScope()); 2283 } 2284 return false; 2285 } 2286 2287 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2288 return std::make_unique<VarDeclFilterCCC>(*this); 2289 } 2290 2291 }; 2292 2293 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2294 private: 2295 Sema &SemaRef; 2296 2297 public: 2298 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2299 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2300 NamedDecl *ND = Candidate.getCorrectionDecl(); 2301 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2302 isa<FunctionDecl>(ND))) { 2303 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2304 SemaRef.getCurScope()); 2305 } 2306 return false; 2307 } 2308 2309 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2310 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2311 } 2312 }; 2313 2314 } // namespace 2315 2316 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2317 CXXScopeSpec &ScopeSpec, 2318 const DeclarationNameInfo &Id, 2319 OpenMPDirectiveKind Kind) { 2320 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2321 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2322 2323 if (Lookup.isAmbiguous()) 2324 return ExprError(); 2325 2326 VarDecl *VD; 2327 if (!Lookup.isSingleResult()) { 2328 VarDeclFilterCCC CCC(*this); 2329 if (TypoCorrection Corrected = 2330 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2331 CTK_ErrorRecovery)) { 2332 diagnoseTypo(Corrected, 2333 PDiag(Lookup.empty() 2334 ? diag::err_undeclared_var_use_suggest 2335 : diag::err_omp_expected_var_arg_suggest) 2336 << Id.getName()); 2337 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2338 } else { 2339 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2340 : diag::err_omp_expected_var_arg) 2341 << Id.getName(); 2342 return ExprError(); 2343 } 2344 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2345 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2346 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2347 return ExprError(); 2348 } 2349 Lookup.suppressDiagnostics(); 2350 2351 // OpenMP [2.9.2, Syntax, C/C++] 2352 // Variables must be file-scope, namespace-scope, or static block-scope. 2353 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2354 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2355 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2356 bool IsDecl = 2357 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2358 Diag(VD->getLocation(), 2359 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2360 << VD; 2361 return ExprError(); 2362 } 2363 2364 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2365 NamedDecl *ND = CanonicalVD; 2366 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2367 // A threadprivate directive for file-scope variables must appear outside 2368 // any definition or declaration. 2369 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2370 !getCurLexicalContext()->isTranslationUnit()) { 2371 Diag(Id.getLoc(), diag::err_omp_var_scope) 2372 << getOpenMPDirectiveName(Kind) << VD; 2373 bool IsDecl = 2374 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2375 Diag(VD->getLocation(), 2376 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2377 << VD; 2378 return ExprError(); 2379 } 2380 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2381 // A threadprivate directive for static class member variables must appear 2382 // in the class definition, in the same scope in which the member 2383 // variables are declared. 2384 if (CanonicalVD->isStaticDataMember() && 2385 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2386 Diag(Id.getLoc(), diag::err_omp_var_scope) 2387 << getOpenMPDirectiveName(Kind) << VD; 2388 bool IsDecl = 2389 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2390 Diag(VD->getLocation(), 2391 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2392 << VD; 2393 return ExprError(); 2394 } 2395 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2396 // A threadprivate directive for namespace-scope variables must appear 2397 // outside any definition or declaration other than the namespace 2398 // definition itself. 2399 if (CanonicalVD->getDeclContext()->isNamespace() && 2400 (!getCurLexicalContext()->isFileContext() || 2401 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2402 Diag(Id.getLoc(), diag::err_omp_var_scope) 2403 << getOpenMPDirectiveName(Kind) << VD; 2404 bool IsDecl = 2405 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2406 Diag(VD->getLocation(), 2407 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2408 << VD; 2409 return ExprError(); 2410 } 2411 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2412 // A threadprivate directive for static block-scope variables must appear 2413 // in the scope of the variable and not in a nested scope. 2414 if (CanonicalVD->isLocalVarDecl() && CurScope && 2415 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2416 Diag(Id.getLoc(), diag::err_omp_var_scope) 2417 << getOpenMPDirectiveName(Kind) << VD; 2418 bool IsDecl = 2419 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2420 Diag(VD->getLocation(), 2421 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2422 << VD; 2423 return ExprError(); 2424 } 2425 2426 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2427 // A threadprivate directive must lexically precede all references to any 2428 // of the variables in its list. 2429 if (Kind == OMPD_threadprivate && VD->isUsed() && 2430 !DSAStack->isThreadPrivate(VD)) { 2431 Diag(Id.getLoc(), diag::err_omp_var_used) 2432 << getOpenMPDirectiveName(Kind) << VD; 2433 return ExprError(); 2434 } 2435 2436 QualType ExprType = VD->getType().getNonReferenceType(); 2437 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2438 SourceLocation(), VD, 2439 /*RefersToEnclosingVariableOrCapture=*/false, 2440 Id.getLoc(), ExprType, VK_LValue); 2441 } 2442 2443 Sema::DeclGroupPtrTy 2444 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2445 ArrayRef<Expr *> VarList) { 2446 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2447 CurContext->addDecl(D); 2448 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2449 } 2450 return nullptr; 2451 } 2452 2453 namespace { 2454 class LocalVarRefChecker final 2455 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2456 Sema &SemaRef; 2457 2458 public: 2459 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2460 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2461 if (VD->hasLocalStorage()) { 2462 SemaRef.Diag(E->getBeginLoc(), 2463 diag::err_omp_local_var_in_threadprivate_init) 2464 << E->getSourceRange(); 2465 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2466 << VD << VD->getSourceRange(); 2467 return true; 2468 } 2469 } 2470 return false; 2471 } 2472 bool VisitStmt(const Stmt *S) { 2473 for (const Stmt *Child : S->children()) { 2474 if (Child && Visit(Child)) 2475 return true; 2476 } 2477 return false; 2478 } 2479 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2480 }; 2481 } // namespace 2482 2483 OMPThreadPrivateDecl * 2484 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2485 SmallVector<Expr *, 8> Vars; 2486 for (Expr *RefExpr : VarList) { 2487 auto *DE = cast<DeclRefExpr>(RefExpr); 2488 auto *VD = cast<VarDecl>(DE->getDecl()); 2489 SourceLocation ILoc = DE->getExprLoc(); 2490 2491 // Mark variable as used. 2492 VD->setReferenced(); 2493 VD->markUsed(Context); 2494 2495 QualType QType = VD->getType(); 2496 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2497 // It will be analyzed later. 2498 Vars.push_back(DE); 2499 continue; 2500 } 2501 2502 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2503 // A threadprivate variable must not have an incomplete type. 2504 if (RequireCompleteType(ILoc, VD->getType(), 2505 diag::err_omp_threadprivate_incomplete_type)) { 2506 continue; 2507 } 2508 2509 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2510 // A threadprivate variable must not have a reference type. 2511 if (VD->getType()->isReferenceType()) { 2512 Diag(ILoc, diag::err_omp_ref_type_arg) 2513 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2514 bool IsDecl = 2515 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2516 Diag(VD->getLocation(), 2517 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2518 << VD; 2519 continue; 2520 } 2521 2522 // Check if this is a TLS variable. If TLS is not being supported, produce 2523 // the corresponding diagnostic. 2524 if ((VD->getTLSKind() != VarDecl::TLS_None && 2525 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2526 getLangOpts().OpenMPUseTLS && 2527 getASTContext().getTargetInfo().isTLSSupported())) || 2528 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2529 !VD->isLocalVarDecl())) { 2530 Diag(ILoc, diag::err_omp_var_thread_local) 2531 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2532 bool IsDecl = 2533 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2534 Diag(VD->getLocation(), 2535 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2536 << VD; 2537 continue; 2538 } 2539 2540 // Check if initial value of threadprivate variable reference variable with 2541 // local storage (it is not supported by runtime). 2542 if (const Expr *Init = VD->getAnyInitializer()) { 2543 LocalVarRefChecker Checker(*this); 2544 if (Checker.Visit(Init)) 2545 continue; 2546 } 2547 2548 Vars.push_back(RefExpr); 2549 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2550 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2551 Context, SourceRange(Loc, Loc))); 2552 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2553 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2554 } 2555 OMPThreadPrivateDecl *D = nullptr; 2556 if (!Vars.empty()) { 2557 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2558 Vars); 2559 D->setAccess(AS_public); 2560 } 2561 return D; 2562 } 2563 2564 static OMPAllocateDeclAttr::AllocatorTypeTy 2565 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2566 if (!Allocator) 2567 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2568 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2569 Allocator->isInstantiationDependent() || 2570 Allocator->containsUnexpandedParameterPack()) 2571 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2572 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2573 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2574 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2575 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2576 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2577 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2578 llvm::FoldingSetNodeID AEId, DAEId; 2579 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2580 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2581 if (AEId == DAEId) { 2582 AllocatorKindRes = AllocatorKind; 2583 break; 2584 } 2585 } 2586 return AllocatorKindRes; 2587 } 2588 2589 static bool checkPreviousOMPAllocateAttribute( 2590 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2591 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2592 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2593 return false; 2594 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2595 Expr *PrevAllocator = A->getAllocator(); 2596 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2597 getAllocatorKind(S, Stack, PrevAllocator); 2598 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2599 if (AllocatorsMatch && 2600 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2601 Allocator && PrevAllocator) { 2602 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2603 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2604 llvm::FoldingSetNodeID AEId, PAEId; 2605 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2606 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2607 AllocatorsMatch = AEId == PAEId; 2608 } 2609 if (!AllocatorsMatch) { 2610 SmallString<256> AllocatorBuffer; 2611 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2612 if (Allocator) 2613 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2614 SmallString<256> PrevAllocatorBuffer; 2615 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2616 if (PrevAllocator) 2617 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2618 S.getPrintingPolicy()); 2619 2620 SourceLocation AllocatorLoc = 2621 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2622 SourceRange AllocatorRange = 2623 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2624 SourceLocation PrevAllocatorLoc = 2625 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2626 SourceRange PrevAllocatorRange = 2627 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2628 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2629 << (Allocator ? 1 : 0) << AllocatorStream.str() 2630 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2631 << AllocatorRange; 2632 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2633 << PrevAllocatorRange; 2634 return true; 2635 } 2636 return false; 2637 } 2638 2639 static void 2640 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2641 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2642 Expr *Allocator, SourceRange SR) { 2643 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2644 return; 2645 if (Allocator && 2646 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2647 Allocator->isInstantiationDependent() || 2648 Allocator->containsUnexpandedParameterPack())) 2649 return; 2650 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2651 Allocator, SR); 2652 VD->addAttr(A); 2653 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2654 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2655 } 2656 2657 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2658 SourceLocation Loc, ArrayRef<Expr *> VarList, 2659 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2660 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2661 Expr *Allocator = nullptr; 2662 if (Clauses.empty()) { 2663 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2664 // allocate directives that appear in a target region must specify an 2665 // allocator clause unless a requires directive with the dynamic_allocators 2666 // clause is present in the same compilation unit. 2667 if (LangOpts.OpenMPIsDevice && 2668 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2669 targetDiag(Loc, diag::err_expected_allocator_clause); 2670 } else { 2671 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2672 } 2673 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2674 getAllocatorKind(*this, DSAStack, Allocator); 2675 SmallVector<Expr *, 8> Vars; 2676 for (Expr *RefExpr : VarList) { 2677 auto *DE = cast<DeclRefExpr>(RefExpr); 2678 auto *VD = cast<VarDecl>(DE->getDecl()); 2679 2680 // Check if this is a TLS variable or global register. 2681 if (VD->getTLSKind() != VarDecl::TLS_None || 2682 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2683 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2684 !VD->isLocalVarDecl())) 2685 continue; 2686 2687 // If the used several times in the allocate directive, the same allocator 2688 // must be used. 2689 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2690 AllocatorKind, Allocator)) 2691 continue; 2692 2693 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2694 // If a list item has a static storage type, the allocator expression in the 2695 // allocator clause must be a constant expression that evaluates to one of 2696 // the predefined memory allocator values. 2697 if (Allocator && VD->hasGlobalStorage()) { 2698 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2699 Diag(Allocator->getExprLoc(), 2700 diag::err_omp_expected_predefined_allocator) 2701 << Allocator->getSourceRange(); 2702 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2703 VarDecl::DeclarationOnly; 2704 Diag(VD->getLocation(), 2705 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2706 << VD; 2707 continue; 2708 } 2709 } 2710 2711 Vars.push_back(RefExpr); 2712 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2713 DE->getSourceRange()); 2714 } 2715 if (Vars.empty()) 2716 return nullptr; 2717 if (!Owner) 2718 Owner = getCurLexicalContext(); 2719 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2720 D->setAccess(AS_public); 2721 Owner->addDecl(D); 2722 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2723 } 2724 2725 Sema::DeclGroupPtrTy 2726 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2727 ArrayRef<OMPClause *> ClauseList) { 2728 OMPRequiresDecl *D = nullptr; 2729 if (!CurContext->isFileContext()) { 2730 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2731 } else { 2732 D = CheckOMPRequiresDecl(Loc, ClauseList); 2733 if (D) { 2734 CurContext->addDecl(D); 2735 DSAStack->addRequiresDecl(D); 2736 } 2737 } 2738 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2739 } 2740 2741 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2742 ArrayRef<OMPClause *> ClauseList) { 2743 /// For target specific clauses, the requires directive cannot be 2744 /// specified after the handling of any of the target regions in the 2745 /// current compilation unit. 2746 ArrayRef<SourceLocation> TargetLocations = 2747 DSAStack->getEncounteredTargetLocs(); 2748 if (!TargetLocations.empty()) { 2749 for (const OMPClause *CNew : ClauseList) { 2750 // Check if any of the requires clauses affect target regions. 2751 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2752 isa<OMPUnifiedAddressClause>(CNew) || 2753 isa<OMPReverseOffloadClause>(CNew) || 2754 isa<OMPDynamicAllocatorsClause>(CNew)) { 2755 Diag(Loc, diag::err_omp_target_before_requires) 2756 << getOpenMPClauseName(CNew->getClauseKind()); 2757 for (SourceLocation TargetLoc : TargetLocations) { 2758 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2759 } 2760 } 2761 } 2762 } 2763 2764 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2765 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2766 ClauseList); 2767 return nullptr; 2768 } 2769 2770 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2771 const ValueDecl *D, 2772 const DSAStackTy::DSAVarData &DVar, 2773 bool IsLoopIterVar = false) { 2774 if (DVar.RefExpr) { 2775 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2776 << getOpenMPClauseName(DVar.CKind); 2777 return; 2778 } 2779 enum { 2780 PDSA_StaticMemberShared, 2781 PDSA_StaticLocalVarShared, 2782 PDSA_LoopIterVarPrivate, 2783 PDSA_LoopIterVarLinear, 2784 PDSA_LoopIterVarLastprivate, 2785 PDSA_ConstVarShared, 2786 PDSA_GlobalVarShared, 2787 PDSA_TaskVarFirstprivate, 2788 PDSA_LocalVarPrivate, 2789 PDSA_Implicit 2790 } Reason = PDSA_Implicit; 2791 bool ReportHint = false; 2792 auto ReportLoc = D->getLocation(); 2793 auto *VD = dyn_cast<VarDecl>(D); 2794 if (IsLoopIterVar) { 2795 if (DVar.CKind == OMPC_private) 2796 Reason = PDSA_LoopIterVarPrivate; 2797 else if (DVar.CKind == OMPC_lastprivate) 2798 Reason = PDSA_LoopIterVarLastprivate; 2799 else 2800 Reason = PDSA_LoopIterVarLinear; 2801 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2802 DVar.CKind == OMPC_firstprivate) { 2803 Reason = PDSA_TaskVarFirstprivate; 2804 ReportLoc = DVar.ImplicitDSALoc; 2805 } else if (VD && VD->isStaticLocal()) 2806 Reason = PDSA_StaticLocalVarShared; 2807 else if (VD && VD->isStaticDataMember()) 2808 Reason = PDSA_StaticMemberShared; 2809 else if (VD && VD->isFileVarDecl()) 2810 Reason = PDSA_GlobalVarShared; 2811 else if (D->getType().isConstant(SemaRef.getASTContext())) 2812 Reason = PDSA_ConstVarShared; 2813 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2814 ReportHint = true; 2815 Reason = PDSA_LocalVarPrivate; 2816 } 2817 if (Reason != PDSA_Implicit) { 2818 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2819 << Reason << ReportHint 2820 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2821 } else if (DVar.ImplicitDSALoc.isValid()) { 2822 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2823 << getOpenMPClauseName(DVar.CKind); 2824 } 2825 } 2826 2827 static OpenMPMapClauseKind 2828 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 2829 bool IsAggregateOrDeclareTarget) { 2830 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 2831 switch (M) { 2832 case OMPC_DEFAULTMAP_MODIFIER_alloc: 2833 Kind = OMPC_MAP_alloc; 2834 break; 2835 case OMPC_DEFAULTMAP_MODIFIER_to: 2836 Kind = OMPC_MAP_to; 2837 break; 2838 case OMPC_DEFAULTMAP_MODIFIER_from: 2839 Kind = OMPC_MAP_from; 2840 break; 2841 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 2842 Kind = OMPC_MAP_tofrom; 2843 break; 2844 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 2845 case OMPC_DEFAULTMAP_MODIFIER_last: 2846 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2847 case OMPC_DEFAULTMAP_MODIFIER_none: 2848 case OMPC_DEFAULTMAP_MODIFIER_default: 2849 case OMPC_DEFAULTMAP_MODIFIER_unknown: 2850 // IsAggregateOrDeclareTarget could be true if: 2851 // 1. the implicit behavior for aggregate is tofrom 2852 // 2. it's a declare target link 2853 if (IsAggregateOrDeclareTarget) { 2854 Kind = OMPC_MAP_tofrom; 2855 break; 2856 } 2857 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2858 } 2859 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 2860 return Kind; 2861 } 2862 2863 namespace { 2864 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2865 DSAStackTy *Stack; 2866 Sema &SemaRef; 2867 bool ErrorFound = false; 2868 bool TryCaptureCXXThisMembers = false; 2869 CapturedStmt *CS = nullptr; 2870 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2871 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 2872 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2873 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2874 2875 void VisitSubCaptures(OMPExecutableDirective *S) { 2876 // Check implicitly captured variables. 2877 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2878 return; 2879 visitSubCaptures(S->getInnermostCapturedStmt()); 2880 // Try to capture inner this->member references to generate correct mappings 2881 // and diagnostics. 2882 if (TryCaptureCXXThisMembers || 2883 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2884 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2885 [](const CapturedStmt::Capture &C) { 2886 return C.capturesThis(); 2887 }))) { 2888 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2889 TryCaptureCXXThisMembers = true; 2890 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2891 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2892 } 2893 } 2894 2895 public: 2896 void VisitDeclRefExpr(DeclRefExpr *E) { 2897 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 2898 E->isValueDependent() || E->containsUnexpandedParameterPack() || 2899 E->isInstantiationDependent()) 2900 return; 2901 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2902 // Check the datasharing rules for the expressions in the clauses. 2903 if (!CS) { 2904 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2905 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2906 Visit(CED->getInit()); 2907 return; 2908 } 2909 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2910 // Do not analyze internal variables and do not enclose them into 2911 // implicit clauses. 2912 return; 2913 VD = VD->getCanonicalDecl(); 2914 // Skip internally declared variables. 2915 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2916 return; 2917 2918 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2919 // Check if the variable has explicit DSA set and stop analysis if it so. 2920 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2921 return; 2922 2923 // Skip internally declared static variables. 2924 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2925 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2926 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2927 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2928 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2929 return; 2930 2931 SourceLocation ELoc = E->getExprLoc(); 2932 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2933 // The default(none) clause requires that each variable that is referenced 2934 // in the construct, and does not have a predetermined data-sharing 2935 // attribute, must have its data-sharing attribute explicitly determined 2936 // by being listed in a data-sharing attribute clause. 2937 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2938 isImplicitOrExplicitTaskingRegion(DKind) && 2939 VarsWithInheritedDSA.count(VD) == 0) { 2940 VarsWithInheritedDSA[VD] = E; 2941 return; 2942 } 2943 2944 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 2945 // If implicit-behavior is none, each variable referenced in the 2946 // construct that does not have a predetermined data-sharing attribute 2947 // and does not appear in a to or link clause on a declare target 2948 // directive must be listed in a data-mapping attribute clause, a 2949 // data-haring attribute clause (including a data-sharing attribute 2950 // clause on a combined construct where target. is one of the 2951 // constituent constructs), or an is_device_ptr clause. 2952 OpenMPDefaultmapClauseKind ClauseKind = 2953 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 2954 if (SemaRef.getLangOpts().OpenMP >= 50) { 2955 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 2956 OMPC_DEFAULTMAP_MODIFIER_none; 2957 if (DVar.CKind == OMPC_unknown && IsModifierNone && 2958 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 2959 // Only check for data-mapping attribute and is_device_ptr here 2960 // since we have already make sure that the declaration does not 2961 // have a data-sharing attribute above 2962 if (!Stack->checkMappableExprComponentListsForDecl( 2963 VD, /*CurrentRegionOnly=*/true, 2964 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 2965 MapExprComponents, 2966 OpenMPClauseKind) { 2967 auto MI = MapExprComponents.rbegin(); 2968 auto ME = MapExprComponents.rend(); 2969 return MI != ME && MI->getAssociatedDeclaration() == VD; 2970 })) { 2971 VarsWithInheritedDSA[VD] = E; 2972 return; 2973 } 2974 } 2975 } 2976 2977 if (isOpenMPTargetExecutionDirective(DKind) && 2978 !Stack->isLoopControlVariable(VD).first) { 2979 if (!Stack->checkMappableExprComponentListsForDecl( 2980 VD, /*CurrentRegionOnly=*/true, 2981 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2982 StackComponents, 2983 OpenMPClauseKind) { 2984 // Variable is used if it has been marked as an array, array 2985 // section or the variable iself. 2986 return StackComponents.size() == 1 || 2987 std::all_of( 2988 std::next(StackComponents.rbegin()), 2989 StackComponents.rend(), 2990 [](const OMPClauseMappableExprCommon:: 2991 MappableComponent &MC) { 2992 return MC.getAssociatedDeclaration() == 2993 nullptr && 2994 (isa<OMPArraySectionExpr>( 2995 MC.getAssociatedExpression()) || 2996 isa<ArraySubscriptExpr>( 2997 MC.getAssociatedExpression())); 2998 }); 2999 })) { 3000 bool IsFirstprivate = false; 3001 // By default lambdas are captured as firstprivates. 3002 if (const auto *RD = 3003 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3004 IsFirstprivate = RD->isLambda(); 3005 IsFirstprivate = 3006 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3007 if (IsFirstprivate) { 3008 ImplicitFirstprivate.emplace_back(E); 3009 } else { 3010 OpenMPDefaultmapClauseModifier M = 3011 Stack->getDefaultmapModifier(ClauseKind); 3012 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3013 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3014 ImplicitMap[Kind].emplace_back(E); 3015 } 3016 return; 3017 } 3018 } 3019 3020 // OpenMP [2.9.3.6, Restrictions, p.2] 3021 // A list item that appears in a reduction clause of the innermost 3022 // enclosing worksharing or parallel construct may not be accessed in an 3023 // explicit task. 3024 DVar = Stack->hasInnermostDSA( 3025 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3026 [](OpenMPDirectiveKind K) { 3027 return isOpenMPParallelDirective(K) || 3028 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3029 }, 3030 /*FromParent=*/true); 3031 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3032 ErrorFound = true; 3033 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3034 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3035 return; 3036 } 3037 3038 // Define implicit data-sharing attributes for task. 3039 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3040 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3041 !Stack->isLoopControlVariable(VD).first) { 3042 ImplicitFirstprivate.push_back(E); 3043 return; 3044 } 3045 3046 // Store implicitly used globals with declare target link for parent 3047 // target. 3048 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3049 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3050 Stack->addToParentTargetRegionLinkGlobals(E); 3051 return; 3052 } 3053 } 3054 } 3055 void VisitMemberExpr(MemberExpr *E) { 3056 if (E->isTypeDependent() || E->isValueDependent() || 3057 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3058 return; 3059 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3060 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3061 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 3062 if (!FD) 3063 return; 3064 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3065 // Check if the variable has explicit DSA set and stop analysis if it 3066 // so. 3067 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3068 return; 3069 3070 if (isOpenMPTargetExecutionDirective(DKind) && 3071 !Stack->isLoopControlVariable(FD).first && 3072 !Stack->checkMappableExprComponentListsForDecl( 3073 FD, /*CurrentRegionOnly=*/true, 3074 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3075 StackComponents, 3076 OpenMPClauseKind) { 3077 return isa<CXXThisExpr>( 3078 cast<MemberExpr>( 3079 StackComponents.back().getAssociatedExpression()) 3080 ->getBase() 3081 ->IgnoreParens()); 3082 })) { 3083 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3084 // A bit-field cannot appear in a map clause. 3085 // 3086 if (FD->isBitField()) 3087 return; 3088 3089 // Check to see if the member expression is referencing a class that 3090 // has already been explicitly mapped 3091 if (Stack->isClassPreviouslyMapped(TE->getType())) 3092 return; 3093 3094 OpenMPDefaultmapClauseModifier Modifier = 3095 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3096 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3097 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3098 ImplicitMap[Kind].emplace_back(E); 3099 return; 3100 } 3101 3102 SourceLocation ELoc = E->getExprLoc(); 3103 // OpenMP [2.9.3.6, Restrictions, p.2] 3104 // A list item that appears in a reduction clause of the innermost 3105 // enclosing worksharing or parallel construct may not be accessed in 3106 // an explicit task. 3107 DVar = Stack->hasInnermostDSA( 3108 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3109 [](OpenMPDirectiveKind K) { 3110 return isOpenMPParallelDirective(K) || 3111 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3112 }, 3113 /*FromParent=*/true); 3114 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3115 ErrorFound = true; 3116 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3117 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3118 return; 3119 } 3120 3121 // Define implicit data-sharing attributes for task. 3122 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3123 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3124 !Stack->isLoopControlVariable(FD).first) { 3125 // Check if there is a captured expression for the current field in the 3126 // region. Do not mark it as firstprivate unless there is no captured 3127 // expression. 3128 // TODO: try to make it firstprivate. 3129 if (DVar.CKind != OMPC_unknown) 3130 ImplicitFirstprivate.push_back(E); 3131 } 3132 return; 3133 } 3134 if (isOpenMPTargetExecutionDirective(DKind)) { 3135 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3136 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3137 /*NoDiagnose=*/true)) 3138 return; 3139 const auto *VD = cast<ValueDecl>( 3140 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3141 if (!Stack->checkMappableExprComponentListsForDecl( 3142 VD, /*CurrentRegionOnly=*/true, 3143 [&CurComponents]( 3144 OMPClauseMappableExprCommon::MappableExprComponentListRef 3145 StackComponents, 3146 OpenMPClauseKind) { 3147 auto CCI = CurComponents.rbegin(); 3148 auto CCE = CurComponents.rend(); 3149 for (const auto &SC : llvm::reverse(StackComponents)) { 3150 // Do both expressions have the same kind? 3151 if (CCI->getAssociatedExpression()->getStmtClass() != 3152 SC.getAssociatedExpression()->getStmtClass()) 3153 if (!(isa<OMPArraySectionExpr>( 3154 SC.getAssociatedExpression()) && 3155 isa<ArraySubscriptExpr>( 3156 CCI->getAssociatedExpression()))) 3157 return false; 3158 3159 const Decl *CCD = CCI->getAssociatedDeclaration(); 3160 const Decl *SCD = SC.getAssociatedDeclaration(); 3161 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3162 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3163 if (SCD != CCD) 3164 return false; 3165 std::advance(CCI, 1); 3166 if (CCI == CCE) 3167 break; 3168 } 3169 return true; 3170 })) { 3171 Visit(E->getBase()); 3172 } 3173 } else if (!TryCaptureCXXThisMembers) { 3174 Visit(E->getBase()); 3175 } 3176 } 3177 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3178 for (OMPClause *C : S->clauses()) { 3179 // Skip analysis of arguments of implicitly defined firstprivate clause 3180 // for task|target directives. 3181 // Skip analysis of arguments of implicitly defined map clause for target 3182 // directives. 3183 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3184 C->isImplicit())) { 3185 for (Stmt *CC : C->children()) { 3186 if (CC) 3187 Visit(CC); 3188 } 3189 } 3190 } 3191 // Check implicitly captured variables. 3192 VisitSubCaptures(S); 3193 } 3194 void VisitStmt(Stmt *S) { 3195 for (Stmt *C : S->children()) { 3196 if (C) { 3197 // Check implicitly captured variables in the task-based directives to 3198 // check if they must be firstprivatized. 3199 Visit(C); 3200 } 3201 } 3202 } 3203 3204 void visitSubCaptures(CapturedStmt *S) { 3205 for (const CapturedStmt::Capture &Cap : S->captures()) { 3206 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3207 continue; 3208 VarDecl *VD = Cap.getCapturedVar(); 3209 // Do not try to map the variable if it or its sub-component was mapped 3210 // already. 3211 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3212 Stack->checkMappableExprComponentListsForDecl( 3213 VD, /*CurrentRegionOnly=*/true, 3214 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3215 OpenMPClauseKind) { return true; })) 3216 continue; 3217 DeclRefExpr *DRE = buildDeclRefExpr( 3218 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3219 Cap.getLocation(), /*RefersToCapture=*/true); 3220 Visit(DRE); 3221 } 3222 } 3223 bool isErrorFound() const { return ErrorFound; } 3224 ArrayRef<Expr *> getImplicitFirstprivate() const { 3225 return ImplicitFirstprivate; 3226 } 3227 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3228 return ImplicitMap[Kind]; 3229 } 3230 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3231 return VarsWithInheritedDSA; 3232 } 3233 3234 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3235 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3236 // Process declare target link variables for the target directives. 3237 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3238 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3239 Visit(E); 3240 } 3241 } 3242 }; 3243 } // namespace 3244 3245 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3246 switch (DKind) { 3247 case OMPD_parallel: 3248 case OMPD_parallel_for: 3249 case OMPD_parallel_for_simd: 3250 case OMPD_parallel_sections: 3251 case OMPD_teams: 3252 case OMPD_teams_distribute: 3253 case OMPD_teams_distribute_simd: { 3254 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3255 QualType KmpInt32PtrTy = 3256 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3257 Sema::CapturedParamNameType Params[] = { 3258 std::make_pair(".global_tid.", KmpInt32PtrTy), 3259 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3260 std::make_pair(StringRef(), QualType()) // __context with shared vars 3261 }; 3262 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3263 Params); 3264 break; 3265 } 3266 case OMPD_target_teams: 3267 case OMPD_target_parallel: 3268 case OMPD_target_parallel_for: 3269 case OMPD_target_parallel_for_simd: 3270 case OMPD_target_teams_distribute: 3271 case OMPD_target_teams_distribute_simd: { 3272 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3273 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3274 QualType KmpInt32PtrTy = 3275 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3276 QualType Args[] = {VoidPtrTy}; 3277 FunctionProtoType::ExtProtoInfo EPI; 3278 EPI.Variadic = true; 3279 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3280 Sema::CapturedParamNameType Params[] = { 3281 std::make_pair(".global_tid.", KmpInt32Ty), 3282 std::make_pair(".part_id.", KmpInt32PtrTy), 3283 std::make_pair(".privates.", VoidPtrTy), 3284 std::make_pair( 3285 ".copy_fn.", 3286 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3287 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3288 std::make_pair(StringRef(), QualType()) // __context with shared vars 3289 }; 3290 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3291 Params, /*OpenMPCaptureLevel=*/0); 3292 // Mark this captured region as inlined, because we don't use outlined 3293 // function directly. 3294 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3295 AlwaysInlineAttr::CreateImplicit( 3296 Context, {}, AttributeCommonInfo::AS_Keyword, 3297 AlwaysInlineAttr::Keyword_forceinline)); 3298 Sema::CapturedParamNameType ParamsTarget[] = { 3299 std::make_pair(StringRef(), QualType()) // __context with shared vars 3300 }; 3301 // Start a captured region for 'target' with no implicit parameters. 3302 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3303 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3304 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3305 std::make_pair(".global_tid.", KmpInt32PtrTy), 3306 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3307 std::make_pair(StringRef(), QualType()) // __context with shared vars 3308 }; 3309 // Start a captured region for 'teams' or 'parallel'. Both regions have 3310 // the same implicit parameters. 3311 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3312 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3313 break; 3314 } 3315 case OMPD_target: 3316 case OMPD_target_simd: { 3317 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3318 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3319 QualType KmpInt32PtrTy = 3320 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3321 QualType Args[] = {VoidPtrTy}; 3322 FunctionProtoType::ExtProtoInfo EPI; 3323 EPI.Variadic = true; 3324 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3325 Sema::CapturedParamNameType Params[] = { 3326 std::make_pair(".global_tid.", KmpInt32Ty), 3327 std::make_pair(".part_id.", KmpInt32PtrTy), 3328 std::make_pair(".privates.", VoidPtrTy), 3329 std::make_pair( 3330 ".copy_fn.", 3331 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3332 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3333 std::make_pair(StringRef(), QualType()) // __context with shared vars 3334 }; 3335 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3336 Params, /*OpenMPCaptureLevel=*/0); 3337 // Mark this captured region as inlined, because we don't use outlined 3338 // function directly. 3339 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3340 AlwaysInlineAttr::CreateImplicit( 3341 Context, {}, AttributeCommonInfo::AS_Keyword, 3342 AlwaysInlineAttr::Keyword_forceinline)); 3343 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3344 std::make_pair(StringRef(), QualType()), 3345 /*OpenMPCaptureLevel=*/1); 3346 break; 3347 } 3348 case OMPD_simd: 3349 case OMPD_for: 3350 case OMPD_for_simd: 3351 case OMPD_sections: 3352 case OMPD_section: 3353 case OMPD_single: 3354 case OMPD_master: 3355 case OMPD_critical: 3356 case OMPD_taskgroup: 3357 case OMPD_distribute: 3358 case OMPD_distribute_simd: 3359 case OMPD_ordered: 3360 case OMPD_atomic: 3361 case OMPD_target_data: { 3362 Sema::CapturedParamNameType Params[] = { 3363 std::make_pair(StringRef(), QualType()) // __context with shared vars 3364 }; 3365 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3366 Params); 3367 break; 3368 } 3369 case OMPD_task: { 3370 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3371 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3372 QualType KmpInt32PtrTy = 3373 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3374 QualType Args[] = {VoidPtrTy}; 3375 FunctionProtoType::ExtProtoInfo EPI; 3376 EPI.Variadic = true; 3377 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3378 Sema::CapturedParamNameType Params[] = { 3379 std::make_pair(".global_tid.", KmpInt32Ty), 3380 std::make_pair(".part_id.", KmpInt32PtrTy), 3381 std::make_pair(".privates.", VoidPtrTy), 3382 std::make_pair( 3383 ".copy_fn.", 3384 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3385 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3386 std::make_pair(StringRef(), QualType()) // __context with shared vars 3387 }; 3388 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3389 Params); 3390 // Mark this captured region as inlined, because we don't use outlined 3391 // function directly. 3392 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3393 AlwaysInlineAttr::CreateImplicit( 3394 Context, {}, AttributeCommonInfo::AS_Keyword, 3395 AlwaysInlineAttr::Keyword_forceinline)); 3396 break; 3397 } 3398 case OMPD_taskloop: 3399 case OMPD_taskloop_simd: 3400 case OMPD_master_taskloop: 3401 case OMPD_master_taskloop_simd: { 3402 QualType KmpInt32Ty = 3403 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3404 .withConst(); 3405 QualType KmpUInt64Ty = 3406 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3407 .withConst(); 3408 QualType KmpInt64Ty = 3409 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3410 .withConst(); 3411 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3412 QualType KmpInt32PtrTy = 3413 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3414 QualType Args[] = {VoidPtrTy}; 3415 FunctionProtoType::ExtProtoInfo EPI; 3416 EPI.Variadic = true; 3417 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3418 Sema::CapturedParamNameType Params[] = { 3419 std::make_pair(".global_tid.", KmpInt32Ty), 3420 std::make_pair(".part_id.", KmpInt32PtrTy), 3421 std::make_pair(".privates.", VoidPtrTy), 3422 std::make_pair( 3423 ".copy_fn.", 3424 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3425 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3426 std::make_pair(".lb.", KmpUInt64Ty), 3427 std::make_pair(".ub.", KmpUInt64Ty), 3428 std::make_pair(".st.", KmpInt64Ty), 3429 std::make_pair(".liter.", KmpInt32Ty), 3430 std::make_pair(".reductions.", VoidPtrTy), 3431 std::make_pair(StringRef(), QualType()) // __context with shared vars 3432 }; 3433 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3434 Params); 3435 // Mark this captured region as inlined, because we don't use outlined 3436 // function directly. 3437 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3438 AlwaysInlineAttr::CreateImplicit( 3439 Context, {}, AttributeCommonInfo::AS_Keyword, 3440 AlwaysInlineAttr::Keyword_forceinline)); 3441 break; 3442 } 3443 case OMPD_parallel_master_taskloop: 3444 case OMPD_parallel_master_taskloop_simd: { 3445 QualType KmpInt32Ty = 3446 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3447 .withConst(); 3448 QualType KmpUInt64Ty = 3449 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3450 .withConst(); 3451 QualType KmpInt64Ty = 3452 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3453 .withConst(); 3454 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3455 QualType KmpInt32PtrTy = 3456 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3457 Sema::CapturedParamNameType ParamsParallel[] = { 3458 std::make_pair(".global_tid.", KmpInt32PtrTy), 3459 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3460 std::make_pair(StringRef(), QualType()) // __context with shared vars 3461 }; 3462 // Start a captured region for 'parallel'. 3463 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3464 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3465 QualType Args[] = {VoidPtrTy}; 3466 FunctionProtoType::ExtProtoInfo EPI; 3467 EPI.Variadic = true; 3468 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3469 Sema::CapturedParamNameType Params[] = { 3470 std::make_pair(".global_tid.", KmpInt32Ty), 3471 std::make_pair(".part_id.", KmpInt32PtrTy), 3472 std::make_pair(".privates.", VoidPtrTy), 3473 std::make_pair( 3474 ".copy_fn.", 3475 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3476 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3477 std::make_pair(".lb.", KmpUInt64Ty), 3478 std::make_pair(".ub.", KmpUInt64Ty), 3479 std::make_pair(".st.", KmpInt64Ty), 3480 std::make_pair(".liter.", KmpInt32Ty), 3481 std::make_pair(".reductions.", VoidPtrTy), 3482 std::make_pair(StringRef(), QualType()) // __context with shared vars 3483 }; 3484 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3485 Params, /*OpenMPCaptureLevel=*/2); 3486 // Mark this captured region as inlined, because we don't use outlined 3487 // function directly. 3488 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3489 AlwaysInlineAttr::CreateImplicit( 3490 Context, {}, AttributeCommonInfo::AS_Keyword, 3491 AlwaysInlineAttr::Keyword_forceinline)); 3492 break; 3493 } 3494 case OMPD_distribute_parallel_for_simd: 3495 case OMPD_distribute_parallel_for: { 3496 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3497 QualType KmpInt32PtrTy = 3498 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3499 Sema::CapturedParamNameType Params[] = { 3500 std::make_pair(".global_tid.", KmpInt32PtrTy), 3501 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3502 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3503 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3504 std::make_pair(StringRef(), QualType()) // __context with shared vars 3505 }; 3506 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3507 Params); 3508 break; 3509 } 3510 case OMPD_target_teams_distribute_parallel_for: 3511 case OMPD_target_teams_distribute_parallel_for_simd: { 3512 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3513 QualType KmpInt32PtrTy = 3514 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3515 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3516 3517 QualType Args[] = {VoidPtrTy}; 3518 FunctionProtoType::ExtProtoInfo EPI; 3519 EPI.Variadic = true; 3520 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3521 Sema::CapturedParamNameType Params[] = { 3522 std::make_pair(".global_tid.", KmpInt32Ty), 3523 std::make_pair(".part_id.", KmpInt32PtrTy), 3524 std::make_pair(".privates.", VoidPtrTy), 3525 std::make_pair( 3526 ".copy_fn.", 3527 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3528 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3529 std::make_pair(StringRef(), QualType()) // __context with shared vars 3530 }; 3531 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3532 Params, /*OpenMPCaptureLevel=*/0); 3533 // Mark this captured region as inlined, because we don't use outlined 3534 // function directly. 3535 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3536 AlwaysInlineAttr::CreateImplicit( 3537 Context, {}, AttributeCommonInfo::AS_Keyword, 3538 AlwaysInlineAttr::Keyword_forceinline)); 3539 Sema::CapturedParamNameType ParamsTarget[] = { 3540 std::make_pair(StringRef(), QualType()) // __context with shared vars 3541 }; 3542 // Start a captured region for 'target' with no implicit parameters. 3543 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3544 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3545 3546 Sema::CapturedParamNameType ParamsTeams[] = { 3547 std::make_pair(".global_tid.", KmpInt32PtrTy), 3548 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3549 std::make_pair(StringRef(), QualType()) // __context with shared vars 3550 }; 3551 // Start a captured region for 'target' with no implicit parameters. 3552 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3553 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3554 3555 Sema::CapturedParamNameType ParamsParallel[] = { 3556 std::make_pair(".global_tid.", KmpInt32PtrTy), 3557 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3558 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3559 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3560 std::make_pair(StringRef(), QualType()) // __context with shared vars 3561 }; 3562 // Start a captured region for 'teams' or 'parallel'. Both regions have 3563 // the same implicit parameters. 3564 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3565 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3566 break; 3567 } 3568 3569 case OMPD_teams_distribute_parallel_for: 3570 case OMPD_teams_distribute_parallel_for_simd: { 3571 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3572 QualType KmpInt32PtrTy = 3573 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3574 3575 Sema::CapturedParamNameType ParamsTeams[] = { 3576 std::make_pair(".global_tid.", KmpInt32PtrTy), 3577 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3578 std::make_pair(StringRef(), QualType()) // __context with shared vars 3579 }; 3580 // Start a captured region for 'target' with no implicit parameters. 3581 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3582 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3583 3584 Sema::CapturedParamNameType ParamsParallel[] = { 3585 std::make_pair(".global_tid.", KmpInt32PtrTy), 3586 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3587 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3588 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3589 std::make_pair(StringRef(), QualType()) // __context with shared vars 3590 }; 3591 // Start a captured region for 'teams' or 'parallel'. Both regions have 3592 // the same implicit parameters. 3593 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3594 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3595 break; 3596 } 3597 case OMPD_target_update: 3598 case OMPD_target_enter_data: 3599 case OMPD_target_exit_data: { 3600 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3601 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3602 QualType KmpInt32PtrTy = 3603 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3604 QualType Args[] = {VoidPtrTy}; 3605 FunctionProtoType::ExtProtoInfo EPI; 3606 EPI.Variadic = true; 3607 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3608 Sema::CapturedParamNameType Params[] = { 3609 std::make_pair(".global_tid.", KmpInt32Ty), 3610 std::make_pair(".part_id.", KmpInt32PtrTy), 3611 std::make_pair(".privates.", VoidPtrTy), 3612 std::make_pair( 3613 ".copy_fn.", 3614 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3615 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3616 std::make_pair(StringRef(), QualType()) // __context with shared vars 3617 }; 3618 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3619 Params); 3620 // Mark this captured region as inlined, because we don't use outlined 3621 // function directly. 3622 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3623 AlwaysInlineAttr::CreateImplicit( 3624 Context, {}, AttributeCommonInfo::AS_Keyword, 3625 AlwaysInlineAttr::Keyword_forceinline)); 3626 break; 3627 } 3628 case OMPD_threadprivate: 3629 case OMPD_allocate: 3630 case OMPD_taskyield: 3631 case OMPD_barrier: 3632 case OMPD_taskwait: 3633 case OMPD_cancellation_point: 3634 case OMPD_cancel: 3635 case OMPD_flush: 3636 case OMPD_declare_reduction: 3637 case OMPD_declare_mapper: 3638 case OMPD_declare_simd: 3639 case OMPD_declare_target: 3640 case OMPD_end_declare_target: 3641 case OMPD_requires: 3642 case OMPD_declare_variant: 3643 llvm_unreachable("OpenMP Directive is not allowed"); 3644 case OMPD_unknown: 3645 llvm_unreachable("Unknown OpenMP directive"); 3646 } 3647 } 3648 3649 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3650 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3651 } 3652 3653 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3654 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3655 getOpenMPCaptureRegions(CaptureRegions, DKind); 3656 return CaptureRegions.size(); 3657 } 3658 3659 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3660 Expr *CaptureExpr, bool WithInit, 3661 bool AsExpression) { 3662 assert(CaptureExpr); 3663 ASTContext &C = S.getASTContext(); 3664 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3665 QualType Ty = Init->getType(); 3666 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3667 if (S.getLangOpts().CPlusPlus) { 3668 Ty = C.getLValueReferenceType(Ty); 3669 } else { 3670 Ty = C.getPointerType(Ty); 3671 ExprResult Res = 3672 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3673 if (!Res.isUsable()) 3674 return nullptr; 3675 Init = Res.get(); 3676 } 3677 WithInit = true; 3678 } 3679 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3680 CaptureExpr->getBeginLoc()); 3681 if (!WithInit) 3682 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3683 S.CurContext->addHiddenDecl(CED); 3684 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3685 return CED; 3686 } 3687 3688 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3689 bool WithInit) { 3690 OMPCapturedExprDecl *CD; 3691 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3692 CD = cast<OMPCapturedExprDecl>(VD); 3693 else 3694 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3695 /*AsExpression=*/false); 3696 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3697 CaptureExpr->getExprLoc()); 3698 } 3699 3700 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3701 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3702 if (!Ref) { 3703 OMPCapturedExprDecl *CD = buildCaptureDecl( 3704 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3705 /*WithInit=*/true, /*AsExpression=*/true); 3706 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3707 CaptureExpr->getExprLoc()); 3708 } 3709 ExprResult Res = Ref; 3710 if (!S.getLangOpts().CPlusPlus && 3711 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3712 Ref->getType()->isPointerType()) { 3713 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3714 if (!Res.isUsable()) 3715 return ExprError(); 3716 } 3717 return S.DefaultLvalueConversion(Res.get()); 3718 } 3719 3720 namespace { 3721 // OpenMP directives parsed in this section are represented as a 3722 // CapturedStatement with an associated statement. If a syntax error 3723 // is detected during the parsing of the associated statement, the 3724 // compiler must abort processing and close the CapturedStatement. 3725 // 3726 // Combined directives such as 'target parallel' have more than one 3727 // nested CapturedStatements. This RAII ensures that we unwind out 3728 // of all the nested CapturedStatements when an error is found. 3729 class CaptureRegionUnwinderRAII { 3730 private: 3731 Sema &S; 3732 bool &ErrorFound; 3733 OpenMPDirectiveKind DKind = OMPD_unknown; 3734 3735 public: 3736 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3737 OpenMPDirectiveKind DKind) 3738 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3739 ~CaptureRegionUnwinderRAII() { 3740 if (ErrorFound) { 3741 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3742 while (--ThisCaptureLevel >= 0) 3743 S.ActOnCapturedRegionError(); 3744 } 3745 } 3746 }; 3747 } // namespace 3748 3749 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3750 // Capture variables captured by reference in lambdas for target-based 3751 // directives. 3752 if (!CurContext->isDependentContext() && 3753 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3754 isOpenMPTargetDataManagementDirective( 3755 DSAStack->getCurrentDirective()))) { 3756 QualType Type = V->getType(); 3757 if (const auto *RD = Type.getCanonicalType() 3758 .getNonReferenceType() 3759 ->getAsCXXRecordDecl()) { 3760 bool SavedForceCaptureByReferenceInTargetExecutable = 3761 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3762 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3763 /*V=*/true); 3764 if (RD->isLambda()) { 3765 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3766 FieldDecl *ThisCapture; 3767 RD->getCaptureFields(Captures, ThisCapture); 3768 for (const LambdaCapture &LC : RD->captures()) { 3769 if (LC.getCaptureKind() == LCK_ByRef) { 3770 VarDecl *VD = LC.getCapturedVar(); 3771 DeclContext *VDC = VD->getDeclContext(); 3772 if (!VDC->Encloses(CurContext)) 3773 continue; 3774 MarkVariableReferenced(LC.getLocation(), VD); 3775 } else if (LC.getCaptureKind() == LCK_This) { 3776 QualType ThisTy = getCurrentThisType(); 3777 if (!ThisTy.isNull() && 3778 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3779 CheckCXXThisCapture(LC.getLocation()); 3780 } 3781 } 3782 } 3783 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3784 SavedForceCaptureByReferenceInTargetExecutable); 3785 } 3786 } 3787 } 3788 3789 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3790 ArrayRef<OMPClause *> Clauses) { 3791 bool ErrorFound = false; 3792 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3793 *this, ErrorFound, DSAStack->getCurrentDirective()); 3794 if (!S.isUsable()) { 3795 ErrorFound = true; 3796 return StmtError(); 3797 } 3798 3799 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3800 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3801 OMPOrderedClause *OC = nullptr; 3802 OMPScheduleClause *SC = nullptr; 3803 SmallVector<const OMPLinearClause *, 4> LCs; 3804 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3805 // This is required for proper codegen. 3806 for (OMPClause *Clause : Clauses) { 3807 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3808 Clause->getClauseKind() == OMPC_in_reduction) { 3809 // Capture taskgroup task_reduction descriptors inside the tasking regions 3810 // with the corresponding in_reduction items. 3811 auto *IRC = cast<OMPInReductionClause>(Clause); 3812 for (Expr *E : IRC->taskgroup_descriptors()) 3813 if (E) 3814 MarkDeclarationsReferencedInExpr(E); 3815 } 3816 if (isOpenMPPrivate(Clause->getClauseKind()) || 3817 Clause->getClauseKind() == OMPC_copyprivate || 3818 (getLangOpts().OpenMPUseTLS && 3819 getASTContext().getTargetInfo().isTLSSupported() && 3820 Clause->getClauseKind() == OMPC_copyin)) { 3821 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3822 // Mark all variables in private list clauses as used in inner region. 3823 for (Stmt *VarRef : Clause->children()) { 3824 if (auto *E = cast_or_null<Expr>(VarRef)) { 3825 MarkDeclarationsReferencedInExpr(E); 3826 } 3827 } 3828 DSAStack->setForceVarCapturing(/*V=*/false); 3829 } else if (CaptureRegions.size() > 1 || 3830 CaptureRegions.back() != OMPD_unknown) { 3831 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3832 PICs.push_back(C); 3833 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3834 if (Expr *E = C->getPostUpdateExpr()) 3835 MarkDeclarationsReferencedInExpr(E); 3836 } 3837 } 3838 if (Clause->getClauseKind() == OMPC_schedule) 3839 SC = cast<OMPScheduleClause>(Clause); 3840 else if (Clause->getClauseKind() == OMPC_ordered) 3841 OC = cast<OMPOrderedClause>(Clause); 3842 else if (Clause->getClauseKind() == OMPC_linear) 3843 LCs.push_back(cast<OMPLinearClause>(Clause)); 3844 } 3845 // OpenMP, 2.7.1 Loop Construct, Restrictions 3846 // The nonmonotonic modifier cannot be specified if an ordered clause is 3847 // specified. 3848 if (SC && 3849 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3850 SC->getSecondScheduleModifier() == 3851 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3852 OC) { 3853 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3854 ? SC->getFirstScheduleModifierLoc() 3855 : SC->getSecondScheduleModifierLoc(), 3856 diag::err_omp_schedule_nonmonotonic_ordered) 3857 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3858 ErrorFound = true; 3859 } 3860 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3861 for (const OMPLinearClause *C : LCs) { 3862 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3863 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3864 } 3865 ErrorFound = true; 3866 } 3867 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3868 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3869 OC->getNumForLoops()) { 3870 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3871 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3872 ErrorFound = true; 3873 } 3874 if (ErrorFound) { 3875 return StmtError(); 3876 } 3877 StmtResult SR = S; 3878 unsigned CompletedRegions = 0; 3879 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3880 // Mark all variables in private list clauses as used in inner region. 3881 // Required for proper codegen of combined directives. 3882 // TODO: add processing for other clauses. 3883 if (ThisCaptureRegion != OMPD_unknown) { 3884 for (const clang::OMPClauseWithPreInit *C : PICs) { 3885 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3886 // Find the particular capture region for the clause if the 3887 // directive is a combined one with multiple capture regions. 3888 // If the directive is not a combined one, the capture region 3889 // associated with the clause is OMPD_unknown and is generated 3890 // only once. 3891 if (CaptureRegion == ThisCaptureRegion || 3892 CaptureRegion == OMPD_unknown) { 3893 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3894 for (Decl *D : DS->decls()) 3895 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3896 } 3897 } 3898 } 3899 } 3900 if (++CompletedRegions == CaptureRegions.size()) 3901 DSAStack->setBodyComplete(); 3902 SR = ActOnCapturedRegionEnd(SR.get()); 3903 } 3904 return SR; 3905 } 3906 3907 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3908 OpenMPDirectiveKind CancelRegion, 3909 SourceLocation StartLoc) { 3910 // CancelRegion is only needed for cancel and cancellation_point. 3911 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3912 return false; 3913 3914 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3915 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3916 return false; 3917 3918 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3919 << getOpenMPDirectiveName(CancelRegion); 3920 return true; 3921 } 3922 3923 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3924 OpenMPDirectiveKind CurrentRegion, 3925 const DeclarationNameInfo &CurrentName, 3926 OpenMPDirectiveKind CancelRegion, 3927 SourceLocation StartLoc) { 3928 if (Stack->getCurScope()) { 3929 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3930 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3931 bool NestingProhibited = false; 3932 bool CloseNesting = true; 3933 bool OrphanSeen = false; 3934 enum { 3935 NoRecommend, 3936 ShouldBeInParallelRegion, 3937 ShouldBeInOrderedRegion, 3938 ShouldBeInTargetRegion, 3939 ShouldBeInTeamsRegion 3940 } Recommend = NoRecommend; 3941 if (isOpenMPSimdDirective(ParentRegion) && 3942 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 3943 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 3944 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 3945 // OpenMP [2.16, Nesting of Regions] 3946 // OpenMP constructs may not be nested inside a simd region. 3947 // OpenMP [2.8.1,simd Construct, Restrictions] 3948 // An ordered construct with the simd clause is the only OpenMP 3949 // construct that can appear in the simd region. 3950 // Allowing a SIMD construct nested in another SIMD construct is an 3951 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3952 // message. 3953 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 3954 // The only OpenMP constructs that can be encountered during execution of 3955 // a simd region are the atomic construct, the loop construct, the simd 3956 // construct and the ordered construct with the simd clause. 3957 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3958 ? diag::err_omp_prohibited_region_simd 3959 : diag::warn_omp_nesting_simd) 3960 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 3961 return CurrentRegion != OMPD_simd; 3962 } 3963 if (ParentRegion == OMPD_atomic) { 3964 // OpenMP [2.16, Nesting of Regions] 3965 // OpenMP constructs may not be nested inside an atomic region. 3966 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3967 return true; 3968 } 3969 if (CurrentRegion == OMPD_section) { 3970 // OpenMP [2.7.2, sections Construct, Restrictions] 3971 // Orphaned section directives are prohibited. That is, the section 3972 // directives must appear within the sections construct and must not be 3973 // encountered elsewhere in the sections region. 3974 if (ParentRegion != OMPD_sections && 3975 ParentRegion != OMPD_parallel_sections) { 3976 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3977 << (ParentRegion != OMPD_unknown) 3978 << getOpenMPDirectiveName(ParentRegion); 3979 return true; 3980 } 3981 return false; 3982 } 3983 // Allow some constructs (except teams and cancellation constructs) to be 3984 // orphaned (they could be used in functions, called from OpenMP regions 3985 // with the required preconditions). 3986 if (ParentRegion == OMPD_unknown && 3987 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3988 CurrentRegion != OMPD_cancellation_point && 3989 CurrentRegion != OMPD_cancel) 3990 return false; 3991 if (CurrentRegion == OMPD_cancellation_point || 3992 CurrentRegion == OMPD_cancel) { 3993 // OpenMP [2.16, Nesting of Regions] 3994 // A cancellation point construct for which construct-type-clause is 3995 // taskgroup must be nested inside a task construct. A cancellation 3996 // point construct for which construct-type-clause is not taskgroup must 3997 // be closely nested inside an OpenMP construct that matches the type 3998 // specified in construct-type-clause. 3999 // A cancel construct for which construct-type-clause is taskgroup must be 4000 // nested inside a task construct. A cancel construct for which 4001 // construct-type-clause is not taskgroup must be closely nested inside an 4002 // OpenMP construct that matches the type specified in 4003 // construct-type-clause. 4004 NestingProhibited = 4005 !((CancelRegion == OMPD_parallel && 4006 (ParentRegion == OMPD_parallel || 4007 ParentRegion == OMPD_target_parallel)) || 4008 (CancelRegion == OMPD_for && 4009 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4010 ParentRegion == OMPD_target_parallel_for || 4011 ParentRegion == OMPD_distribute_parallel_for || 4012 ParentRegion == OMPD_teams_distribute_parallel_for || 4013 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4014 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 4015 (CancelRegion == OMPD_sections && 4016 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4017 ParentRegion == OMPD_parallel_sections))); 4018 OrphanSeen = ParentRegion == OMPD_unknown; 4019 } else if (CurrentRegion == OMPD_master) { 4020 // OpenMP [2.16, Nesting of Regions] 4021 // A master region may not be closely nested inside a worksharing, 4022 // atomic, or explicit task region. 4023 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4024 isOpenMPTaskingDirective(ParentRegion); 4025 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4026 // OpenMP [2.16, Nesting of Regions] 4027 // A critical region may not be nested (closely or otherwise) inside a 4028 // critical region with the same name. Note that this restriction is not 4029 // sufficient to prevent deadlock. 4030 SourceLocation PreviousCriticalLoc; 4031 bool DeadLock = Stack->hasDirective( 4032 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4033 const DeclarationNameInfo &DNI, 4034 SourceLocation Loc) { 4035 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4036 PreviousCriticalLoc = Loc; 4037 return true; 4038 } 4039 return false; 4040 }, 4041 false /* skip top directive */); 4042 if (DeadLock) { 4043 SemaRef.Diag(StartLoc, 4044 diag::err_omp_prohibited_region_critical_same_name) 4045 << CurrentName.getName(); 4046 if (PreviousCriticalLoc.isValid()) 4047 SemaRef.Diag(PreviousCriticalLoc, 4048 diag::note_omp_previous_critical_region); 4049 return true; 4050 } 4051 } else if (CurrentRegion == OMPD_barrier) { 4052 // OpenMP [2.16, Nesting of Regions] 4053 // A barrier region may not be closely nested inside a worksharing, 4054 // explicit task, critical, ordered, atomic, or master region. 4055 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4056 isOpenMPTaskingDirective(ParentRegion) || 4057 ParentRegion == OMPD_master || 4058 ParentRegion == OMPD_critical || 4059 ParentRegion == OMPD_ordered; 4060 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4061 !isOpenMPParallelDirective(CurrentRegion) && 4062 !isOpenMPTeamsDirective(CurrentRegion)) { 4063 // OpenMP [2.16, Nesting of Regions] 4064 // A worksharing region may not be closely nested inside a worksharing, 4065 // explicit task, critical, ordered, atomic, or master region. 4066 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4067 isOpenMPTaskingDirective(ParentRegion) || 4068 ParentRegion == OMPD_master || 4069 ParentRegion == OMPD_critical || 4070 ParentRegion == OMPD_ordered; 4071 Recommend = ShouldBeInParallelRegion; 4072 } else if (CurrentRegion == OMPD_ordered) { 4073 // OpenMP [2.16, Nesting of Regions] 4074 // An ordered region may not be closely nested inside a critical, 4075 // atomic, or explicit task region. 4076 // An ordered region must be closely nested inside a loop region (or 4077 // parallel loop region) with an ordered clause. 4078 // OpenMP [2.8.1,simd Construct, Restrictions] 4079 // An ordered construct with the simd clause is the only OpenMP construct 4080 // that can appear in the simd region. 4081 NestingProhibited = ParentRegion == OMPD_critical || 4082 isOpenMPTaskingDirective(ParentRegion) || 4083 !(isOpenMPSimdDirective(ParentRegion) || 4084 Stack->isParentOrderedRegion()); 4085 Recommend = ShouldBeInOrderedRegion; 4086 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4087 // OpenMP [2.16, Nesting of Regions] 4088 // If specified, a teams construct must be contained within a target 4089 // construct. 4090 NestingProhibited = 4091 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4092 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4093 ParentRegion != OMPD_target); 4094 OrphanSeen = ParentRegion == OMPD_unknown; 4095 Recommend = ShouldBeInTargetRegion; 4096 } 4097 if (!NestingProhibited && 4098 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4099 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4100 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4101 // OpenMP [2.16, Nesting of Regions] 4102 // distribute, parallel, parallel sections, parallel workshare, and the 4103 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4104 // constructs that can be closely nested in the teams region. 4105 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4106 !isOpenMPDistributeDirective(CurrentRegion); 4107 Recommend = ShouldBeInParallelRegion; 4108 } 4109 if (!NestingProhibited && 4110 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4111 // OpenMP 4.5 [2.17 Nesting of Regions] 4112 // The region associated with the distribute construct must be strictly 4113 // nested inside a teams region 4114 NestingProhibited = 4115 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4116 Recommend = ShouldBeInTeamsRegion; 4117 } 4118 if (!NestingProhibited && 4119 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4120 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4121 // OpenMP 4.5 [2.17 Nesting of Regions] 4122 // If a target, target update, target data, target enter data, or 4123 // target exit data construct is encountered during execution of a 4124 // target region, the behavior is unspecified. 4125 NestingProhibited = Stack->hasDirective( 4126 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4127 SourceLocation) { 4128 if (isOpenMPTargetExecutionDirective(K)) { 4129 OffendingRegion = K; 4130 return true; 4131 } 4132 return false; 4133 }, 4134 false /* don't skip top directive */); 4135 CloseNesting = false; 4136 } 4137 if (NestingProhibited) { 4138 if (OrphanSeen) { 4139 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4140 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4141 } else { 4142 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4143 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4144 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4145 } 4146 return true; 4147 } 4148 } 4149 return false; 4150 } 4151 4152 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4153 ArrayRef<OMPClause *> Clauses, 4154 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4155 bool ErrorFound = false; 4156 unsigned NamedModifiersNumber = 0; 4157 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 4158 OMPD_unknown + 1); 4159 SmallVector<SourceLocation, 4> NameModifierLoc; 4160 for (const OMPClause *C : Clauses) { 4161 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4162 // At most one if clause without a directive-name-modifier can appear on 4163 // the directive. 4164 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4165 if (FoundNameModifiers[CurNM]) { 4166 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4167 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4168 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4169 ErrorFound = true; 4170 } else if (CurNM != OMPD_unknown) { 4171 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4172 ++NamedModifiersNumber; 4173 } 4174 FoundNameModifiers[CurNM] = IC; 4175 if (CurNM == OMPD_unknown) 4176 continue; 4177 // Check if the specified name modifier is allowed for the current 4178 // directive. 4179 // At most one if clause with the particular directive-name-modifier can 4180 // appear on the directive. 4181 bool MatchFound = false; 4182 for (auto NM : AllowedNameModifiers) { 4183 if (CurNM == NM) { 4184 MatchFound = true; 4185 break; 4186 } 4187 } 4188 if (!MatchFound) { 4189 S.Diag(IC->getNameModifierLoc(), 4190 diag::err_omp_wrong_if_directive_name_modifier) 4191 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4192 ErrorFound = true; 4193 } 4194 } 4195 } 4196 // If any if clause on the directive includes a directive-name-modifier then 4197 // all if clauses on the directive must include a directive-name-modifier. 4198 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4199 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4200 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4201 diag::err_omp_no_more_if_clause); 4202 } else { 4203 std::string Values; 4204 std::string Sep(", "); 4205 unsigned AllowedCnt = 0; 4206 unsigned TotalAllowedNum = 4207 AllowedNameModifiers.size() - NamedModifiersNumber; 4208 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4209 ++Cnt) { 4210 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4211 if (!FoundNameModifiers[NM]) { 4212 Values += "'"; 4213 Values += getOpenMPDirectiveName(NM); 4214 Values += "'"; 4215 if (AllowedCnt + 2 == TotalAllowedNum) 4216 Values += " or "; 4217 else if (AllowedCnt + 1 != TotalAllowedNum) 4218 Values += Sep; 4219 ++AllowedCnt; 4220 } 4221 } 4222 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4223 diag::err_omp_unnamed_if_clause) 4224 << (TotalAllowedNum > 1) << Values; 4225 } 4226 for (SourceLocation Loc : NameModifierLoc) { 4227 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4228 } 4229 ErrorFound = true; 4230 } 4231 return ErrorFound; 4232 } 4233 4234 static std::pair<ValueDecl *, bool> 4235 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4236 SourceRange &ERange, bool AllowArraySection = false) { 4237 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4238 RefExpr->containsUnexpandedParameterPack()) 4239 return std::make_pair(nullptr, true); 4240 4241 // OpenMP [3.1, C/C++] 4242 // A list item is a variable name. 4243 // OpenMP [2.9.3.3, Restrictions, p.1] 4244 // A variable that is part of another variable (as an array or 4245 // structure element) cannot appear in a private clause. 4246 RefExpr = RefExpr->IgnoreParens(); 4247 enum { 4248 NoArrayExpr = -1, 4249 ArraySubscript = 0, 4250 OMPArraySection = 1 4251 } IsArrayExpr = NoArrayExpr; 4252 if (AllowArraySection) { 4253 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4254 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4255 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4256 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4257 RefExpr = Base; 4258 IsArrayExpr = ArraySubscript; 4259 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4260 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4261 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4262 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4263 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4264 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4265 RefExpr = Base; 4266 IsArrayExpr = OMPArraySection; 4267 } 4268 } 4269 ELoc = RefExpr->getExprLoc(); 4270 ERange = RefExpr->getSourceRange(); 4271 RefExpr = RefExpr->IgnoreParenImpCasts(); 4272 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4273 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4274 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4275 (S.getCurrentThisType().isNull() || !ME || 4276 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4277 !isa<FieldDecl>(ME->getMemberDecl()))) { 4278 if (IsArrayExpr != NoArrayExpr) { 4279 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4280 << ERange; 4281 } else { 4282 S.Diag(ELoc, 4283 AllowArraySection 4284 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4285 : diag::err_omp_expected_var_name_member_expr) 4286 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4287 } 4288 return std::make_pair(nullptr, false); 4289 } 4290 return std::make_pair( 4291 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4292 } 4293 4294 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4295 ArrayRef<OMPClause *> Clauses) { 4296 assert(!S.CurContext->isDependentContext() && 4297 "Expected non-dependent context."); 4298 auto AllocateRange = 4299 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4300 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4301 DeclToCopy; 4302 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4303 return isOpenMPPrivate(C->getClauseKind()); 4304 }); 4305 for (OMPClause *Cl : PrivateRange) { 4306 MutableArrayRef<Expr *>::iterator I, It, Et; 4307 if (Cl->getClauseKind() == OMPC_private) { 4308 auto *PC = cast<OMPPrivateClause>(Cl); 4309 I = PC->private_copies().begin(); 4310 It = PC->varlist_begin(); 4311 Et = PC->varlist_end(); 4312 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4313 auto *PC = cast<OMPFirstprivateClause>(Cl); 4314 I = PC->private_copies().begin(); 4315 It = PC->varlist_begin(); 4316 Et = PC->varlist_end(); 4317 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4318 auto *PC = cast<OMPLastprivateClause>(Cl); 4319 I = PC->private_copies().begin(); 4320 It = PC->varlist_begin(); 4321 Et = PC->varlist_end(); 4322 } else if (Cl->getClauseKind() == OMPC_linear) { 4323 auto *PC = cast<OMPLinearClause>(Cl); 4324 I = PC->privates().begin(); 4325 It = PC->varlist_begin(); 4326 Et = PC->varlist_end(); 4327 } else if (Cl->getClauseKind() == OMPC_reduction) { 4328 auto *PC = cast<OMPReductionClause>(Cl); 4329 I = PC->privates().begin(); 4330 It = PC->varlist_begin(); 4331 Et = PC->varlist_end(); 4332 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4333 auto *PC = cast<OMPTaskReductionClause>(Cl); 4334 I = PC->privates().begin(); 4335 It = PC->varlist_begin(); 4336 Et = PC->varlist_end(); 4337 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4338 auto *PC = cast<OMPInReductionClause>(Cl); 4339 I = PC->privates().begin(); 4340 It = PC->varlist_begin(); 4341 Et = PC->varlist_end(); 4342 } else { 4343 llvm_unreachable("Expected private clause."); 4344 } 4345 for (Expr *E : llvm::make_range(It, Et)) { 4346 if (!*I) { 4347 ++I; 4348 continue; 4349 } 4350 SourceLocation ELoc; 4351 SourceRange ERange; 4352 Expr *SimpleRefExpr = E; 4353 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4354 /*AllowArraySection=*/true); 4355 DeclToCopy.try_emplace(Res.first, 4356 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4357 ++I; 4358 } 4359 } 4360 for (OMPClause *C : AllocateRange) { 4361 auto *AC = cast<OMPAllocateClause>(C); 4362 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4363 getAllocatorKind(S, Stack, AC->getAllocator()); 4364 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4365 // For task, taskloop or target directives, allocation requests to memory 4366 // allocators with the trait access set to thread result in unspecified 4367 // behavior. 4368 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4369 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4370 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4371 S.Diag(AC->getAllocator()->getExprLoc(), 4372 diag::warn_omp_allocate_thread_on_task_target_directive) 4373 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4374 } 4375 for (Expr *E : AC->varlists()) { 4376 SourceLocation ELoc; 4377 SourceRange ERange; 4378 Expr *SimpleRefExpr = E; 4379 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4380 ValueDecl *VD = Res.first; 4381 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4382 if (!isOpenMPPrivate(Data.CKind)) { 4383 S.Diag(E->getExprLoc(), 4384 diag::err_omp_expected_private_copy_for_allocate); 4385 continue; 4386 } 4387 VarDecl *PrivateVD = DeclToCopy[VD]; 4388 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4389 AllocatorKind, AC->getAllocator())) 4390 continue; 4391 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4392 E->getSourceRange()); 4393 } 4394 } 4395 } 4396 4397 StmtResult Sema::ActOnOpenMPExecutableDirective( 4398 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4399 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4400 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4401 StmtResult Res = StmtError(); 4402 // First check CancelRegion which is then used in checkNestingOfRegions. 4403 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4404 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4405 StartLoc)) 4406 return StmtError(); 4407 4408 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4409 VarsWithInheritedDSAType VarsWithInheritedDSA; 4410 bool ErrorFound = false; 4411 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4412 if (AStmt && !CurContext->isDependentContext()) { 4413 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4414 4415 // Check default data sharing attributes for referenced variables. 4416 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4417 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4418 Stmt *S = AStmt; 4419 while (--ThisCaptureLevel >= 0) 4420 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4421 DSAChecker.Visit(S); 4422 if (!isOpenMPTargetDataManagementDirective(Kind) && 4423 !isOpenMPTaskingDirective(Kind)) { 4424 // Visit subcaptures to generate implicit clauses for captured vars. 4425 auto *CS = cast<CapturedStmt>(AStmt); 4426 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4427 getOpenMPCaptureRegions(CaptureRegions, Kind); 4428 // Ignore outer tasking regions for target directives. 4429 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4430 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4431 DSAChecker.visitSubCaptures(CS); 4432 } 4433 if (DSAChecker.isErrorFound()) 4434 return StmtError(); 4435 // Generate list of implicitly defined firstprivate variables. 4436 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4437 4438 SmallVector<Expr *, 4> ImplicitFirstprivates( 4439 DSAChecker.getImplicitFirstprivate().begin(), 4440 DSAChecker.getImplicitFirstprivate().end()); 4441 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4442 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4443 ArrayRef<Expr *> ImplicitMap = 4444 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4445 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4446 } 4447 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4448 for (OMPClause *C : Clauses) { 4449 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4450 for (Expr *E : IRC->taskgroup_descriptors()) 4451 if (E) 4452 ImplicitFirstprivates.emplace_back(E); 4453 } 4454 } 4455 if (!ImplicitFirstprivates.empty()) { 4456 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4457 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4458 SourceLocation())) { 4459 ClausesWithImplicit.push_back(Implicit); 4460 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4461 ImplicitFirstprivates.size(); 4462 } else { 4463 ErrorFound = true; 4464 } 4465 } 4466 int ClauseKindCnt = -1; 4467 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4468 ++ClauseKindCnt; 4469 if (ImplicitMap.empty()) 4470 continue; 4471 CXXScopeSpec MapperIdScopeSpec; 4472 DeclarationNameInfo MapperId; 4473 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4474 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4475 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4476 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4477 ImplicitMap, OMPVarListLocTy())) { 4478 ClausesWithImplicit.emplace_back(Implicit); 4479 ErrorFound |= 4480 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4481 } else { 4482 ErrorFound = true; 4483 } 4484 } 4485 } 4486 4487 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4488 switch (Kind) { 4489 case OMPD_parallel: 4490 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4491 EndLoc); 4492 AllowedNameModifiers.push_back(OMPD_parallel); 4493 break; 4494 case OMPD_simd: 4495 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4496 VarsWithInheritedDSA); 4497 if (LangOpts.OpenMP >= 50) 4498 AllowedNameModifiers.push_back(OMPD_simd); 4499 break; 4500 case OMPD_for: 4501 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4502 VarsWithInheritedDSA); 4503 break; 4504 case OMPD_for_simd: 4505 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4506 EndLoc, VarsWithInheritedDSA); 4507 if (LangOpts.OpenMP >= 50) 4508 AllowedNameModifiers.push_back(OMPD_simd); 4509 break; 4510 case OMPD_sections: 4511 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4512 EndLoc); 4513 break; 4514 case OMPD_section: 4515 assert(ClausesWithImplicit.empty() && 4516 "No clauses are allowed for 'omp section' directive"); 4517 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4518 break; 4519 case OMPD_single: 4520 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4521 EndLoc); 4522 break; 4523 case OMPD_master: 4524 assert(ClausesWithImplicit.empty() && 4525 "No clauses are allowed for 'omp master' directive"); 4526 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4527 break; 4528 case OMPD_critical: 4529 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4530 StartLoc, EndLoc); 4531 break; 4532 case OMPD_parallel_for: 4533 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4534 EndLoc, VarsWithInheritedDSA); 4535 AllowedNameModifiers.push_back(OMPD_parallel); 4536 break; 4537 case OMPD_parallel_for_simd: 4538 Res = ActOnOpenMPParallelForSimdDirective( 4539 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4540 AllowedNameModifiers.push_back(OMPD_parallel); 4541 break; 4542 case OMPD_parallel_sections: 4543 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4544 StartLoc, EndLoc); 4545 AllowedNameModifiers.push_back(OMPD_parallel); 4546 break; 4547 case OMPD_task: 4548 Res = 4549 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4550 AllowedNameModifiers.push_back(OMPD_task); 4551 break; 4552 case OMPD_taskyield: 4553 assert(ClausesWithImplicit.empty() && 4554 "No clauses are allowed for 'omp taskyield' directive"); 4555 assert(AStmt == nullptr && 4556 "No associated statement allowed for 'omp taskyield' directive"); 4557 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4558 break; 4559 case OMPD_barrier: 4560 assert(ClausesWithImplicit.empty() && 4561 "No clauses are allowed for 'omp barrier' directive"); 4562 assert(AStmt == nullptr && 4563 "No associated statement allowed for 'omp barrier' directive"); 4564 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4565 break; 4566 case OMPD_taskwait: 4567 assert(ClausesWithImplicit.empty() && 4568 "No clauses are allowed for 'omp taskwait' directive"); 4569 assert(AStmt == nullptr && 4570 "No associated statement allowed for 'omp taskwait' directive"); 4571 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4572 break; 4573 case OMPD_taskgroup: 4574 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4575 EndLoc); 4576 break; 4577 case OMPD_flush: 4578 assert(AStmt == nullptr && 4579 "No associated statement allowed for 'omp flush' directive"); 4580 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4581 break; 4582 case OMPD_ordered: 4583 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4584 EndLoc); 4585 break; 4586 case OMPD_atomic: 4587 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4588 EndLoc); 4589 break; 4590 case OMPD_teams: 4591 Res = 4592 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4593 break; 4594 case OMPD_target: 4595 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4596 EndLoc); 4597 AllowedNameModifiers.push_back(OMPD_target); 4598 break; 4599 case OMPD_target_parallel: 4600 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4601 StartLoc, EndLoc); 4602 AllowedNameModifiers.push_back(OMPD_target); 4603 AllowedNameModifiers.push_back(OMPD_parallel); 4604 break; 4605 case OMPD_target_parallel_for: 4606 Res = ActOnOpenMPTargetParallelForDirective( 4607 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4608 AllowedNameModifiers.push_back(OMPD_target); 4609 AllowedNameModifiers.push_back(OMPD_parallel); 4610 break; 4611 case OMPD_cancellation_point: 4612 assert(ClausesWithImplicit.empty() && 4613 "No clauses are allowed for 'omp cancellation point' directive"); 4614 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4615 "cancellation point' directive"); 4616 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4617 break; 4618 case OMPD_cancel: 4619 assert(AStmt == nullptr && 4620 "No associated statement allowed for 'omp cancel' directive"); 4621 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4622 CancelRegion); 4623 AllowedNameModifiers.push_back(OMPD_cancel); 4624 break; 4625 case OMPD_target_data: 4626 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4627 EndLoc); 4628 AllowedNameModifiers.push_back(OMPD_target_data); 4629 break; 4630 case OMPD_target_enter_data: 4631 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4632 EndLoc, AStmt); 4633 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4634 break; 4635 case OMPD_target_exit_data: 4636 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4637 EndLoc, AStmt); 4638 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4639 break; 4640 case OMPD_taskloop: 4641 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4642 EndLoc, VarsWithInheritedDSA); 4643 AllowedNameModifiers.push_back(OMPD_taskloop); 4644 break; 4645 case OMPD_taskloop_simd: 4646 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4647 EndLoc, VarsWithInheritedDSA); 4648 AllowedNameModifiers.push_back(OMPD_taskloop); 4649 break; 4650 case OMPD_master_taskloop: 4651 Res = ActOnOpenMPMasterTaskLoopDirective( 4652 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4653 AllowedNameModifiers.push_back(OMPD_taskloop); 4654 break; 4655 case OMPD_master_taskloop_simd: 4656 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4657 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4658 AllowedNameModifiers.push_back(OMPD_taskloop); 4659 break; 4660 case OMPD_parallel_master_taskloop: 4661 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4662 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4663 AllowedNameModifiers.push_back(OMPD_taskloop); 4664 AllowedNameModifiers.push_back(OMPD_parallel); 4665 break; 4666 case OMPD_parallel_master_taskloop_simd: 4667 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4668 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4669 AllowedNameModifiers.push_back(OMPD_taskloop); 4670 AllowedNameModifiers.push_back(OMPD_parallel); 4671 break; 4672 case OMPD_distribute: 4673 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4674 EndLoc, VarsWithInheritedDSA); 4675 break; 4676 case OMPD_target_update: 4677 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4678 EndLoc, AStmt); 4679 AllowedNameModifiers.push_back(OMPD_target_update); 4680 break; 4681 case OMPD_distribute_parallel_for: 4682 Res = ActOnOpenMPDistributeParallelForDirective( 4683 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4684 AllowedNameModifiers.push_back(OMPD_parallel); 4685 break; 4686 case OMPD_distribute_parallel_for_simd: 4687 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4688 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4689 AllowedNameModifiers.push_back(OMPD_parallel); 4690 break; 4691 case OMPD_distribute_simd: 4692 Res = ActOnOpenMPDistributeSimdDirective( 4693 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4694 break; 4695 case OMPD_target_parallel_for_simd: 4696 Res = ActOnOpenMPTargetParallelForSimdDirective( 4697 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4698 AllowedNameModifiers.push_back(OMPD_target); 4699 AllowedNameModifiers.push_back(OMPD_parallel); 4700 break; 4701 case OMPD_target_simd: 4702 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4703 EndLoc, VarsWithInheritedDSA); 4704 AllowedNameModifiers.push_back(OMPD_target); 4705 break; 4706 case OMPD_teams_distribute: 4707 Res = ActOnOpenMPTeamsDistributeDirective( 4708 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4709 break; 4710 case OMPD_teams_distribute_simd: 4711 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4712 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4713 break; 4714 case OMPD_teams_distribute_parallel_for_simd: 4715 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4716 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4717 AllowedNameModifiers.push_back(OMPD_parallel); 4718 break; 4719 case OMPD_teams_distribute_parallel_for: 4720 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4721 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4722 AllowedNameModifiers.push_back(OMPD_parallel); 4723 break; 4724 case OMPD_target_teams: 4725 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4726 EndLoc); 4727 AllowedNameModifiers.push_back(OMPD_target); 4728 break; 4729 case OMPD_target_teams_distribute: 4730 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4731 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4732 AllowedNameModifiers.push_back(OMPD_target); 4733 break; 4734 case OMPD_target_teams_distribute_parallel_for: 4735 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4736 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4737 AllowedNameModifiers.push_back(OMPD_target); 4738 AllowedNameModifiers.push_back(OMPD_parallel); 4739 break; 4740 case OMPD_target_teams_distribute_parallel_for_simd: 4741 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4742 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4743 AllowedNameModifiers.push_back(OMPD_target); 4744 AllowedNameModifiers.push_back(OMPD_parallel); 4745 break; 4746 case OMPD_target_teams_distribute_simd: 4747 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4748 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4749 AllowedNameModifiers.push_back(OMPD_target); 4750 break; 4751 case OMPD_declare_target: 4752 case OMPD_end_declare_target: 4753 case OMPD_threadprivate: 4754 case OMPD_allocate: 4755 case OMPD_declare_reduction: 4756 case OMPD_declare_mapper: 4757 case OMPD_declare_simd: 4758 case OMPD_requires: 4759 case OMPD_declare_variant: 4760 llvm_unreachable("OpenMP Directive is not allowed"); 4761 case OMPD_unknown: 4762 llvm_unreachable("Unknown OpenMP directive"); 4763 } 4764 4765 ErrorFound = Res.isInvalid() || ErrorFound; 4766 4767 // Check variables in the clauses if default(none) was specified. 4768 if (DSAStack->getDefaultDSA() == DSA_none) { 4769 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4770 for (OMPClause *C : Clauses) { 4771 switch (C->getClauseKind()) { 4772 case OMPC_num_threads: 4773 case OMPC_dist_schedule: 4774 // Do not analyse if no parent teams directive. 4775 if (isOpenMPTeamsDirective(Kind)) 4776 break; 4777 continue; 4778 case OMPC_if: 4779 if (isOpenMPTeamsDirective(Kind) && 4780 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4781 break; 4782 if (isOpenMPParallelDirective(Kind) && 4783 isOpenMPTaskLoopDirective(Kind) && 4784 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 4785 break; 4786 continue; 4787 case OMPC_schedule: 4788 break; 4789 case OMPC_grainsize: 4790 case OMPC_num_tasks: 4791 case OMPC_final: 4792 case OMPC_priority: 4793 // Do not analyze if no parent parallel directive. 4794 if (isOpenMPParallelDirective(Kind)) 4795 break; 4796 continue; 4797 case OMPC_ordered: 4798 case OMPC_device: 4799 case OMPC_num_teams: 4800 case OMPC_thread_limit: 4801 case OMPC_hint: 4802 case OMPC_collapse: 4803 case OMPC_safelen: 4804 case OMPC_simdlen: 4805 case OMPC_default: 4806 case OMPC_proc_bind: 4807 case OMPC_private: 4808 case OMPC_firstprivate: 4809 case OMPC_lastprivate: 4810 case OMPC_shared: 4811 case OMPC_reduction: 4812 case OMPC_task_reduction: 4813 case OMPC_in_reduction: 4814 case OMPC_linear: 4815 case OMPC_aligned: 4816 case OMPC_copyin: 4817 case OMPC_copyprivate: 4818 case OMPC_nowait: 4819 case OMPC_untied: 4820 case OMPC_mergeable: 4821 case OMPC_allocate: 4822 case OMPC_read: 4823 case OMPC_write: 4824 case OMPC_update: 4825 case OMPC_capture: 4826 case OMPC_seq_cst: 4827 case OMPC_depend: 4828 case OMPC_threads: 4829 case OMPC_simd: 4830 case OMPC_map: 4831 case OMPC_nogroup: 4832 case OMPC_defaultmap: 4833 case OMPC_to: 4834 case OMPC_from: 4835 case OMPC_use_device_ptr: 4836 case OMPC_is_device_ptr: 4837 continue; 4838 case OMPC_allocator: 4839 case OMPC_flush: 4840 case OMPC_threadprivate: 4841 case OMPC_uniform: 4842 case OMPC_unknown: 4843 case OMPC_unified_address: 4844 case OMPC_unified_shared_memory: 4845 case OMPC_reverse_offload: 4846 case OMPC_dynamic_allocators: 4847 case OMPC_atomic_default_mem_order: 4848 case OMPC_device_type: 4849 case OMPC_match: 4850 llvm_unreachable("Unexpected clause"); 4851 } 4852 for (Stmt *CC : C->children()) { 4853 if (CC) 4854 DSAChecker.Visit(CC); 4855 } 4856 } 4857 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4858 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4859 } 4860 for (const auto &P : VarsWithInheritedDSA) { 4861 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4862 continue; 4863 ErrorFound = true; 4864 if (DSAStack->getDefaultDSA() == DSA_none) { 4865 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4866 << P.first << P.second->getSourceRange(); 4867 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4868 } else if (getLangOpts().OpenMP >= 50) { 4869 Diag(P.second->getExprLoc(), 4870 diag::err_omp_defaultmap_no_attr_for_variable) 4871 << P.first << P.second->getSourceRange(); 4872 Diag(DSAStack->getDefaultDSALocation(), 4873 diag::note_omp_defaultmap_attr_none); 4874 } 4875 } 4876 4877 if (!AllowedNameModifiers.empty()) 4878 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4879 ErrorFound; 4880 4881 if (ErrorFound) 4882 return StmtError(); 4883 4884 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4885 Res.getAs<OMPExecutableDirective>() 4886 ->getStructuredBlock() 4887 ->setIsOMPStructuredBlock(true); 4888 } 4889 4890 if (!CurContext->isDependentContext() && 4891 isOpenMPTargetExecutionDirective(Kind) && 4892 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4893 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4894 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4895 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4896 // Register target to DSA Stack. 4897 DSAStack->addTargetDirLocation(StartLoc); 4898 } 4899 4900 return Res; 4901 } 4902 4903 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4904 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4905 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4906 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4907 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4908 assert(Aligneds.size() == Alignments.size()); 4909 assert(Linears.size() == LinModifiers.size()); 4910 assert(Linears.size() == Steps.size()); 4911 if (!DG || DG.get().isNull()) 4912 return DeclGroupPtrTy(); 4913 4914 const int SimdId = 0; 4915 if (!DG.get().isSingleDecl()) { 4916 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4917 << SimdId; 4918 return DG; 4919 } 4920 Decl *ADecl = DG.get().getSingleDecl(); 4921 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4922 ADecl = FTD->getTemplatedDecl(); 4923 4924 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4925 if (!FD) { 4926 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4927 return DeclGroupPtrTy(); 4928 } 4929 4930 // OpenMP [2.8.2, declare simd construct, Description] 4931 // The parameter of the simdlen clause must be a constant positive integer 4932 // expression. 4933 ExprResult SL; 4934 if (Simdlen) 4935 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4936 // OpenMP [2.8.2, declare simd construct, Description] 4937 // The special this pointer can be used as if was one of the arguments to the 4938 // function in any of the linear, aligned, or uniform clauses. 4939 // The uniform clause declares one or more arguments to have an invariant 4940 // value for all concurrent invocations of the function in the execution of a 4941 // single SIMD loop. 4942 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4943 const Expr *UniformedLinearThis = nullptr; 4944 for (const Expr *E : Uniforms) { 4945 E = E->IgnoreParenImpCasts(); 4946 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4947 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4948 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4949 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4950 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4951 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4952 continue; 4953 } 4954 if (isa<CXXThisExpr>(E)) { 4955 UniformedLinearThis = E; 4956 continue; 4957 } 4958 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4959 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4960 } 4961 // OpenMP [2.8.2, declare simd construct, Description] 4962 // The aligned clause declares that the object to which each list item points 4963 // is aligned to the number of bytes expressed in the optional parameter of 4964 // the aligned clause. 4965 // The special this pointer can be used as if was one of the arguments to the 4966 // function in any of the linear, aligned, or uniform clauses. 4967 // The type of list items appearing in the aligned clause must be array, 4968 // pointer, reference to array, or reference to pointer. 4969 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4970 const Expr *AlignedThis = nullptr; 4971 for (const Expr *E : Aligneds) { 4972 E = E->IgnoreParenImpCasts(); 4973 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4974 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4975 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4976 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4977 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4978 ->getCanonicalDecl() == CanonPVD) { 4979 // OpenMP [2.8.1, simd construct, Restrictions] 4980 // A list-item cannot appear in more than one aligned clause. 4981 if (AlignedArgs.count(CanonPVD) > 0) { 4982 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4983 << 1 << E->getSourceRange(); 4984 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4985 diag::note_omp_explicit_dsa) 4986 << getOpenMPClauseName(OMPC_aligned); 4987 continue; 4988 } 4989 AlignedArgs[CanonPVD] = E; 4990 QualType QTy = PVD->getType() 4991 .getNonReferenceType() 4992 .getUnqualifiedType() 4993 .getCanonicalType(); 4994 const Type *Ty = QTy.getTypePtrOrNull(); 4995 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4996 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4997 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4998 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4999 } 5000 continue; 5001 } 5002 } 5003 if (isa<CXXThisExpr>(E)) { 5004 if (AlignedThis) { 5005 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 5006 << 2 << E->getSourceRange(); 5007 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5008 << getOpenMPClauseName(OMPC_aligned); 5009 } 5010 AlignedThis = E; 5011 continue; 5012 } 5013 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5014 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5015 } 5016 // The optional parameter of the aligned clause, alignment, must be a constant 5017 // positive integer expression. If no optional parameter is specified, 5018 // implementation-defined default alignments for SIMD instructions on the 5019 // target platforms are assumed. 5020 SmallVector<const Expr *, 4> NewAligns; 5021 for (Expr *E : Alignments) { 5022 ExprResult Align; 5023 if (E) 5024 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5025 NewAligns.push_back(Align.get()); 5026 } 5027 // OpenMP [2.8.2, declare simd construct, Description] 5028 // The linear clause declares one or more list items to be private to a SIMD 5029 // lane and to have a linear relationship with respect to the iteration space 5030 // of a loop. 5031 // The special this pointer can be used as if was one of the arguments to the 5032 // function in any of the linear, aligned, or uniform clauses. 5033 // When a linear-step expression is specified in a linear clause it must be 5034 // either a constant integer expression or an integer-typed parameter that is 5035 // specified in a uniform clause on the directive. 5036 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5037 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5038 auto MI = LinModifiers.begin(); 5039 for (const Expr *E : Linears) { 5040 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5041 ++MI; 5042 E = E->IgnoreParenImpCasts(); 5043 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5044 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5045 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5046 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5047 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5048 ->getCanonicalDecl() == CanonPVD) { 5049 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5050 // A list-item cannot appear in more than one linear clause. 5051 if (LinearArgs.count(CanonPVD) > 0) { 5052 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5053 << getOpenMPClauseName(OMPC_linear) 5054 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5055 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5056 diag::note_omp_explicit_dsa) 5057 << getOpenMPClauseName(OMPC_linear); 5058 continue; 5059 } 5060 // Each argument can appear in at most one uniform or linear clause. 5061 if (UniformedArgs.count(CanonPVD) > 0) { 5062 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5063 << getOpenMPClauseName(OMPC_linear) 5064 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5065 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5066 diag::note_omp_explicit_dsa) 5067 << getOpenMPClauseName(OMPC_uniform); 5068 continue; 5069 } 5070 LinearArgs[CanonPVD] = E; 5071 if (E->isValueDependent() || E->isTypeDependent() || 5072 E->isInstantiationDependent() || 5073 E->containsUnexpandedParameterPack()) 5074 continue; 5075 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5076 PVD->getOriginalType()); 5077 continue; 5078 } 5079 } 5080 if (isa<CXXThisExpr>(E)) { 5081 if (UniformedLinearThis) { 5082 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5083 << getOpenMPClauseName(OMPC_linear) 5084 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5085 << E->getSourceRange(); 5086 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5087 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5088 : OMPC_linear); 5089 continue; 5090 } 5091 UniformedLinearThis = E; 5092 if (E->isValueDependent() || E->isTypeDependent() || 5093 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5094 continue; 5095 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5096 E->getType()); 5097 continue; 5098 } 5099 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5100 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5101 } 5102 Expr *Step = nullptr; 5103 Expr *NewStep = nullptr; 5104 SmallVector<Expr *, 4> NewSteps; 5105 for (Expr *E : Steps) { 5106 // Skip the same step expression, it was checked already. 5107 if (Step == E || !E) { 5108 NewSteps.push_back(E ? NewStep : nullptr); 5109 continue; 5110 } 5111 Step = E; 5112 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5113 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5114 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5115 if (UniformedArgs.count(CanonPVD) == 0) { 5116 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5117 << Step->getSourceRange(); 5118 } else if (E->isValueDependent() || E->isTypeDependent() || 5119 E->isInstantiationDependent() || 5120 E->containsUnexpandedParameterPack() || 5121 CanonPVD->getType()->hasIntegerRepresentation()) { 5122 NewSteps.push_back(Step); 5123 } else { 5124 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5125 << Step->getSourceRange(); 5126 } 5127 continue; 5128 } 5129 NewStep = Step; 5130 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5131 !Step->isInstantiationDependent() && 5132 !Step->containsUnexpandedParameterPack()) { 5133 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5134 .get(); 5135 if (NewStep) 5136 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5137 } 5138 NewSteps.push_back(NewStep); 5139 } 5140 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5141 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5142 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5143 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5144 const_cast<Expr **>(Linears.data()), Linears.size(), 5145 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5146 NewSteps.data(), NewSteps.size(), SR); 5147 ADecl->addAttr(NewAttr); 5148 return DG; 5149 } 5150 5151 Optional<std::pair<FunctionDecl *, Expr *>> 5152 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5153 Expr *VariantRef, SourceRange SR) { 5154 if (!DG || DG.get().isNull()) 5155 return None; 5156 5157 const int VariantId = 1; 5158 // Must be applied only to single decl. 5159 if (!DG.get().isSingleDecl()) { 5160 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5161 << VariantId << SR; 5162 return None; 5163 } 5164 Decl *ADecl = DG.get().getSingleDecl(); 5165 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5166 ADecl = FTD->getTemplatedDecl(); 5167 5168 // Decl must be a function. 5169 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5170 if (!FD) { 5171 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5172 << VariantId << SR; 5173 return None; 5174 } 5175 5176 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5177 return FD->hasAttrs() && 5178 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5179 FD->hasAttr<TargetAttr>()); 5180 }; 5181 // OpenMP is not compatible with CPU-specific attributes. 5182 if (HasMultiVersionAttributes(FD)) { 5183 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5184 << SR; 5185 return None; 5186 } 5187 5188 // Allow #pragma omp declare variant only if the function is not used. 5189 if (FD->isUsed(false)) 5190 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5191 << FD->getLocation(); 5192 5193 // Check if the function was emitted already. 5194 const FunctionDecl *Definition; 5195 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5196 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5197 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5198 << FD->getLocation(); 5199 5200 // The VariantRef must point to function. 5201 if (!VariantRef) { 5202 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5203 return None; 5204 } 5205 5206 // Do not check templates, wait until instantiation. 5207 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5208 VariantRef->containsUnexpandedParameterPack() || 5209 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5210 return std::make_pair(FD, VariantRef); 5211 5212 // Convert VariantRef expression to the type of the original function to 5213 // resolve possible conflicts. 5214 ExprResult VariantRefCast; 5215 if (LangOpts.CPlusPlus) { 5216 QualType FnPtrType; 5217 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5218 if (Method && !Method->isStatic()) { 5219 const Type *ClassType = 5220 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5221 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5222 ExprResult ER; 5223 { 5224 // Build adrr_of unary op to correctly handle type checks for member 5225 // functions. 5226 Sema::TentativeAnalysisScope Trap(*this); 5227 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5228 VariantRef); 5229 } 5230 if (!ER.isUsable()) { 5231 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5232 << VariantId << VariantRef->getSourceRange(); 5233 return None; 5234 } 5235 VariantRef = ER.get(); 5236 } else { 5237 FnPtrType = Context.getPointerType(FD->getType()); 5238 } 5239 ImplicitConversionSequence ICS = 5240 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5241 /*SuppressUserConversions=*/false, 5242 /*AllowExplicit=*/false, 5243 /*InOverloadResolution=*/false, 5244 /*CStyle=*/false, 5245 /*AllowObjCWritebackConversion=*/false); 5246 if (ICS.isFailure()) { 5247 Diag(VariantRef->getExprLoc(), 5248 diag::err_omp_declare_variant_incompat_types) 5249 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 5250 return None; 5251 } 5252 VariantRefCast = PerformImplicitConversion( 5253 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5254 if (!VariantRefCast.isUsable()) 5255 return None; 5256 // Drop previously built artificial addr_of unary op for member functions. 5257 if (Method && !Method->isStatic()) { 5258 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5259 if (auto *UO = dyn_cast<UnaryOperator>( 5260 PossibleAddrOfVariantRef->IgnoreImplicit())) 5261 VariantRefCast = UO->getSubExpr(); 5262 } 5263 } else { 5264 VariantRefCast = VariantRef; 5265 } 5266 5267 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5268 if (!ER.isUsable() || 5269 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5270 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5271 << VariantId << VariantRef->getSourceRange(); 5272 return None; 5273 } 5274 5275 // The VariantRef must point to function. 5276 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5277 if (!DRE) { 5278 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5279 << VariantId << VariantRef->getSourceRange(); 5280 return None; 5281 } 5282 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5283 if (!NewFD) { 5284 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5285 << VariantId << VariantRef->getSourceRange(); 5286 return None; 5287 } 5288 5289 // Check if variant function is not marked with declare variant directive. 5290 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5291 Diag(VariantRef->getExprLoc(), 5292 diag::warn_omp_declare_variant_marked_as_declare_variant) 5293 << VariantRef->getSourceRange(); 5294 SourceRange SR = 5295 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5296 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5297 return None; 5298 } 5299 5300 enum DoesntSupport { 5301 VirtFuncs = 1, 5302 Constructors = 3, 5303 Destructors = 4, 5304 DeletedFuncs = 5, 5305 DefaultedFuncs = 6, 5306 ConstexprFuncs = 7, 5307 ConstevalFuncs = 8, 5308 }; 5309 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5310 if (CXXFD->isVirtual()) { 5311 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5312 << VirtFuncs; 5313 return None; 5314 } 5315 5316 if (isa<CXXConstructorDecl>(FD)) { 5317 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5318 << Constructors; 5319 return None; 5320 } 5321 5322 if (isa<CXXDestructorDecl>(FD)) { 5323 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5324 << Destructors; 5325 return None; 5326 } 5327 } 5328 5329 if (FD->isDeleted()) { 5330 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5331 << DeletedFuncs; 5332 return None; 5333 } 5334 5335 if (FD->isDefaulted()) { 5336 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5337 << DefaultedFuncs; 5338 return None; 5339 } 5340 5341 if (FD->isConstexpr()) { 5342 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5343 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5344 return None; 5345 } 5346 5347 // Check general compatibility. 5348 if (areMultiversionVariantFunctionsCompatible( 5349 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5350 PartialDiagnosticAt( 5351 SR.getBegin(), 5352 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5353 PartialDiagnosticAt( 5354 VariantRef->getExprLoc(), 5355 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5356 PartialDiagnosticAt(VariantRef->getExprLoc(), 5357 PDiag(diag::err_omp_declare_variant_diff) 5358 << FD->getLocation()), 5359 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5360 /*CLinkageMayDiffer=*/true)) 5361 return None; 5362 return std::make_pair(FD, cast<Expr>(DRE)); 5363 } 5364 5365 void Sema::ActOnOpenMPDeclareVariantDirective( 5366 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5367 ArrayRef<OMPCtxSelectorData> Data) { 5368 if (Data.empty()) 5369 return; 5370 SmallVector<Expr *, 4> CtxScores; 5371 SmallVector<unsigned, 4> CtxSets; 5372 SmallVector<unsigned, 4> Ctxs; 5373 SmallVector<StringRef, 4> ImplVendors, DeviceKinds; 5374 bool IsError = false; 5375 for (const OMPCtxSelectorData &D : Data) { 5376 OpenMPContextSelectorSetKind CtxSet = D.CtxSet; 5377 OpenMPContextSelectorKind Ctx = D.Ctx; 5378 if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown) 5379 return; 5380 Expr *Score = nullptr; 5381 if (D.Score.isUsable()) { 5382 Score = D.Score.get(); 5383 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5384 !Score->isInstantiationDependent() && 5385 !Score->containsUnexpandedParameterPack()) { 5386 Score = 5387 PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score) 5388 .get(); 5389 if (Score) 5390 Score = VerifyIntegerConstantExpression(Score).get(); 5391 } 5392 } else { 5393 // OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors. 5394 // The kind, arch, and isa selectors are given the values 2^l, 2^(l+1) and 5395 // 2^(l+2), respectively, where l is the number of traits in the construct 5396 // set. 5397 // TODO: implement correct logic for isa and arch traits. 5398 // TODO: take the construct context set into account when it is 5399 // implemented. 5400 int L = 0; // Currently set the number of traits in construct set to 0, 5401 // since the construct trait set in not supported yet. 5402 if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind) 5403 Score = ActOnIntegerConstant(SourceLocation(), std::pow(2, L)).get(); 5404 else 5405 Score = ActOnIntegerConstant(SourceLocation(), 0).get(); 5406 } 5407 switch (Ctx) { 5408 case OMP_CTX_vendor: 5409 assert(CtxSet == OMP_CTX_SET_implementation && 5410 "Expected implementation context selector set."); 5411 ImplVendors.append(D.Names.begin(), D.Names.end()); 5412 break; 5413 case OMP_CTX_kind: 5414 assert(CtxSet == OMP_CTX_SET_device && 5415 "Expected device context selector set."); 5416 DeviceKinds.append(D.Names.begin(), D.Names.end()); 5417 break; 5418 case OMP_CTX_unknown: 5419 llvm_unreachable("Unknown context selector kind."); 5420 } 5421 IsError = IsError || !Score; 5422 CtxSets.push_back(CtxSet); 5423 Ctxs.push_back(Ctx); 5424 CtxScores.push_back(Score); 5425 } 5426 if (!IsError) { 5427 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5428 Context, VariantRef, CtxScores.begin(), CtxScores.size(), 5429 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(), 5430 ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(), 5431 DeviceKinds.size(), SR); 5432 FD->addAttr(NewAttr); 5433 } 5434 } 5435 5436 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5437 FunctionDecl *Func, 5438 bool MightBeOdrUse) { 5439 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5440 5441 if (!Func->isDependentContext() && Func->hasAttrs()) { 5442 for (OMPDeclareVariantAttr *A : 5443 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5444 // TODO: add checks for active OpenMP context where possible. 5445 Expr *VariantRef = A->getVariantFuncRef(); 5446 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5447 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5448 if (!F->isDefined() && F->isTemplateInstantiation()) 5449 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5450 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5451 } 5452 } 5453 } 5454 5455 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5456 Stmt *AStmt, 5457 SourceLocation StartLoc, 5458 SourceLocation EndLoc) { 5459 if (!AStmt) 5460 return StmtError(); 5461 5462 auto *CS = cast<CapturedStmt>(AStmt); 5463 // 1.2.2 OpenMP Language Terminology 5464 // Structured block - An executable statement with a single entry at the 5465 // top and a single exit at the bottom. 5466 // The point of exit cannot be a branch out of the structured block. 5467 // longjmp() and throw() must not violate the entry/exit criteria. 5468 CS->getCapturedDecl()->setNothrow(); 5469 5470 setFunctionHasBranchProtectedScope(); 5471 5472 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5473 DSAStack->isCancelRegion()); 5474 } 5475 5476 namespace { 5477 /// Iteration space of a single for loop. 5478 struct LoopIterationSpace final { 5479 /// True if the condition operator is the strict compare operator (<, > or 5480 /// !=). 5481 bool IsStrictCompare = false; 5482 /// Condition of the loop. 5483 Expr *PreCond = nullptr; 5484 /// This expression calculates the number of iterations in the loop. 5485 /// It is always possible to calculate it before starting the loop. 5486 Expr *NumIterations = nullptr; 5487 /// The loop counter variable. 5488 Expr *CounterVar = nullptr; 5489 /// Private loop counter variable. 5490 Expr *PrivateCounterVar = nullptr; 5491 /// This is initializer for the initial value of #CounterVar. 5492 Expr *CounterInit = nullptr; 5493 /// This is step for the #CounterVar used to generate its update: 5494 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5495 Expr *CounterStep = nullptr; 5496 /// Should step be subtracted? 5497 bool Subtract = false; 5498 /// Source range of the loop init. 5499 SourceRange InitSrcRange; 5500 /// Source range of the loop condition. 5501 SourceRange CondSrcRange; 5502 /// Source range of the loop increment. 5503 SourceRange IncSrcRange; 5504 /// Minimum value that can have the loop control variable. Used to support 5505 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5506 /// since only such variables can be used in non-loop invariant expressions. 5507 Expr *MinValue = nullptr; 5508 /// Maximum value that can have the loop control variable. Used to support 5509 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5510 /// since only such variables can be used in non-loop invariant expressions. 5511 Expr *MaxValue = nullptr; 5512 /// true, if the lower bound depends on the outer loop control var. 5513 bool IsNonRectangularLB = false; 5514 /// true, if the upper bound depends on the outer loop control var. 5515 bool IsNonRectangularUB = false; 5516 /// Index of the loop this loop depends on and forms non-rectangular loop 5517 /// nest. 5518 unsigned LoopDependentIdx = 0; 5519 /// Final condition for the non-rectangular loop nest support. It is used to 5520 /// check that the number of iterations for this particular counter must be 5521 /// finished. 5522 Expr *FinalCondition = nullptr; 5523 }; 5524 5525 /// Helper class for checking canonical form of the OpenMP loops and 5526 /// extracting iteration space of each loop in the loop nest, that will be used 5527 /// for IR generation. 5528 class OpenMPIterationSpaceChecker { 5529 /// Reference to Sema. 5530 Sema &SemaRef; 5531 /// Data-sharing stack. 5532 DSAStackTy &Stack; 5533 /// A location for diagnostics (when there is no some better location). 5534 SourceLocation DefaultLoc; 5535 /// A location for diagnostics (when increment is not compatible). 5536 SourceLocation ConditionLoc; 5537 /// A source location for referring to loop init later. 5538 SourceRange InitSrcRange; 5539 /// A source location for referring to condition later. 5540 SourceRange ConditionSrcRange; 5541 /// A source location for referring to increment later. 5542 SourceRange IncrementSrcRange; 5543 /// Loop variable. 5544 ValueDecl *LCDecl = nullptr; 5545 /// Reference to loop variable. 5546 Expr *LCRef = nullptr; 5547 /// Lower bound (initializer for the var). 5548 Expr *LB = nullptr; 5549 /// Upper bound. 5550 Expr *UB = nullptr; 5551 /// Loop step (increment). 5552 Expr *Step = nullptr; 5553 /// This flag is true when condition is one of: 5554 /// Var < UB 5555 /// Var <= UB 5556 /// UB > Var 5557 /// UB >= Var 5558 /// This will have no value when the condition is != 5559 llvm::Optional<bool> TestIsLessOp; 5560 /// This flag is true when condition is strict ( < or > ). 5561 bool TestIsStrictOp = false; 5562 /// This flag is true when step is subtracted on each iteration. 5563 bool SubtractStep = false; 5564 /// The outer loop counter this loop depends on (if any). 5565 const ValueDecl *DepDecl = nullptr; 5566 /// Contains number of loop (starts from 1) on which loop counter init 5567 /// expression of this loop depends on. 5568 Optional<unsigned> InitDependOnLC; 5569 /// Contains number of loop (starts from 1) on which loop counter condition 5570 /// expression of this loop depends on. 5571 Optional<unsigned> CondDependOnLC; 5572 /// Checks if the provide statement depends on the loop counter. 5573 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5574 /// Original condition required for checking of the exit condition for 5575 /// non-rectangular loop. 5576 Expr *Condition = nullptr; 5577 5578 public: 5579 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5580 SourceLocation DefaultLoc) 5581 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5582 ConditionLoc(DefaultLoc) {} 5583 /// Check init-expr for canonical loop form and save loop counter 5584 /// variable - #Var and its initialization value - #LB. 5585 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5586 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5587 /// for less/greater and for strict/non-strict comparison. 5588 bool checkAndSetCond(Expr *S); 5589 /// Check incr-expr for canonical loop form and return true if it 5590 /// does not conform, otherwise save loop step (#Step). 5591 bool checkAndSetInc(Expr *S); 5592 /// Return the loop counter variable. 5593 ValueDecl *getLoopDecl() const { return LCDecl; } 5594 /// Return the reference expression to loop counter variable. 5595 Expr *getLoopDeclRefExpr() const { return LCRef; } 5596 /// Source range of the loop init. 5597 SourceRange getInitSrcRange() const { return InitSrcRange; } 5598 /// Source range of the loop condition. 5599 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5600 /// Source range of the loop increment. 5601 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5602 /// True if the step should be subtracted. 5603 bool shouldSubtractStep() const { return SubtractStep; } 5604 /// True, if the compare operator is strict (<, > or !=). 5605 bool isStrictTestOp() const { return TestIsStrictOp; } 5606 /// Build the expression to calculate the number of iterations. 5607 Expr *buildNumIterations( 5608 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5609 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5610 /// Build the precondition expression for the loops. 5611 Expr * 5612 buildPreCond(Scope *S, Expr *Cond, 5613 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5614 /// Build reference expression to the counter be used for codegen. 5615 DeclRefExpr * 5616 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5617 DSAStackTy &DSA) const; 5618 /// Build reference expression to the private counter be used for 5619 /// codegen. 5620 Expr *buildPrivateCounterVar() const; 5621 /// Build initialization of the counter be used for codegen. 5622 Expr *buildCounterInit() const; 5623 /// Build step of the counter be used for codegen. 5624 Expr *buildCounterStep() const; 5625 /// Build loop data with counter value for depend clauses in ordered 5626 /// directives. 5627 Expr * 5628 buildOrderedLoopData(Scope *S, Expr *Counter, 5629 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5630 SourceLocation Loc, Expr *Inc = nullptr, 5631 OverloadedOperatorKind OOK = OO_Amp); 5632 /// Builds the minimum value for the loop counter. 5633 std::pair<Expr *, Expr *> buildMinMaxValues( 5634 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5635 /// Builds final condition for the non-rectangular loops. 5636 Expr *buildFinalCondition(Scope *S) const; 5637 /// Return true if any expression is dependent. 5638 bool dependent() const; 5639 /// Returns true if the initializer forms non-rectangular loop. 5640 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5641 /// Returns true if the condition forms non-rectangular loop. 5642 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5643 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5644 unsigned getLoopDependentIdx() const { 5645 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5646 } 5647 5648 private: 5649 /// Check the right-hand side of an assignment in the increment 5650 /// expression. 5651 bool checkAndSetIncRHS(Expr *RHS); 5652 /// Helper to set loop counter variable and its initializer. 5653 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5654 bool EmitDiags); 5655 /// Helper to set upper bound. 5656 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5657 SourceRange SR, SourceLocation SL); 5658 /// Helper to set loop increment. 5659 bool setStep(Expr *NewStep, bool Subtract); 5660 }; 5661 5662 bool OpenMPIterationSpaceChecker::dependent() const { 5663 if (!LCDecl) { 5664 assert(!LB && !UB && !Step); 5665 return false; 5666 } 5667 return LCDecl->getType()->isDependentType() || 5668 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5669 (Step && Step->isValueDependent()); 5670 } 5671 5672 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5673 Expr *NewLCRefExpr, 5674 Expr *NewLB, bool EmitDiags) { 5675 // State consistency checking to ensure correct usage. 5676 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5677 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5678 if (!NewLCDecl || !NewLB) 5679 return true; 5680 LCDecl = getCanonicalDecl(NewLCDecl); 5681 LCRef = NewLCRefExpr; 5682 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5683 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5684 if ((Ctor->isCopyOrMoveConstructor() || 5685 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5686 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5687 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5688 LB = NewLB; 5689 if (EmitDiags) 5690 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5691 return false; 5692 } 5693 5694 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5695 llvm::Optional<bool> LessOp, 5696 bool StrictOp, SourceRange SR, 5697 SourceLocation SL) { 5698 // State consistency checking to ensure correct usage. 5699 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5700 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5701 if (!NewUB) 5702 return true; 5703 UB = NewUB; 5704 if (LessOp) 5705 TestIsLessOp = LessOp; 5706 TestIsStrictOp = StrictOp; 5707 ConditionSrcRange = SR; 5708 ConditionLoc = SL; 5709 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5710 return false; 5711 } 5712 5713 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5714 // State consistency checking to ensure correct usage. 5715 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5716 if (!NewStep) 5717 return true; 5718 if (!NewStep->isValueDependent()) { 5719 // Check that the step is integer expression. 5720 SourceLocation StepLoc = NewStep->getBeginLoc(); 5721 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5722 StepLoc, getExprAsWritten(NewStep)); 5723 if (Val.isInvalid()) 5724 return true; 5725 NewStep = Val.get(); 5726 5727 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5728 // If test-expr is of form var relational-op b and relational-op is < or 5729 // <= then incr-expr must cause var to increase on each iteration of the 5730 // loop. If test-expr is of form var relational-op b and relational-op is 5731 // > or >= then incr-expr must cause var to decrease on each iteration of 5732 // the loop. 5733 // If test-expr is of form b relational-op var and relational-op is < or 5734 // <= then incr-expr must cause var to decrease on each iteration of the 5735 // loop. If test-expr is of form b relational-op var and relational-op is 5736 // > or >= then incr-expr must cause var to increase on each iteration of 5737 // the loop. 5738 llvm::APSInt Result; 5739 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5740 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5741 bool IsConstNeg = 5742 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5743 bool IsConstPos = 5744 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5745 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5746 5747 // != with increment is treated as <; != with decrement is treated as > 5748 if (!TestIsLessOp.hasValue()) 5749 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5750 if (UB && (IsConstZero || 5751 (TestIsLessOp.getValue() ? 5752 (IsConstNeg || (IsUnsigned && Subtract)) : 5753 (IsConstPos || (IsUnsigned && !Subtract))))) { 5754 SemaRef.Diag(NewStep->getExprLoc(), 5755 diag::err_omp_loop_incr_not_compatible) 5756 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5757 SemaRef.Diag(ConditionLoc, 5758 diag::note_omp_loop_cond_requres_compatible_incr) 5759 << TestIsLessOp.getValue() << ConditionSrcRange; 5760 return true; 5761 } 5762 if (TestIsLessOp.getValue() == Subtract) { 5763 NewStep = 5764 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5765 .get(); 5766 Subtract = !Subtract; 5767 } 5768 } 5769 5770 Step = NewStep; 5771 SubtractStep = Subtract; 5772 return false; 5773 } 5774 5775 namespace { 5776 /// Checker for the non-rectangular loops. Checks if the initializer or 5777 /// condition expression references loop counter variable. 5778 class LoopCounterRefChecker final 5779 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5780 Sema &SemaRef; 5781 DSAStackTy &Stack; 5782 const ValueDecl *CurLCDecl = nullptr; 5783 const ValueDecl *DepDecl = nullptr; 5784 const ValueDecl *PrevDepDecl = nullptr; 5785 bool IsInitializer = true; 5786 unsigned BaseLoopId = 0; 5787 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5788 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5789 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5790 << (IsInitializer ? 0 : 1); 5791 return false; 5792 } 5793 const auto &&Data = Stack.isLoopControlVariable(VD); 5794 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5795 // The type of the loop iterator on which we depend may not have a random 5796 // access iterator type. 5797 if (Data.first && VD->getType()->isRecordType()) { 5798 SmallString<128> Name; 5799 llvm::raw_svector_ostream OS(Name); 5800 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5801 /*Qualified=*/true); 5802 SemaRef.Diag(E->getExprLoc(), 5803 diag::err_omp_wrong_dependency_iterator_type) 5804 << OS.str(); 5805 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5806 return false; 5807 } 5808 if (Data.first && 5809 (DepDecl || (PrevDepDecl && 5810 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5811 if (!DepDecl && PrevDepDecl) 5812 DepDecl = PrevDepDecl; 5813 SmallString<128> Name; 5814 llvm::raw_svector_ostream OS(Name); 5815 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5816 /*Qualified=*/true); 5817 SemaRef.Diag(E->getExprLoc(), 5818 diag::err_omp_invariant_or_linear_dependency) 5819 << OS.str(); 5820 return false; 5821 } 5822 if (Data.first) { 5823 DepDecl = VD; 5824 BaseLoopId = Data.first; 5825 } 5826 return Data.first; 5827 } 5828 5829 public: 5830 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5831 const ValueDecl *VD = E->getDecl(); 5832 if (isa<VarDecl>(VD)) 5833 return checkDecl(E, VD); 5834 return false; 5835 } 5836 bool VisitMemberExpr(const MemberExpr *E) { 5837 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5838 const ValueDecl *VD = E->getMemberDecl(); 5839 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5840 return checkDecl(E, VD); 5841 } 5842 return false; 5843 } 5844 bool VisitStmt(const Stmt *S) { 5845 bool Res = false; 5846 for (const Stmt *Child : S->children()) 5847 Res = (Child && Visit(Child)) || Res; 5848 return Res; 5849 } 5850 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5851 const ValueDecl *CurLCDecl, bool IsInitializer, 5852 const ValueDecl *PrevDepDecl = nullptr) 5853 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5854 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5855 unsigned getBaseLoopId() const { 5856 assert(CurLCDecl && "Expected loop dependency."); 5857 return BaseLoopId; 5858 } 5859 const ValueDecl *getDepDecl() const { 5860 assert(CurLCDecl && "Expected loop dependency."); 5861 return DepDecl; 5862 } 5863 }; 5864 } // namespace 5865 5866 Optional<unsigned> 5867 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5868 bool IsInitializer) { 5869 // Check for the non-rectangular loops. 5870 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5871 DepDecl); 5872 if (LoopStmtChecker.Visit(S)) { 5873 DepDecl = LoopStmtChecker.getDepDecl(); 5874 return LoopStmtChecker.getBaseLoopId(); 5875 } 5876 return llvm::None; 5877 } 5878 5879 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5880 // Check init-expr for canonical loop form and save loop counter 5881 // variable - #Var and its initialization value - #LB. 5882 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5883 // var = lb 5884 // integer-type var = lb 5885 // random-access-iterator-type var = lb 5886 // pointer-type var = lb 5887 // 5888 if (!S) { 5889 if (EmitDiags) { 5890 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5891 } 5892 return true; 5893 } 5894 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5895 if (!ExprTemp->cleanupsHaveSideEffects()) 5896 S = ExprTemp->getSubExpr(); 5897 5898 InitSrcRange = S->getSourceRange(); 5899 if (Expr *E = dyn_cast<Expr>(S)) 5900 S = E->IgnoreParens(); 5901 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5902 if (BO->getOpcode() == BO_Assign) { 5903 Expr *LHS = BO->getLHS()->IgnoreParens(); 5904 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5905 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5906 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5907 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5908 EmitDiags); 5909 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5910 } 5911 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5912 if (ME->isArrow() && 5913 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5914 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5915 EmitDiags); 5916 } 5917 } 5918 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5919 if (DS->isSingleDecl()) { 5920 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5921 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5922 // Accept non-canonical init form here but emit ext. warning. 5923 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5924 SemaRef.Diag(S->getBeginLoc(), 5925 diag::ext_omp_loop_not_canonical_init) 5926 << S->getSourceRange(); 5927 return setLCDeclAndLB( 5928 Var, 5929 buildDeclRefExpr(SemaRef, Var, 5930 Var->getType().getNonReferenceType(), 5931 DS->getBeginLoc()), 5932 Var->getInit(), EmitDiags); 5933 } 5934 } 5935 } 5936 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5937 if (CE->getOperator() == OO_Equal) { 5938 Expr *LHS = CE->getArg(0); 5939 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5940 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5941 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5942 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5943 EmitDiags); 5944 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5945 } 5946 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5947 if (ME->isArrow() && 5948 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5949 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5950 EmitDiags); 5951 } 5952 } 5953 } 5954 5955 if (dependent() || SemaRef.CurContext->isDependentContext()) 5956 return false; 5957 if (EmitDiags) { 5958 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5959 << S->getSourceRange(); 5960 } 5961 return true; 5962 } 5963 5964 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5965 /// variable (which may be the loop variable) if possible. 5966 static const ValueDecl *getInitLCDecl(const Expr *E) { 5967 if (!E) 5968 return nullptr; 5969 E = getExprAsWritten(E); 5970 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5971 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5972 if ((Ctor->isCopyOrMoveConstructor() || 5973 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5974 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5975 E = CE->getArg(0)->IgnoreParenImpCasts(); 5976 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5977 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5978 return getCanonicalDecl(VD); 5979 } 5980 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5981 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5982 return getCanonicalDecl(ME->getMemberDecl()); 5983 return nullptr; 5984 } 5985 5986 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5987 // Check test-expr for canonical form, save upper-bound UB, flags for 5988 // less/greater and for strict/non-strict comparison. 5989 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5990 // var relational-op b 5991 // b relational-op var 5992 // 5993 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5994 if (!S) { 5995 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5996 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5997 return true; 5998 } 5999 Condition = S; 6000 S = getExprAsWritten(S); 6001 SourceLocation CondLoc = S->getBeginLoc(); 6002 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6003 if (BO->isRelationalOp()) { 6004 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6005 return setUB(BO->getRHS(), 6006 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6007 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6008 BO->getSourceRange(), BO->getOperatorLoc()); 6009 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6010 return setUB(BO->getLHS(), 6011 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6012 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6013 BO->getSourceRange(), BO->getOperatorLoc()); 6014 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6015 return setUB( 6016 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6017 /*LessOp=*/llvm::None, 6018 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6019 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6020 if (CE->getNumArgs() == 2) { 6021 auto Op = CE->getOperator(); 6022 switch (Op) { 6023 case OO_Greater: 6024 case OO_GreaterEqual: 6025 case OO_Less: 6026 case OO_LessEqual: 6027 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6028 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6029 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6030 CE->getOperatorLoc()); 6031 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6032 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6033 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6034 CE->getOperatorLoc()); 6035 break; 6036 case OO_ExclaimEqual: 6037 if (IneqCondIsCanonical) 6038 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6039 : CE->getArg(0), 6040 /*LessOp=*/llvm::None, 6041 /*StrictOp=*/true, CE->getSourceRange(), 6042 CE->getOperatorLoc()); 6043 break; 6044 default: 6045 break; 6046 } 6047 } 6048 } 6049 if (dependent() || SemaRef.CurContext->isDependentContext()) 6050 return false; 6051 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6052 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6053 return true; 6054 } 6055 6056 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6057 // RHS of canonical loop form increment can be: 6058 // var + incr 6059 // incr + var 6060 // var - incr 6061 // 6062 RHS = RHS->IgnoreParenImpCasts(); 6063 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6064 if (BO->isAdditiveOp()) { 6065 bool IsAdd = BO->getOpcode() == BO_Add; 6066 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6067 return setStep(BO->getRHS(), !IsAdd); 6068 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6069 return setStep(BO->getLHS(), /*Subtract=*/false); 6070 } 6071 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6072 bool IsAdd = CE->getOperator() == OO_Plus; 6073 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6074 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6075 return setStep(CE->getArg(1), !IsAdd); 6076 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6077 return setStep(CE->getArg(0), /*Subtract=*/false); 6078 } 6079 } 6080 if (dependent() || SemaRef.CurContext->isDependentContext()) 6081 return false; 6082 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6083 << RHS->getSourceRange() << LCDecl; 6084 return true; 6085 } 6086 6087 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6088 // Check incr-expr for canonical loop form and return true if it 6089 // does not conform. 6090 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6091 // ++var 6092 // var++ 6093 // --var 6094 // var-- 6095 // var += incr 6096 // var -= incr 6097 // var = var + incr 6098 // var = incr + var 6099 // var = var - incr 6100 // 6101 if (!S) { 6102 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6103 return true; 6104 } 6105 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6106 if (!ExprTemp->cleanupsHaveSideEffects()) 6107 S = ExprTemp->getSubExpr(); 6108 6109 IncrementSrcRange = S->getSourceRange(); 6110 S = S->IgnoreParens(); 6111 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6112 if (UO->isIncrementDecrementOp() && 6113 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6114 return setStep(SemaRef 6115 .ActOnIntegerConstant(UO->getBeginLoc(), 6116 (UO->isDecrementOp() ? -1 : 1)) 6117 .get(), 6118 /*Subtract=*/false); 6119 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6120 switch (BO->getOpcode()) { 6121 case BO_AddAssign: 6122 case BO_SubAssign: 6123 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6124 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6125 break; 6126 case BO_Assign: 6127 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6128 return checkAndSetIncRHS(BO->getRHS()); 6129 break; 6130 default: 6131 break; 6132 } 6133 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6134 switch (CE->getOperator()) { 6135 case OO_PlusPlus: 6136 case OO_MinusMinus: 6137 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6138 return setStep(SemaRef 6139 .ActOnIntegerConstant( 6140 CE->getBeginLoc(), 6141 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6142 .get(), 6143 /*Subtract=*/false); 6144 break; 6145 case OO_PlusEqual: 6146 case OO_MinusEqual: 6147 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6148 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6149 break; 6150 case OO_Equal: 6151 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6152 return checkAndSetIncRHS(CE->getArg(1)); 6153 break; 6154 default: 6155 break; 6156 } 6157 } 6158 if (dependent() || SemaRef.CurContext->isDependentContext()) 6159 return false; 6160 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6161 << S->getSourceRange() << LCDecl; 6162 return true; 6163 } 6164 6165 static ExprResult 6166 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6167 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6168 if (SemaRef.CurContext->isDependentContext()) 6169 return ExprResult(Capture); 6170 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6171 return SemaRef.PerformImplicitConversion( 6172 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6173 /*AllowExplicit=*/true); 6174 auto I = Captures.find(Capture); 6175 if (I != Captures.end()) 6176 return buildCapture(SemaRef, Capture, I->second); 6177 DeclRefExpr *Ref = nullptr; 6178 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6179 Captures[Capture] = Ref; 6180 return Res; 6181 } 6182 6183 /// Build the expression to calculate the number of iterations. 6184 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6185 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6186 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6187 ExprResult Diff; 6188 QualType VarType = LCDecl->getType().getNonReferenceType(); 6189 if (VarType->isIntegerType() || VarType->isPointerType() || 6190 SemaRef.getLangOpts().CPlusPlus) { 6191 Expr *LBVal = LB; 6192 Expr *UBVal = UB; 6193 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6194 // max(LB(MinVal), LB(MaxVal)) 6195 if (InitDependOnLC) { 6196 const LoopIterationSpace &IS = 6197 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6198 InitDependOnLC.getValueOr( 6199 CondDependOnLC.getValueOr(0))]; 6200 if (!IS.MinValue || !IS.MaxValue) 6201 return nullptr; 6202 // OuterVar = Min 6203 ExprResult MinValue = 6204 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6205 if (!MinValue.isUsable()) 6206 return nullptr; 6207 6208 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6209 IS.CounterVar, MinValue.get()); 6210 if (!LBMinVal.isUsable()) 6211 return nullptr; 6212 // OuterVar = Min, LBVal 6213 LBMinVal = 6214 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6215 if (!LBMinVal.isUsable()) 6216 return nullptr; 6217 // (OuterVar = Min, LBVal) 6218 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6219 if (!LBMinVal.isUsable()) 6220 return nullptr; 6221 6222 // OuterVar = Max 6223 ExprResult MaxValue = 6224 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6225 if (!MaxValue.isUsable()) 6226 return nullptr; 6227 6228 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6229 IS.CounterVar, MaxValue.get()); 6230 if (!LBMaxVal.isUsable()) 6231 return nullptr; 6232 // OuterVar = Max, LBVal 6233 LBMaxVal = 6234 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6235 if (!LBMaxVal.isUsable()) 6236 return nullptr; 6237 // (OuterVar = Max, LBVal) 6238 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6239 if (!LBMaxVal.isUsable()) 6240 return nullptr; 6241 6242 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6243 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6244 if (!LBMin || !LBMax) 6245 return nullptr; 6246 // LB(MinVal) < LB(MaxVal) 6247 ExprResult MinLessMaxRes = 6248 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6249 if (!MinLessMaxRes.isUsable()) 6250 return nullptr; 6251 Expr *MinLessMax = 6252 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6253 if (!MinLessMax) 6254 return nullptr; 6255 if (TestIsLessOp.getValue()) { 6256 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6257 // LB(MaxVal)) 6258 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6259 MinLessMax, LBMin, LBMax); 6260 if (!MinLB.isUsable()) 6261 return nullptr; 6262 LBVal = MinLB.get(); 6263 } else { 6264 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6265 // LB(MaxVal)) 6266 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6267 MinLessMax, LBMax, LBMin); 6268 if (!MaxLB.isUsable()) 6269 return nullptr; 6270 LBVal = MaxLB.get(); 6271 } 6272 } 6273 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6274 // min(UB(MinVal), UB(MaxVal)) 6275 if (CondDependOnLC) { 6276 const LoopIterationSpace &IS = 6277 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6278 InitDependOnLC.getValueOr( 6279 CondDependOnLC.getValueOr(0))]; 6280 if (!IS.MinValue || !IS.MaxValue) 6281 return nullptr; 6282 // OuterVar = Min 6283 ExprResult MinValue = 6284 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6285 if (!MinValue.isUsable()) 6286 return nullptr; 6287 6288 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6289 IS.CounterVar, MinValue.get()); 6290 if (!UBMinVal.isUsable()) 6291 return nullptr; 6292 // OuterVar = Min, UBVal 6293 UBMinVal = 6294 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6295 if (!UBMinVal.isUsable()) 6296 return nullptr; 6297 // (OuterVar = Min, UBVal) 6298 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6299 if (!UBMinVal.isUsable()) 6300 return nullptr; 6301 6302 // OuterVar = Max 6303 ExprResult MaxValue = 6304 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6305 if (!MaxValue.isUsable()) 6306 return nullptr; 6307 6308 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6309 IS.CounterVar, MaxValue.get()); 6310 if (!UBMaxVal.isUsable()) 6311 return nullptr; 6312 // OuterVar = Max, UBVal 6313 UBMaxVal = 6314 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6315 if (!UBMaxVal.isUsable()) 6316 return nullptr; 6317 // (OuterVar = Max, UBVal) 6318 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6319 if (!UBMaxVal.isUsable()) 6320 return nullptr; 6321 6322 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6323 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6324 if (!UBMin || !UBMax) 6325 return nullptr; 6326 // UB(MinVal) > UB(MaxVal) 6327 ExprResult MinGreaterMaxRes = 6328 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6329 if (!MinGreaterMaxRes.isUsable()) 6330 return nullptr; 6331 Expr *MinGreaterMax = 6332 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6333 if (!MinGreaterMax) 6334 return nullptr; 6335 if (TestIsLessOp.getValue()) { 6336 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6337 // UB(MaxVal)) 6338 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6339 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6340 if (!MaxUB.isUsable()) 6341 return nullptr; 6342 UBVal = MaxUB.get(); 6343 } else { 6344 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6345 // UB(MaxVal)) 6346 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6347 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6348 if (!MinUB.isUsable()) 6349 return nullptr; 6350 UBVal = MinUB.get(); 6351 } 6352 } 6353 // Upper - Lower 6354 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6355 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6356 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6357 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6358 if (!Upper || !Lower) 6359 return nullptr; 6360 6361 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6362 6363 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6364 // BuildBinOp already emitted error, this one is to point user to upper 6365 // and lower bound, and to tell what is passed to 'operator-'. 6366 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6367 << Upper->getSourceRange() << Lower->getSourceRange(); 6368 return nullptr; 6369 } 6370 } 6371 6372 if (!Diff.isUsable()) 6373 return nullptr; 6374 6375 // Upper - Lower [- 1] 6376 if (TestIsStrictOp) 6377 Diff = SemaRef.BuildBinOp( 6378 S, DefaultLoc, BO_Sub, Diff.get(), 6379 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6380 if (!Diff.isUsable()) 6381 return nullptr; 6382 6383 // Upper - Lower [- 1] + Step 6384 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6385 if (!NewStep.isUsable()) 6386 return nullptr; 6387 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6388 if (!Diff.isUsable()) 6389 return nullptr; 6390 6391 // Parentheses (for dumping/debugging purposes only). 6392 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6393 if (!Diff.isUsable()) 6394 return nullptr; 6395 6396 // (Upper - Lower [- 1] + Step) / Step 6397 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6398 if (!Diff.isUsable()) 6399 return nullptr; 6400 6401 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6402 QualType Type = Diff.get()->getType(); 6403 ASTContext &C = SemaRef.Context; 6404 bool UseVarType = VarType->hasIntegerRepresentation() && 6405 C.getTypeSize(Type) > C.getTypeSize(VarType); 6406 if (!Type->isIntegerType() || UseVarType) { 6407 unsigned NewSize = 6408 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6409 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6410 : Type->hasSignedIntegerRepresentation(); 6411 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6412 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6413 Diff = SemaRef.PerformImplicitConversion( 6414 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6415 if (!Diff.isUsable()) 6416 return nullptr; 6417 } 6418 } 6419 if (LimitedType) { 6420 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6421 if (NewSize != C.getTypeSize(Type)) { 6422 if (NewSize < C.getTypeSize(Type)) { 6423 assert(NewSize == 64 && "incorrect loop var size"); 6424 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6425 << InitSrcRange << ConditionSrcRange; 6426 } 6427 QualType NewType = C.getIntTypeForBitwidth( 6428 NewSize, Type->hasSignedIntegerRepresentation() || 6429 C.getTypeSize(Type) < NewSize); 6430 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6431 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6432 Sema::AA_Converting, true); 6433 if (!Diff.isUsable()) 6434 return nullptr; 6435 } 6436 } 6437 } 6438 6439 return Diff.get(); 6440 } 6441 6442 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6443 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6444 // Do not build for iterators, they cannot be used in non-rectangular loop 6445 // nests. 6446 if (LCDecl->getType()->isRecordType()) 6447 return std::make_pair(nullptr, nullptr); 6448 // If we subtract, the min is in the condition, otherwise the min is in the 6449 // init value. 6450 Expr *MinExpr = nullptr; 6451 Expr *MaxExpr = nullptr; 6452 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6453 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6454 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6455 : CondDependOnLC.hasValue(); 6456 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6457 : InitDependOnLC.hasValue(); 6458 Expr *Lower = 6459 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6460 Expr *Upper = 6461 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6462 if (!Upper || !Lower) 6463 return std::make_pair(nullptr, nullptr); 6464 6465 if (TestIsLessOp.getValue()) 6466 MinExpr = Lower; 6467 else 6468 MaxExpr = Upper; 6469 6470 // Build minimum/maximum value based on number of iterations. 6471 ExprResult Diff; 6472 QualType VarType = LCDecl->getType().getNonReferenceType(); 6473 6474 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6475 if (!Diff.isUsable()) 6476 return std::make_pair(nullptr, nullptr); 6477 6478 // Upper - Lower [- 1] 6479 if (TestIsStrictOp) 6480 Diff = SemaRef.BuildBinOp( 6481 S, DefaultLoc, BO_Sub, Diff.get(), 6482 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6483 if (!Diff.isUsable()) 6484 return std::make_pair(nullptr, nullptr); 6485 6486 // Upper - Lower [- 1] + Step 6487 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6488 if (!NewStep.isUsable()) 6489 return std::make_pair(nullptr, nullptr); 6490 6491 // Parentheses (for dumping/debugging purposes only). 6492 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6493 if (!Diff.isUsable()) 6494 return std::make_pair(nullptr, nullptr); 6495 6496 // (Upper - Lower [- 1]) / Step 6497 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6498 if (!Diff.isUsable()) 6499 return std::make_pair(nullptr, nullptr); 6500 6501 // ((Upper - Lower [- 1]) / Step) * Step 6502 // Parentheses (for dumping/debugging purposes only). 6503 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6504 if (!Diff.isUsable()) 6505 return std::make_pair(nullptr, nullptr); 6506 6507 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6508 if (!Diff.isUsable()) 6509 return std::make_pair(nullptr, nullptr); 6510 6511 // Convert to the original type or ptrdiff_t, if original type is pointer. 6512 if (!VarType->isAnyPointerType() && 6513 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6514 Diff = SemaRef.PerformImplicitConversion( 6515 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6516 } else if (VarType->isAnyPointerType() && 6517 !SemaRef.Context.hasSameType( 6518 Diff.get()->getType(), 6519 SemaRef.Context.getUnsignedPointerDiffType())) { 6520 Diff = SemaRef.PerformImplicitConversion( 6521 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6522 Sema::AA_Converting, /*AllowExplicit=*/true); 6523 } 6524 if (!Diff.isUsable()) 6525 return std::make_pair(nullptr, nullptr); 6526 6527 // Parentheses (for dumping/debugging purposes only). 6528 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6529 if (!Diff.isUsable()) 6530 return std::make_pair(nullptr, nullptr); 6531 6532 if (TestIsLessOp.getValue()) { 6533 // MinExpr = Lower; 6534 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6535 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6536 if (!Diff.isUsable()) 6537 return std::make_pair(nullptr, nullptr); 6538 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6539 if (!Diff.isUsable()) 6540 return std::make_pair(nullptr, nullptr); 6541 MaxExpr = Diff.get(); 6542 } else { 6543 // MaxExpr = Upper; 6544 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6545 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6546 if (!Diff.isUsable()) 6547 return std::make_pair(nullptr, nullptr); 6548 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6549 if (!Diff.isUsable()) 6550 return std::make_pair(nullptr, nullptr); 6551 MinExpr = Diff.get(); 6552 } 6553 6554 return std::make_pair(MinExpr, MaxExpr); 6555 } 6556 6557 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6558 if (InitDependOnLC || CondDependOnLC) 6559 return Condition; 6560 return nullptr; 6561 } 6562 6563 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6564 Scope *S, Expr *Cond, 6565 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6566 // Do not build a precondition when the condition/initialization is dependent 6567 // to prevent pessimistic early loop exit. 6568 // TODO: this can be improved by calculating min/max values but not sure that 6569 // it will be very effective. 6570 if (CondDependOnLC || InitDependOnLC) 6571 return SemaRef.PerformImplicitConversion( 6572 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6573 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6574 /*AllowExplicit=*/true).get(); 6575 6576 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6577 Sema::TentativeAnalysisScope Trap(SemaRef); 6578 6579 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6580 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6581 if (!NewLB.isUsable() || !NewUB.isUsable()) 6582 return nullptr; 6583 6584 ExprResult CondExpr = 6585 SemaRef.BuildBinOp(S, DefaultLoc, 6586 TestIsLessOp.getValue() ? 6587 (TestIsStrictOp ? BO_LT : BO_LE) : 6588 (TestIsStrictOp ? BO_GT : BO_GE), 6589 NewLB.get(), NewUB.get()); 6590 if (CondExpr.isUsable()) { 6591 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6592 SemaRef.Context.BoolTy)) 6593 CondExpr = SemaRef.PerformImplicitConversion( 6594 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6595 /*AllowExplicit=*/true); 6596 } 6597 6598 // Otherwise use original loop condition and evaluate it in runtime. 6599 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6600 } 6601 6602 /// Build reference expression to the counter be used for codegen. 6603 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6604 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6605 DSAStackTy &DSA) const { 6606 auto *VD = dyn_cast<VarDecl>(LCDecl); 6607 if (!VD) { 6608 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6609 DeclRefExpr *Ref = buildDeclRefExpr( 6610 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6611 const DSAStackTy::DSAVarData Data = 6612 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6613 // If the loop control decl is explicitly marked as private, do not mark it 6614 // as captured again. 6615 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6616 Captures.insert(std::make_pair(LCRef, Ref)); 6617 return Ref; 6618 } 6619 return cast<DeclRefExpr>(LCRef); 6620 } 6621 6622 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6623 if (LCDecl && !LCDecl->isInvalidDecl()) { 6624 QualType Type = LCDecl->getType().getNonReferenceType(); 6625 VarDecl *PrivateVar = buildVarDecl( 6626 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6627 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6628 isa<VarDecl>(LCDecl) 6629 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6630 : nullptr); 6631 if (PrivateVar->isInvalidDecl()) 6632 return nullptr; 6633 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6634 } 6635 return nullptr; 6636 } 6637 6638 /// Build initialization of the counter to be used for codegen. 6639 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6640 6641 /// Build step of the counter be used for codegen. 6642 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6643 6644 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6645 Scope *S, Expr *Counter, 6646 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6647 Expr *Inc, OverloadedOperatorKind OOK) { 6648 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6649 if (!Cnt) 6650 return nullptr; 6651 if (Inc) { 6652 assert((OOK == OO_Plus || OOK == OO_Minus) && 6653 "Expected only + or - operations for depend clauses."); 6654 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6655 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6656 if (!Cnt) 6657 return nullptr; 6658 } 6659 ExprResult Diff; 6660 QualType VarType = LCDecl->getType().getNonReferenceType(); 6661 if (VarType->isIntegerType() || VarType->isPointerType() || 6662 SemaRef.getLangOpts().CPlusPlus) { 6663 // Upper - Lower 6664 Expr *Upper = TestIsLessOp.getValue() 6665 ? Cnt 6666 : tryBuildCapture(SemaRef, UB, Captures).get(); 6667 Expr *Lower = TestIsLessOp.getValue() 6668 ? tryBuildCapture(SemaRef, LB, Captures).get() 6669 : Cnt; 6670 if (!Upper || !Lower) 6671 return nullptr; 6672 6673 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6674 6675 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6676 // BuildBinOp already emitted error, this one is to point user to upper 6677 // and lower bound, and to tell what is passed to 'operator-'. 6678 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6679 << Upper->getSourceRange() << Lower->getSourceRange(); 6680 return nullptr; 6681 } 6682 } 6683 6684 if (!Diff.isUsable()) 6685 return nullptr; 6686 6687 // Parentheses (for dumping/debugging purposes only). 6688 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6689 if (!Diff.isUsable()) 6690 return nullptr; 6691 6692 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6693 if (!NewStep.isUsable()) 6694 return nullptr; 6695 // (Upper - Lower) / Step 6696 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6697 if (!Diff.isUsable()) 6698 return nullptr; 6699 6700 return Diff.get(); 6701 } 6702 } // namespace 6703 6704 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6705 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6706 assert(Init && "Expected loop in canonical form."); 6707 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6708 if (AssociatedLoops > 0 && 6709 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6710 DSAStack->loopStart(); 6711 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6712 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6713 if (ValueDecl *D = ISC.getLoopDecl()) { 6714 auto *VD = dyn_cast<VarDecl>(D); 6715 DeclRefExpr *PrivateRef = nullptr; 6716 if (!VD) { 6717 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6718 VD = Private; 6719 } else { 6720 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6721 /*WithInit=*/false); 6722 VD = cast<VarDecl>(PrivateRef->getDecl()); 6723 } 6724 } 6725 DSAStack->addLoopControlVariable(D, VD); 6726 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6727 if (LD != D->getCanonicalDecl()) { 6728 DSAStack->resetPossibleLoopCounter(); 6729 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6730 MarkDeclarationsReferencedInExpr( 6731 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6732 Var->getType().getNonLValueExprType(Context), 6733 ForLoc, /*RefersToCapture=*/true)); 6734 } 6735 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6736 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6737 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6738 // associated for-loop of a simd construct with just one associated 6739 // for-loop may be listed in a linear clause with a constant-linear-step 6740 // that is the increment of the associated for-loop. The loop iteration 6741 // variable(s) in the associated for-loop(s) of a for or parallel for 6742 // construct may be listed in a private or lastprivate clause. 6743 DSAStackTy::DSAVarData DVar = 6744 DSAStack->getTopDSA(D, /*FromParent=*/false); 6745 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6746 // is declared in the loop and it is predetermined as a private. 6747 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6748 OpenMPClauseKind PredeterminedCKind = 6749 isOpenMPSimdDirective(DKind) 6750 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6751 : OMPC_private; 6752 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6753 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6754 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6755 DVar.CKind != OMPC_private))) || 6756 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6757 DKind == OMPD_master_taskloop || 6758 DKind == OMPD_parallel_master_taskloop || 6759 isOpenMPDistributeDirective(DKind)) && 6760 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6761 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6762 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6763 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6764 << getOpenMPClauseName(DVar.CKind) 6765 << getOpenMPDirectiveName(DKind) 6766 << getOpenMPClauseName(PredeterminedCKind); 6767 if (DVar.RefExpr == nullptr) 6768 DVar.CKind = PredeterminedCKind; 6769 reportOriginalDsa(*this, DSAStack, D, DVar, 6770 /*IsLoopIterVar=*/true); 6771 } else if (LoopDeclRefExpr) { 6772 // Make the loop iteration variable private (for worksharing 6773 // constructs), linear (for simd directives with the only one 6774 // associated loop) or lastprivate (for simd directives with several 6775 // collapsed or ordered loops). 6776 if (DVar.CKind == OMPC_unknown) 6777 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6778 PrivateRef); 6779 } 6780 } 6781 } 6782 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6783 } 6784 } 6785 6786 /// Called on a for stmt to check and extract its iteration space 6787 /// for further processing (such as collapsing). 6788 static bool checkOpenMPIterationSpace( 6789 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6790 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6791 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6792 Expr *OrderedLoopCountExpr, 6793 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6794 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6795 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6796 // OpenMP [2.9.1, Canonical Loop Form] 6797 // for (init-expr; test-expr; incr-expr) structured-block 6798 // for (range-decl: range-expr) structured-block 6799 auto *For = dyn_cast_or_null<ForStmt>(S); 6800 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6801 // Ranged for is supported only in OpenMP 5.0. 6802 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6803 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6804 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6805 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6806 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6807 if (TotalNestedLoopCount > 1) { 6808 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6809 SemaRef.Diag(DSA.getConstructLoc(), 6810 diag::note_omp_collapse_ordered_expr) 6811 << 2 << CollapseLoopCountExpr->getSourceRange() 6812 << OrderedLoopCountExpr->getSourceRange(); 6813 else if (CollapseLoopCountExpr) 6814 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6815 diag::note_omp_collapse_ordered_expr) 6816 << 0 << CollapseLoopCountExpr->getSourceRange(); 6817 else 6818 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6819 diag::note_omp_collapse_ordered_expr) 6820 << 1 << OrderedLoopCountExpr->getSourceRange(); 6821 } 6822 return true; 6823 } 6824 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6825 "No loop body."); 6826 6827 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6828 For ? For->getForLoc() : CXXFor->getForLoc()); 6829 6830 // Check init. 6831 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6832 if (ISC.checkAndSetInit(Init)) 6833 return true; 6834 6835 bool HasErrors = false; 6836 6837 // Check loop variable's type. 6838 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6839 // OpenMP [2.6, Canonical Loop Form] 6840 // Var is one of the following: 6841 // A variable of signed or unsigned integer type. 6842 // For C++, a variable of a random access iterator type. 6843 // For C, a variable of a pointer type. 6844 QualType VarType = LCDecl->getType().getNonReferenceType(); 6845 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6846 !VarType->isPointerType() && 6847 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6848 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6849 << SemaRef.getLangOpts().CPlusPlus; 6850 HasErrors = true; 6851 } 6852 6853 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6854 // a Construct 6855 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6856 // parallel for construct is (are) private. 6857 // The loop iteration variable in the associated for-loop of a simd 6858 // construct with just one associated for-loop is linear with a 6859 // constant-linear-step that is the increment of the associated for-loop. 6860 // Exclude loop var from the list of variables with implicitly defined data 6861 // sharing attributes. 6862 VarsWithImplicitDSA.erase(LCDecl); 6863 6864 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6865 6866 // Check test-expr. 6867 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6868 6869 // Check incr-expr. 6870 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6871 } 6872 6873 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6874 return HasErrors; 6875 6876 // Build the loop's iteration space representation. 6877 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6878 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6879 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6880 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6881 (isOpenMPWorksharingDirective(DKind) || 6882 isOpenMPTaskLoopDirective(DKind) || 6883 isOpenMPDistributeDirective(DKind)), 6884 Captures); 6885 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6886 ISC.buildCounterVar(Captures, DSA); 6887 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6888 ISC.buildPrivateCounterVar(); 6889 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6890 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6891 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6892 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6893 ISC.getConditionSrcRange(); 6894 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6895 ISC.getIncrementSrcRange(); 6896 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6897 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6898 ISC.isStrictTestOp(); 6899 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6900 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6901 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6902 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6903 ISC.buildFinalCondition(DSA.getCurScope()); 6904 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6905 ISC.doesInitDependOnLC(); 6906 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6907 ISC.doesCondDependOnLC(); 6908 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6909 ISC.getLoopDependentIdx(); 6910 6911 HasErrors |= 6912 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6913 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6914 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6915 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6916 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6917 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6918 if (!HasErrors && DSA.isOrderedRegion()) { 6919 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6920 if (CurrentNestedLoopCount < 6921 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6922 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6923 CurrentNestedLoopCount, 6924 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6925 DSA.getOrderedRegionParam().second->setLoopCounter( 6926 CurrentNestedLoopCount, 6927 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6928 } 6929 } 6930 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6931 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6932 // Erroneous case - clause has some problems. 6933 continue; 6934 } 6935 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6936 Pair.second.size() <= CurrentNestedLoopCount) { 6937 // Erroneous case - clause has some problems. 6938 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6939 continue; 6940 } 6941 Expr *CntValue; 6942 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6943 CntValue = ISC.buildOrderedLoopData( 6944 DSA.getCurScope(), 6945 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6946 Pair.first->getDependencyLoc()); 6947 else 6948 CntValue = ISC.buildOrderedLoopData( 6949 DSA.getCurScope(), 6950 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6951 Pair.first->getDependencyLoc(), 6952 Pair.second[CurrentNestedLoopCount].first, 6953 Pair.second[CurrentNestedLoopCount].second); 6954 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6955 } 6956 } 6957 6958 return HasErrors; 6959 } 6960 6961 /// Build 'VarRef = Start. 6962 static ExprResult 6963 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6964 ExprResult Start, bool IsNonRectangularLB, 6965 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6966 // Build 'VarRef = Start. 6967 ExprResult NewStart = IsNonRectangularLB 6968 ? Start.get() 6969 : tryBuildCapture(SemaRef, Start.get(), Captures); 6970 if (!NewStart.isUsable()) 6971 return ExprError(); 6972 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6973 VarRef.get()->getType())) { 6974 NewStart = SemaRef.PerformImplicitConversion( 6975 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6976 /*AllowExplicit=*/true); 6977 if (!NewStart.isUsable()) 6978 return ExprError(); 6979 } 6980 6981 ExprResult Init = 6982 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6983 return Init; 6984 } 6985 6986 /// Build 'VarRef = Start + Iter * Step'. 6987 static ExprResult buildCounterUpdate( 6988 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6989 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6990 bool IsNonRectangularLB, 6991 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6992 // Add parentheses (for debugging purposes only). 6993 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6994 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6995 !Step.isUsable()) 6996 return ExprError(); 6997 6998 ExprResult NewStep = Step; 6999 if (Captures) 7000 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7001 if (NewStep.isInvalid()) 7002 return ExprError(); 7003 ExprResult Update = 7004 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7005 if (!Update.isUsable()) 7006 return ExprError(); 7007 7008 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7009 // 'VarRef = Start (+|-) Iter * Step'. 7010 if (!Start.isUsable()) 7011 return ExprError(); 7012 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7013 if (!NewStart.isUsable()) 7014 return ExprError(); 7015 if (Captures && !IsNonRectangularLB) 7016 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7017 if (NewStart.isInvalid()) 7018 return ExprError(); 7019 7020 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7021 ExprResult SavedUpdate = Update; 7022 ExprResult UpdateVal; 7023 if (VarRef.get()->getType()->isOverloadableType() || 7024 NewStart.get()->getType()->isOverloadableType() || 7025 Update.get()->getType()->isOverloadableType()) { 7026 Sema::TentativeAnalysisScope Trap(SemaRef); 7027 7028 Update = 7029 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7030 if (Update.isUsable()) { 7031 UpdateVal = 7032 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7033 VarRef.get(), SavedUpdate.get()); 7034 if (UpdateVal.isUsable()) { 7035 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7036 UpdateVal.get()); 7037 } 7038 } 7039 } 7040 7041 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7042 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7043 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7044 NewStart.get(), SavedUpdate.get()); 7045 if (!Update.isUsable()) 7046 return ExprError(); 7047 7048 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7049 VarRef.get()->getType())) { 7050 Update = SemaRef.PerformImplicitConversion( 7051 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7052 if (!Update.isUsable()) 7053 return ExprError(); 7054 } 7055 7056 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7057 } 7058 return Update; 7059 } 7060 7061 /// Convert integer expression \a E to make it have at least \a Bits 7062 /// bits. 7063 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7064 if (E == nullptr) 7065 return ExprError(); 7066 ASTContext &C = SemaRef.Context; 7067 QualType OldType = E->getType(); 7068 unsigned HasBits = C.getTypeSize(OldType); 7069 if (HasBits >= Bits) 7070 return ExprResult(E); 7071 // OK to convert to signed, because new type has more bits than old. 7072 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7073 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7074 true); 7075 } 7076 7077 /// Check if the given expression \a E is a constant integer that fits 7078 /// into \a Bits bits. 7079 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7080 if (E == nullptr) 7081 return false; 7082 llvm::APSInt Result; 7083 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7084 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7085 return false; 7086 } 7087 7088 /// Build preinits statement for the given declarations. 7089 static Stmt *buildPreInits(ASTContext &Context, 7090 MutableArrayRef<Decl *> PreInits) { 7091 if (!PreInits.empty()) { 7092 return new (Context) DeclStmt( 7093 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7094 SourceLocation(), SourceLocation()); 7095 } 7096 return nullptr; 7097 } 7098 7099 /// Build preinits statement for the given declarations. 7100 static Stmt * 7101 buildPreInits(ASTContext &Context, 7102 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7103 if (!Captures.empty()) { 7104 SmallVector<Decl *, 16> PreInits; 7105 for (const auto &Pair : Captures) 7106 PreInits.push_back(Pair.second->getDecl()); 7107 return buildPreInits(Context, PreInits); 7108 } 7109 return nullptr; 7110 } 7111 7112 /// Build postupdate expression for the given list of postupdates expressions. 7113 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7114 Expr *PostUpdate = nullptr; 7115 if (!PostUpdates.empty()) { 7116 for (Expr *E : PostUpdates) { 7117 Expr *ConvE = S.BuildCStyleCastExpr( 7118 E->getExprLoc(), 7119 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7120 E->getExprLoc(), E) 7121 .get(); 7122 PostUpdate = PostUpdate 7123 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7124 PostUpdate, ConvE) 7125 .get() 7126 : ConvE; 7127 } 7128 } 7129 return PostUpdate; 7130 } 7131 7132 /// Called on a for stmt to check itself and nested loops (if any). 7133 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7134 /// number of collapsed loops otherwise. 7135 static unsigned 7136 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7137 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7138 DSAStackTy &DSA, 7139 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7140 OMPLoopDirective::HelperExprs &Built) { 7141 unsigned NestedLoopCount = 1; 7142 if (CollapseLoopCountExpr) { 7143 // Found 'collapse' clause - calculate collapse number. 7144 Expr::EvalResult Result; 7145 if (!CollapseLoopCountExpr->isValueDependent() && 7146 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7147 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7148 } else { 7149 Built.clear(/*Size=*/1); 7150 return 1; 7151 } 7152 } 7153 unsigned OrderedLoopCount = 1; 7154 if (OrderedLoopCountExpr) { 7155 // Found 'ordered' clause - calculate collapse number. 7156 Expr::EvalResult EVResult; 7157 if (!OrderedLoopCountExpr->isValueDependent() && 7158 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7159 SemaRef.getASTContext())) { 7160 llvm::APSInt Result = EVResult.Val.getInt(); 7161 if (Result.getLimitedValue() < NestedLoopCount) { 7162 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7163 diag::err_omp_wrong_ordered_loop_count) 7164 << OrderedLoopCountExpr->getSourceRange(); 7165 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7166 diag::note_collapse_loop_count) 7167 << CollapseLoopCountExpr->getSourceRange(); 7168 } 7169 OrderedLoopCount = Result.getLimitedValue(); 7170 } else { 7171 Built.clear(/*Size=*/1); 7172 return 1; 7173 } 7174 } 7175 // This is helper routine for loop directives (e.g., 'for', 'simd', 7176 // 'for simd', etc.). 7177 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7178 SmallVector<LoopIterationSpace, 4> IterSpaces( 7179 std::max(OrderedLoopCount, NestedLoopCount)); 7180 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7181 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7182 if (checkOpenMPIterationSpace( 7183 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7184 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7185 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7186 return 0; 7187 // Move on to the next nested for loop, or to the loop body. 7188 // OpenMP [2.8.1, simd construct, Restrictions] 7189 // All loops associated with the construct must be perfectly nested; that 7190 // is, there must be no intervening code nor any OpenMP directive between 7191 // any two loops. 7192 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7193 CurStmt = For->getBody(); 7194 } else { 7195 assert(isa<CXXForRangeStmt>(CurStmt) && 7196 "Expected canonical for or range-based for loops."); 7197 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7198 } 7199 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7200 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7201 } 7202 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7203 if (checkOpenMPIterationSpace( 7204 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7205 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7206 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7207 return 0; 7208 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7209 // Handle initialization of captured loop iterator variables. 7210 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7211 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7212 Captures[DRE] = DRE; 7213 } 7214 } 7215 // Move on to the next nested for loop, or to the loop body. 7216 // OpenMP [2.8.1, simd construct, Restrictions] 7217 // All loops associated with the construct must be perfectly nested; that 7218 // is, there must be no intervening code nor any OpenMP directive between 7219 // any two loops. 7220 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7221 CurStmt = For->getBody(); 7222 } else { 7223 assert(isa<CXXForRangeStmt>(CurStmt) && 7224 "Expected canonical for or range-based for loops."); 7225 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7226 } 7227 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7228 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7229 } 7230 7231 Built.clear(/* size */ NestedLoopCount); 7232 7233 if (SemaRef.CurContext->isDependentContext()) 7234 return NestedLoopCount; 7235 7236 // An example of what is generated for the following code: 7237 // 7238 // #pragma omp simd collapse(2) ordered(2) 7239 // for (i = 0; i < NI; ++i) 7240 // for (k = 0; k < NK; ++k) 7241 // for (j = J0; j < NJ; j+=2) { 7242 // <loop body> 7243 // } 7244 // 7245 // We generate the code below. 7246 // Note: the loop body may be outlined in CodeGen. 7247 // Note: some counters may be C++ classes, operator- is used to find number of 7248 // iterations and operator+= to calculate counter value. 7249 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7250 // or i64 is currently supported). 7251 // 7252 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7253 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7254 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7255 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7256 // // similar updates for vars in clauses (e.g. 'linear') 7257 // <loop body (using local i and j)> 7258 // } 7259 // i = NI; // assign final values of counters 7260 // j = NJ; 7261 // 7262 7263 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7264 // the iteration counts of the collapsed for loops. 7265 // Precondition tests if there is at least one iteration (all conditions are 7266 // true). 7267 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7268 Expr *N0 = IterSpaces[0].NumIterations; 7269 ExprResult LastIteration32 = 7270 widenIterationCount(/*Bits=*/32, 7271 SemaRef 7272 .PerformImplicitConversion( 7273 N0->IgnoreImpCasts(), N0->getType(), 7274 Sema::AA_Converting, /*AllowExplicit=*/true) 7275 .get(), 7276 SemaRef); 7277 ExprResult LastIteration64 = widenIterationCount( 7278 /*Bits=*/64, 7279 SemaRef 7280 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7281 Sema::AA_Converting, 7282 /*AllowExplicit=*/true) 7283 .get(), 7284 SemaRef); 7285 7286 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7287 return NestedLoopCount; 7288 7289 ASTContext &C = SemaRef.Context; 7290 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7291 7292 Scope *CurScope = DSA.getCurScope(); 7293 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7294 if (PreCond.isUsable()) { 7295 PreCond = 7296 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7297 PreCond.get(), IterSpaces[Cnt].PreCond); 7298 } 7299 Expr *N = IterSpaces[Cnt].NumIterations; 7300 SourceLocation Loc = N->getExprLoc(); 7301 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7302 if (LastIteration32.isUsable()) 7303 LastIteration32 = SemaRef.BuildBinOp( 7304 CurScope, Loc, BO_Mul, LastIteration32.get(), 7305 SemaRef 7306 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7307 Sema::AA_Converting, 7308 /*AllowExplicit=*/true) 7309 .get()); 7310 if (LastIteration64.isUsable()) 7311 LastIteration64 = SemaRef.BuildBinOp( 7312 CurScope, Loc, BO_Mul, LastIteration64.get(), 7313 SemaRef 7314 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7315 Sema::AA_Converting, 7316 /*AllowExplicit=*/true) 7317 .get()); 7318 } 7319 7320 // Choose either the 32-bit or 64-bit version. 7321 ExprResult LastIteration = LastIteration64; 7322 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7323 (LastIteration32.isUsable() && 7324 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7325 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7326 fitsInto( 7327 /*Bits=*/32, 7328 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7329 LastIteration64.get(), SemaRef)))) 7330 LastIteration = LastIteration32; 7331 QualType VType = LastIteration.get()->getType(); 7332 QualType RealVType = VType; 7333 QualType StrideVType = VType; 7334 if (isOpenMPTaskLoopDirective(DKind)) { 7335 VType = 7336 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7337 StrideVType = 7338 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7339 } 7340 7341 if (!LastIteration.isUsable()) 7342 return 0; 7343 7344 // Save the number of iterations. 7345 ExprResult NumIterations = LastIteration; 7346 { 7347 LastIteration = SemaRef.BuildBinOp( 7348 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7349 LastIteration.get(), 7350 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7351 if (!LastIteration.isUsable()) 7352 return 0; 7353 } 7354 7355 // Calculate the last iteration number beforehand instead of doing this on 7356 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7357 llvm::APSInt Result; 7358 bool IsConstant = 7359 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7360 ExprResult CalcLastIteration; 7361 if (!IsConstant) { 7362 ExprResult SaveRef = 7363 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7364 LastIteration = SaveRef; 7365 7366 // Prepare SaveRef + 1. 7367 NumIterations = SemaRef.BuildBinOp( 7368 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7369 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7370 if (!NumIterations.isUsable()) 7371 return 0; 7372 } 7373 7374 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7375 7376 // Build variables passed into runtime, necessary for worksharing directives. 7377 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7378 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7379 isOpenMPDistributeDirective(DKind)) { 7380 // Lower bound variable, initialized with zero. 7381 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7382 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7383 SemaRef.AddInitializerToDecl(LBDecl, 7384 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7385 /*DirectInit*/ false); 7386 7387 // Upper bound variable, initialized with last iteration number. 7388 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7389 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7390 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7391 /*DirectInit*/ false); 7392 7393 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7394 // This will be used to implement clause 'lastprivate'. 7395 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7396 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7397 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7398 SemaRef.AddInitializerToDecl(ILDecl, 7399 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7400 /*DirectInit*/ false); 7401 7402 // Stride variable returned by runtime (we initialize it to 1 by default). 7403 VarDecl *STDecl = 7404 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7405 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7406 SemaRef.AddInitializerToDecl(STDecl, 7407 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7408 /*DirectInit*/ false); 7409 7410 // Build expression: UB = min(UB, LastIteration) 7411 // It is necessary for CodeGen of directives with static scheduling. 7412 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7413 UB.get(), LastIteration.get()); 7414 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7415 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7416 LastIteration.get(), UB.get()); 7417 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7418 CondOp.get()); 7419 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7420 7421 // If we have a combined directive that combines 'distribute', 'for' or 7422 // 'simd' we need to be able to access the bounds of the schedule of the 7423 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7424 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7425 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7426 // Lower bound variable, initialized with zero. 7427 VarDecl *CombLBDecl = 7428 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7429 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7430 SemaRef.AddInitializerToDecl( 7431 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7432 /*DirectInit*/ false); 7433 7434 // Upper bound variable, initialized with last iteration number. 7435 VarDecl *CombUBDecl = 7436 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7437 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7438 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7439 /*DirectInit*/ false); 7440 7441 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7442 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7443 ExprResult CombCondOp = 7444 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7445 LastIteration.get(), CombUB.get()); 7446 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7447 CombCondOp.get()); 7448 CombEUB = 7449 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7450 7451 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7452 // We expect to have at least 2 more parameters than the 'parallel' 7453 // directive does - the lower and upper bounds of the previous schedule. 7454 assert(CD->getNumParams() >= 4 && 7455 "Unexpected number of parameters in loop combined directive"); 7456 7457 // Set the proper type for the bounds given what we learned from the 7458 // enclosed loops. 7459 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7460 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7461 7462 // Previous lower and upper bounds are obtained from the region 7463 // parameters. 7464 PrevLB = 7465 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7466 PrevUB = 7467 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7468 } 7469 } 7470 7471 // Build the iteration variable and its initialization before loop. 7472 ExprResult IV; 7473 ExprResult Init, CombInit; 7474 { 7475 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7476 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7477 Expr *RHS = 7478 (isOpenMPWorksharingDirective(DKind) || 7479 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7480 ? LB.get() 7481 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7482 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7483 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7484 7485 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7486 Expr *CombRHS = 7487 (isOpenMPWorksharingDirective(DKind) || 7488 isOpenMPTaskLoopDirective(DKind) || 7489 isOpenMPDistributeDirective(DKind)) 7490 ? CombLB.get() 7491 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7492 CombInit = 7493 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7494 CombInit = 7495 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7496 } 7497 } 7498 7499 bool UseStrictCompare = 7500 RealVType->hasUnsignedIntegerRepresentation() && 7501 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7502 return LIS.IsStrictCompare; 7503 }); 7504 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7505 // unsigned IV)) for worksharing loops. 7506 SourceLocation CondLoc = AStmt->getBeginLoc(); 7507 Expr *BoundUB = UB.get(); 7508 if (UseStrictCompare) { 7509 BoundUB = 7510 SemaRef 7511 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7512 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7513 .get(); 7514 BoundUB = 7515 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7516 } 7517 ExprResult Cond = 7518 (isOpenMPWorksharingDirective(DKind) || 7519 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7520 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7521 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7522 BoundUB) 7523 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7524 NumIterations.get()); 7525 ExprResult CombDistCond; 7526 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7527 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7528 NumIterations.get()); 7529 } 7530 7531 ExprResult CombCond; 7532 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7533 Expr *BoundCombUB = CombUB.get(); 7534 if (UseStrictCompare) { 7535 BoundCombUB = 7536 SemaRef 7537 .BuildBinOp( 7538 CurScope, CondLoc, BO_Add, BoundCombUB, 7539 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7540 .get(); 7541 BoundCombUB = 7542 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7543 .get(); 7544 } 7545 CombCond = 7546 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7547 IV.get(), BoundCombUB); 7548 } 7549 // Loop increment (IV = IV + 1) 7550 SourceLocation IncLoc = AStmt->getBeginLoc(); 7551 ExprResult Inc = 7552 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7553 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7554 if (!Inc.isUsable()) 7555 return 0; 7556 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7557 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7558 if (!Inc.isUsable()) 7559 return 0; 7560 7561 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7562 // Used for directives with static scheduling. 7563 // In combined construct, add combined version that use CombLB and CombUB 7564 // base variables for the update 7565 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7566 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7567 isOpenMPDistributeDirective(DKind)) { 7568 // LB + ST 7569 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7570 if (!NextLB.isUsable()) 7571 return 0; 7572 // LB = LB + ST 7573 NextLB = 7574 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7575 NextLB = 7576 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7577 if (!NextLB.isUsable()) 7578 return 0; 7579 // UB + ST 7580 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7581 if (!NextUB.isUsable()) 7582 return 0; 7583 // UB = UB + ST 7584 NextUB = 7585 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7586 NextUB = 7587 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7588 if (!NextUB.isUsable()) 7589 return 0; 7590 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7591 CombNextLB = 7592 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7593 if (!NextLB.isUsable()) 7594 return 0; 7595 // LB = LB + ST 7596 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7597 CombNextLB.get()); 7598 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7599 /*DiscardedValue*/ false); 7600 if (!CombNextLB.isUsable()) 7601 return 0; 7602 // UB + ST 7603 CombNextUB = 7604 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7605 if (!CombNextUB.isUsable()) 7606 return 0; 7607 // UB = UB + ST 7608 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7609 CombNextUB.get()); 7610 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7611 /*DiscardedValue*/ false); 7612 if (!CombNextUB.isUsable()) 7613 return 0; 7614 } 7615 } 7616 7617 // Create increment expression for distribute loop when combined in a same 7618 // directive with for as IV = IV + ST; ensure upper bound expression based 7619 // on PrevUB instead of NumIterations - used to implement 'for' when found 7620 // in combination with 'distribute', like in 'distribute parallel for' 7621 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7622 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7623 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7624 DistCond = SemaRef.BuildBinOp( 7625 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7626 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7627 7628 DistInc = 7629 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7630 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7631 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7632 DistInc.get()); 7633 DistInc = 7634 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7635 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7636 7637 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7638 // construct 7639 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7640 ExprResult IsUBGreater = 7641 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7642 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7643 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7644 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7645 CondOp.get()); 7646 PrevEUB = 7647 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7648 7649 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7650 // parallel for is in combination with a distribute directive with 7651 // schedule(static, 1) 7652 Expr *BoundPrevUB = PrevUB.get(); 7653 if (UseStrictCompare) { 7654 BoundPrevUB = 7655 SemaRef 7656 .BuildBinOp( 7657 CurScope, CondLoc, BO_Add, BoundPrevUB, 7658 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7659 .get(); 7660 BoundPrevUB = 7661 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7662 .get(); 7663 } 7664 ParForInDistCond = 7665 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7666 IV.get(), BoundPrevUB); 7667 } 7668 7669 // Build updates and final values of the loop counters. 7670 bool HasErrors = false; 7671 Built.Counters.resize(NestedLoopCount); 7672 Built.Inits.resize(NestedLoopCount); 7673 Built.Updates.resize(NestedLoopCount); 7674 Built.Finals.resize(NestedLoopCount); 7675 Built.DependentCounters.resize(NestedLoopCount); 7676 Built.DependentInits.resize(NestedLoopCount); 7677 Built.FinalsConditions.resize(NestedLoopCount); 7678 { 7679 // We implement the following algorithm for obtaining the 7680 // original loop iteration variable values based on the 7681 // value of the collapsed loop iteration variable IV. 7682 // 7683 // Let n+1 be the number of collapsed loops in the nest. 7684 // Iteration variables (I0, I1, .... In) 7685 // Iteration counts (N0, N1, ... Nn) 7686 // 7687 // Acc = IV; 7688 // 7689 // To compute Ik for loop k, 0 <= k <= n, generate: 7690 // Prod = N(k+1) * N(k+2) * ... * Nn; 7691 // Ik = Acc / Prod; 7692 // Acc -= Ik * Prod; 7693 // 7694 ExprResult Acc = IV; 7695 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7696 LoopIterationSpace &IS = IterSpaces[Cnt]; 7697 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7698 ExprResult Iter; 7699 7700 // Compute prod 7701 ExprResult Prod = 7702 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7703 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7704 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7705 IterSpaces[K].NumIterations); 7706 7707 // Iter = Acc / Prod 7708 // If there is at least one more inner loop to avoid 7709 // multiplication by 1. 7710 if (Cnt + 1 < NestedLoopCount) 7711 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7712 Acc.get(), Prod.get()); 7713 else 7714 Iter = Acc; 7715 if (!Iter.isUsable()) { 7716 HasErrors = true; 7717 break; 7718 } 7719 7720 // Update Acc: 7721 // Acc -= Iter * Prod 7722 // Check if there is at least one more inner loop to avoid 7723 // multiplication by 1. 7724 if (Cnt + 1 < NestedLoopCount) 7725 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7726 Iter.get(), Prod.get()); 7727 else 7728 Prod = Iter; 7729 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7730 Acc.get(), Prod.get()); 7731 7732 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7733 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7734 DeclRefExpr *CounterVar = buildDeclRefExpr( 7735 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7736 /*RefersToCapture=*/true); 7737 ExprResult Init = 7738 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7739 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7740 if (!Init.isUsable()) { 7741 HasErrors = true; 7742 break; 7743 } 7744 ExprResult Update = buildCounterUpdate( 7745 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7746 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7747 if (!Update.isUsable()) { 7748 HasErrors = true; 7749 break; 7750 } 7751 7752 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7753 ExprResult Final = 7754 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7755 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7756 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7757 if (!Final.isUsable()) { 7758 HasErrors = true; 7759 break; 7760 } 7761 7762 if (!Update.isUsable() || !Final.isUsable()) { 7763 HasErrors = true; 7764 break; 7765 } 7766 // Save results 7767 Built.Counters[Cnt] = IS.CounterVar; 7768 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7769 Built.Inits[Cnt] = Init.get(); 7770 Built.Updates[Cnt] = Update.get(); 7771 Built.Finals[Cnt] = Final.get(); 7772 Built.DependentCounters[Cnt] = nullptr; 7773 Built.DependentInits[Cnt] = nullptr; 7774 Built.FinalsConditions[Cnt] = nullptr; 7775 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7776 Built.DependentCounters[Cnt] = 7777 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7778 Built.DependentInits[Cnt] = 7779 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7780 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7781 } 7782 } 7783 } 7784 7785 if (HasErrors) 7786 return 0; 7787 7788 // Save results 7789 Built.IterationVarRef = IV.get(); 7790 Built.LastIteration = LastIteration.get(); 7791 Built.NumIterations = NumIterations.get(); 7792 Built.CalcLastIteration = SemaRef 7793 .ActOnFinishFullExpr(CalcLastIteration.get(), 7794 /*DiscardedValue=*/false) 7795 .get(); 7796 Built.PreCond = PreCond.get(); 7797 Built.PreInits = buildPreInits(C, Captures); 7798 Built.Cond = Cond.get(); 7799 Built.Init = Init.get(); 7800 Built.Inc = Inc.get(); 7801 Built.LB = LB.get(); 7802 Built.UB = UB.get(); 7803 Built.IL = IL.get(); 7804 Built.ST = ST.get(); 7805 Built.EUB = EUB.get(); 7806 Built.NLB = NextLB.get(); 7807 Built.NUB = NextUB.get(); 7808 Built.PrevLB = PrevLB.get(); 7809 Built.PrevUB = PrevUB.get(); 7810 Built.DistInc = DistInc.get(); 7811 Built.PrevEUB = PrevEUB.get(); 7812 Built.DistCombinedFields.LB = CombLB.get(); 7813 Built.DistCombinedFields.UB = CombUB.get(); 7814 Built.DistCombinedFields.EUB = CombEUB.get(); 7815 Built.DistCombinedFields.Init = CombInit.get(); 7816 Built.DistCombinedFields.Cond = CombCond.get(); 7817 Built.DistCombinedFields.NLB = CombNextLB.get(); 7818 Built.DistCombinedFields.NUB = CombNextUB.get(); 7819 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7820 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7821 7822 return NestedLoopCount; 7823 } 7824 7825 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7826 auto CollapseClauses = 7827 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7828 if (CollapseClauses.begin() != CollapseClauses.end()) 7829 return (*CollapseClauses.begin())->getNumForLoops(); 7830 return nullptr; 7831 } 7832 7833 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7834 auto OrderedClauses = 7835 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7836 if (OrderedClauses.begin() != OrderedClauses.end()) 7837 return (*OrderedClauses.begin())->getNumForLoops(); 7838 return nullptr; 7839 } 7840 7841 static bool checkSimdlenSafelenSpecified(Sema &S, 7842 const ArrayRef<OMPClause *> Clauses) { 7843 const OMPSafelenClause *Safelen = nullptr; 7844 const OMPSimdlenClause *Simdlen = nullptr; 7845 7846 for (const OMPClause *Clause : Clauses) { 7847 if (Clause->getClauseKind() == OMPC_safelen) 7848 Safelen = cast<OMPSafelenClause>(Clause); 7849 else if (Clause->getClauseKind() == OMPC_simdlen) 7850 Simdlen = cast<OMPSimdlenClause>(Clause); 7851 if (Safelen && Simdlen) 7852 break; 7853 } 7854 7855 if (Simdlen && Safelen) { 7856 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7857 const Expr *SafelenLength = Safelen->getSafelen(); 7858 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7859 SimdlenLength->isInstantiationDependent() || 7860 SimdlenLength->containsUnexpandedParameterPack()) 7861 return false; 7862 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7863 SafelenLength->isInstantiationDependent() || 7864 SafelenLength->containsUnexpandedParameterPack()) 7865 return false; 7866 Expr::EvalResult SimdlenResult, SafelenResult; 7867 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7868 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7869 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7870 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7871 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7872 // If both simdlen and safelen clauses are specified, the value of the 7873 // simdlen parameter must be less than or equal to the value of the safelen 7874 // parameter. 7875 if (SimdlenRes > SafelenRes) { 7876 S.Diag(SimdlenLength->getExprLoc(), 7877 diag::err_omp_wrong_simdlen_safelen_values) 7878 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7879 return true; 7880 } 7881 } 7882 return false; 7883 } 7884 7885 StmtResult 7886 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7887 SourceLocation StartLoc, SourceLocation EndLoc, 7888 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7889 if (!AStmt) 7890 return StmtError(); 7891 7892 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7893 OMPLoopDirective::HelperExprs B; 7894 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7895 // define the nested loops number. 7896 unsigned NestedLoopCount = checkOpenMPLoop( 7897 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7898 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7899 if (NestedLoopCount == 0) 7900 return StmtError(); 7901 7902 assert((CurContext->isDependentContext() || B.builtAll()) && 7903 "omp simd loop exprs were not built"); 7904 7905 if (!CurContext->isDependentContext()) { 7906 // Finalize the clauses that need pre-built expressions for CodeGen. 7907 for (OMPClause *C : Clauses) { 7908 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7909 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7910 B.NumIterations, *this, CurScope, 7911 DSAStack)) 7912 return StmtError(); 7913 } 7914 } 7915 7916 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7917 return StmtError(); 7918 7919 setFunctionHasBranchProtectedScope(); 7920 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7921 Clauses, AStmt, B); 7922 } 7923 7924 StmtResult 7925 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7926 SourceLocation StartLoc, SourceLocation EndLoc, 7927 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7928 if (!AStmt) 7929 return StmtError(); 7930 7931 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7932 OMPLoopDirective::HelperExprs B; 7933 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7934 // define the nested loops number. 7935 unsigned NestedLoopCount = checkOpenMPLoop( 7936 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7937 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7938 if (NestedLoopCount == 0) 7939 return StmtError(); 7940 7941 assert((CurContext->isDependentContext() || B.builtAll()) && 7942 "omp for loop exprs were not built"); 7943 7944 if (!CurContext->isDependentContext()) { 7945 // Finalize the clauses that need pre-built expressions for CodeGen. 7946 for (OMPClause *C : Clauses) { 7947 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7948 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7949 B.NumIterations, *this, CurScope, 7950 DSAStack)) 7951 return StmtError(); 7952 } 7953 } 7954 7955 setFunctionHasBranchProtectedScope(); 7956 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7957 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7958 } 7959 7960 StmtResult Sema::ActOnOpenMPForSimdDirective( 7961 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7962 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7963 if (!AStmt) 7964 return StmtError(); 7965 7966 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7967 OMPLoopDirective::HelperExprs B; 7968 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7969 // define the nested loops number. 7970 unsigned NestedLoopCount = 7971 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7972 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7973 VarsWithImplicitDSA, B); 7974 if (NestedLoopCount == 0) 7975 return StmtError(); 7976 7977 assert((CurContext->isDependentContext() || B.builtAll()) && 7978 "omp for simd loop exprs were not built"); 7979 7980 if (!CurContext->isDependentContext()) { 7981 // Finalize the clauses that need pre-built expressions for CodeGen. 7982 for (OMPClause *C : Clauses) { 7983 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7984 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7985 B.NumIterations, *this, CurScope, 7986 DSAStack)) 7987 return StmtError(); 7988 } 7989 } 7990 7991 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7992 return StmtError(); 7993 7994 setFunctionHasBranchProtectedScope(); 7995 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7996 Clauses, AStmt, B); 7997 } 7998 7999 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8000 Stmt *AStmt, 8001 SourceLocation StartLoc, 8002 SourceLocation EndLoc) { 8003 if (!AStmt) 8004 return StmtError(); 8005 8006 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8007 auto BaseStmt = AStmt; 8008 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8009 BaseStmt = CS->getCapturedStmt(); 8010 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8011 auto S = C->children(); 8012 if (S.begin() == S.end()) 8013 return StmtError(); 8014 // All associated statements must be '#pragma omp section' except for 8015 // the first one. 8016 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8017 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8018 if (SectionStmt) 8019 Diag(SectionStmt->getBeginLoc(), 8020 diag::err_omp_sections_substmt_not_section); 8021 return StmtError(); 8022 } 8023 cast<OMPSectionDirective>(SectionStmt) 8024 ->setHasCancel(DSAStack->isCancelRegion()); 8025 } 8026 } else { 8027 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8028 return StmtError(); 8029 } 8030 8031 setFunctionHasBranchProtectedScope(); 8032 8033 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8034 DSAStack->isCancelRegion()); 8035 } 8036 8037 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8038 SourceLocation StartLoc, 8039 SourceLocation EndLoc) { 8040 if (!AStmt) 8041 return StmtError(); 8042 8043 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8044 8045 setFunctionHasBranchProtectedScope(); 8046 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8047 8048 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8049 DSAStack->isCancelRegion()); 8050 } 8051 8052 StmtResult Sema::ActOnOpenMPSingleDirective(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 setFunctionHasBranchProtectedScope(); 8062 8063 // OpenMP [2.7.3, single Construct, Restrictions] 8064 // The copyprivate clause must not be used with the nowait clause. 8065 const OMPClause *Nowait = nullptr; 8066 const OMPClause *Copyprivate = nullptr; 8067 for (const OMPClause *Clause : Clauses) { 8068 if (Clause->getClauseKind() == OMPC_nowait) 8069 Nowait = Clause; 8070 else if (Clause->getClauseKind() == OMPC_copyprivate) 8071 Copyprivate = Clause; 8072 if (Copyprivate && Nowait) { 8073 Diag(Copyprivate->getBeginLoc(), 8074 diag::err_omp_single_copyprivate_with_nowait); 8075 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8076 return StmtError(); 8077 } 8078 } 8079 8080 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8081 } 8082 8083 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8084 SourceLocation StartLoc, 8085 SourceLocation EndLoc) { 8086 if (!AStmt) 8087 return StmtError(); 8088 8089 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8090 8091 setFunctionHasBranchProtectedScope(); 8092 8093 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8094 } 8095 8096 StmtResult Sema::ActOnOpenMPCriticalDirective( 8097 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8098 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8099 if (!AStmt) 8100 return StmtError(); 8101 8102 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8103 8104 bool ErrorFound = false; 8105 llvm::APSInt Hint; 8106 SourceLocation HintLoc; 8107 bool DependentHint = false; 8108 for (const OMPClause *C : Clauses) { 8109 if (C->getClauseKind() == OMPC_hint) { 8110 if (!DirName.getName()) { 8111 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8112 ErrorFound = true; 8113 } 8114 Expr *E = cast<OMPHintClause>(C)->getHint(); 8115 if (E->isTypeDependent() || E->isValueDependent() || 8116 E->isInstantiationDependent()) { 8117 DependentHint = true; 8118 } else { 8119 Hint = E->EvaluateKnownConstInt(Context); 8120 HintLoc = C->getBeginLoc(); 8121 } 8122 } 8123 } 8124 if (ErrorFound) 8125 return StmtError(); 8126 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8127 if (Pair.first && DirName.getName() && !DependentHint) { 8128 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8129 Diag(StartLoc, diag::err_omp_critical_with_hint); 8130 if (HintLoc.isValid()) 8131 Diag(HintLoc, diag::note_omp_critical_hint_here) 8132 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8133 else 8134 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8135 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8136 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8137 << 1 8138 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8139 /*Radix=*/10, /*Signed=*/false); 8140 } else { 8141 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8142 } 8143 } 8144 } 8145 8146 setFunctionHasBranchProtectedScope(); 8147 8148 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8149 Clauses, AStmt); 8150 if (!Pair.first && DirName.getName() && !DependentHint) 8151 DSAStack->addCriticalWithHint(Dir, Hint); 8152 return Dir; 8153 } 8154 8155 StmtResult Sema::ActOnOpenMPParallelForDirective( 8156 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8157 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8158 if (!AStmt) 8159 return StmtError(); 8160 8161 auto *CS = cast<CapturedStmt>(AStmt); 8162 // 1.2.2 OpenMP Language Terminology 8163 // Structured block - An executable statement with a single entry at the 8164 // top and a single exit at the bottom. 8165 // The point of exit cannot be a branch out of the structured block. 8166 // longjmp() and throw() must not violate the entry/exit criteria. 8167 CS->getCapturedDecl()->setNothrow(); 8168 8169 OMPLoopDirective::HelperExprs B; 8170 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8171 // define the nested loops number. 8172 unsigned NestedLoopCount = 8173 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8174 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8175 VarsWithImplicitDSA, B); 8176 if (NestedLoopCount == 0) 8177 return StmtError(); 8178 8179 assert((CurContext->isDependentContext() || B.builtAll()) && 8180 "omp parallel for loop exprs were not built"); 8181 8182 if (!CurContext->isDependentContext()) { 8183 // Finalize the clauses that need pre-built expressions for CodeGen. 8184 for (OMPClause *C : Clauses) { 8185 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8186 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8187 B.NumIterations, *this, CurScope, 8188 DSAStack)) 8189 return StmtError(); 8190 } 8191 } 8192 8193 setFunctionHasBranchProtectedScope(); 8194 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8195 NestedLoopCount, Clauses, AStmt, B, 8196 DSAStack->isCancelRegion()); 8197 } 8198 8199 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8200 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8201 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8202 if (!AStmt) 8203 return StmtError(); 8204 8205 auto *CS = cast<CapturedStmt>(AStmt); 8206 // 1.2.2 OpenMP Language Terminology 8207 // Structured block - An executable statement with a single entry at the 8208 // top and a single exit at the bottom. 8209 // The point of exit cannot be a branch out of the structured block. 8210 // longjmp() and throw() must not violate the entry/exit criteria. 8211 CS->getCapturedDecl()->setNothrow(); 8212 8213 OMPLoopDirective::HelperExprs B; 8214 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8215 // define the nested loops number. 8216 unsigned NestedLoopCount = 8217 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8218 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8219 VarsWithImplicitDSA, B); 8220 if (NestedLoopCount == 0) 8221 return StmtError(); 8222 8223 if (!CurContext->isDependentContext()) { 8224 // Finalize the clauses that need pre-built expressions for CodeGen. 8225 for (OMPClause *C : Clauses) { 8226 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8227 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8228 B.NumIterations, *this, CurScope, 8229 DSAStack)) 8230 return StmtError(); 8231 } 8232 } 8233 8234 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8235 return StmtError(); 8236 8237 setFunctionHasBranchProtectedScope(); 8238 return OMPParallelForSimdDirective::Create( 8239 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8240 } 8241 8242 StmtResult 8243 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8244 Stmt *AStmt, SourceLocation StartLoc, 8245 SourceLocation EndLoc) { 8246 if (!AStmt) 8247 return StmtError(); 8248 8249 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8250 auto BaseStmt = AStmt; 8251 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8252 BaseStmt = CS->getCapturedStmt(); 8253 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8254 auto S = C->children(); 8255 if (S.begin() == S.end()) 8256 return StmtError(); 8257 // All associated statements must be '#pragma omp section' except for 8258 // the first one. 8259 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8260 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8261 if (SectionStmt) 8262 Diag(SectionStmt->getBeginLoc(), 8263 diag::err_omp_parallel_sections_substmt_not_section); 8264 return StmtError(); 8265 } 8266 cast<OMPSectionDirective>(SectionStmt) 8267 ->setHasCancel(DSAStack->isCancelRegion()); 8268 } 8269 } else { 8270 Diag(AStmt->getBeginLoc(), 8271 diag::err_omp_parallel_sections_not_compound_stmt); 8272 return StmtError(); 8273 } 8274 8275 setFunctionHasBranchProtectedScope(); 8276 8277 return OMPParallelSectionsDirective::Create( 8278 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8279 } 8280 8281 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8282 Stmt *AStmt, SourceLocation StartLoc, 8283 SourceLocation EndLoc) { 8284 if (!AStmt) 8285 return StmtError(); 8286 8287 auto *CS = cast<CapturedStmt>(AStmt); 8288 // 1.2.2 OpenMP Language Terminology 8289 // Structured block - An executable statement with a single entry at the 8290 // top and a single exit at the bottom. 8291 // The point of exit cannot be a branch out of the structured block. 8292 // longjmp() and throw() must not violate the entry/exit criteria. 8293 CS->getCapturedDecl()->setNothrow(); 8294 8295 setFunctionHasBranchProtectedScope(); 8296 8297 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8298 DSAStack->isCancelRegion()); 8299 } 8300 8301 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8302 SourceLocation EndLoc) { 8303 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8304 } 8305 8306 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8307 SourceLocation EndLoc) { 8308 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8309 } 8310 8311 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8312 SourceLocation EndLoc) { 8313 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8314 } 8315 8316 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8317 Stmt *AStmt, 8318 SourceLocation StartLoc, 8319 SourceLocation EndLoc) { 8320 if (!AStmt) 8321 return StmtError(); 8322 8323 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8324 8325 setFunctionHasBranchProtectedScope(); 8326 8327 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8328 AStmt, 8329 DSAStack->getTaskgroupReductionRef()); 8330 } 8331 8332 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8333 SourceLocation StartLoc, 8334 SourceLocation EndLoc) { 8335 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8336 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8337 } 8338 8339 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8340 Stmt *AStmt, 8341 SourceLocation StartLoc, 8342 SourceLocation EndLoc) { 8343 const OMPClause *DependFound = nullptr; 8344 const OMPClause *DependSourceClause = nullptr; 8345 const OMPClause *DependSinkClause = nullptr; 8346 bool ErrorFound = false; 8347 const OMPThreadsClause *TC = nullptr; 8348 const OMPSIMDClause *SC = nullptr; 8349 for (const OMPClause *C : Clauses) { 8350 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8351 DependFound = C; 8352 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8353 if (DependSourceClause) { 8354 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8355 << getOpenMPDirectiveName(OMPD_ordered) 8356 << getOpenMPClauseName(OMPC_depend) << 2; 8357 ErrorFound = true; 8358 } else { 8359 DependSourceClause = C; 8360 } 8361 if (DependSinkClause) { 8362 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8363 << 0; 8364 ErrorFound = true; 8365 } 8366 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8367 if (DependSourceClause) { 8368 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8369 << 1; 8370 ErrorFound = true; 8371 } 8372 DependSinkClause = C; 8373 } 8374 } else if (C->getClauseKind() == OMPC_threads) { 8375 TC = cast<OMPThreadsClause>(C); 8376 } else if (C->getClauseKind() == OMPC_simd) { 8377 SC = cast<OMPSIMDClause>(C); 8378 } 8379 } 8380 if (!ErrorFound && !SC && 8381 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8382 // OpenMP [2.8.1,simd Construct, Restrictions] 8383 // An ordered construct with the simd clause is the only OpenMP construct 8384 // that can appear in the simd region. 8385 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8386 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8387 ErrorFound = true; 8388 } else if (DependFound && (TC || SC)) { 8389 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8390 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8391 ErrorFound = true; 8392 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8393 Diag(DependFound->getBeginLoc(), 8394 diag::err_omp_ordered_directive_without_param); 8395 ErrorFound = true; 8396 } else if (TC || Clauses.empty()) { 8397 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8398 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8399 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8400 << (TC != nullptr); 8401 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8402 ErrorFound = true; 8403 } 8404 } 8405 if ((!AStmt && !DependFound) || ErrorFound) 8406 return StmtError(); 8407 8408 if (AStmt) { 8409 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8410 8411 setFunctionHasBranchProtectedScope(); 8412 } 8413 8414 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8415 } 8416 8417 namespace { 8418 /// Helper class for checking expression in 'omp atomic [update]' 8419 /// construct. 8420 class OpenMPAtomicUpdateChecker { 8421 /// Error results for atomic update expressions. 8422 enum ExprAnalysisErrorCode { 8423 /// A statement is not an expression statement. 8424 NotAnExpression, 8425 /// Expression is not builtin binary or unary operation. 8426 NotABinaryOrUnaryExpression, 8427 /// Unary operation is not post-/pre- increment/decrement operation. 8428 NotAnUnaryIncDecExpression, 8429 /// An expression is not of scalar type. 8430 NotAScalarType, 8431 /// A binary operation is not an assignment operation. 8432 NotAnAssignmentOp, 8433 /// RHS part of the binary operation is not a binary expression. 8434 NotABinaryExpression, 8435 /// RHS part is not additive/multiplicative/shift/biwise binary 8436 /// expression. 8437 NotABinaryOperator, 8438 /// RHS binary operation does not have reference to the updated LHS 8439 /// part. 8440 NotAnUpdateExpression, 8441 /// No errors is found. 8442 NoError 8443 }; 8444 /// Reference to Sema. 8445 Sema &SemaRef; 8446 /// A location for note diagnostics (when error is found). 8447 SourceLocation NoteLoc; 8448 /// 'x' lvalue part of the source atomic expression. 8449 Expr *X; 8450 /// 'expr' rvalue part of the source atomic expression. 8451 Expr *E; 8452 /// Helper expression of the form 8453 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8454 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8455 Expr *UpdateExpr; 8456 /// Is 'x' a LHS in a RHS part of full update expression. It is 8457 /// important for non-associative operations. 8458 bool IsXLHSInRHSPart; 8459 BinaryOperatorKind Op; 8460 SourceLocation OpLoc; 8461 /// true if the source expression is a postfix unary operation, false 8462 /// if it is a prefix unary operation. 8463 bool IsPostfixUpdate; 8464 8465 public: 8466 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8467 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8468 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8469 /// Check specified statement that it is suitable for 'atomic update' 8470 /// constructs and extract 'x', 'expr' and Operation from the original 8471 /// expression. If DiagId and NoteId == 0, then only check is performed 8472 /// without error notification. 8473 /// \param DiagId Diagnostic which should be emitted if error is found. 8474 /// \param NoteId Diagnostic note for the main error message. 8475 /// \return true if statement is not an update expression, false otherwise. 8476 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8477 /// Return the 'x' lvalue part of the source atomic expression. 8478 Expr *getX() const { return X; } 8479 /// Return the 'expr' rvalue part of the source atomic expression. 8480 Expr *getExpr() const { return E; } 8481 /// Return the update expression used in calculation of the updated 8482 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8483 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8484 Expr *getUpdateExpr() const { return UpdateExpr; } 8485 /// Return true if 'x' is LHS in RHS part of full update expression, 8486 /// false otherwise. 8487 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8488 8489 /// true if the source expression is a postfix unary operation, false 8490 /// if it is a prefix unary operation. 8491 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8492 8493 private: 8494 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8495 unsigned NoteId = 0); 8496 }; 8497 } // namespace 8498 8499 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8500 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8501 ExprAnalysisErrorCode ErrorFound = NoError; 8502 SourceLocation ErrorLoc, NoteLoc; 8503 SourceRange ErrorRange, NoteRange; 8504 // Allowed constructs are: 8505 // x = x binop expr; 8506 // x = expr binop x; 8507 if (AtomicBinOp->getOpcode() == BO_Assign) { 8508 X = AtomicBinOp->getLHS(); 8509 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8510 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8511 if (AtomicInnerBinOp->isMultiplicativeOp() || 8512 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8513 AtomicInnerBinOp->isBitwiseOp()) { 8514 Op = AtomicInnerBinOp->getOpcode(); 8515 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8516 Expr *LHS = AtomicInnerBinOp->getLHS(); 8517 Expr *RHS = AtomicInnerBinOp->getRHS(); 8518 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8519 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8520 /*Canonical=*/true); 8521 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8522 /*Canonical=*/true); 8523 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8524 /*Canonical=*/true); 8525 if (XId == LHSId) { 8526 E = RHS; 8527 IsXLHSInRHSPart = true; 8528 } else if (XId == RHSId) { 8529 E = LHS; 8530 IsXLHSInRHSPart = false; 8531 } else { 8532 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8533 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8534 NoteLoc = X->getExprLoc(); 8535 NoteRange = X->getSourceRange(); 8536 ErrorFound = NotAnUpdateExpression; 8537 } 8538 } else { 8539 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8540 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8541 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8542 NoteRange = SourceRange(NoteLoc, NoteLoc); 8543 ErrorFound = NotABinaryOperator; 8544 } 8545 } else { 8546 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8547 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8548 ErrorFound = NotABinaryExpression; 8549 } 8550 } else { 8551 ErrorLoc = AtomicBinOp->getExprLoc(); 8552 ErrorRange = AtomicBinOp->getSourceRange(); 8553 NoteLoc = AtomicBinOp->getOperatorLoc(); 8554 NoteRange = SourceRange(NoteLoc, NoteLoc); 8555 ErrorFound = NotAnAssignmentOp; 8556 } 8557 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8558 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8559 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8560 return true; 8561 } 8562 if (SemaRef.CurContext->isDependentContext()) 8563 E = X = UpdateExpr = nullptr; 8564 return ErrorFound != NoError; 8565 } 8566 8567 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8568 unsigned NoteId) { 8569 ExprAnalysisErrorCode ErrorFound = NoError; 8570 SourceLocation ErrorLoc, NoteLoc; 8571 SourceRange ErrorRange, NoteRange; 8572 // Allowed constructs are: 8573 // x++; 8574 // x--; 8575 // ++x; 8576 // --x; 8577 // x binop= expr; 8578 // x = x binop expr; 8579 // x = expr binop x; 8580 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8581 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8582 if (AtomicBody->getType()->isScalarType() || 8583 AtomicBody->isInstantiationDependent()) { 8584 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8585 AtomicBody->IgnoreParenImpCasts())) { 8586 // Check for Compound Assignment Operation 8587 Op = BinaryOperator::getOpForCompoundAssignment( 8588 AtomicCompAssignOp->getOpcode()); 8589 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8590 E = AtomicCompAssignOp->getRHS(); 8591 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8592 IsXLHSInRHSPart = true; 8593 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8594 AtomicBody->IgnoreParenImpCasts())) { 8595 // Check for Binary Operation 8596 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8597 return true; 8598 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8599 AtomicBody->IgnoreParenImpCasts())) { 8600 // Check for Unary Operation 8601 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8602 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8603 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8604 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8605 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8606 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8607 IsXLHSInRHSPart = true; 8608 } else { 8609 ErrorFound = NotAnUnaryIncDecExpression; 8610 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8611 ErrorRange = AtomicUnaryOp->getSourceRange(); 8612 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8613 NoteRange = SourceRange(NoteLoc, NoteLoc); 8614 } 8615 } else if (!AtomicBody->isInstantiationDependent()) { 8616 ErrorFound = NotABinaryOrUnaryExpression; 8617 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8618 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8619 } 8620 } else { 8621 ErrorFound = NotAScalarType; 8622 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8623 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8624 } 8625 } else { 8626 ErrorFound = NotAnExpression; 8627 NoteLoc = ErrorLoc = S->getBeginLoc(); 8628 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8629 } 8630 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8631 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8632 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8633 return true; 8634 } 8635 if (SemaRef.CurContext->isDependentContext()) 8636 E = X = UpdateExpr = nullptr; 8637 if (ErrorFound == NoError && E && X) { 8638 // Build an update expression of form 'OpaqueValueExpr(x) binop 8639 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8640 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8641 auto *OVEX = new (SemaRef.getASTContext()) 8642 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8643 auto *OVEExpr = new (SemaRef.getASTContext()) 8644 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8645 ExprResult Update = 8646 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8647 IsXLHSInRHSPart ? OVEExpr : OVEX); 8648 if (Update.isInvalid()) 8649 return true; 8650 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8651 Sema::AA_Casting); 8652 if (Update.isInvalid()) 8653 return true; 8654 UpdateExpr = Update.get(); 8655 } 8656 return ErrorFound != NoError; 8657 } 8658 8659 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8660 Stmt *AStmt, 8661 SourceLocation StartLoc, 8662 SourceLocation EndLoc) { 8663 if (!AStmt) 8664 return StmtError(); 8665 8666 auto *CS = cast<CapturedStmt>(AStmt); 8667 // 1.2.2 OpenMP Language Terminology 8668 // Structured block - An executable statement with a single entry at the 8669 // top and a single exit at the bottom. 8670 // The point of exit cannot be a branch out of the structured block. 8671 // longjmp() and throw() must not violate the entry/exit criteria. 8672 OpenMPClauseKind AtomicKind = OMPC_unknown; 8673 SourceLocation AtomicKindLoc; 8674 for (const OMPClause *C : Clauses) { 8675 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8676 C->getClauseKind() == OMPC_update || 8677 C->getClauseKind() == OMPC_capture) { 8678 if (AtomicKind != OMPC_unknown) { 8679 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8680 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8681 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8682 << getOpenMPClauseName(AtomicKind); 8683 } else { 8684 AtomicKind = C->getClauseKind(); 8685 AtomicKindLoc = C->getBeginLoc(); 8686 } 8687 } 8688 } 8689 8690 Stmt *Body = CS->getCapturedStmt(); 8691 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8692 Body = EWC->getSubExpr(); 8693 8694 Expr *X = nullptr; 8695 Expr *V = nullptr; 8696 Expr *E = nullptr; 8697 Expr *UE = nullptr; 8698 bool IsXLHSInRHSPart = false; 8699 bool IsPostfixUpdate = false; 8700 // OpenMP [2.12.6, atomic Construct] 8701 // In the next expressions: 8702 // * x and v (as applicable) are both l-value expressions with scalar type. 8703 // * During the execution of an atomic region, multiple syntactic 8704 // occurrences of x must designate the same storage location. 8705 // * Neither of v and expr (as applicable) may access the storage location 8706 // designated by x. 8707 // * Neither of x and expr (as applicable) may access the storage location 8708 // designated by v. 8709 // * expr is an expression with scalar type. 8710 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8711 // * binop, binop=, ++, and -- are not overloaded operators. 8712 // * The expression x binop expr must be numerically equivalent to x binop 8713 // (expr). This requirement is satisfied if the operators in expr have 8714 // precedence greater than binop, or by using parentheses around expr or 8715 // subexpressions of expr. 8716 // * The expression expr binop x must be numerically equivalent to (expr) 8717 // binop x. This requirement is satisfied if the operators in expr have 8718 // precedence equal to or greater than binop, or by using parentheses around 8719 // expr or subexpressions of expr. 8720 // * For forms that allow multiple occurrences of x, the number of times 8721 // that x is evaluated is unspecified. 8722 if (AtomicKind == OMPC_read) { 8723 enum { 8724 NotAnExpression, 8725 NotAnAssignmentOp, 8726 NotAScalarType, 8727 NotAnLValue, 8728 NoError 8729 } ErrorFound = NoError; 8730 SourceLocation ErrorLoc, NoteLoc; 8731 SourceRange ErrorRange, NoteRange; 8732 // If clause is read: 8733 // v = x; 8734 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8735 const auto *AtomicBinOp = 8736 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8737 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8738 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8739 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8740 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8741 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8742 if (!X->isLValue() || !V->isLValue()) { 8743 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8744 ErrorFound = NotAnLValue; 8745 ErrorLoc = AtomicBinOp->getExprLoc(); 8746 ErrorRange = AtomicBinOp->getSourceRange(); 8747 NoteLoc = NotLValueExpr->getExprLoc(); 8748 NoteRange = NotLValueExpr->getSourceRange(); 8749 } 8750 } else if (!X->isInstantiationDependent() || 8751 !V->isInstantiationDependent()) { 8752 const Expr *NotScalarExpr = 8753 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8754 ? V 8755 : X; 8756 ErrorFound = NotAScalarType; 8757 ErrorLoc = AtomicBinOp->getExprLoc(); 8758 ErrorRange = AtomicBinOp->getSourceRange(); 8759 NoteLoc = NotScalarExpr->getExprLoc(); 8760 NoteRange = NotScalarExpr->getSourceRange(); 8761 } 8762 } else if (!AtomicBody->isInstantiationDependent()) { 8763 ErrorFound = NotAnAssignmentOp; 8764 ErrorLoc = AtomicBody->getExprLoc(); 8765 ErrorRange = AtomicBody->getSourceRange(); 8766 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8767 : AtomicBody->getExprLoc(); 8768 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8769 : AtomicBody->getSourceRange(); 8770 } 8771 } else { 8772 ErrorFound = NotAnExpression; 8773 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8774 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8775 } 8776 if (ErrorFound != NoError) { 8777 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8778 << ErrorRange; 8779 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8780 << NoteRange; 8781 return StmtError(); 8782 } 8783 if (CurContext->isDependentContext()) 8784 V = X = nullptr; 8785 } else if (AtomicKind == OMPC_write) { 8786 enum { 8787 NotAnExpression, 8788 NotAnAssignmentOp, 8789 NotAScalarType, 8790 NotAnLValue, 8791 NoError 8792 } ErrorFound = NoError; 8793 SourceLocation ErrorLoc, NoteLoc; 8794 SourceRange ErrorRange, NoteRange; 8795 // If clause is write: 8796 // x = expr; 8797 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8798 const auto *AtomicBinOp = 8799 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8800 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8801 X = AtomicBinOp->getLHS(); 8802 E = AtomicBinOp->getRHS(); 8803 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8804 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8805 if (!X->isLValue()) { 8806 ErrorFound = NotAnLValue; 8807 ErrorLoc = AtomicBinOp->getExprLoc(); 8808 ErrorRange = AtomicBinOp->getSourceRange(); 8809 NoteLoc = X->getExprLoc(); 8810 NoteRange = X->getSourceRange(); 8811 } 8812 } else if (!X->isInstantiationDependent() || 8813 !E->isInstantiationDependent()) { 8814 const Expr *NotScalarExpr = 8815 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8816 ? E 8817 : X; 8818 ErrorFound = NotAScalarType; 8819 ErrorLoc = AtomicBinOp->getExprLoc(); 8820 ErrorRange = AtomicBinOp->getSourceRange(); 8821 NoteLoc = NotScalarExpr->getExprLoc(); 8822 NoteRange = NotScalarExpr->getSourceRange(); 8823 } 8824 } else if (!AtomicBody->isInstantiationDependent()) { 8825 ErrorFound = NotAnAssignmentOp; 8826 ErrorLoc = AtomicBody->getExprLoc(); 8827 ErrorRange = AtomicBody->getSourceRange(); 8828 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8829 : AtomicBody->getExprLoc(); 8830 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8831 : AtomicBody->getSourceRange(); 8832 } 8833 } else { 8834 ErrorFound = NotAnExpression; 8835 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8836 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8837 } 8838 if (ErrorFound != NoError) { 8839 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8840 << ErrorRange; 8841 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8842 << NoteRange; 8843 return StmtError(); 8844 } 8845 if (CurContext->isDependentContext()) 8846 E = X = nullptr; 8847 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8848 // If clause is update: 8849 // x++; 8850 // x--; 8851 // ++x; 8852 // --x; 8853 // x binop= expr; 8854 // x = x binop expr; 8855 // x = expr binop x; 8856 OpenMPAtomicUpdateChecker Checker(*this); 8857 if (Checker.checkStatement( 8858 Body, (AtomicKind == OMPC_update) 8859 ? diag::err_omp_atomic_update_not_expression_statement 8860 : diag::err_omp_atomic_not_expression_statement, 8861 diag::note_omp_atomic_update)) 8862 return StmtError(); 8863 if (!CurContext->isDependentContext()) { 8864 E = Checker.getExpr(); 8865 X = Checker.getX(); 8866 UE = Checker.getUpdateExpr(); 8867 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8868 } 8869 } else if (AtomicKind == OMPC_capture) { 8870 enum { 8871 NotAnAssignmentOp, 8872 NotACompoundStatement, 8873 NotTwoSubstatements, 8874 NotASpecificExpression, 8875 NoError 8876 } ErrorFound = NoError; 8877 SourceLocation ErrorLoc, NoteLoc; 8878 SourceRange ErrorRange, NoteRange; 8879 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8880 // If clause is a capture: 8881 // v = x++; 8882 // v = x--; 8883 // v = ++x; 8884 // v = --x; 8885 // v = x binop= expr; 8886 // v = x = x binop expr; 8887 // v = x = expr binop x; 8888 const auto *AtomicBinOp = 8889 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8890 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8891 V = AtomicBinOp->getLHS(); 8892 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8893 OpenMPAtomicUpdateChecker Checker(*this); 8894 if (Checker.checkStatement( 8895 Body, diag::err_omp_atomic_capture_not_expression_statement, 8896 diag::note_omp_atomic_update)) 8897 return StmtError(); 8898 E = Checker.getExpr(); 8899 X = Checker.getX(); 8900 UE = Checker.getUpdateExpr(); 8901 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8902 IsPostfixUpdate = Checker.isPostfixUpdate(); 8903 } else if (!AtomicBody->isInstantiationDependent()) { 8904 ErrorLoc = AtomicBody->getExprLoc(); 8905 ErrorRange = AtomicBody->getSourceRange(); 8906 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8907 : AtomicBody->getExprLoc(); 8908 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8909 : AtomicBody->getSourceRange(); 8910 ErrorFound = NotAnAssignmentOp; 8911 } 8912 if (ErrorFound != NoError) { 8913 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8914 << ErrorRange; 8915 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8916 return StmtError(); 8917 } 8918 if (CurContext->isDependentContext()) 8919 UE = V = E = X = nullptr; 8920 } else { 8921 // If clause is a capture: 8922 // { v = x; x = expr; } 8923 // { v = x; x++; } 8924 // { v = x; x--; } 8925 // { v = x; ++x; } 8926 // { v = x; --x; } 8927 // { v = x; x binop= expr; } 8928 // { v = x; x = x binop expr; } 8929 // { v = x; x = expr binop x; } 8930 // { x++; v = x; } 8931 // { x--; v = x; } 8932 // { ++x; v = x; } 8933 // { --x; v = x; } 8934 // { x binop= expr; v = x; } 8935 // { x = x binop expr; v = x; } 8936 // { x = expr binop x; v = x; } 8937 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8938 // Check that this is { expr1; expr2; } 8939 if (CS->size() == 2) { 8940 Stmt *First = CS->body_front(); 8941 Stmt *Second = CS->body_back(); 8942 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8943 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8944 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8945 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8946 // Need to find what subexpression is 'v' and what is 'x'. 8947 OpenMPAtomicUpdateChecker Checker(*this); 8948 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8949 BinaryOperator *BinOp = nullptr; 8950 if (IsUpdateExprFound) { 8951 BinOp = dyn_cast<BinaryOperator>(First); 8952 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8953 } 8954 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8955 // { v = x; x++; } 8956 // { v = x; x--; } 8957 // { v = x; ++x; } 8958 // { v = x; --x; } 8959 // { v = x; x binop= expr; } 8960 // { v = x; x = x binop expr; } 8961 // { v = x; x = expr binop x; } 8962 // Check that the first expression has form v = x. 8963 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8964 llvm::FoldingSetNodeID XId, PossibleXId; 8965 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8966 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8967 IsUpdateExprFound = XId == PossibleXId; 8968 if (IsUpdateExprFound) { 8969 V = BinOp->getLHS(); 8970 X = Checker.getX(); 8971 E = Checker.getExpr(); 8972 UE = Checker.getUpdateExpr(); 8973 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8974 IsPostfixUpdate = true; 8975 } 8976 } 8977 if (!IsUpdateExprFound) { 8978 IsUpdateExprFound = !Checker.checkStatement(First); 8979 BinOp = nullptr; 8980 if (IsUpdateExprFound) { 8981 BinOp = dyn_cast<BinaryOperator>(Second); 8982 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8983 } 8984 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8985 // { x++; v = x; } 8986 // { x--; v = x; } 8987 // { ++x; v = x; } 8988 // { --x; v = x; } 8989 // { x binop= expr; v = x; } 8990 // { x = x binop expr; v = x; } 8991 // { x = expr binop x; v = x; } 8992 // Check that the second expression has form v = x. 8993 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8994 llvm::FoldingSetNodeID XId, PossibleXId; 8995 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8996 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8997 IsUpdateExprFound = XId == PossibleXId; 8998 if (IsUpdateExprFound) { 8999 V = BinOp->getLHS(); 9000 X = Checker.getX(); 9001 E = Checker.getExpr(); 9002 UE = Checker.getUpdateExpr(); 9003 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9004 IsPostfixUpdate = false; 9005 } 9006 } 9007 } 9008 if (!IsUpdateExprFound) { 9009 // { v = x; x = expr; } 9010 auto *FirstExpr = dyn_cast<Expr>(First); 9011 auto *SecondExpr = dyn_cast<Expr>(Second); 9012 if (!FirstExpr || !SecondExpr || 9013 !(FirstExpr->isInstantiationDependent() || 9014 SecondExpr->isInstantiationDependent())) { 9015 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9016 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9017 ErrorFound = NotAnAssignmentOp; 9018 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9019 : First->getBeginLoc(); 9020 NoteRange = ErrorRange = FirstBinOp 9021 ? FirstBinOp->getSourceRange() 9022 : SourceRange(ErrorLoc, ErrorLoc); 9023 } else { 9024 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9025 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9026 ErrorFound = NotAnAssignmentOp; 9027 NoteLoc = ErrorLoc = SecondBinOp 9028 ? SecondBinOp->getOperatorLoc() 9029 : Second->getBeginLoc(); 9030 NoteRange = ErrorRange = 9031 SecondBinOp ? SecondBinOp->getSourceRange() 9032 : SourceRange(ErrorLoc, ErrorLoc); 9033 } else { 9034 Expr *PossibleXRHSInFirst = 9035 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9036 Expr *PossibleXLHSInSecond = 9037 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9038 llvm::FoldingSetNodeID X1Id, X2Id; 9039 PossibleXRHSInFirst->Profile(X1Id, Context, 9040 /*Canonical=*/true); 9041 PossibleXLHSInSecond->Profile(X2Id, Context, 9042 /*Canonical=*/true); 9043 IsUpdateExprFound = X1Id == X2Id; 9044 if (IsUpdateExprFound) { 9045 V = FirstBinOp->getLHS(); 9046 X = SecondBinOp->getLHS(); 9047 E = SecondBinOp->getRHS(); 9048 UE = nullptr; 9049 IsXLHSInRHSPart = false; 9050 IsPostfixUpdate = true; 9051 } else { 9052 ErrorFound = NotASpecificExpression; 9053 ErrorLoc = FirstBinOp->getExprLoc(); 9054 ErrorRange = FirstBinOp->getSourceRange(); 9055 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9056 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9057 } 9058 } 9059 } 9060 } 9061 } 9062 } else { 9063 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9064 NoteRange = ErrorRange = 9065 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9066 ErrorFound = NotTwoSubstatements; 9067 } 9068 } else { 9069 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9070 NoteRange = ErrorRange = 9071 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9072 ErrorFound = NotACompoundStatement; 9073 } 9074 if (ErrorFound != NoError) { 9075 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9076 << ErrorRange; 9077 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9078 return StmtError(); 9079 } 9080 if (CurContext->isDependentContext()) 9081 UE = V = E = X = nullptr; 9082 } 9083 } 9084 9085 setFunctionHasBranchProtectedScope(); 9086 9087 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9088 X, V, E, UE, IsXLHSInRHSPart, 9089 IsPostfixUpdate); 9090 } 9091 9092 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9093 Stmt *AStmt, 9094 SourceLocation StartLoc, 9095 SourceLocation EndLoc) { 9096 if (!AStmt) 9097 return StmtError(); 9098 9099 auto *CS = cast<CapturedStmt>(AStmt); 9100 // 1.2.2 OpenMP Language Terminology 9101 // Structured block - An executable statement with a single entry at the 9102 // top and a single exit at the bottom. 9103 // The point of exit cannot be a branch out of the structured block. 9104 // longjmp() and throw() must not violate the entry/exit criteria. 9105 CS->getCapturedDecl()->setNothrow(); 9106 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9107 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9108 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9109 // 1.2.2 OpenMP Language Terminology 9110 // Structured block - An executable statement with a single entry at the 9111 // top and a single exit at the bottom. 9112 // The point of exit cannot be a branch out of the structured block. 9113 // longjmp() and throw() must not violate the entry/exit criteria. 9114 CS->getCapturedDecl()->setNothrow(); 9115 } 9116 9117 // OpenMP [2.16, Nesting of Regions] 9118 // If specified, a teams construct must be contained within a target 9119 // construct. That target construct must contain no statements or directives 9120 // outside of the teams construct. 9121 if (DSAStack->hasInnerTeamsRegion()) { 9122 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9123 bool OMPTeamsFound = true; 9124 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9125 auto I = CS->body_begin(); 9126 while (I != CS->body_end()) { 9127 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9128 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9129 OMPTeamsFound) { 9130 9131 OMPTeamsFound = false; 9132 break; 9133 } 9134 ++I; 9135 } 9136 assert(I != CS->body_end() && "Not found statement"); 9137 S = *I; 9138 } else { 9139 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9140 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9141 } 9142 if (!OMPTeamsFound) { 9143 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9144 Diag(DSAStack->getInnerTeamsRegionLoc(), 9145 diag::note_omp_nested_teams_construct_here); 9146 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9147 << isa<OMPExecutableDirective>(S); 9148 return StmtError(); 9149 } 9150 } 9151 9152 setFunctionHasBranchProtectedScope(); 9153 9154 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9155 } 9156 9157 StmtResult 9158 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9159 Stmt *AStmt, SourceLocation StartLoc, 9160 SourceLocation EndLoc) { 9161 if (!AStmt) 9162 return StmtError(); 9163 9164 auto *CS = cast<CapturedStmt>(AStmt); 9165 // 1.2.2 OpenMP Language Terminology 9166 // Structured block - An executable statement with a single entry at the 9167 // top and a single exit at the bottom. 9168 // The point of exit cannot be a branch out of the structured block. 9169 // longjmp() and throw() must not violate the entry/exit criteria. 9170 CS->getCapturedDecl()->setNothrow(); 9171 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9172 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9173 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9174 // 1.2.2 OpenMP Language Terminology 9175 // Structured block - An executable statement with a single entry at the 9176 // top and a single exit at the bottom. 9177 // The point of exit cannot be a branch out of the structured block. 9178 // longjmp() and throw() must not violate the entry/exit criteria. 9179 CS->getCapturedDecl()->setNothrow(); 9180 } 9181 9182 setFunctionHasBranchProtectedScope(); 9183 9184 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9185 AStmt); 9186 } 9187 9188 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9189 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9190 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9191 if (!AStmt) 9192 return StmtError(); 9193 9194 auto *CS = cast<CapturedStmt>(AStmt); 9195 // 1.2.2 OpenMP Language Terminology 9196 // Structured block - An executable statement with a single entry at the 9197 // top and a single exit at the bottom. 9198 // The point of exit cannot be a branch out of the structured block. 9199 // longjmp() and throw() must not violate the entry/exit criteria. 9200 CS->getCapturedDecl()->setNothrow(); 9201 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9202 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9203 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9204 // 1.2.2 OpenMP Language Terminology 9205 // Structured block - An executable statement with a single entry at the 9206 // top and a single exit at the bottom. 9207 // The point of exit cannot be a branch out of the structured block. 9208 // longjmp() and throw() must not violate the entry/exit criteria. 9209 CS->getCapturedDecl()->setNothrow(); 9210 } 9211 9212 OMPLoopDirective::HelperExprs B; 9213 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9214 // define the nested loops number. 9215 unsigned NestedLoopCount = 9216 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9217 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9218 VarsWithImplicitDSA, B); 9219 if (NestedLoopCount == 0) 9220 return StmtError(); 9221 9222 assert((CurContext->isDependentContext() || B.builtAll()) && 9223 "omp target parallel for loop exprs were not built"); 9224 9225 if (!CurContext->isDependentContext()) { 9226 // Finalize the clauses that need pre-built expressions for CodeGen. 9227 for (OMPClause *C : Clauses) { 9228 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9229 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9230 B.NumIterations, *this, CurScope, 9231 DSAStack)) 9232 return StmtError(); 9233 } 9234 } 9235 9236 setFunctionHasBranchProtectedScope(); 9237 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9238 NestedLoopCount, Clauses, AStmt, 9239 B, DSAStack->isCancelRegion()); 9240 } 9241 9242 /// Check for existence of a map clause in the list of clauses. 9243 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9244 const OpenMPClauseKind K) { 9245 return llvm::any_of( 9246 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9247 } 9248 9249 template <typename... Params> 9250 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9251 const Params... ClauseTypes) { 9252 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9253 } 9254 9255 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9256 Stmt *AStmt, 9257 SourceLocation StartLoc, 9258 SourceLocation EndLoc) { 9259 if (!AStmt) 9260 return StmtError(); 9261 9262 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9263 9264 // OpenMP [2.10.1, Restrictions, p. 97] 9265 // At least one map clause must appear on the directive. 9266 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9267 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9268 << "'map' or 'use_device_ptr'" 9269 << getOpenMPDirectiveName(OMPD_target_data); 9270 return StmtError(); 9271 } 9272 9273 setFunctionHasBranchProtectedScope(); 9274 9275 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9276 AStmt); 9277 } 9278 9279 StmtResult 9280 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9281 SourceLocation StartLoc, 9282 SourceLocation EndLoc, Stmt *AStmt) { 9283 if (!AStmt) 9284 return StmtError(); 9285 9286 auto *CS = cast<CapturedStmt>(AStmt); 9287 // 1.2.2 OpenMP Language Terminology 9288 // Structured block - An executable statement with a single entry at the 9289 // top and a single exit at the bottom. 9290 // The point of exit cannot be a branch out of the structured block. 9291 // longjmp() and throw() must not violate the entry/exit criteria. 9292 CS->getCapturedDecl()->setNothrow(); 9293 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9294 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9295 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9296 // 1.2.2 OpenMP Language Terminology 9297 // Structured block - An executable statement with a single entry at the 9298 // top and a single exit at the bottom. 9299 // The point of exit cannot be a branch out of the structured block. 9300 // longjmp() and throw() must not violate the entry/exit criteria. 9301 CS->getCapturedDecl()->setNothrow(); 9302 } 9303 9304 // OpenMP [2.10.2, Restrictions, p. 99] 9305 // At least one map clause must appear on the directive. 9306 if (!hasClauses(Clauses, OMPC_map)) { 9307 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9308 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9309 return StmtError(); 9310 } 9311 9312 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9313 AStmt); 9314 } 9315 9316 StmtResult 9317 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9318 SourceLocation StartLoc, 9319 SourceLocation EndLoc, Stmt *AStmt) { 9320 if (!AStmt) 9321 return StmtError(); 9322 9323 auto *CS = cast<CapturedStmt>(AStmt); 9324 // 1.2.2 OpenMP Language Terminology 9325 // Structured block - An executable statement with a single entry at the 9326 // top and a single exit at the bottom. 9327 // The point of exit cannot be a branch out of the structured block. 9328 // longjmp() and throw() must not violate the entry/exit criteria. 9329 CS->getCapturedDecl()->setNothrow(); 9330 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9331 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9332 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9333 // 1.2.2 OpenMP Language Terminology 9334 // Structured block - An executable statement with a single entry at the 9335 // top and a single exit at the bottom. 9336 // The point of exit cannot be a branch out of the structured block. 9337 // longjmp() and throw() must not violate the entry/exit criteria. 9338 CS->getCapturedDecl()->setNothrow(); 9339 } 9340 9341 // OpenMP [2.10.3, Restrictions, p. 102] 9342 // At least one map clause must appear on the directive. 9343 if (!hasClauses(Clauses, OMPC_map)) { 9344 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9345 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9346 return StmtError(); 9347 } 9348 9349 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9350 AStmt); 9351 } 9352 9353 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9354 SourceLocation StartLoc, 9355 SourceLocation EndLoc, 9356 Stmt *AStmt) { 9357 if (!AStmt) 9358 return StmtError(); 9359 9360 auto *CS = cast<CapturedStmt>(AStmt); 9361 // 1.2.2 OpenMP Language Terminology 9362 // Structured block - An executable statement with a single entry at the 9363 // top and a single exit at the bottom. 9364 // The point of exit cannot be a branch out of the structured block. 9365 // longjmp() and throw() must not violate the entry/exit criteria. 9366 CS->getCapturedDecl()->setNothrow(); 9367 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9368 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9369 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9370 // 1.2.2 OpenMP Language Terminology 9371 // Structured block - An executable statement with a single entry at the 9372 // top and a single exit at the bottom. 9373 // The point of exit cannot be a branch out of the structured block. 9374 // longjmp() and throw() must not violate the entry/exit criteria. 9375 CS->getCapturedDecl()->setNothrow(); 9376 } 9377 9378 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9379 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9380 return StmtError(); 9381 } 9382 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9383 AStmt); 9384 } 9385 9386 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9387 Stmt *AStmt, SourceLocation StartLoc, 9388 SourceLocation EndLoc) { 9389 if (!AStmt) 9390 return StmtError(); 9391 9392 auto *CS = cast<CapturedStmt>(AStmt); 9393 // 1.2.2 OpenMP Language Terminology 9394 // Structured block - An executable statement with a single entry at the 9395 // top and a single exit at the bottom. 9396 // The point of exit cannot be a branch out of the structured block. 9397 // longjmp() and throw() must not violate the entry/exit criteria. 9398 CS->getCapturedDecl()->setNothrow(); 9399 9400 setFunctionHasBranchProtectedScope(); 9401 9402 DSAStack->setParentTeamsRegionLoc(StartLoc); 9403 9404 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9405 } 9406 9407 StmtResult 9408 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9409 SourceLocation EndLoc, 9410 OpenMPDirectiveKind CancelRegion) { 9411 if (DSAStack->isParentNowaitRegion()) { 9412 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9413 return StmtError(); 9414 } 9415 if (DSAStack->isParentOrderedRegion()) { 9416 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9417 return StmtError(); 9418 } 9419 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9420 CancelRegion); 9421 } 9422 9423 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9424 SourceLocation StartLoc, 9425 SourceLocation EndLoc, 9426 OpenMPDirectiveKind CancelRegion) { 9427 if (DSAStack->isParentNowaitRegion()) { 9428 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9429 return StmtError(); 9430 } 9431 if (DSAStack->isParentOrderedRegion()) { 9432 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9433 return StmtError(); 9434 } 9435 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9436 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9437 CancelRegion); 9438 } 9439 9440 static bool checkGrainsizeNumTasksClauses(Sema &S, 9441 ArrayRef<OMPClause *> Clauses) { 9442 const OMPClause *PrevClause = nullptr; 9443 bool ErrorFound = false; 9444 for (const OMPClause *C : Clauses) { 9445 if (C->getClauseKind() == OMPC_grainsize || 9446 C->getClauseKind() == OMPC_num_tasks) { 9447 if (!PrevClause) 9448 PrevClause = C; 9449 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9450 S.Diag(C->getBeginLoc(), 9451 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9452 << getOpenMPClauseName(C->getClauseKind()) 9453 << getOpenMPClauseName(PrevClause->getClauseKind()); 9454 S.Diag(PrevClause->getBeginLoc(), 9455 diag::note_omp_previous_grainsize_num_tasks) 9456 << getOpenMPClauseName(PrevClause->getClauseKind()); 9457 ErrorFound = true; 9458 } 9459 } 9460 } 9461 return ErrorFound; 9462 } 9463 9464 static bool checkReductionClauseWithNogroup(Sema &S, 9465 ArrayRef<OMPClause *> Clauses) { 9466 const OMPClause *ReductionClause = nullptr; 9467 const OMPClause *NogroupClause = nullptr; 9468 for (const OMPClause *C : Clauses) { 9469 if (C->getClauseKind() == OMPC_reduction) { 9470 ReductionClause = C; 9471 if (NogroupClause) 9472 break; 9473 continue; 9474 } 9475 if (C->getClauseKind() == OMPC_nogroup) { 9476 NogroupClause = C; 9477 if (ReductionClause) 9478 break; 9479 continue; 9480 } 9481 } 9482 if (ReductionClause && NogroupClause) { 9483 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9484 << SourceRange(NogroupClause->getBeginLoc(), 9485 NogroupClause->getEndLoc()); 9486 return true; 9487 } 9488 return false; 9489 } 9490 9491 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9492 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9493 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9494 if (!AStmt) 9495 return StmtError(); 9496 9497 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9498 OMPLoopDirective::HelperExprs B; 9499 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9500 // define the nested loops number. 9501 unsigned NestedLoopCount = 9502 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9503 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9504 VarsWithImplicitDSA, B); 9505 if (NestedLoopCount == 0) 9506 return StmtError(); 9507 9508 assert((CurContext->isDependentContext() || B.builtAll()) && 9509 "omp for loop exprs were not built"); 9510 9511 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9512 // The grainsize clause and num_tasks clause are mutually exclusive and may 9513 // not appear on the same taskloop directive. 9514 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9515 return StmtError(); 9516 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9517 // If a reduction clause is present on the taskloop directive, the nogroup 9518 // clause must not be specified. 9519 if (checkReductionClauseWithNogroup(*this, Clauses)) 9520 return StmtError(); 9521 9522 setFunctionHasBranchProtectedScope(); 9523 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9524 NestedLoopCount, Clauses, AStmt, B); 9525 } 9526 9527 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9528 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9529 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9530 if (!AStmt) 9531 return StmtError(); 9532 9533 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9534 OMPLoopDirective::HelperExprs B; 9535 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9536 // define the nested loops number. 9537 unsigned NestedLoopCount = 9538 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9539 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9540 VarsWithImplicitDSA, B); 9541 if (NestedLoopCount == 0) 9542 return StmtError(); 9543 9544 assert((CurContext->isDependentContext() || B.builtAll()) && 9545 "omp for loop exprs were not built"); 9546 9547 if (!CurContext->isDependentContext()) { 9548 // Finalize the clauses that need pre-built expressions for CodeGen. 9549 for (OMPClause *C : Clauses) { 9550 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9551 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9552 B.NumIterations, *this, CurScope, 9553 DSAStack)) 9554 return StmtError(); 9555 } 9556 } 9557 9558 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9559 // The grainsize clause and num_tasks clause are mutually exclusive and may 9560 // not appear on the same taskloop directive. 9561 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9562 return StmtError(); 9563 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9564 // If a reduction clause is present on the taskloop directive, the nogroup 9565 // clause must not be specified. 9566 if (checkReductionClauseWithNogroup(*this, Clauses)) 9567 return StmtError(); 9568 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9569 return StmtError(); 9570 9571 setFunctionHasBranchProtectedScope(); 9572 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9573 NestedLoopCount, Clauses, AStmt, B); 9574 } 9575 9576 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9577 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9578 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9579 if (!AStmt) 9580 return StmtError(); 9581 9582 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9583 OMPLoopDirective::HelperExprs B; 9584 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9585 // define the nested loops number. 9586 unsigned NestedLoopCount = 9587 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9588 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9589 VarsWithImplicitDSA, B); 9590 if (NestedLoopCount == 0) 9591 return StmtError(); 9592 9593 assert((CurContext->isDependentContext() || B.builtAll()) && 9594 "omp for loop exprs were not built"); 9595 9596 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9597 // The grainsize clause and num_tasks clause are mutually exclusive and may 9598 // not appear on the same taskloop directive. 9599 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9600 return StmtError(); 9601 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9602 // If a reduction clause is present on the taskloop directive, the nogroup 9603 // clause must not be specified. 9604 if (checkReductionClauseWithNogroup(*this, Clauses)) 9605 return StmtError(); 9606 9607 setFunctionHasBranchProtectedScope(); 9608 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9609 NestedLoopCount, Clauses, AStmt, B); 9610 } 9611 9612 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9613 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9614 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9615 if (!AStmt) 9616 return StmtError(); 9617 9618 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9619 OMPLoopDirective::HelperExprs B; 9620 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9621 // define the nested loops number. 9622 unsigned NestedLoopCount = 9623 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9624 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9625 VarsWithImplicitDSA, B); 9626 if (NestedLoopCount == 0) 9627 return StmtError(); 9628 9629 assert((CurContext->isDependentContext() || B.builtAll()) && 9630 "omp for loop exprs were not built"); 9631 9632 if (!CurContext->isDependentContext()) { 9633 // Finalize the clauses that need pre-built expressions for CodeGen. 9634 for (OMPClause *C : Clauses) { 9635 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9636 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9637 B.NumIterations, *this, CurScope, 9638 DSAStack)) 9639 return StmtError(); 9640 } 9641 } 9642 9643 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9644 // The grainsize clause and num_tasks clause are mutually exclusive and may 9645 // not appear on the same taskloop directive. 9646 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9647 return StmtError(); 9648 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9649 // If a reduction clause is present on the taskloop directive, the nogroup 9650 // clause must not be specified. 9651 if (checkReductionClauseWithNogroup(*this, Clauses)) 9652 return StmtError(); 9653 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9654 return StmtError(); 9655 9656 setFunctionHasBranchProtectedScope(); 9657 return OMPMasterTaskLoopSimdDirective::Create( 9658 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9659 } 9660 9661 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9662 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9663 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9664 if (!AStmt) 9665 return StmtError(); 9666 9667 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9668 auto *CS = cast<CapturedStmt>(AStmt); 9669 // 1.2.2 OpenMP Language Terminology 9670 // Structured block - An executable statement with a single entry at the 9671 // top and a single exit at the bottom. 9672 // The point of exit cannot be a branch out of the structured block. 9673 // longjmp() and throw() must not violate the entry/exit criteria. 9674 CS->getCapturedDecl()->setNothrow(); 9675 for (int ThisCaptureLevel = 9676 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9677 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9678 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9679 // 1.2.2 OpenMP Language Terminology 9680 // Structured block - An executable statement with a single entry at the 9681 // top and a single exit at the bottom. 9682 // The point of exit cannot be a branch out of the structured block. 9683 // longjmp() and throw() must not violate the entry/exit criteria. 9684 CS->getCapturedDecl()->setNothrow(); 9685 } 9686 9687 OMPLoopDirective::HelperExprs B; 9688 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9689 // define the nested loops number. 9690 unsigned NestedLoopCount = checkOpenMPLoop( 9691 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9692 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9693 VarsWithImplicitDSA, B); 9694 if (NestedLoopCount == 0) 9695 return StmtError(); 9696 9697 assert((CurContext->isDependentContext() || B.builtAll()) && 9698 "omp for loop exprs were not built"); 9699 9700 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9701 // The grainsize clause and num_tasks clause are mutually exclusive and may 9702 // not appear on the same taskloop directive. 9703 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9704 return StmtError(); 9705 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9706 // If a reduction clause is present on the taskloop directive, the nogroup 9707 // clause must not be specified. 9708 if (checkReductionClauseWithNogroup(*this, Clauses)) 9709 return StmtError(); 9710 9711 setFunctionHasBranchProtectedScope(); 9712 return OMPParallelMasterTaskLoopDirective::Create( 9713 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9714 } 9715 9716 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9717 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9718 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9719 if (!AStmt) 9720 return StmtError(); 9721 9722 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9723 auto *CS = cast<CapturedStmt>(AStmt); 9724 // 1.2.2 OpenMP Language Terminology 9725 // Structured block - An executable statement with a single entry at the 9726 // top and a single exit at the bottom. 9727 // The point of exit cannot be a branch out of the structured block. 9728 // longjmp() and throw() must not violate the entry/exit criteria. 9729 CS->getCapturedDecl()->setNothrow(); 9730 for (int ThisCaptureLevel = 9731 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9732 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9733 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9734 // 1.2.2 OpenMP Language Terminology 9735 // Structured block - An executable statement with a single entry at the 9736 // top and a single exit at the bottom. 9737 // The point of exit cannot be a branch out of the structured block. 9738 // longjmp() and throw() must not violate the entry/exit criteria. 9739 CS->getCapturedDecl()->setNothrow(); 9740 } 9741 9742 OMPLoopDirective::HelperExprs B; 9743 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9744 // define the nested loops number. 9745 unsigned NestedLoopCount = checkOpenMPLoop( 9746 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9747 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9748 VarsWithImplicitDSA, B); 9749 if (NestedLoopCount == 0) 9750 return StmtError(); 9751 9752 assert((CurContext->isDependentContext() || B.builtAll()) && 9753 "omp for loop exprs were not built"); 9754 9755 if (!CurContext->isDependentContext()) { 9756 // Finalize the clauses that need pre-built expressions for CodeGen. 9757 for (OMPClause *C : Clauses) { 9758 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9759 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9760 B.NumIterations, *this, CurScope, 9761 DSAStack)) 9762 return StmtError(); 9763 } 9764 } 9765 9766 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9767 // The grainsize clause and num_tasks clause are mutually exclusive and may 9768 // not appear on the same taskloop directive. 9769 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9770 return StmtError(); 9771 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9772 // If a reduction clause is present on the taskloop directive, the nogroup 9773 // clause must not be specified. 9774 if (checkReductionClauseWithNogroup(*this, Clauses)) 9775 return StmtError(); 9776 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9777 return StmtError(); 9778 9779 setFunctionHasBranchProtectedScope(); 9780 return OMPParallelMasterTaskLoopSimdDirective::Create( 9781 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9782 } 9783 9784 StmtResult Sema::ActOnOpenMPDistributeDirective( 9785 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9786 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9787 if (!AStmt) 9788 return StmtError(); 9789 9790 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9791 OMPLoopDirective::HelperExprs B; 9792 // In presence of clause 'collapse' with number of loops, it will 9793 // define the nested loops number. 9794 unsigned NestedLoopCount = 9795 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9796 nullptr /*ordered not a clause on distribute*/, AStmt, 9797 *this, *DSAStack, VarsWithImplicitDSA, B); 9798 if (NestedLoopCount == 0) 9799 return StmtError(); 9800 9801 assert((CurContext->isDependentContext() || B.builtAll()) && 9802 "omp for loop exprs were not built"); 9803 9804 setFunctionHasBranchProtectedScope(); 9805 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9806 NestedLoopCount, Clauses, AStmt, B); 9807 } 9808 9809 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9810 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9811 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9812 if (!AStmt) 9813 return StmtError(); 9814 9815 auto *CS = cast<CapturedStmt>(AStmt); 9816 // 1.2.2 OpenMP Language Terminology 9817 // Structured block - An executable statement with a single entry at the 9818 // top and a single exit at the bottom. 9819 // The point of exit cannot be a branch out of the structured block. 9820 // longjmp() and throw() must not violate the entry/exit criteria. 9821 CS->getCapturedDecl()->setNothrow(); 9822 for (int ThisCaptureLevel = 9823 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9824 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9825 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9826 // 1.2.2 OpenMP Language Terminology 9827 // Structured block - An executable statement with a single entry at the 9828 // top and a single exit at the bottom. 9829 // The point of exit cannot be a branch out of the structured block. 9830 // longjmp() and throw() must not violate the entry/exit criteria. 9831 CS->getCapturedDecl()->setNothrow(); 9832 } 9833 9834 OMPLoopDirective::HelperExprs B; 9835 // In presence of clause 'collapse' with number of loops, it will 9836 // define the nested loops number. 9837 unsigned NestedLoopCount = checkOpenMPLoop( 9838 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9839 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9840 VarsWithImplicitDSA, B); 9841 if (NestedLoopCount == 0) 9842 return StmtError(); 9843 9844 assert((CurContext->isDependentContext() || B.builtAll()) && 9845 "omp for loop exprs were not built"); 9846 9847 setFunctionHasBranchProtectedScope(); 9848 return OMPDistributeParallelForDirective::Create( 9849 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9850 DSAStack->isCancelRegion()); 9851 } 9852 9853 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9854 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9855 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9856 if (!AStmt) 9857 return StmtError(); 9858 9859 auto *CS = cast<CapturedStmt>(AStmt); 9860 // 1.2.2 OpenMP Language Terminology 9861 // Structured block - An executable statement with a single entry at the 9862 // top and a single exit at the bottom. 9863 // The point of exit cannot be a branch out of the structured block. 9864 // longjmp() and throw() must not violate the entry/exit criteria. 9865 CS->getCapturedDecl()->setNothrow(); 9866 for (int ThisCaptureLevel = 9867 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9868 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9869 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9870 // 1.2.2 OpenMP Language Terminology 9871 // Structured block - An executable statement with a single entry at the 9872 // top and a single exit at the bottom. 9873 // The point of exit cannot be a branch out of the structured block. 9874 // longjmp() and throw() must not violate the entry/exit criteria. 9875 CS->getCapturedDecl()->setNothrow(); 9876 } 9877 9878 OMPLoopDirective::HelperExprs B; 9879 // In presence of clause 'collapse' with number of loops, it will 9880 // define the nested loops number. 9881 unsigned NestedLoopCount = checkOpenMPLoop( 9882 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9883 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9884 VarsWithImplicitDSA, B); 9885 if (NestedLoopCount == 0) 9886 return StmtError(); 9887 9888 assert((CurContext->isDependentContext() || B.builtAll()) && 9889 "omp for loop exprs were not built"); 9890 9891 if (!CurContext->isDependentContext()) { 9892 // Finalize the clauses that need pre-built expressions for CodeGen. 9893 for (OMPClause *C : Clauses) { 9894 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9895 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9896 B.NumIterations, *this, CurScope, 9897 DSAStack)) 9898 return StmtError(); 9899 } 9900 } 9901 9902 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9903 return StmtError(); 9904 9905 setFunctionHasBranchProtectedScope(); 9906 return OMPDistributeParallelForSimdDirective::Create( 9907 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9908 } 9909 9910 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9911 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9912 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9913 if (!AStmt) 9914 return StmtError(); 9915 9916 auto *CS = cast<CapturedStmt>(AStmt); 9917 // 1.2.2 OpenMP Language Terminology 9918 // Structured block - An executable statement with a single entry at the 9919 // top and a single exit at the bottom. 9920 // The point of exit cannot be a branch out of the structured block. 9921 // longjmp() and throw() must not violate the entry/exit criteria. 9922 CS->getCapturedDecl()->setNothrow(); 9923 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9924 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9925 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9926 // 1.2.2 OpenMP Language Terminology 9927 // Structured block - An executable statement with a single entry at the 9928 // top and a single exit at the bottom. 9929 // The point of exit cannot be a branch out of the structured block. 9930 // longjmp() and throw() must not violate the entry/exit criteria. 9931 CS->getCapturedDecl()->setNothrow(); 9932 } 9933 9934 OMPLoopDirective::HelperExprs B; 9935 // In presence of clause 'collapse' with number of loops, it will 9936 // define the nested loops number. 9937 unsigned NestedLoopCount = 9938 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9939 nullptr /*ordered not a clause on distribute*/, CS, *this, 9940 *DSAStack, VarsWithImplicitDSA, B); 9941 if (NestedLoopCount == 0) 9942 return StmtError(); 9943 9944 assert((CurContext->isDependentContext() || B.builtAll()) && 9945 "omp for loop exprs were not built"); 9946 9947 if (!CurContext->isDependentContext()) { 9948 // Finalize the clauses that need pre-built expressions for CodeGen. 9949 for (OMPClause *C : Clauses) { 9950 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9951 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9952 B.NumIterations, *this, CurScope, 9953 DSAStack)) 9954 return StmtError(); 9955 } 9956 } 9957 9958 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9959 return StmtError(); 9960 9961 setFunctionHasBranchProtectedScope(); 9962 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9963 NestedLoopCount, Clauses, AStmt, B); 9964 } 9965 9966 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9967 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9968 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9969 if (!AStmt) 9970 return StmtError(); 9971 9972 auto *CS = cast<CapturedStmt>(AStmt); 9973 // 1.2.2 OpenMP Language Terminology 9974 // Structured block - An executable statement with a single entry at the 9975 // top and a single exit at the bottom. 9976 // The point of exit cannot be a branch out of the structured block. 9977 // longjmp() and throw() must not violate the entry/exit criteria. 9978 CS->getCapturedDecl()->setNothrow(); 9979 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9980 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9981 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9982 // 1.2.2 OpenMP Language Terminology 9983 // Structured block - An executable statement with a single entry at the 9984 // top and a single exit at the bottom. 9985 // The point of exit cannot be a branch out of the structured block. 9986 // longjmp() and throw() must not violate the entry/exit criteria. 9987 CS->getCapturedDecl()->setNothrow(); 9988 } 9989 9990 OMPLoopDirective::HelperExprs B; 9991 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9992 // define the nested loops number. 9993 unsigned NestedLoopCount = checkOpenMPLoop( 9994 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9995 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9996 VarsWithImplicitDSA, B); 9997 if (NestedLoopCount == 0) 9998 return StmtError(); 9999 10000 assert((CurContext->isDependentContext() || B.builtAll()) && 10001 "omp target parallel for simd loop exprs were not built"); 10002 10003 if (!CurContext->isDependentContext()) { 10004 // Finalize the clauses that need pre-built expressions for CodeGen. 10005 for (OMPClause *C : Clauses) { 10006 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10007 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10008 B.NumIterations, *this, CurScope, 10009 DSAStack)) 10010 return StmtError(); 10011 } 10012 } 10013 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10014 return StmtError(); 10015 10016 setFunctionHasBranchProtectedScope(); 10017 return OMPTargetParallelForSimdDirective::Create( 10018 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10019 } 10020 10021 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10022 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10023 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10024 if (!AStmt) 10025 return StmtError(); 10026 10027 auto *CS = cast<CapturedStmt>(AStmt); 10028 // 1.2.2 OpenMP Language Terminology 10029 // Structured block - An executable statement with a single entry at the 10030 // top and a single exit at the bottom. 10031 // The point of exit cannot be a branch out of the structured block. 10032 // longjmp() and throw() must not violate the entry/exit criteria. 10033 CS->getCapturedDecl()->setNothrow(); 10034 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10035 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10036 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10037 // 1.2.2 OpenMP Language Terminology 10038 // Structured block - An executable statement with a single entry at the 10039 // top and a single exit at the bottom. 10040 // The point of exit cannot be a branch out of the structured block. 10041 // longjmp() and throw() must not violate the entry/exit criteria. 10042 CS->getCapturedDecl()->setNothrow(); 10043 } 10044 10045 OMPLoopDirective::HelperExprs B; 10046 // In presence of clause 'collapse' with number of loops, it will define the 10047 // nested loops number. 10048 unsigned NestedLoopCount = 10049 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10050 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10051 VarsWithImplicitDSA, B); 10052 if (NestedLoopCount == 0) 10053 return StmtError(); 10054 10055 assert((CurContext->isDependentContext() || B.builtAll()) && 10056 "omp target simd loop exprs were not built"); 10057 10058 if (!CurContext->isDependentContext()) { 10059 // Finalize the clauses that need pre-built expressions for CodeGen. 10060 for (OMPClause *C : Clauses) { 10061 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10062 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10063 B.NumIterations, *this, CurScope, 10064 DSAStack)) 10065 return StmtError(); 10066 } 10067 } 10068 10069 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10070 return StmtError(); 10071 10072 setFunctionHasBranchProtectedScope(); 10073 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10074 NestedLoopCount, Clauses, AStmt, B); 10075 } 10076 10077 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10078 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10079 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10080 if (!AStmt) 10081 return StmtError(); 10082 10083 auto *CS = cast<CapturedStmt>(AStmt); 10084 // 1.2.2 OpenMP Language Terminology 10085 // Structured block - An executable statement with a single entry at the 10086 // top and a single exit at the bottom. 10087 // The point of exit cannot be a branch out of the structured block. 10088 // longjmp() and throw() must not violate the entry/exit criteria. 10089 CS->getCapturedDecl()->setNothrow(); 10090 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10091 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10092 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10093 // 1.2.2 OpenMP Language Terminology 10094 // Structured block - An executable statement with a single entry at the 10095 // top and a single exit at the bottom. 10096 // The point of exit cannot be a branch out of the structured block. 10097 // longjmp() and throw() must not violate the entry/exit criteria. 10098 CS->getCapturedDecl()->setNothrow(); 10099 } 10100 10101 OMPLoopDirective::HelperExprs B; 10102 // In presence of clause 'collapse' with number of loops, it will 10103 // define the nested loops number. 10104 unsigned NestedLoopCount = 10105 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10106 nullptr /*ordered not a clause on distribute*/, CS, *this, 10107 *DSAStack, VarsWithImplicitDSA, B); 10108 if (NestedLoopCount == 0) 10109 return StmtError(); 10110 10111 assert((CurContext->isDependentContext() || B.builtAll()) && 10112 "omp teams distribute loop exprs were not built"); 10113 10114 setFunctionHasBranchProtectedScope(); 10115 10116 DSAStack->setParentTeamsRegionLoc(StartLoc); 10117 10118 return OMPTeamsDistributeDirective::Create( 10119 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10120 } 10121 10122 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10123 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10124 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10125 if (!AStmt) 10126 return StmtError(); 10127 10128 auto *CS = cast<CapturedStmt>(AStmt); 10129 // 1.2.2 OpenMP Language Terminology 10130 // Structured block - An executable statement with a single entry at the 10131 // top and a single exit at the bottom. 10132 // The point of exit cannot be a branch out of the structured block. 10133 // longjmp() and throw() must not violate the entry/exit criteria. 10134 CS->getCapturedDecl()->setNothrow(); 10135 for (int ThisCaptureLevel = 10136 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10137 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10138 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10139 // 1.2.2 OpenMP Language Terminology 10140 // Structured block - An executable statement with a single entry at the 10141 // top and a single exit at the bottom. 10142 // The point of exit cannot be a branch out of the structured block. 10143 // longjmp() and throw() must not violate the entry/exit criteria. 10144 CS->getCapturedDecl()->setNothrow(); 10145 } 10146 10147 10148 OMPLoopDirective::HelperExprs B; 10149 // In presence of clause 'collapse' with number of loops, it will 10150 // define the nested loops number. 10151 unsigned NestedLoopCount = checkOpenMPLoop( 10152 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10153 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10154 VarsWithImplicitDSA, B); 10155 10156 if (NestedLoopCount == 0) 10157 return StmtError(); 10158 10159 assert((CurContext->isDependentContext() || B.builtAll()) && 10160 "omp teams distribute simd loop exprs were not built"); 10161 10162 if (!CurContext->isDependentContext()) { 10163 // Finalize the clauses that need pre-built expressions for CodeGen. 10164 for (OMPClause *C : Clauses) { 10165 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10166 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10167 B.NumIterations, *this, CurScope, 10168 DSAStack)) 10169 return StmtError(); 10170 } 10171 } 10172 10173 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10174 return StmtError(); 10175 10176 setFunctionHasBranchProtectedScope(); 10177 10178 DSAStack->setParentTeamsRegionLoc(StartLoc); 10179 10180 return OMPTeamsDistributeSimdDirective::Create( 10181 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10182 } 10183 10184 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10185 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10186 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10187 if (!AStmt) 10188 return StmtError(); 10189 10190 auto *CS = cast<CapturedStmt>(AStmt); 10191 // 1.2.2 OpenMP Language Terminology 10192 // Structured block - An executable statement with a single entry at the 10193 // top and a single exit at the bottom. 10194 // The point of exit cannot be a branch out of the structured block. 10195 // longjmp() and throw() must not violate the entry/exit criteria. 10196 CS->getCapturedDecl()->setNothrow(); 10197 10198 for (int ThisCaptureLevel = 10199 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10200 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10201 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10202 // 1.2.2 OpenMP Language Terminology 10203 // Structured block - An executable statement with a single entry at the 10204 // top and a single exit at the bottom. 10205 // The point of exit cannot be a branch out of the structured block. 10206 // longjmp() and throw() must not violate the entry/exit criteria. 10207 CS->getCapturedDecl()->setNothrow(); 10208 } 10209 10210 OMPLoopDirective::HelperExprs B; 10211 // In presence of clause 'collapse' with number of loops, it will 10212 // define the nested loops number. 10213 unsigned NestedLoopCount = checkOpenMPLoop( 10214 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10215 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10216 VarsWithImplicitDSA, B); 10217 10218 if (NestedLoopCount == 0) 10219 return StmtError(); 10220 10221 assert((CurContext->isDependentContext() || B.builtAll()) && 10222 "omp for loop exprs were not built"); 10223 10224 if (!CurContext->isDependentContext()) { 10225 // Finalize the clauses that need pre-built expressions for CodeGen. 10226 for (OMPClause *C : Clauses) { 10227 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10228 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10229 B.NumIterations, *this, CurScope, 10230 DSAStack)) 10231 return StmtError(); 10232 } 10233 } 10234 10235 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10236 return StmtError(); 10237 10238 setFunctionHasBranchProtectedScope(); 10239 10240 DSAStack->setParentTeamsRegionLoc(StartLoc); 10241 10242 return OMPTeamsDistributeParallelForSimdDirective::Create( 10243 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10244 } 10245 10246 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10247 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10248 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10249 if (!AStmt) 10250 return StmtError(); 10251 10252 auto *CS = cast<CapturedStmt>(AStmt); 10253 // 1.2.2 OpenMP Language Terminology 10254 // Structured block - An executable statement with a single entry at the 10255 // top and a single exit at the bottom. 10256 // The point of exit cannot be a branch out of the structured block. 10257 // longjmp() and throw() must not violate the entry/exit criteria. 10258 CS->getCapturedDecl()->setNothrow(); 10259 10260 for (int ThisCaptureLevel = 10261 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10262 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10263 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10264 // 1.2.2 OpenMP Language Terminology 10265 // Structured block - An executable statement with a single entry at the 10266 // top and a single exit at the bottom. 10267 // The point of exit cannot be a branch out of the structured block. 10268 // longjmp() and throw() must not violate the entry/exit criteria. 10269 CS->getCapturedDecl()->setNothrow(); 10270 } 10271 10272 OMPLoopDirective::HelperExprs B; 10273 // In presence of clause 'collapse' with number of loops, it will 10274 // define the nested loops number. 10275 unsigned NestedLoopCount = checkOpenMPLoop( 10276 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10277 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10278 VarsWithImplicitDSA, B); 10279 10280 if (NestedLoopCount == 0) 10281 return StmtError(); 10282 10283 assert((CurContext->isDependentContext() || B.builtAll()) && 10284 "omp for loop exprs were not built"); 10285 10286 setFunctionHasBranchProtectedScope(); 10287 10288 DSAStack->setParentTeamsRegionLoc(StartLoc); 10289 10290 return OMPTeamsDistributeParallelForDirective::Create( 10291 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10292 DSAStack->isCancelRegion()); 10293 } 10294 10295 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10296 Stmt *AStmt, 10297 SourceLocation StartLoc, 10298 SourceLocation EndLoc) { 10299 if (!AStmt) 10300 return StmtError(); 10301 10302 auto *CS = cast<CapturedStmt>(AStmt); 10303 // 1.2.2 OpenMP Language Terminology 10304 // Structured block - An executable statement with a single entry at the 10305 // top and a single exit at the bottom. 10306 // The point of exit cannot be a branch out of the structured block. 10307 // longjmp() and throw() must not violate the entry/exit criteria. 10308 CS->getCapturedDecl()->setNothrow(); 10309 10310 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10311 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10312 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10313 // 1.2.2 OpenMP Language Terminology 10314 // Structured block - An executable statement with a single entry at the 10315 // top and a single exit at the bottom. 10316 // The point of exit cannot be a branch out of the structured block. 10317 // longjmp() and throw() must not violate the entry/exit criteria. 10318 CS->getCapturedDecl()->setNothrow(); 10319 } 10320 setFunctionHasBranchProtectedScope(); 10321 10322 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10323 AStmt); 10324 } 10325 10326 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10327 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10328 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10329 if (!AStmt) 10330 return StmtError(); 10331 10332 auto *CS = cast<CapturedStmt>(AStmt); 10333 // 1.2.2 OpenMP Language Terminology 10334 // Structured block - An executable statement with a single entry at the 10335 // top and a single exit at the bottom. 10336 // The point of exit cannot be a branch out of the structured block. 10337 // longjmp() and throw() must not violate the entry/exit criteria. 10338 CS->getCapturedDecl()->setNothrow(); 10339 for (int ThisCaptureLevel = 10340 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10341 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10342 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10343 // 1.2.2 OpenMP Language Terminology 10344 // Structured block - An executable statement with a single entry at the 10345 // top and a single exit at the bottom. 10346 // The point of exit cannot be a branch out of the structured block. 10347 // longjmp() and throw() must not violate the entry/exit criteria. 10348 CS->getCapturedDecl()->setNothrow(); 10349 } 10350 10351 OMPLoopDirective::HelperExprs B; 10352 // In presence of clause 'collapse' with number of loops, it will 10353 // define the nested loops number. 10354 unsigned NestedLoopCount = checkOpenMPLoop( 10355 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10356 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10357 VarsWithImplicitDSA, B); 10358 if (NestedLoopCount == 0) 10359 return StmtError(); 10360 10361 assert((CurContext->isDependentContext() || B.builtAll()) && 10362 "omp target teams distribute loop exprs were not built"); 10363 10364 setFunctionHasBranchProtectedScope(); 10365 return OMPTargetTeamsDistributeDirective::Create( 10366 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10367 } 10368 10369 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10370 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10371 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10372 if (!AStmt) 10373 return StmtError(); 10374 10375 auto *CS = cast<CapturedStmt>(AStmt); 10376 // 1.2.2 OpenMP Language Terminology 10377 // Structured block - An executable statement with a single entry at the 10378 // top and a single exit at the bottom. 10379 // The point of exit cannot be a branch out of the structured block. 10380 // longjmp() and throw() must not violate the entry/exit criteria. 10381 CS->getCapturedDecl()->setNothrow(); 10382 for (int ThisCaptureLevel = 10383 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10384 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10385 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10386 // 1.2.2 OpenMP Language Terminology 10387 // Structured block - An executable statement with a single entry at the 10388 // top and a single exit at the bottom. 10389 // The point of exit cannot be a branch out of the structured block. 10390 // longjmp() and throw() must not violate the entry/exit criteria. 10391 CS->getCapturedDecl()->setNothrow(); 10392 } 10393 10394 OMPLoopDirective::HelperExprs B; 10395 // In presence of clause 'collapse' with number of loops, it will 10396 // define the nested loops number. 10397 unsigned NestedLoopCount = checkOpenMPLoop( 10398 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10399 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10400 VarsWithImplicitDSA, B); 10401 if (NestedLoopCount == 0) 10402 return StmtError(); 10403 10404 assert((CurContext->isDependentContext() || B.builtAll()) && 10405 "omp target teams distribute parallel for loop exprs were not built"); 10406 10407 if (!CurContext->isDependentContext()) { 10408 // Finalize the clauses that need pre-built expressions for CodeGen. 10409 for (OMPClause *C : Clauses) { 10410 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10411 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10412 B.NumIterations, *this, CurScope, 10413 DSAStack)) 10414 return StmtError(); 10415 } 10416 } 10417 10418 setFunctionHasBranchProtectedScope(); 10419 return OMPTargetTeamsDistributeParallelForDirective::Create( 10420 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10421 DSAStack->isCancelRegion()); 10422 } 10423 10424 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10425 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10426 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10427 if (!AStmt) 10428 return StmtError(); 10429 10430 auto *CS = cast<CapturedStmt>(AStmt); 10431 // 1.2.2 OpenMP Language Terminology 10432 // Structured block - An executable statement with a single entry at the 10433 // top and a single exit at the bottom. 10434 // The point of exit cannot be a branch out of the structured block. 10435 // longjmp() and throw() must not violate the entry/exit criteria. 10436 CS->getCapturedDecl()->setNothrow(); 10437 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10438 OMPD_target_teams_distribute_parallel_for_simd); 10439 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10440 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10441 // 1.2.2 OpenMP Language Terminology 10442 // Structured block - An executable statement with a single entry at the 10443 // top and a single exit at the bottom. 10444 // The point of exit cannot be a branch out of the structured block. 10445 // longjmp() and throw() must not violate the entry/exit criteria. 10446 CS->getCapturedDecl()->setNothrow(); 10447 } 10448 10449 OMPLoopDirective::HelperExprs B; 10450 // In presence of clause 'collapse' with number of loops, it will 10451 // define the nested loops number. 10452 unsigned NestedLoopCount = 10453 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10454 getCollapseNumberExpr(Clauses), 10455 nullptr /*ordered not a clause on distribute*/, CS, *this, 10456 *DSAStack, VarsWithImplicitDSA, B); 10457 if (NestedLoopCount == 0) 10458 return StmtError(); 10459 10460 assert((CurContext->isDependentContext() || B.builtAll()) && 10461 "omp target teams distribute parallel for simd loop exprs were not " 10462 "built"); 10463 10464 if (!CurContext->isDependentContext()) { 10465 // Finalize the clauses that need pre-built expressions for CodeGen. 10466 for (OMPClause *C : Clauses) { 10467 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10468 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10469 B.NumIterations, *this, CurScope, 10470 DSAStack)) 10471 return StmtError(); 10472 } 10473 } 10474 10475 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10476 return StmtError(); 10477 10478 setFunctionHasBranchProtectedScope(); 10479 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10480 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10481 } 10482 10483 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10484 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10485 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10486 if (!AStmt) 10487 return StmtError(); 10488 10489 auto *CS = cast<CapturedStmt>(AStmt); 10490 // 1.2.2 OpenMP Language Terminology 10491 // Structured block - An executable statement with a single entry at the 10492 // top and a single exit at the bottom. 10493 // The point of exit cannot be a branch out of the structured block. 10494 // longjmp() and throw() must not violate the entry/exit criteria. 10495 CS->getCapturedDecl()->setNothrow(); 10496 for (int ThisCaptureLevel = 10497 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10498 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10499 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10500 // 1.2.2 OpenMP Language Terminology 10501 // Structured block - An executable statement with a single entry at the 10502 // top and a single exit at the bottom. 10503 // The point of exit cannot be a branch out of the structured block. 10504 // longjmp() and throw() must not violate the entry/exit criteria. 10505 CS->getCapturedDecl()->setNothrow(); 10506 } 10507 10508 OMPLoopDirective::HelperExprs B; 10509 // In presence of clause 'collapse' with number of loops, it will 10510 // define the nested loops number. 10511 unsigned NestedLoopCount = checkOpenMPLoop( 10512 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10513 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10514 VarsWithImplicitDSA, B); 10515 if (NestedLoopCount == 0) 10516 return StmtError(); 10517 10518 assert((CurContext->isDependentContext() || B.builtAll()) && 10519 "omp target teams distribute simd loop exprs were not built"); 10520 10521 if (!CurContext->isDependentContext()) { 10522 // Finalize the clauses that need pre-built expressions for CodeGen. 10523 for (OMPClause *C : Clauses) { 10524 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10525 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10526 B.NumIterations, *this, CurScope, 10527 DSAStack)) 10528 return StmtError(); 10529 } 10530 } 10531 10532 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10533 return StmtError(); 10534 10535 setFunctionHasBranchProtectedScope(); 10536 return OMPTargetTeamsDistributeSimdDirective::Create( 10537 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10538 } 10539 10540 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10541 SourceLocation StartLoc, 10542 SourceLocation LParenLoc, 10543 SourceLocation EndLoc) { 10544 OMPClause *Res = nullptr; 10545 switch (Kind) { 10546 case OMPC_final: 10547 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10548 break; 10549 case OMPC_num_threads: 10550 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10551 break; 10552 case OMPC_safelen: 10553 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10554 break; 10555 case OMPC_simdlen: 10556 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10557 break; 10558 case OMPC_allocator: 10559 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10560 break; 10561 case OMPC_collapse: 10562 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10563 break; 10564 case OMPC_ordered: 10565 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10566 break; 10567 case OMPC_device: 10568 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10569 break; 10570 case OMPC_num_teams: 10571 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10572 break; 10573 case OMPC_thread_limit: 10574 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10575 break; 10576 case OMPC_priority: 10577 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10578 break; 10579 case OMPC_grainsize: 10580 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10581 break; 10582 case OMPC_num_tasks: 10583 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10584 break; 10585 case OMPC_hint: 10586 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10587 break; 10588 case OMPC_if: 10589 case OMPC_default: 10590 case OMPC_proc_bind: 10591 case OMPC_schedule: 10592 case OMPC_private: 10593 case OMPC_firstprivate: 10594 case OMPC_lastprivate: 10595 case OMPC_shared: 10596 case OMPC_reduction: 10597 case OMPC_task_reduction: 10598 case OMPC_in_reduction: 10599 case OMPC_linear: 10600 case OMPC_aligned: 10601 case OMPC_copyin: 10602 case OMPC_copyprivate: 10603 case OMPC_nowait: 10604 case OMPC_untied: 10605 case OMPC_mergeable: 10606 case OMPC_threadprivate: 10607 case OMPC_allocate: 10608 case OMPC_flush: 10609 case OMPC_read: 10610 case OMPC_write: 10611 case OMPC_update: 10612 case OMPC_capture: 10613 case OMPC_seq_cst: 10614 case OMPC_depend: 10615 case OMPC_threads: 10616 case OMPC_simd: 10617 case OMPC_map: 10618 case OMPC_nogroup: 10619 case OMPC_dist_schedule: 10620 case OMPC_defaultmap: 10621 case OMPC_unknown: 10622 case OMPC_uniform: 10623 case OMPC_to: 10624 case OMPC_from: 10625 case OMPC_use_device_ptr: 10626 case OMPC_is_device_ptr: 10627 case OMPC_unified_address: 10628 case OMPC_unified_shared_memory: 10629 case OMPC_reverse_offload: 10630 case OMPC_dynamic_allocators: 10631 case OMPC_atomic_default_mem_order: 10632 case OMPC_device_type: 10633 case OMPC_match: 10634 llvm_unreachable("Clause is not allowed."); 10635 } 10636 return Res; 10637 } 10638 10639 // An OpenMP directive such as 'target parallel' has two captured regions: 10640 // for the 'target' and 'parallel' respectively. This function returns 10641 // the region in which to capture expressions associated with a clause. 10642 // A return value of OMPD_unknown signifies that the expression should not 10643 // be captured. 10644 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10645 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10646 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10647 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10648 switch (CKind) { 10649 case OMPC_if: 10650 switch (DKind) { 10651 case OMPD_target_parallel: 10652 case OMPD_target_parallel_for: 10653 case OMPD_target_parallel_for_simd: 10654 // If this clause applies to the nested 'parallel' region, capture within 10655 // the 'target' region, otherwise do not capture. 10656 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10657 CaptureRegion = OMPD_target; 10658 break; 10659 case OMPD_target_teams_distribute_parallel_for: 10660 case OMPD_target_teams_distribute_parallel_for_simd: 10661 // If this clause applies to the nested 'parallel' region, capture within 10662 // the 'teams' region, otherwise do not capture. 10663 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10664 CaptureRegion = OMPD_teams; 10665 break; 10666 case OMPD_teams_distribute_parallel_for: 10667 case OMPD_teams_distribute_parallel_for_simd: 10668 CaptureRegion = OMPD_teams; 10669 break; 10670 case OMPD_target_update: 10671 case OMPD_target_enter_data: 10672 case OMPD_target_exit_data: 10673 CaptureRegion = OMPD_task; 10674 break; 10675 case OMPD_parallel_master_taskloop: 10676 case OMPD_parallel_master_taskloop_simd: 10677 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10678 CaptureRegion = OMPD_parallel; 10679 break; 10680 case OMPD_cancel: 10681 case OMPD_parallel: 10682 case OMPD_parallel_sections: 10683 case OMPD_parallel_for: 10684 case OMPD_parallel_for_simd: 10685 case OMPD_target: 10686 case OMPD_target_simd: 10687 case OMPD_target_teams: 10688 case OMPD_target_teams_distribute: 10689 case OMPD_target_teams_distribute_simd: 10690 case OMPD_distribute_parallel_for: 10691 case OMPD_distribute_parallel_for_simd: 10692 case OMPD_task: 10693 case OMPD_taskloop: 10694 case OMPD_taskloop_simd: 10695 case OMPD_master_taskloop: 10696 case OMPD_master_taskloop_simd: 10697 case OMPD_target_data: 10698 case OMPD_simd: 10699 case OMPD_for_simd: 10700 // Do not capture if-clause expressions. 10701 break; 10702 case OMPD_threadprivate: 10703 case OMPD_allocate: 10704 case OMPD_taskyield: 10705 case OMPD_barrier: 10706 case OMPD_taskwait: 10707 case OMPD_cancellation_point: 10708 case OMPD_flush: 10709 case OMPD_declare_reduction: 10710 case OMPD_declare_mapper: 10711 case OMPD_declare_simd: 10712 case OMPD_declare_variant: 10713 case OMPD_declare_target: 10714 case OMPD_end_declare_target: 10715 case OMPD_teams: 10716 case OMPD_for: 10717 case OMPD_sections: 10718 case OMPD_section: 10719 case OMPD_single: 10720 case OMPD_master: 10721 case OMPD_critical: 10722 case OMPD_taskgroup: 10723 case OMPD_distribute: 10724 case OMPD_ordered: 10725 case OMPD_atomic: 10726 case OMPD_distribute_simd: 10727 case OMPD_teams_distribute: 10728 case OMPD_teams_distribute_simd: 10729 case OMPD_requires: 10730 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10731 case OMPD_unknown: 10732 llvm_unreachable("Unknown OpenMP directive"); 10733 } 10734 break; 10735 case OMPC_num_threads: 10736 switch (DKind) { 10737 case OMPD_target_parallel: 10738 case OMPD_target_parallel_for: 10739 case OMPD_target_parallel_for_simd: 10740 CaptureRegion = OMPD_target; 10741 break; 10742 case OMPD_teams_distribute_parallel_for: 10743 case OMPD_teams_distribute_parallel_for_simd: 10744 case OMPD_target_teams_distribute_parallel_for: 10745 case OMPD_target_teams_distribute_parallel_for_simd: 10746 CaptureRegion = OMPD_teams; 10747 break; 10748 case OMPD_parallel: 10749 case OMPD_parallel_sections: 10750 case OMPD_parallel_for: 10751 case OMPD_parallel_for_simd: 10752 case OMPD_distribute_parallel_for: 10753 case OMPD_distribute_parallel_for_simd: 10754 case OMPD_parallel_master_taskloop: 10755 case OMPD_parallel_master_taskloop_simd: 10756 // Do not capture num_threads-clause expressions. 10757 break; 10758 case OMPD_target_data: 10759 case OMPD_target_enter_data: 10760 case OMPD_target_exit_data: 10761 case OMPD_target_update: 10762 case OMPD_target: 10763 case OMPD_target_simd: 10764 case OMPD_target_teams: 10765 case OMPD_target_teams_distribute: 10766 case OMPD_target_teams_distribute_simd: 10767 case OMPD_cancel: 10768 case OMPD_task: 10769 case OMPD_taskloop: 10770 case OMPD_taskloop_simd: 10771 case OMPD_master_taskloop: 10772 case OMPD_master_taskloop_simd: 10773 case OMPD_threadprivate: 10774 case OMPD_allocate: 10775 case OMPD_taskyield: 10776 case OMPD_barrier: 10777 case OMPD_taskwait: 10778 case OMPD_cancellation_point: 10779 case OMPD_flush: 10780 case OMPD_declare_reduction: 10781 case OMPD_declare_mapper: 10782 case OMPD_declare_simd: 10783 case OMPD_declare_variant: 10784 case OMPD_declare_target: 10785 case OMPD_end_declare_target: 10786 case OMPD_teams: 10787 case OMPD_simd: 10788 case OMPD_for: 10789 case OMPD_for_simd: 10790 case OMPD_sections: 10791 case OMPD_section: 10792 case OMPD_single: 10793 case OMPD_master: 10794 case OMPD_critical: 10795 case OMPD_taskgroup: 10796 case OMPD_distribute: 10797 case OMPD_ordered: 10798 case OMPD_atomic: 10799 case OMPD_distribute_simd: 10800 case OMPD_teams_distribute: 10801 case OMPD_teams_distribute_simd: 10802 case OMPD_requires: 10803 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10804 case OMPD_unknown: 10805 llvm_unreachable("Unknown OpenMP directive"); 10806 } 10807 break; 10808 case OMPC_num_teams: 10809 switch (DKind) { 10810 case OMPD_target_teams: 10811 case OMPD_target_teams_distribute: 10812 case OMPD_target_teams_distribute_simd: 10813 case OMPD_target_teams_distribute_parallel_for: 10814 case OMPD_target_teams_distribute_parallel_for_simd: 10815 CaptureRegion = OMPD_target; 10816 break; 10817 case OMPD_teams_distribute_parallel_for: 10818 case OMPD_teams_distribute_parallel_for_simd: 10819 case OMPD_teams: 10820 case OMPD_teams_distribute: 10821 case OMPD_teams_distribute_simd: 10822 // Do not capture num_teams-clause expressions. 10823 break; 10824 case OMPD_distribute_parallel_for: 10825 case OMPD_distribute_parallel_for_simd: 10826 case OMPD_task: 10827 case OMPD_taskloop: 10828 case OMPD_taskloop_simd: 10829 case OMPD_master_taskloop: 10830 case OMPD_master_taskloop_simd: 10831 case OMPD_parallel_master_taskloop: 10832 case OMPD_parallel_master_taskloop_simd: 10833 case OMPD_target_data: 10834 case OMPD_target_enter_data: 10835 case OMPD_target_exit_data: 10836 case OMPD_target_update: 10837 case OMPD_cancel: 10838 case OMPD_parallel: 10839 case OMPD_parallel_sections: 10840 case OMPD_parallel_for: 10841 case OMPD_parallel_for_simd: 10842 case OMPD_target: 10843 case OMPD_target_simd: 10844 case OMPD_target_parallel: 10845 case OMPD_target_parallel_for: 10846 case OMPD_target_parallel_for_simd: 10847 case OMPD_threadprivate: 10848 case OMPD_allocate: 10849 case OMPD_taskyield: 10850 case OMPD_barrier: 10851 case OMPD_taskwait: 10852 case OMPD_cancellation_point: 10853 case OMPD_flush: 10854 case OMPD_declare_reduction: 10855 case OMPD_declare_mapper: 10856 case OMPD_declare_simd: 10857 case OMPD_declare_variant: 10858 case OMPD_declare_target: 10859 case OMPD_end_declare_target: 10860 case OMPD_simd: 10861 case OMPD_for: 10862 case OMPD_for_simd: 10863 case OMPD_sections: 10864 case OMPD_section: 10865 case OMPD_single: 10866 case OMPD_master: 10867 case OMPD_critical: 10868 case OMPD_taskgroup: 10869 case OMPD_distribute: 10870 case OMPD_ordered: 10871 case OMPD_atomic: 10872 case OMPD_distribute_simd: 10873 case OMPD_requires: 10874 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10875 case OMPD_unknown: 10876 llvm_unreachable("Unknown OpenMP directive"); 10877 } 10878 break; 10879 case OMPC_thread_limit: 10880 switch (DKind) { 10881 case OMPD_target_teams: 10882 case OMPD_target_teams_distribute: 10883 case OMPD_target_teams_distribute_simd: 10884 case OMPD_target_teams_distribute_parallel_for: 10885 case OMPD_target_teams_distribute_parallel_for_simd: 10886 CaptureRegion = OMPD_target; 10887 break; 10888 case OMPD_teams_distribute_parallel_for: 10889 case OMPD_teams_distribute_parallel_for_simd: 10890 case OMPD_teams: 10891 case OMPD_teams_distribute: 10892 case OMPD_teams_distribute_simd: 10893 // Do not capture thread_limit-clause expressions. 10894 break; 10895 case OMPD_distribute_parallel_for: 10896 case OMPD_distribute_parallel_for_simd: 10897 case OMPD_task: 10898 case OMPD_taskloop: 10899 case OMPD_taskloop_simd: 10900 case OMPD_master_taskloop: 10901 case OMPD_master_taskloop_simd: 10902 case OMPD_parallel_master_taskloop: 10903 case OMPD_parallel_master_taskloop_simd: 10904 case OMPD_target_data: 10905 case OMPD_target_enter_data: 10906 case OMPD_target_exit_data: 10907 case OMPD_target_update: 10908 case OMPD_cancel: 10909 case OMPD_parallel: 10910 case OMPD_parallel_sections: 10911 case OMPD_parallel_for: 10912 case OMPD_parallel_for_simd: 10913 case OMPD_target: 10914 case OMPD_target_simd: 10915 case OMPD_target_parallel: 10916 case OMPD_target_parallel_for: 10917 case OMPD_target_parallel_for_simd: 10918 case OMPD_threadprivate: 10919 case OMPD_allocate: 10920 case OMPD_taskyield: 10921 case OMPD_barrier: 10922 case OMPD_taskwait: 10923 case OMPD_cancellation_point: 10924 case OMPD_flush: 10925 case OMPD_declare_reduction: 10926 case OMPD_declare_mapper: 10927 case OMPD_declare_simd: 10928 case OMPD_declare_variant: 10929 case OMPD_declare_target: 10930 case OMPD_end_declare_target: 10931 case OMPD_simd: 10932 case OMPD_for: 10933 case OMPD_for_simd: 10934 case OMPD_sections: 10935 case OMPD_section: 10936 case OMPD_single: 10937 case OMPD_master: 10938 case OMPD_critical: 10939 case OMPD_taskgroup: 10940 case OMPD_distribute: 10941 case OMPD_ordered: 10942 case OMPD_atomic: 10943 case OMPD_distribute_simd: 10944 case OMPD_requires: 10945 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10946 case OMPD_unknown: 10947 llvm_unreachable("Unknown OpenMP directive"); 10948 } 10949 break; 10950 case OMPC_schedule: 10951 switch (DKind) { 10952 case OMPD_parallel_for: 10953 case OMPD_parallel_for_simd: 10954 case OMPD_distribute_parallel_for: 10955 case OMPD_distribute_parallel_for_simd: 10956 case OMPD_teams_distribute_parallel_for: 10957 case OMPD_teams_distribute_parallel_for_simd: 10958 case OMPD_target_parallel_for: 10959 case OMPD_target_parallel_for_simd: 10960 case OMPD_target_teams_distribute_parallel_for: 10961 case OMPD_target_teams_distribute_parallel_for_simd: 10962 CaptureRegion = OMPD_parallel; 10963 break; 10964 case OMPD_for: 10965 case OMPD_for_simd: 10966 // Do not capture schedule-clause expressions. 10967 break; 10968 case OMPD_task: 10969 case OMPD_taskloop: 10970 case OMPD_taskloop_simd: 10971 case OMPD_master_taskloop: 10972 case OMPD_master_taskloop_simd: 10973 case OMPD_parallel_master_taskloop: 10974 case OMPD_parallel_master_taskloop_simd: 10975 case OMPD_target_data: 10976 case OMPD_target_enter_data: 10977 case OMPD_target_exit_data: 10978 case OMPD_target_update: 10979 case OMPD_teams: 10980 case OMPD_teams_distribute: 10981 case OMPD_teams_distribute_simd: 10982 case OMPD_target_teams_distribute: 10983 case OMPD_target_teams_distribute_simd: 10984 case OMPD_target: 10985 case OMPD_target_simd: 10986 case OMPD_target_parallel: 10987 case OMPD_cancel: 10988 case OMPD_parallel: 10989 case OMPD_parallel_sections: 10990 case OMPD_threadprivate: 10991 case OMPD_allocate: 10992 case OMPD_taskyield: 10993 case OMPD_barrier: 10994 case OMPD_taskwait: 10995 case OMPD_cancellation_point: 10996 case OMPD_flush: 10997 case OMPD_declare_reduction: 10998 case OMPD_declare_mapper: 10999 case OMPD_declare_simd: 11000 case OMPD_declare_variant: 11001 case OMPD_declare_target: 11002 case OMPD_end_declare_target: 11003 case OMPD_simd: 11004 case OMPD_sections: 11005 case OMPD_section: 11006 case OMPD_single: 11007 case OMPD_master: 11008 case OMPD_critical: 11009 case OMPD_taskgroup: 11010 case OMPD_distribute: 11011 case OMPD_ordered: 11012 case OMPD_atomic: 11013 case OMPD_distribute_simd: 11014 case OMPD_target_teams: 11015 case OMPD_requires: 11016 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11017 case OMPD_unknown: 11018 llvm_unreachable("Unknown OpenMP directive"); 11019 } 11020 break; 11021 case OMPC_dist_schedule: 11022 switch (DKind) { 11023 case OMPD_teams_distribute_parallel_for: 11024 case OMPD_teams_distribute_parallel_for_simd: 11025 case OMPD_teams_distribute: 11026 case OMPD_teams_distribute_simd: 11027 case OMPD_target_teams_distribute_parallel_for: 11028 case OMPD_target_teams_distribute_parallel_for_simd: 11029 case OMPD_target_teams_distribute: 11030 case OMPD_target_teams_distribute_simd: 11031 CaptureRegion = OMPD_teams; 11032 break; 11033 case OMPD_distribute_parallel_for: 11034 case OMPD_distribute_parallel_for_simd: 11035 case OMPD_distribute: 11036 case OMPD_distribute_simd: 11037 // Do not capture thread_limit-clause expressions. 11038 break; 11039 case OMPD_parallel_for: 11040 case OMPD_parallel_for_simd: 11041 case OMPD_target_parallel_for_simd: 11042 case OMPD_target_parallel_for: 11043 case OMPD_task: 11044 case OMPD_taskloop: 11045 case OMPD_taskloop_simd: 11046 case OMPD_master_taskloop: 11047 case OMPD_master_taskloop_simd: 11048 case OMPD_parallel_master_taskloop: 11049 case OMPD_parallel_master_taskloop_simd: 11050 case OMPD_target_data: 11051 case OMPD_target_enter_data: 11052 case OMPD_target_exit_data: 11053 case OMPD_target_update: 11054 case OMPD_teams: 11055 case OMPD_target: 11056 case OMPD_target_simd: 11057 case OMPD_target_parallel: 11058 case OMPD_cancel: 11059 case OMPD_parallel: 11060 case OMPD_parallel_sections: 11061 case OMPD_threadprivate: 11062 case OMPD_allocate: 11063 case OMPD_taskyield: 11064 case OMPD_barrier: 11065 case OMPD_taskwait: 11066 case OMPD_cancellation_point: 11067 case OMPD_flush: 11068 case OMPD_declare_reduction: 11069 case OMPD_declare_mapper: 11070 case OMPD_declare_simd: 11071 case OMPD_declare_variant: 11072 case OMPD_declare_target: 11073 case OMPD_end_declare_target: 11074 case OMPD_simd: 11075 case OMPD_for: 11076 case OMPD_for_simd: 11077 case OMPD_sections: 11078 case OMPD_section: 11079 case OMPD_single: 11080 case OMPD_master: 11081 case OMPD_critical: 11082 case OMPD_taskgroup: 11083 case OMPD_ordered: 11084 case OMPD_atomic: 11085 case OMPD_target_teams: 11086 case OMPD_requires: 11087 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11088 case OMPD_unknown: 11089 llvm_unreachable("Unknown OpenMP directive"); 11090 } 11091 break; 11092 case OMPC_device: 11093 switch (DKind) { 11094 case OMPD_target_update: 11095 case OMPD_target_enter_data: 11096 case OMPD_target_exit_data: 11097 case OMPD_target: 11098 case OMPD_target_simd: 11099 case OMPD_target_teams: 11100 case OMPD_target_parallel: 11101 case OMPD_target_teams_distribute: 11102 case OMPD_target_teams_distribute_simd: 11103 case OMPD_target_parallel_for: 11104 case OMPD_target_parallel_for_simd: 11105 case OMPD_target_teams_distribute_parallel_for: 11106 case OMPD_target_teams_distribute_parallel_for_simd: 11107 CaptureRegion = OMPD_task; 11108 break; 11109 case OMPD_target_data: 11110 // Do not capture device-clause expressions. 11111 break; 11112 case OMPD_teams_distribute_parallel_for: 11113 case OMPD_teams_distribute_parallel_for_simd: 11114 case OMPD_teams: 11115 case OMPD_teams_distribute: 11116 case OMPD_teams_distribute_simd: 11117 case OMPD_distribute_parallel_for: 11118 case OMPD_distribute_parallel_for_simd: 11119 case OMPD_task: 11120 case OMPD_taskloop: 11121 case OMPD_taskloop_simd: 11122 case OMPD_master_taskloop: 11123 case OMPD_master_taskloop_simd: 11124 case OMPD_parallel_master_taskloop: 11125 case OMPD_parallel_master_taskloop_simd: 11126 case OMPD_cancel: 11127 case OMPD_parallel: 11128 case OMPD_parallel_sections: 11129 case OMPD_parallel_for: 11130 case OMPD_parallel_for_simd: 11131 case OMPD_threadprivate: 11132 case OMPD_allocate: 11133 case OMPD_taskyield: 11134 case OMPD_barrier: 11135 case OMPD_taskwait: 11136 case OMPD_cancellation_point: 11137 case OMPD_flush: 11138 case OMPD_declare_reduction: 11139 case OMPD_declare_mapper: 11140 case OMPD_declare_simd: 11141 case OMPD_declare_variant: 11142 case OMPD_declare_target: 11143 case OMPD_end_declare_target: 11144 case OMPD_simd: 11145 case OMPD_for: 11146 case OMPD_for_simd: 11147 case OMPD_sections: 11148 case OMPD_section: 11149 case OMPD_single: 11150 case OMPD_master: 11151 case OMPD_critical: 11152 case OMPD_taskgroup: 11153 case OMPD_distribute: 11154 case OMPD_ordered: 11155 case OMPD_atomic: 11156 case OMPD_distribute_simd: 11157 case OMPD_requires: 11158 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11159 case OMPD_unknown: 11160 llvm_unreachable("Unknown OpenMP directive"); 11161 } 11162 break; 11163 case OMPC_grainsize: 11164 case OMPC_num_tasks: 11165 case OMPC_final: 11166 case OMPC_priority: 11167 switch (DKind) { 11168 case OMPD_task: 11169 case OMPD_taskloop: 11170 case OMPD_taskloop_simd: 11171 case OMPD_master_taskloop: 11172 case OMPD_master_taskloop_simd: 11173 break; 11174 case OMPD_parallel_master_taskloop: 11175 case OMPD_parallel_master_taskloop_simd: 11176 CaptureRegion = OMPD_parallel; 11177 break; 11178 case OMPD_target_update: 11179 case OMPD_target_enter_data: 11180 case OMPD_target_exit_data: 11181 case OMPD_target: 11182 case OMPD_target_simd: 11183 case OMPD_target_teams: 11184 case OMPD_target_parallel: 11185 case OMPD_target_teams_distribute: 11186 case OMPD_target_teams_distribute_simd: 11187 case OMPD_target_parallel_for: 11188 case OMPD_target_parallel_for_simd: 11189 case OMPD_target_teams_distribute_parallel_for: 11190 case OMPD_target_teams_distribute_parallel_for_simd: 11191 case OMPD_target_data: 11192 case OMPD_teams_distribute_parallel_for: 11193 case OMPD_teams_distribute_parallel_for_simd: 11194 case OMPD_teams: 11195 case OMPD_teams_distribute: 11196 case OMPD_teams_distribute_simd: 11197 case OMPD_distribute_parallel_for: 11198 case OMPD_distribute_parallel_for_simd: 11199 case OMPD_cancel: 11200 case OMPD_parallel: 11201 case OMPD_parallel_sections: 11202 case OMPD_parallel_for: 11203 case OMPD_parallel_for_simd: 11204 case OMPD_threadprivate: 11205 case OMPD_allocate: 11206 case OMPD_taskyield: 11207 case OMPD_barrier: 11208 case OMPD_taskwait: 11209 case OMPD_cancellation_point: 11210 case OMPD_flush: 11211 case OMPD_declare_reduction: 11212 case OMPD_declare_mapper: 11213 case OMPD_declare_simd: 11214 case OMPD_declare_variant: 11215 case OMPD_declare_target: 11216 case OMPD_end_declare_target: 11217 case OMPD_simd: 11218 case OMPD_for: 11219 case OMPD_for_simd: 11220 case OMPD_sections: 11221 case OMPD_section: 11222 case OMPD_single: 11223 case OMPD_master: 11224 case OMPD_critical: 11225 case OMPD_taskgroup: 11226 case OMPD_distribute: 11227 case OMPD_ordered: 11228 case OMPD_atomic: 11229 case OMPD_distribute_simd: 11230 case OMPD_requires: 11231 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11232 case OMPD_unknown: 11233 llvm_unreachable("Unknown OpenMP directive"); 11234 } 11235 break; 11236 case OMPC_firstprivate: 11237 case OMPC_lastprivate: 11238 case OMPC_reduction: 11239 case OMPC_task_reduction: 11240 case OMPC_in_reduction: 11241 case OMPC_linear: 11242 case OMPC_default: 11243 case OMPC_proc_bind: 11244 case OMPC_safelen: 11245 case OMPC_simdlen: 11246 case OMPC_allocator: 11247 case OMPC_collapse: 11248 case OMPC_private: 11249 case OMPC_shared: 11250 case OMPC_aligned: 11251 case OMPC_copyin: 11252 case OMPC_copyprivate: 11253 case OMPC_ordered: 11254 case OMPC_nowait: 11255 case OMPC_untied: 11256 case OMPC_mergeable: 11257 case OMPC_threadprivate: 11258 case OMPC_allocate: 11259 case OMPC_flush: 11260 case OMPC_read: 11261 case OMPC_write: 11262 case OMPC_update: 11263 case OMPC_capture: 11264 case OMPC_seq_cst: 11265 case OMPC_depend: 11266 case OMPC_threads: 11267 case OMPC_simd: 11268 case OMPC_map: 11269 case OMPC_nogroup: 11270 case OMPC_hint: 11271 case OMPC_defaultmap: 11272 case OMPC_unknown: 11273 case OMPC_uniform: 11274 case OMPC_to: 11275 case OMPC_from: 11276 case OMPC_use_device_ptr: 11277 case OMPC_is_device_ptr: 11278 case OMPC_unified_address: 11279 case OMPC_unified_shared_memory: 11280 case OMPC_reverse_offload: 11281 case OMPC_dynamic_allocators: 11282 case OMPC_atomic_default_mem_order: 11283 case OMPC_device_type: 11284 case OMPC_match: 11285 llvm_unreachable("Unexpected OpenMP clause."); 11286 } 11287 return CaptureRegion; 11288 } 11289 11290 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11291 Expr *Condition, SourceLocation StartLoc, 11292 SourceLocation LParenLoc, 11293 SourceLocation NameModifierLoc, 11294 SourceLocation ColonLoc, 11295 SourceLocation EndLoc) { 11296 Expr *ValExpr = Condition; 11297 Stmt *HelperValStmt = nullptr; 11298 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11299 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11300 !Condition->isInstantiationDependent() && 11301 !Condition->containsUnexpandedParameterPack()) { 11302 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11303 if (Val.isInvalid()) 11304 return nullptr; 11305 11306 ValExpr = Val.get(); 11307 11308 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11309 CaptureRegion = 11310 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 11311 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11312 ValExpr = MakeFullExpr(ValExpr).get(); 11313 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11314 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11315 HelperValStmt = buildPreInits(Context, Captures); 11316 } 11317 } 11318 11319 return new (Context) 11320 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11321 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11322 } 11323 11324 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11325 SourceLocation StartLoc, 11326 SourceLocation LParenLoc, 11327 SourceLocation EndLoc) { 11328 Expr *ValExpr = Condition; 11329 Stmt *HelperValStmt = nullptr; 11330 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11331 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11332 !Condition->isInstantiationDependent() && 11333 !Condition->containsUnexpandedParameterPack()) { 11334 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11335 if (Val.isInvalid()) 11336 return nullptr; 11337 11338 ValExpr = MakeFullExpr(Val.get()).get(); 11339 11340 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11341 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final); 11342 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11343 ValExpr = MakeFullExpr(ValExpr).get(); 11344 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11345 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11346 HelperValStmt = buildPreInits(Context, Captures); 11347 } 11348 } 11349 11350 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11351 StartLoc, LParenLoc, EndLoc); 11352 } 11353 11354 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11355 Expr *Op) { 11356 if (!Op) 11357 return ExprError(); 11358 11359 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11360 public: 11361 IntConvertDiagnoser() 11362 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11363 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11364 QualType T) override { 11365 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11366 } 11367 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11368 QualType T) override { 11369 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11370 } 11371 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11372 QualType T, 11373 QualType ConvTy) override { 11374 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11375 } 11376 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11377 QualType ConvTy) override { 11378 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11379 << ConvTy->isEnumeralType() << ConvTy; 11380 } 11381 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11382 QualType T) override { 11383 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11384 } 11385 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11386 QualType ConvTy) override { 11387 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11388 << ConvTy->isEnumeralType() << ConvTy; 11389 } 11390 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11391 QualType) override { 11392 llvm_unreachable("conversion functions are permitted"); 11393 } 11394 } ConvertDiagnoser; 11395 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11396 } 11397 11398 static bool 11399 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11400 bool StrictlyPositive, bool BuildCapture = false, 11401 OpenMPDirectiveKind DKind = OMPD_unknown, 11402 OpenMPDirectiveKind *CaptureRegion = nullptr, 11403 Stmt **HelperValStmt = nullptr) { 11404 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11405 !ValExpr->isInstantiationDependent()) { 11406 SourceLocation Loc = ValExpr->getExprLoc(); 11407 ExprResult Value = 11408 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11409 if (Value.isInvalid()) 11410 return false; 11411 11412 ValExpr = Value.get(); 11413 // The expression must evaluate to a non-negative integer value. 11414 llvm::APSInt Result; 11415 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11416 Result.isSigned() && 11417 !((!StrictlyPositive && Result.isNonNegative()) || 11418 (StrictlyPositive && Result.isStrictlyPositive()))) { 11419 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11420 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11421 << ValExpr->getSourceRange(); 11422 return false; 11423 } 11424 if (!BuildCapture) 11425 return true; 11426 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind); 11427 if (*CaptureRegion != OMPD_unknown && 11428 !SemaRef.CurContext->isDependentContext()) { 11429 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11430 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11431 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11432 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11433 } 11434 } 11435 return true; 11436 } 11437 11438 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11439 SourceLocation StartLoc, 11440 SourceLocation LParenLoc, 11441 SourceLocation EndLoc) { 11442 Expr *ValExpr = NumThreads; 11443 Stmt *HelperValStmt = nullptr; 11444 11445 // OpenMP [2.5, Restrictions] 11446 // The num_threads expression must evaluate to a positive integer value. 11447 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11448 /*StrictlyPositive=*/true)) 11449 return nullptr; 11450 11451 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11452 OpenMPDirectiveKind CaptureRegion = 11453 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 11454 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11455 ValExpr = MakeFullExpr(ValExpr).get(); 11456 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11457 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11458 HelperValStmt = buildPreInits(Context, Captures); 11459 } 11460 11461 return new (Context) OMPNumThreadsClause( 11462 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11463 } 11464 11465 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11466 OpenMPClauseKind CKind, 11467 bool StrictlyPositive) { 11468 if (!E) 11469 return ExprError(); 11470 if (E->isValueDependent() || E->isTypeDependent() || 11471 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11472 return E; 11473 llvm::APSInt Result; 11474 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11475 if (ICE.isInvalid()) 11476 return ExprError(); 11477 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11478 (!StrictlyPositive && !Result.isNonNegative())) { 11479 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11480 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11481 << E->getSourceRange(); 11482 return ExprError(); 11483 } 11484 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11485 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11486 << E->getSourceRange(); 11487 return ExprError(); 11488 } 11489 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11490 DSAStack->setAssociatedLoops(Result.getExtValue()); 11491 else if (CKind == OMPC_ordered) 11492 DSAStack->setAssociatedLoops(Result.getExtValue()); 11493 return ICE; 11494 } 11495 11496 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11497 SourceLocation LParenLoc, 11498 SourceLocation EndLoc) { 11499 // OpenMP [2.8.1, simd construct, Description] 11500 // The parameter of the safelen clause must be a constant 11501 // positive integer expression. 11502 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11503 if (Safelen.isInvalid()) 11504 return nullptr; 11505 return new (Context) 11506 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11507 } 11508 11509 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11510 SourceLocation LParenLoc, 11511 SourceLocation EndLoc) { 11512 // OpenMP [2.8.1, simd construct, Description] 11513 // The parameter of the simdlen clause must be a constant 11514 // positive integer expression. 11515 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11516 if (Simdlen.isInvalid()) 11517 return nullptr; 11518 return new (Context) 11519 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11520 } 11521 11522 /// Tries to find omp_allocator_handle_t type. 11523 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11524 DSAStackTy *Stack) { 11525 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11526 if (!OMPAllocatorHandleT.isNull()) 11527 return true; 11528 // Build the predefined allocator expressions. 11529 bool ErrorFound = false; 11530 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11531 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11532 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11533 StringRef Allocator = 11534 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11535 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11536 auto *VD = dyn_cast_or_null<ValueDecl>( 11537 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11538 if (!VD) { 11539 ErrorFound = true; 11540 break; 11541 } 11542 QualType AllocatorType = 11543 VD->getType().getNonLValueExprType(S.getASTContext()); 11544 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11545 if (!Res.isUsable()) { 11546 ErrorFound = true; 11547 break; 11548 } 11549 if (OMPAllocatorHandleT.isNull()) 11550 OMPAllocatorHandleT = AllocatorType; 11551 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11552 ErrorFound = true; 11553 break; 11554 } 11555 Stack->setAllocator(AllocatorKind, Res.get()); 11556 } 11557 if (ErrorFound) { 11558 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11559 return false; 11560 } 11561 OMPAllocatorHandleT.addConst(); 11562 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11563 return true; 11564 } 11565 11566 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11567 SourceLocation LParenLoc, 11568 SourceLocation EndLoc) { 11569 // OpenMP [2.11.3, allocate Directive, Description] 11570 // allocator is an expression of omp_allocator_handle_t type. 11571 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11572 return nullptr; 11573 11574 ExprResult Allocator = DefaultLvalueConversion(A); 11575 if (Allocator.isInvalid()) 11576 return nullptr; 11577 Allocator = PerformImplicitConversion(Allocator.get(), 11578 DSAStack->getOMPAllocatorHandleT(), 11579 Sema::AA_Initializing, 11580 /*AllowExplicit=*/true); 11581 if (Allocator.isInvalid()) 11582 return nullptr; 11583 return new (Context) 11584 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11585 } 11586 11587 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11588 SourceLocation StartLoc, 11589 SourceLocation LParenLoc, 11590 SourceLocation EndLoc) { 11591 // OpenMP [2.7.1, loop construct, Description] 11592 // OpenMP [2.8.1, simd construct, Description] 11593 // OpenMP [2.9.6, distribute construct, Description] 11594 // The parameter of the collapse clause must be a constant 11595 // positive integer expression. 11596 ExprResult NumForLoopsResult = 11597 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11598 if (NumForLoopsResult.isInvalid()) 11599 return nullptr; 11600 return new (Context) 11601 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11602 } 11603 11604 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11605 SourceLocation EndLoc, 11606 SourceLocation LParenLoc, 11607 Expr *NumForLoops) { 11608 // OpenMP [2.7.1, loop construct, Description] 11609 // OpenMP [2.8.1, simd construct, Description] 11610 // OpenMP [2.9.6, distribute construct, Description] 11611 // The parameter of the ordered clause must be a constant 11612 // positive integer expression if any. 11613 if (NumForLoops && LParenLoc.isValid()) { 11614 ExprResult NumForLoopsResult = 11615 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11616 if (NumForLoopsResult.isInvalid()) 11617 return nullptr; 11618 NumForLoops = NumForLoopsResult.get(); 11619 } else { 11620 NumForLoops = nullptr; 11621 } 11622 auto *Clause = OMPOrderedClause::Create( 11623 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11624 StartLoc, LParenLoc, EndLoc); 11625 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11626 return Clause; 11627 } 11628 11629 OMPClause *Sema::ActOnOpenMPSimpleClause( 11630 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11631 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11632 OMPClause *Res = nullptr; 11633 switch (Kind) { 11634 case OMPC_default: 11635 Res = 11636 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11637 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11638 break; 11639 case OMPC_proc_bind: 11640 Res = ActOnOpenMPProcBindClause( 11641 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11642 LParenLoc, EndLoc); 11643 break; 11644 case OMPC_atomic_default_mem_order: 11645 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11646 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11647 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11648 break; 11649 case OMPC_if: 11650 case OMPC_final: 11651 case OMPC_num_threads: 11652 case OMPC_safelen: 11653 case OMPC_simdlen: 11654 case OMPC_allocator: 11655 case OMPC_collapse: 11656 case OMPC_schedule: 11657 case OMPC_private: 11658 case OMPC_firstprivate: 11659 case OMPC_lastprivate: 11660 case OMPC_shared: 11661 case OMPC_reduction: 11662 case OMPC_task_reduction: 11663 case OMPC_in_reduction: 11664 case OMPC_linear: 11665 case OMPC_aligned: 11666 case OMPC_copyin: 11667 case OMPC_copyprivate: 11668 case OMPC_ordered: 11669 case OMPC_nowait: 11670 case OMPC_untied: 11671 case OMPC_mergeable: 11672 case OMPC_threadprivate: 11673 case OMPC_allocate: 11674 case OMPC_flush: 11675 case OMPC_read: 11676 case OMPC_write: 11677 case OMPC_update: 11678 case OMPC_capture: 11679 case OMPC_seq_cst: 11680 case OMPC_depend: 11681 case OMPC_device: 11682 case OMPC_threads: 11683 case OMPC_simd: 11684 case OMPC_map: 11685 case OMPC_num_teams: 11686 case OMPC_thread_limit: 11687 case OMPC_priority: 11688 case OMPC_grainsize: 11689 case OMPC_nogroup: 11690 case OMPC_num_tasks: 11691 case OMPC_hint: 11692 case OMPC_dist_schedule: 11693 case OMPC_defaultmap: 11694 case OMPC_unknown: 11695 case OMPC_uniform: 11696 case OMPC_to: 11697 case OMPC_from: 11698 case OMPC_use_device_ptr: 11699 case OMPC_is_device_ptr: 11700 case OMPC_unified_address: 11701 case OMPC_unified_shared_memory: 11702 case OMPC_reverse_offload: 11703 case OMPC_dynamic_allocators: 11704 case OMPC_device_type: 11705 case OMPC_match: 11706 llvm_unreachable("Clause is not allowed."); 11707 } 11708 return Res; 11709 } 11710 11711 static std::string 11712 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11713 ArrayRef<unsigned> Exclude = llvm::None) { 11714 SmallString<256> Buffer; 11715 llvm::raw_svector_ostream Out(Buffer); 11716 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11717 unsigned Skipped = Exclude.size(); 11718 auto S = Exclude.begin(), E = Exclude.end(); 11719 for (unsigned I = First; I < Last; ++I) { 11720 if (std::find(S, E, I) != E) { 11721 --Skipped; 11722 continue; 11723 } 11724 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11725 if (I == Bound - Skipped) 11726 Out << " or "; 11727 else if (I != Bound + 1 - Skipped) 11728 Out << ", "; 11729 } 11730 return Out.str(); 11731 } 11732 11733 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11734 SourceLocation KindKwLoc, 11735 SourceLocation StartLoc, 11736 SourceLocation LParenLoc, 11737 SourceLocation EndLoc) { 11738 if (Kind == OMPC_DEFAULT_unknown) { 11739 static_assert(OMPC_DEFAULT_unknown > 0, 11740 "OMPC_DEFAULT_unknown not greater than 0"); 11741 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11742 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11743 /*Last=*/OMPC_DEFAULT_unknown) 11744 << getOpenMPClauseName(OMPC_default); 11745 return nullptr; 11746 } 11747 switch (Kind) { 11748 case OMPC_DEFAULT_none: 11749 DSAStack->setDefaultDSANone(KindKwLoc); 11750 break; 11751 case OMPC_DEFAULT_shared: 11752 DSAStack->setDefaultDSAShared(KindKwLoc); 11753 break; 11754 case OMPC_DEFAULT_unknown: 11755 llvm_unreachable("Clause kind is not allowed."); 11756 break; 11757 } 11758 return new (Context) 11759 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11760 } 11761 11762 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11763 SourceLocation KindKwLoc, 11764 SourceLocation StartLoc, 11765 SourceLocation LParenLoc, 11766 SourceLocation EndLoc) { 11767 if (Kind == OMPC_PROC_BIND_unknown) { 11768 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11769 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11770 /*Last=*/OMPC_PROC_BIND_unknown) 11771 << getOpenMPClauseName(OMPC_proc_bind); 11772 return nullptr; 11773 } 11774 return new (Context) 11775 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11776 } 11777 11778 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11779 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11780 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11781 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11782 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11783 << getListOfPossibleValues( 11784 OMPC_atomic_default_mem_order, /*First=*/0, 11785 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11786 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11787 return nullptr; 11788 } 11789 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11790 LParenLoc, EndLoc); 11791 } 11792 11793 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11794 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11795 SourceLocation StartLoc, SourceLocation LParenLoc, 11796 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11797 SourceLocation EndLoc) { 11798 OMPClause *Res = nullptr; 11799 switch (Kind) { 11800 case OMPC_schedule: 11801 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11802 assert(Argument.size() == NumberOfElements && 11803 ArgumentLoc.size() == NumberOfElements); 11804 Res = ActOnOpenMPScheduleClause( 11805 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11806 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11807 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11808 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11809 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11810 break; 11811 case OMPC_if: 11812 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11813 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11814 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11815 DelimLoc, EndLoc); 11816 break; 11817 case OMPC_dist_schedule: 11818 Res = ActOnOpenMPDistScheduleClause( 11819 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11820 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11821 break; 11822 case OMPC_defaultmap: 11823 enum { Modifier, DefaultmapKind }; 11824 Res = ActOnOpenMPDefaultmapClause( 11825 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11826 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11827 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11828 EndLoc); 11829 break; 11830 case OMPC_final: 11831 case OMPC_num_threads: 11832 case OMPC_safelen: 11833 case OMPC_simdlen: 11834 case OMPC_allocator: 11835 case OMPC_collapse: 11836 case OMPC_default: 11837 case OMPC_proc_bind: 11838 case OMPC_private: 11839 case OMPC_firstprivate: 11840 case OMPC_lastprivate: 11841 case OMPC_shared: 11842 case OMPC_reduction: 11843 case OMPC_task_reduction: 11844 case OMPC_in_reduction: 11845 case OMPC_linear: 11846 case OMPC_aligned: 11847 case OMPC_copyin: 11848 case OMPC_copyprivate: 11849 case OMPC_ordered: 11850 case OMPC_nowait: 11851 case OMPC_untied: 11852 case OMPC_mergeable: 11853 case OMPC_threadprivate: 11854 case OMPC_allocate: 11855 case OMPC_flush: 11856 case OMPC_read: 11857 case OMPC_write: 11858 case OMPC_update: 11859 case OMPC_capture: 11860 case OMPC_seq_cst: 11861 case OMPC_depend: 11862 case OMPC_device: 11863 case OMPC_threads: 11864 case OMPC_simd: 11865 case OMPC_map: 11866 case OMPC_num_teams: 11867 case OMPC_thread_limit: 11868 case OMPC_priority: 11869 case OMPC_grainsize: 11870 case OMPC_nogroup: 11871 case OMPC_num_tasks: 11872 case OMPC_hint: 11873 case OMPC_unknown: 11874 case OMPC_uniform: 11875 case OMPC_to: 11876 case OMPC_from: 11877 case OMPC_use_device_ptr: 11878 case OMPC_is_device_ptr: 11879 case OMPC_unified_address: 11880 case OMPC_unified_shared_memory: 11881 case OMPC_reverse_offload: 11882 case OMPC_dynamic_allocators: 11883 case OMPC_atomic_default_mem_order: 11884 case OMPC_device_type: 11885 case OMPC_match: 11886 llvm_unreachable("Clause is not allowed."); 11887 } 11888 return Res; 11889 } 11890 11891 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11892 OpenMPScheduleClauseModifier M2, 11893 SourceLocation M1Loc, SourceLocation M2Loc) { 11894 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11895 SmallVector<unsigned, 2> Excluded; 11896 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11897 Excluded.push_back(M2); 11898 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11899 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11900 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11901 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11902 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11903 << getListOfPossibleValues(OMPC_schedule, 11904 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11905 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11906 Excluded) 11907 << getOpenMPClauseName(OMPC_schedule); 11908 return true; 11909 } 11910 return false; 11911 } 11912 11913 OMPClause *Sema::ActOnOpenMPScheduleClause( 11914 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11915 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11916 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11917 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11918 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11919 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11920 return nullptr; 11921 // OpenMP, 2.7.1, Loop Construct, Restrictions 11922 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11923 // but not both. 11924 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11925 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11926 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11927 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11928 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11929 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11930 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11931 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11932 return nullptr; 11933 } 11934 if (Kind == OMPC_SCHEDULE_unknown) { 11935 std::string Values; 11936 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11937 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11938 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11939 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11940 Exclude); 11941 } else { 11942 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11943 /*Last=*/OMPC_SCHEDULE_unknown); 11944 } 11945 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11946 << Values << getOpenMPClauseName(OMPC_schedule); 11947 return nullptr; 11948 } 11949 // OpenMP, 2.7.1, Loop Construct, Restrictions 11950 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11951 // schedule(guided). 11952 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11953 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11954 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11955 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11956 diag::err_omp_schedule_nonmonotonic_static); 11957 return nullptr; 11958 } 11959 Expr *ValExpr = ChunkSize; 11960 Stmt *HelperValStmt = nullptr; 11961 if (ChunkSize) { 11962 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11963 !ChunkSize->isInstantiationDependent() && 11964 !ChunkSize->containsUnexpandedParameterPack()) { 11965 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11966 ExprResult Val = 11967 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11968 if (Val.isInvalid()) 11969 return nullptr; 11970 11971 ValExpr = Val.get(); 11972 11973 // OpenMP [2.7.1, Restrictions] 11974 // chunk_size must be a loop invariant integer expression with a positive 11975 // value. 11976 llvm::APSInt Result; 11977 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11978 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11979 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11980 << "schedule" << 1 << ChunkSize->getSourceRange(); 11981 return nullptr; 11982 } 11983 } else if (getOpenMPCaptureRegionForClause( 11984 DSAStack->getCurrentDirective(), OMPC_schedule) != 11985 OMPD_unknown && 11986 !CurContext->isDependentContext()) { 11987 ValExpr = MakeFullExpr(ValExpr).get(); 11988 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11989 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11990 HelperValStmt = buildPreInits(Context, Captures); 11991 } 11992 } 11993 } 11994 11995 return new (Context) 11996 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11997 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11998 } 11999 12000 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12001 SourceLocation StartLoc, 12002 SourceLocation EndLoc) { 12003 OMPClause *Res = nullptr; 12004 switch (Kind) { 12005 case OMPC_ordered: 12006 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12007 break; 12008 case OMPC_nowait: 12009 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12010 break; 12011 case OMPC_untied: 12012 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12013 break; 12014 case OMPC_mergeable: 12015 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12016 break; 12017 case OMPC_read: 12018 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12019 break; 12020 case OMPC_write: 12021 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12022 break; 12023 case OMPC_update: 12024 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12025 break; 12026 case OMPC_capture: 12027 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12028 break; 12029 case OMPC_seq_cst: 12030 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12031 break; 12032 case OMPC_threads: 12033 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12034 break; 12035 case OMPC_simd: 12036 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12037 break; 12038 case OMPC_nogroup: 12039 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12040 break; 12041 case OMPC_unified_address: 12042 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12043 break; 12044 case OMPC_unified_shared_memory: 12045 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12046 break; 12047 case OMPC_reverse_offload: 12048 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12049 break; 12050 case OMPC_dynamic_allocators: 12051 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12052 break; 12053 case OMPC_if: 12054 case OMPC_final: 12055 case OMPC_num_threads: 12056 case OMPC_safelen: 12057 case OMPC_simdlen: 12058 case OMPC_allocator: 12059 case OMPC_collapse: 12060 case OMPC_schedule: 12061 case OMPC_private: 12062 case OMPC_firstprivate: 12063 case OMPC_lastprivate: 12064 case OMPC_shared: 12065 case OMPC_reduction: 12066 case OMPC_task_reduction: 12067 case OMPC_in_reduction: 12068 case OMPC_linear: 12069 case OMPC_aligned: 12070 case OMPC_copyin: 12071 case OMPC_copyprivate: 12072 case OMPC_default: 12073 case OMPC_proc_bind: 12074 case OMPC_threadprivate: 12075 case OMPC_allocate: 12076 case OMPC_flush: 12077 case OMPC_depend: 12078 case OMPC_device: 12079 case OMPC_map: 12080 case OMPC_num_teams: 12081 case OMPC_thread_limit: 12082 case OMPC_priority: 12083 case OMPC_grainsize: 12084 case OMPC_num_tasks: 12085 case OMPC_hint: 12086 case OMPC_dist_schedule: 12087 case OMPC_defaultmap: 12088 case OMPC_unknown: 12089 case OMPC_uniform: 12090 case OMPC_to: 12091 case OMPC_from: 12092 case OMPC_use_device_ptr: 12093 case OMPC_is_device_ptr: 12094 case OMPC_atomic_default_mem_order: 12095 case OMPC_device_type: 12096 case OMPC_match: 12097 llvm_unreachable("Clause is not allowed."); 12098 } 12099 return Res; 12100 } 12101 12102 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12103 SourceLocation EndLoc) { 12104 DSAStack->setNowaitRegion(); 12105 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12106 } 12107 12108 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12109 SourceLocation EndLoc) { 12110 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12111 } 12112 12113 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12114 SourceLocation EndLoc) { 12115 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12116 } 12117 12118 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12119 SourceLocation EndLoc) { 12120 return new (Context) OMPReadClause(StartLoc, EndLoc); 12121 } 12122 12123 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12124 SourceLocation EndLoc) { 12125 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12126 } 12127 12128 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12129 SourceLocation EndLoc) { 12130 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 12131 } 12132 12133 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12134 SourceLocation EndLoc) { 12135 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12136 } 12137 12138 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12139 SourceLocation EndLoc) { 12140 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12141 } 12142 12143 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12144 SourceLocation EndLoc) { 12145 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12146 } 12147 12148 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12149 SourceLocation EndLoc) { 12150 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12151 } 12152 12153 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12154 SourceLocation EndLoc) { 12155 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12156 } 12157 12158 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12159 SourceLocation EndLoc) { 12160 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12161 } 12162 12163 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12164 SourceLocation EndLoc) { 12165 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12166 } 12167 12168 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12169 SourceLocation EndLoc) { 12170 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12171 } 12172 12173 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12174 SourceLocation EndLoc) { 12175 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12176 } 12177 12178 OMPClause *Sema::ActOnOpenMPVarListClause( 12179 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12180 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12181 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12182 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 12183 OpenMPLinearClauseKind LinKind, 12184 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12185 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 12186 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 12187 SourceLocation StartLoc = Locs.StartLoc; 12188 SourceLocation LParenLoc = Locs.LParenLoc; 12189 SourceLocation EndLoc = Locs.EndLoc; 12190 OMPClause *Res = nullptr; 12191 switch (Kind) { 12192 case OMPC_private: 12193 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12194 break; 12195 case OMPC_firstprivate: 12196 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12197 break; 12198 case OMPC_lastprivate: 12199 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12200 break; 12201 case OMPC_shared: 12202 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12203 break; 12204 case OMPC_reduction: 12205 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12206 EndLoc, ReductionOrMapperIdScopeSpec, 12207 ReductionOrMapperId); 12208 break; 12209 case OMPC_task_reduction: 12210 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12211 EndLoc, ReductionOrMapperIdScopeSpec, 12212 ReductionOrMapperId); 12213 break; 12214 case OMPC_in_reduction: 12215 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12216 EndLoc, ReductionOrMapperIdScopeSpec, 12217 ReductionOrMapperId); 12218 break; 12219 case OMPC_linear: 12220 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 12221 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 12222 break; 12223 case OMPC_aligned: 12224 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12225 ColonLoc, EndLoc); 12226 break; 12227 case OMPC_copyin: 12228 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12229 break; 12230 case OMPC_copyprivate: 12231 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12232 break; 12233 case OMPC_flush: 12234 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12235 break; 12236 case OMPC_depend: 12237 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 12238 StartLoc, LParenLoc, EndLoc); 12239 break; 12240 case OMPC_map: 12241 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 12242 ReductionOrMapperIdScopeSpec, 12243 ReductionOrMapperId, MapType, IsMapTypeImplicit, 12244 DepLinMapLoc, ColonLoc, VarList, Locs); 12245 break; 12246 case OMPC_to: 12247 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12248 ReductionOrMapperId, Locs); 12249 break; 12250 case OMPC_from: 12251 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12252 ReductionOrMapperId, Locs); 12253 break; 12254 case OMPC_use_device_ptr: 12255 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12256 break; 12257 case OMPC_is_device_ptr: 12258 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12259 break; 12260 case OMPC_allocate: 12261 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12262 ColonLoc, EndLoc); 12263 break; 12264 case OMPC_if: 12265 case OMPC_final: 12266 case OMPC_num_threads: 12267 case OMPC_safelen: 12268 case OMPC_simdlen: 12269 case OMPC_allocator: 12270 case OMPC_collapse: 12271 case OMPC_default: 12272 case OMPC_proc_bind: 12273 case OMPC_schedule: 12274 case OMPC_ordered: 12275 case OMPC_nowait: 12276 case OMPC_untied: 12277 case OMPC_mergeable: 12278 case OMPC_threadprivate: 12279 case OMPC_read: 12280 case OMPC_write: 12281 case OMPC_update: 12282 case OMPC_capture: 12283 case OMPC_seq_cst: 12284 case OMPC_device: 12285 case OMPC_threads: 12286 case OMPC_simd: 12287 case OMPC_num_teams: 12288 case OMPC_thread_limit: 12289 case OMPC_priority: 12290 case OMPC_grainsize: 12291 case OMPC_nogroup: 12292 case OMPC_num_tasks: 12293 case OMPC_hint: 12294 case OMPC_dist_schedule: 12295 case OMPC_defaultmap: 12296 case OMPC_unknown: 12297 case OMPC_uniform: 12298 case OMPC_unified_address: 12299 case OMPC_unified_shared_memory: 12300 case OMPC_reverse_offload: 12301 case OMPC_dynamic_allocators: 12302 case OMPC_atomic_default_mem_order: 12303 case OMPC_device_type: 12304 case OMPC_match: 12305 llvm_unreachable("Clause is not allowed."); 12306 } 12307 return Res; 12308 } 12309 12310 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12311 ExprObjectKind OK, SourceLocation Loc) { 12312 ExprResult Res = BuildDeclRefExpr( 12313 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12314 if (!Res.isUsable()) 12315 return ExprError(); 12316 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12317 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12318 if (!Res.isUsable()) 12319 return ExprError(); 12320 } 12321 if (VK != VK_LValue && Res.get()->isGLValue()) { 12322 Res = DefaultLvalueConversion(Res.get()); 12323 if (!Res.isUsable()) 12324 return ExprError(); 12325 } 12326 return Res; 12327 } 12328 12329 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12330 SourceLocation StartLoc, 12331 SourceLocation LParenLoc, 12332 SourceLocation EndLoc) { 12333 SmallVector<Expr *, 8> Vars; 12334 SmallVector<Expr *, 8> PrivateCopies; 12335 for (Expr *RefExpr : VarList) { 12336 assert(RefExpr && "NULL expr in OpenMP private clause."); 12337 SourceLocation ELoc; 12338 SourceRange ERange; 12339 Expr *SimpleRefExpr = RefExpr; 12340 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12341 if (Res.second) { 12342 // It will be analyzed later. 12343 Vars.push_back(RefExpr); 12344 PrivateCopies.push_back(nullptr); 12345 } 12346 ValueDecl *D = Res.first; 12347 if (!D) 12348 continue; 12349 12350 QualType Type = D->getType(); 12351 auto *VD = dyn_cast<VarDecl>(D); 12352 12353 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12354 // A variable that appears in a private clause must not have an incomplete 12355 // type or a reference type. 12356 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12357 continue; 12358 Type = Type.getNonReferenceType(); 12359 12360 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12361 // A variable that is privatized must not have a const-qualified type 12362 // unless it is of class type with a mutable member. This restriction does 12363 // not apply to the firstprivate clause. 12364 // 12365 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12366 // A variable that appears in a private clause must not have a 12367 // const-qualified type unless it is of class type with a mutable member. 12368 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12369 continue; 12370 12371 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12372 // in a Construct] 12373 // Variables with the predetermined data-sharing attributes may not be 12374 // listed in data-sharing attributes clauses, except for the cases 12375 // listed below. For these exceptions only, listing a predetermined 12376 // variable in a data-sharing attribute clause is allowed and overrides 12377 // the variable's predetermined data-sharing attributes. 12378 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12379 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12380 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12381 << getOpenMPClauseName(OMPC_private); 12382 reportOriginalDsa(*this, DSAStack, D, DVar); 12383 continue; 12384 } 12385 12386 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12387 // Variably modified types are not supported for tasks. 12388 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12389 isOpenMPTaskingDirective(CurrDir)) { 12390 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12391 << getOpenMPClauseName(OMPC_private) << Type 12392 << getOpenMPDirectiveName(CurrDir); 12393 bool IsDecl = 12394 !VD || 12395 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12396 Diag(D->getLocation(), 12397 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12398 << D; 12399 continue; 12400 } 12401 12402 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12403 // A list item cannot appear in both a map clause and a data-sharing 12404 // attribute clause on the same construct 12405 // 12406 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12407 // A list item cannot appear in both a map clause and a data-sharing 12408 // attribute clause on the same construct unless the construct is a 12409 // combined construct. 12410 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12411 CurrDir == OMPD_target) { 12412 OpenMPClauseKind ConflictKind; 12413 if (DSAStack->checkMappableExprComponentListsForDecl( 12414 VD, /*CurrentRegionOnly=*/true, 12415 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12416 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12417 ConflictKind = WhereFoundClauseKind; 12418 return true; 12419 })) { 12420 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12421 << getOpenMPClauseName(OMPC_private) 12422 << getOpenMPClauseName(ConflictKind) 12423 << getOpenMPDirectiveName(CurrDir); 12424 reportOriginalDsa(*this, DSAStack, D, DVar); 12425 continue; 12426 } 12427 } 12428 12429 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12430 // A variable of class type (or array thereof) that appears in a private 12431 // clause requires an accessible, unambiguous default constructor for the 12432 // class type. 12433 // Generate helper private variable and initialize it with the default 12434 // value. The address of the original variable is replaced by the address of 12435 // the new private variable in CodeGen. This new variable is not added to 12436 // IdResolver, so the code in the OpenMP region uses original variable for 12437 // proper diagnostics. 12438 Type = Type.getUnqualifiedType(); 12439 VarDecl *VDPrivate = 12440 buildVarDecl(*this, ELoc, Type, D->getName(), 12441 D->hasAttrs() ? &D->getAttrs() : nullptr, 12442 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12443 ActOnUninitializedDecl(VDPrivate); 12444 if (VDPrivate->isInvalidDecl()) 12445 continue; 12446 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12447 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12448 12449 DeclRefExpr *Ref = nullptr; 12450 if (!VD && !CurContext->isDependentContext()) 12451 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12452 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12453 Vars.push_back((VD || CurContext->isDependentContext()) 12454 ? RefExpr->IgnoreParens() 12455 : Ref); 12456 PrivateCopies.push_back(VDPrivateRefExpr); 12457 } 12458 12459 if (Vars.empty()) 12460 return nullptr; 12461 12462 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12463 PrivateCopies); 12464 } 12465 12466 namespace { 12467 class DiagsUninitializedSeveretyRAII { 12468 private: 12469 DiagnosticsEngine &Diags; 12470 SourceLocation SavedLoc; 12471 bool IsIgnored = false; 12472 12473 public: 12474 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12475 bool IsIgnored) 12476 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12477 if (!IsIgnored) { 12478 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12479 /*Map*/ diag::Severity::Ignored, Loc); 12480 } 12481 } 12482 ~DiagsUninitializedSeveretyRAII() { 12483 if (!IsIgnored) 12484 Diags.popMappings(SavedLoc); 12485 } 12486 }; 12487 } 12488 12489 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12490 SourceLocation StartLoc, 12491 SourceLocation LParenLoc, 12492 SourceLocation EndLoc) { 12493 SmallVector<Expr *, 8> Vars; 12494 SmallVector<Expr *, 8> PrivateCopies; 12495 SmallVector<Expr *, 8> Inits; 12496 SmallVector<Decl *, 4> ExprCaptures; 12497 bool IsImplicitClause = 12498 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12499 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12500 12501 for (Expr *RefExpr : VarList) { 12502 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12503 SourceLocation ELoc; 12504 SourceRange ERange; 12505 Expr *SimpleRefExpr = RefExpr; 12506 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12507 if (Res.second) { 12508 // It will be analyzed later. 12509 Vars.push_back(RefExpr); 12510 PrivateCopies.push_back(nullptr); 12511 Inits.push_back(nullptr); 12512 } 12513 ValueDecl *D = Res.first; 12514 if (!D) 12515 continue; 12516 12517 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12518 QualType Type = D->getType(); 12519 auto *VD = dyn_cast<VarDecl>(D); 12520 12521 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12522 // A variable that appears in a private clause must not have an incomplete 12523 // type or a reference type. 12524 if (RequireCompleteType(ELoc, Type, 12525 diag::err_omp_firstprivate_incomplete_type)) 12526 continue; 12527 Type = Type.getNonReferenceType(); 12528 12529 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12530 // A variable of class type (or array thereof) that appears in a private 12531 // clause requires an accessible, unambiguous copy constructor for the 12532 // class type. 12533 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12534 12535 // If an implicit firstprivate variable found it was checked already. 12536 DSAStackTy::DSAVarData TopDVar; 12537 if (!IsImplicitClause) { 12538 DSAStackTy::DSAVarData DVar = 12539 DSAStack->getTopDSA(D, /*FromParent=*/false); 12540 TopDVar = DVar; 12541 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12542 bool IsConstant = ElemType.isConstant(Context); 12543 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12544 // A list item that specifies a given variable may not appear in more 12545 // than one clause on the same directive, except that a variable may be 12546 // specified in both firstprivate and lastprivate clauses. 12547 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12548 // A list item may appear in a firstprivate or lastprivate clause but not 12549 // both. 12550 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12551 (isOpenMPDistributeDirective(CurrDir) || 12552 DVar.CKind != OMPC_lastprivate) && 12553 DVar.RefExpr) { 12554 Diag(ELoc, diag::err_omp_wrong_dsa) 12555 << getOpenMPClauseName(DVar.CKind) 12556 << getOpenMPClauseName(OMPC_firstprivate); 12557 reportOriginalDsa(*this, DSAStack, D, DVar); 12558 continue; 12559 } 12560 12561 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12562 // in a Construct] 12563 // Variables with the predetermined data-sharing attributes may not be 12564 // listed in data-sharing attributes clauses, except for the cases 12565 // listed below. For these exceptions only, listing a predetermined 12566 // variable in a data-sharing attribute clause is allowed and overrides 12567 // the variable's predetermined data-sharing attributes. 12568 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12569 // in a Construct, C/C++, p.2] 12570 // Variables with const-qualified type having no mutable member may be 12571 // listed in a firstprivate clause, even if they are static data members. 12572 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12573 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12574 Diag(ELoc, diag::err_omp_wrong_dsa) 12575 << getOpenMPClauseName(DVar.CKind) 12576 << getOpenMPClauseName(OMPC_firstprivate); 12577 reportOriginalDsa(*this, DSAStack, D, DVar); 12578 continue; 12579 } 12580 12581 // OpenMP [2.9.3.4, Restrictions, p.2] 12582 // A list item that is private within a parallel region must not appear 12583 // in a firstprivate clause on a worksharing construct if any of the 12584 // worksharing regions arising from the worksharing construct ever bind 12585 // to any of the parallel regions arising from the parallel construct. 12586 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12587 // A list item that is private within a teams region must not appear in a 12588 // firstprivate clause on a distribute construct if any of the distribute 12589 // regions arising from the distribute construct ever bind to any of the 12590 // teams regions arising from the teams construct. 12591 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12592 // A list item that appears in a reduction clause of a teams construct 12593 // must not appear in a firstprivate clause on a distribute construct if 12594 // any of the distribute regions arising from the distribute construct 12595 // ever bind to any of the teams regions arising from the teams construct. 12596 if ((isOpenMPWorksharingDirective(CurrDir) || 12597 isOpenMPDistributeDirective(CurrDir)) && 12598 !isOpenMPParallelDirective(CurrDir) && 12599 !isOpenMPTeamsDirective(CurrDir)) { 12600 DVar = DSAStack->getImplicitDSA(D, true); 12601 if (DVar.CKind != OMPC_shared && 12602 (isOpenMPParallelDirective(DVar.DKind) || 12603 isOpenMPTeamsDirective(DVar.DKind) || 12604 DVar.DKind == OMPD_unknown)) { 12605 Diag(ELoc, diag::err_omp_required_access) 12606 << getOpenMPClauseName(OMPC_firstprivate) 12607 << getOpenMPClauseName(OMPC_shared); 12608 reportOriginalDsa(*this, DSAStack, D, DVar); 12609 continue; 12610 } 12611 } 12612 // OpenMP [2.9.3.4, Restrictions, p.3] 12613 // A list item that appears in a reduction clause of a parallel construct 12614 // must not appear in a firstprivate clause on a worksharing or task 12615 // construct if any of the worksharing or task regions arising from the 12616 // worksharing or task construct ever bind to any of the parallel regions 12617 // arising from the parallel construct. 12618 // OpenMP [2.9.3.4, Restrictions, p.4] 12619 // A list item that appears in a reduction clause in worksharing 12620 // construct must not appear in a firstprivate clause in a task construct 12621 // encountered during execution of any of the worksharing regions arising 12622 // from the worksharing construct. 12623 if (isOpenMPTaskingDirective(CurrDir)) { 12624 DVar = DSAStack->hasInnermostDSA( 12625 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12626 [](OpenMPDirectiveKind K) { 12627 return isOpenMPParallelDirective(K) || 12628 isOpenMPWorksharingDirective(K) || 12629 isOpenMPTeamsDirective(K); 12630 }, 12631 /*FromParent=*/true); 12632 if (DVar.CKind == OMPC_reduction && 12633 (isOpenMPParallelDirective(DVar.DKind) || 12634 isOpenMPWorksharingDirective(DVar.DKind) || 12635 isOpenMPTeamsDirective(DVar.DKind))) { 12636 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12637 << getOpenMPDirectiveName(DVar.DKind); 12638 reportOriginalDsa(*this, DSAStack, D, DVar); 12639 continue; 12640 } 12641 } 12642 12643 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12644 // A list item cannot appear in both a map clause and a data-sharing 12645 // attribute clause on the same construct 12646 // 12647 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12648 // A list item cannot appear in both a map clause and a data-sharing 12649 // attribute clause on the same construct unless the construct is a 12650 // combined construct. 12651 if ((LangOpts.OpenMP <= 45 && 12652 isOpenMPTargetExecutionDirective(CurrDir)) || 12653 CurrDir == OMPD_target) { 12654 OpenMPClauseKind ConflictKind; 12655 if (DSAStack->checkMappableExprComponentListsForDecl( 12656 VD, /*CurrentRegionOnly=*/true, 12657 [&ConflictKind]( 12658 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12659 OpenMPClauseKind WhereFoundClauseKind) { 12660 ConflictKind = WhereFoundClauseKind; 12661 return true; 12662 })) { 12663 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12664 << getOpenMPClauseName(OMPC_firstprivate) 12665 << getOpenMPClauseName(ConflictKind) 12666 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12667 reportOriginalDsa(*this, DSAStack, D, DVar); 12668 continue; 12669 } 12670 } 12671 } 12672 12673 // Variably modified types are not supported for tasks. 12674 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12675 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12676 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12677 << getOpenMPClauseName(OMPC_firstprivate) << Type 12678 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12679 bool IsDecl = 12680 !VD || 12681 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12682 Diag(D->getLocation(), 12683 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12684 << D; 12685 continue; 12686 } 12687 12688 Type = Type.getUnqualifiedType(); 12689 VarDecl *VDPrivate = 12690 buildVarDecl(*this, ELoc, Type, D->getName(), 12691 D->hasAttrs() ? &D->getAttrs() : nullptr, 12692 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12693 // Generate helper private variable and initialize it with the value of the 12694 // original variable. The address of the original variable is replaced by 12695 // the address of the new private variable in the CodeGen. This new variable 12696 // is not added to IdResolver, so the code in the OpenMP region uses 12697 // original variable for proper diagnostics and variable capturing. 12698 Expr *VDInitRefExpr = nullptr; 12699 // For arrays generate initializer for single element and replace it by the 12700 // original array element in CodeGen. 12701 if (Type->isArrayType()) { 12702 VarDecl *VDInit = 12703 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12704 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12705 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12706 ElemType = ElemType.getUnqualifiedType(); 12707 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12708 ".firstprivate.temp"); 12709 InitializedEntity Entity = 12710 InitializedEntity::InitializeVariable(VDInitTemp); 12711 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12712 12713 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12714 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12715 if (Result.isInvalid()) 12716 VDPrivate->setInvalidDecl(); 12717 else 12718 VDPrivate->setInit(Result.getAs<Expr>()); 12719 // Remove temp variable declaration. 12720 Context.Deallocate(VDInitTemp); 12721 } else { 12722 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12723 ".firstprivate.temp"); 12724 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12725 RefExpr->getExprLoc()); 12726 AddInitializerToDecl(VDPrivate, 12727 DefaultLvalueConversion(VDInitRefExpr).get(), 12728 /*DirectInit=*/false); 12729 } 12730 if (VDPrivate->isInvalidDecl()) { 12731 if (IsImplicitClause) { 12732 Diag(RefExpr->getExprLoc(), 12733 diag::note_omp_task_predetermined_firstprivate_here); 12734 } 12735 continue; 12736 } 12737 CurContext->addDecl(VDPrivate); 12738 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12739 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12740 RefExpr->getExprLoc()); 12741 DeclRefExpr *Ref = nullptr; 12742 if (!VD && !CurContext->isDependentContext()) { 12743 if (TopDVar.CKind == OMPC_lastprivate) { 12744 Ref = TopDVar.PrivateCopy; 12745 } else { 12746 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12747 if (!isOpenMPCapturedDecl(D)) 12748 ExprCaptures.push_back(Ref->getDecl()); 12749 } 12750 } 12751 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12752 Vars.push_back((VD || CurContext->isDependentContext()) 12753 ? RefExpr->IgnoreParens() 12754 : Ref); 12755 PrivateCopies.push_back(VDPrivateRefExpr); 12756 Inits.push_back(VDInitRefExpr); 12757 } 12758 12759 if (Vars.empty()) 12760 return nullptr; 12761 12762 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12763 Vars, PrivateCopies, Inits, 12764 buildPreInits(Context, ExprCaptures)); 12765 } 12766 12767 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12768 SourceLocation StartLoc, 12769 SourceLocation LParenLoc, 12770 SourceLocation EndLoc) { 12771 SmallVector<Expr *, 8> Vars; 12772 SmallVector<Expr *, 8> SrcExprs; 12773 SmallVector<Expr *, 8> DstExprs; 12774 SmallVector<Expr *, 8> AssignmentOps; 12775 SmallVector<Decl *, 4> ExprCaptures; 12776 SmallVector<Expr *, 4> ExprPostUpdates; 12777 for (Expr *RefExpr : VarList) { 12778 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12779 SourceLocation ELoc; 12780 SourceRange ERange; 12781 Expr *SimpleRefExpr = RefExpr; 12782 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12783 if (Res.second) { 12784 // It will be analyzed later. 12785 Vars.push_back(RefExpr); 12786 SrcExprs.push_back(nullptr); 12787 DstExprs.push_back(nullptr); 12788 AssignmentOps.push_back(nullptr); 12789 } 12790 ValueDecl *D = Res.first; 12791 if (!D) 12792 continue; 12793 12794 QualType Type = D->getType(); 12795 auto *VD = dyn_cast<VarDecl>(D); 12796 12797 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12798 // A variable that appears in a lastprivate clause must not have an 12799 // incomplete type or a reference type. 12800 if (RequireCompleteType(ELoc, Type, 12801 diag::err_omp_lastprivate_incomplete_type)) 12802 continue; 12803 Type = Type.getNonReferenceType(); 12804 12805 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12806 // A variable that is privatized must not have a const-qualified type 12807 // unless it is of class type with a mutable member. This restriction does 12808 // not apply to the firstprivate clause. 12809 // 12810 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12811 // A variable that appears in a lastprivate clause must not have a 12812 // const-qualified type unless it is of class type with a mutable member. 12813 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12814 continue; 12815 12816 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12817 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12818 // in a Construct] 12819 // Variables with the predetermined data-sharing attributes may not be 12820 // listed in data-sharing attributes clauses, except for the cases 12821 // listed below. 12822 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12823 // A list item may appear in a firstprivate or lastprivate clause but not 12824 // both. 12825 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12826 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12827 (isOpenMPDistributeDirective(CurrDir) || 12828 DVar.CKind != OMPC_firstprivate) && 12829 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12830 Diag(ELoc, diag::err_omp_wrong_dsa) 12831 << getOpenMPClauseName(DVar.CKind) 12832 << getOpenMPClauseName(OMPC_lastprivate); 12833 reportOriginalDsa(*this, DSAStack, D, DVar); 12834 continue; 12835 } 12836 12837 // OpenMP [2.14.3.5, Restrictions, p.2] 12838 // A list item that is private within a parallel region, or that appears in 12839 // the reduction clause of a parallel construct, must not appear in a 12840 // lastprivate clause on a worksharing construct if any of the corresponding 12841 // worksharing regions ever binds to any of the corresponding parallel 12842 // regions. 12843 DSAStackTy::DSAVarData TopDVar = DVar; 12844 if (isOpenMPWorksharingDirective(CurrDir) && 12845 !isOpenMPParallelDirective(CurrDir) && 12846 !isOpenMPTeamsDirective(CurrDir)) { 12847 DVar = DSAStack->getImplicitDSA(D, true); 12848 if (DVar.CKind != OMPC_shared) { 12849 Diag(ELoc, diag::err_omp_required_access) 12850 << getOpenMPClauseName(OMPC_lastprivate) 12851 << getOpenMPClauseName(OMPC_shared); 12852 reportOriginalDsa(*this, DSAStack, D, DVar); 12853 continue; 12854 } 12855 } 12856 12857 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12858 // A variable of class type (or array thereof) that appears in a 12859 // lastprivate clause requires an accessible, unambiguous default 12860 // constructor for the class type, unless the list item is also specified 12861 // in a firstprivate clause. 12862 // A variable of class type (or array thereof) that appears in a 12863 // lastprivate clause requires an accessible, unambiguous copy assignment 12864 // operator for the class type. 12865 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12866 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12867 Type.getUnqualifiedType(), ".lastprivate.src", 12868 D->hasAttrs() ? &D->getAttrs() : nullptr); 12869 DeclRefExpr *PseudoSrcExpr = 12870 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12871 VarDecl *DstVD = 12872 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12873 D->hasAttrs() ? &D->getAttrs() : nullptr); 12874 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12875 // For arrays generate assignment operation for single element and replace 12876 // it by the original array element in CodeGen. 12877 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12878 PseudoDstExpr, PseudoSrcExpr); 12879 if (AssignmentOp.isInvalid()) 12880 continue; 12881 AssignmentOp = 12882 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12883 if (AssignmentOp.isInvalid()) 12884 continue; 12885 12886 DeclRefExpr *Ref = nullptr; 12887 if (!VD && !CurContext->isDependentContext()) { 12888 if (TopDVar.CKind == OMPC_firstprivate) { 12889 Ref = TopDVar.PrivateCopy; 12890 } else { 12891 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12892 if (!isOpenMPCapturedDecl(D)) 12893 ExprCaptures.push_back(Ref->getDecl()); 12894 } 12895 if (TopDVar.CKind == OMPC_firstprivate || 12896 (!isOpenMPCapturedDecl(D) && 12897 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12898 ExprResult RefRes = DefaultLvalueConversion(Ref); 12899 if (!RefRes.isUsable()) 12900 continue; 12901 ExprResult PostUpdateRes = 12902 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12903 RefRes.get()); 12904 if (!PostUpdateRes.isUsable()) 12905 continue; 12906 ExprPostUpdates.push_back( 12907 IgnoredValueConversions(PostUpdateRes.get()).get()); 12908 } 12909 } 12910 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12911 Vars.push_back((VD || CurContext->isDependentContext()) 12912 ? RefExpr->IgnoreParens() 12913 : Ref); 12914 SrcExprs.push_back(PseudoSrcExpr); 12915 DstExprs.push_back(PseudoDstExpr); 12916 AssignmentOps.push_back(AssignmentOp.get()); 12917 } 12918 12919 if (Vars.empty()) 12920 return nullptr; 12921 12922 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12923 Vars, SrcExprs, DstExprs, AssignmentOps, 12924 buildPreInits(Context, ExprCaptures), 12925 buildPostUpdate(*this, ExprPostUpdates)); 12926 } 12927 12928 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12929 SourceLocation StartLoc, 12930 SourceLocation LParenLoc, 12931 SourceLocation EndLoc) { 12932 SmallVector<Expr *, 8> Vars; 12933 for (Expr *RefExpr : VarList) { 12934 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12935 SourceLocation ELoc; 12936 SourceRange ERange; 12937 Expr *SimpleRefExpr = RefExpr; 12938 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12939 if (Res.second) { 12940 // It will be analyzed later. 12941 Vars.push_back(RefExpr); 12942 } 12943 ValueDecl *D = Res.first; 12944 if (!D) 12945 continue; 12946 12947 auto *VD = dyn_cast<VarDecl>(D); 12948 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12949 // in a Construct] 12950 // Variables with the predetermined data-sharing attributes may not be 12951 // listed in data-sharing attributes clauses, except for the cases 12952 // listed below. For these exceptions only, listing a predetermined 12953 // variable in a data-sharing attribute clause is allowed and overrides 12954 // the variable's predetermined data-sharing attributes. 12955 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12956 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12957 DVar.RefExpr) { 12958 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12959 << getOpenMPClauseName(OMPC_shared); 12960 reportOriginalDsa(*this, DSAStack, D, DVar); 12961 continue; 12962 } 12963 12964 DeclRefExpr *Ref = nullptr; 12965 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12966 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12967 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12968 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12969 ? RefExpr->IgnoreParens() 12970 : Ref); 12971 } 12972 12973 if (Vars.empty()) 12974 return nullptr; 12975 12976 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12977 } 12978 12979 namespace { 12980 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12981 DSAStackTy *Stack; 12982 12983 public: 12984 bool VisitDeclRefExpr(DeclRefExpr *E) { 12985 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12986 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12987 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12988 return false; 12989 if (DVar.CKind != OMPC_unknown) 12990 return true; 12991 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12992 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12993 /*FromParent=*/true); 12994 return DVarPrivate.CKind != OMPC_unknown; 12995 } 12996 return false; 12997 } 12998 bool VisitStmt(Stmt *S) { 12999 for (Stmt *Child : S->children()) { 13000 if (Child && Visit(Child)) 13001 return true; 13002 } 13003 return false; 13004 } 13005 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13006 }; 13007 } // namespace 13008 13009 namespace { 13010 // Transform MemberExpression for specified FieldDecl of current class to 13011 // DeclRefExpr to specified OMPCapturedExprDecl. 13012 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13013 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13014 ValueDecl *Field = nullptr; 13015 DeclRefExpr *CapturedExpr = nullptr; 13016 13017 public: 13018 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13019 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13020 13021 ExprResult TransformMemberExpr(MemberExpr *E) { 13022 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13023 E->getMemberDecl() == Field) { 13024 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13025 return CapturedExpr; 13026 } 13027 return BaseTransform::TransformMemberExpr(E); 13028 } 13029 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13030 }; 13031 } // namespace 13032 13033 template <typename T, typename U> 13034 static T filterLookupForUDReductionAndMapper( 13035 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13036 for (U &Set : Lookups) { 13037 for (auto *D : Set) { 13038 if (T Res = Gen(cast<ValueDecl>(D))) 13039 return Res; 13040 } 13041 } 13042 return T(); 13043 } 13044 13045 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13046 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13047 13048 for (auto RD : D->redecls()) { 13049 // Don't bother with extra checks if we already know this one isn't visible. 13050 if (RD == D) 13051 continue; 13052 13053 auto ND = cast<NamedDecl>(RD); 13054 if (LookupResult::isVisible(SemaRef, ND)) 13055 return ND; 13056 } 13057 13058 return nullptr; 13059 } 13060 13061 static void 13062 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13063 SourceLocation Loc, QualType Ty, 13064 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13065 // Find all of the associated namespaces and classes based on the 13066 // arguments we have. 13067 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13068 Sema::AssociatedClassSet AssociatedClasses; 13069 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13070 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13071 AssociatedClasses); 13072 13073 // C++ [basic.lookup.argdep]p3: 13074 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13075 // and let Y be the lookup set produced by argument dependent 13076 // lookup (defined as follows). If X contains [...] then Y is 13077 // empty. Otherwise Y is the set of declarations found in the 13078 // namespaces associated with the argument types as described 13079 // below. The set of declarations found by the lookup of the name 13080 // is the union of X and Y. 13081 // 13082 // Here, we compute Y and add its members to the overloaded 13083 // candidate set. 13084 for (auto *NS : AssociatedNamespaces) { 13085 // When considering an associated namespace, the lookup is the 13086 // same as the lookup performed when the associated namespace is 13087 // used as a qualifier (3.4.3.2) except that: 13088 // 13089 // -- Any using-directives in the associated namespace are 13090 // ignored. 13091 // 13092 // -- Any namespace-scope friend functions declared in 13093 // associated classes are visible within their respective 13094 // namespaces even if they are not visible during an ordinary 13095 // lookup (11.4). 13096 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13097 for (auto *D : R) { 13098 auto *Underlying = D; 13099 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13100 Underlying = USD->getTargetDecl(); 13101 13102 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13103 !isa<OMPDeclareMapperDecl>(Underlying)) 13104 continue; 13105 13106 if (!SemaRef.isVisible(D)) { 13107 D = findAcceptableDecl(SemaRef, D); 13108 if (!D) 13109 continue; 13110 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13111 Underlying = USD->getTargetDecl(); 13112 } 13113 Lookups.emplace_back(); 13114 Lookups.back().addDecl(Underlying); 13115 } 13116 } 13117 } 13118 13119 static ExprResult 13120 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13121 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13122 const DeclarationNameInfo &ReductionId, QualType Ty, 13123 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13124 if (ReductionIdScopeSpec.isInvalid()) 13125 return ExprError(); 13126 SmallVector<UnresolvedSet<8>, 4> Lookups; 13127 if (S) { 13128 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13129 Lookup.suppressDiagnostics(); 13130 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13131 NamedDecl *D = Lookup.getRepresentativeDecl(); 13132 do { 13133 S = S->getParent(); 13134 } while (S && !S->isDeclScope(D)); 13135 if (S) 13136 S = S->getParent(); 13137 Lookups.emplace_back(); 13138 Lookups.back().append(Lookup.begin(), Lookup.end()); 13139 Lookup.clear(); 13140 } 13141 } else if (auto *ULE = 13142 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13143 Lookups.push_back(UnresolvedSet<8>()); 13144 Decl *PrevD = nullptr; 13145 for (NamedDecl *D : ULE->decls()) { 13146 if (D == PrevD) 13147 Lookups.push_back(UnresolvedSet<8>()); 13148 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13149 Lookups.back().addDecl(DRD); 13150 PrevD = D; 13151 } 13152 } 13153 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13154 Ty->isInstantiationDependentType() || 13155 Ty->containsUnexpandedParameterPack() || 13156 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13157 return !D->isInvalidDecl() && 13158 (D->getType()->isDependentType() || 13159 D->getType()->isInstantiationDependentType() || 13160 D->getType()->containsUnexpandedParameterPack()); 13161 })) { 13162 UnresolvedSet<8> ResSet; 13163 for (const UnresolvedSet<8> &Set : Lookups) { 13164 if (Set.empty()) 13165 continue; 13166 ResSet.append(Set.begin(), Set.end()); 13167 // The last item marks the end of all declarations at the specified scope. 13168 ResSet.addDecl(Set[Set.size() - 1]); 13169 } 13170 return UnresolvedLookupExpr::Create( 13171 SemaRef.Context, /*NamingClass=*/nullptr, 13172 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13173 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13174 } 13175 // Lookup inside the classes. 13176 // C++ [over.match.oper]p3: 13177 // For a unary operator @ with an operand of a type whose 13178 // cv-unqualified version is T1, and for a binary operator @ with 13179 // a left operand of a type whose cv-unqualified version is T1 and 13180 // a right operand of a type whose cv-unqualified version is T2, 13181 // three sets of candidate functions, designated member 13182 // candidates, non-member candidates and built-in candidates, are 13183 // constructed as follows: 13184 // -- If T1 is a complete class type or a class currently being 13185 // defined, the set of member candidates is the result of the 13186 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13187 // the set of member candidates is empty. 13188 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13189 Lookup.suppressDiagnostics(); 13190 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13191 // Complete the type if it can be completed. 13192 // If the type is neither complete nor being defined, bail out now. 13193 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13194 TyRec->getDecl()->getDefinition()) { 13195 Lookup.clear(); 13196 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13197 if (Lookup.empty()) { 13198 Lookups.emplace_back(); 13199 Lookups.back().append(Lookup.begin(), Lookup.end()); 13200 } 13201 } 13202 } 13203 // Perform ADL. 13204 if (SemaRef.getLangOpts().CPlusPlus) 13205 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13206 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13207 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13208 if (!D->isInvalidDecl() && 13209 SemaRef.Context.hasSameType(D->getType(), Ty)) 13210 return D; 13211 return nullptr; 13212 })) 13213 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13214 VK_LValue, Loc); 13215 if (SemaRef.getLangOpts().CPlusPlus) { 13216 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13217 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13218 if (!D->isInvalidDecl() && 13219 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13220 !Ty.isMoreQualifiedThan(D->getType())) 13221 return D; 13222 return nullptr; 13223 })) { 13224 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13225 /*DetectVirtual=*/false); 13226 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13227 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13228 VD->getType().getUnqualifiedType()))) { 13229 if (SemaRef.CheckBaseClassAccess( 13230 Loc, VD->getType(), Ty, Paths.front(), 13231 /*DiagID=*/0) != Sema::AR_inaccessible) { 13232 SemaRef.BuildBasePathArray(Paths, BasePath); 13233 return SemaRef.BuildDeclRefExpr( 13234 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13235 } 13236 } 13237 } 13238 } 13239 } 13240 if (ReductionIdScopeSpec.isSet()) { 13241 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 13242 return ExprError(); 13243 } 13244 return ExprEmpty(); 13245 } 13246 13247 namespace { 13248 /// Data for the reduction-based clauses. 13249 struct ReductionData { 13250 /// List of original reduction items. 13251 SmallVector<Expr *, 8> Vars; 13252 /// List of private copies of the reduction items. 13253 SmallVector<Expr *, 8> Privates; 13254 /// LHS expressions for the reduction_op expressions. 13255 SmallVector<Expr *, 8> LHSs; 13256 /// RHS expressions for the reduction_op expressions. 13257 SmallVector<Expr *, 8> RHSs; 13258 /// Reduction operation expression. 13259 SmallVector<Expr *, 8> ReductionOps; 13260 /// Taskgroup descriptors for the corresponding reduction items in 13261 /// in_reduction clauses. 13262 SmallVector<Expr *, 8> TaskgroupDescriptors; 13263 /// List of captures for clause. 13264 SmallVector<Decl *, 4> ExprCaptures; 13265 /// List of postupdate expressions. 13266 SmallVector<Expr *, 4> ExprPostUpdates; 13267 ReductionData() = delete; 13268 /// Reserves required memory for the reduction data. 13269 ReductionData(unsigned Size) { 13270 Vars.reserve(Size); 13271 Privates.reserve(Size); 13272 LHSs.reserve(Size); 13273 RHSs.reserve(Size); 13274 ReductionOps.reserve(Size); 13275 TaskgroupDescriptors.reserve(Size); 13276 ExprCaptures.reserve(Size); 13277 ExprPostUpdates.reserve(Size); 13278 } 13279 /// Stores reduction item and reduction operation only (required for dependent 13280 /// reduction item). 13281 void push(Expr *Item, Expr *ReductionOp) { 13282 Vars.emplace_back(Item); 13283 Privates.emplace_back(nullptr); 13284 LHSs.emplace_back(nullptr); 13285 RHSs.emplace_back(nullptr); 13286 ReductionOps.emplace_back(ReductionOp); 13287 TaskgroupDescriptors.emplace_back(nullptr); 13288 } 13289 /// Stores reduction data. 13290 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13291 Expr *TaskgroupDescriptor) { 13292 Vars.emplace_back(Item); 13293 Privates.emplace_back(Private); 13294 LHSs.emplace_back(LHS); 13295 RHSs.emplace_back(RHS); 13296 ReductionOps.emplace_back(ReductionOp); 13297 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13298 } 13299 }; 13300 } // namespace 13301 13302 static bool checkOMPArraySectionConstantForReduction( 13303 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13304 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13305 const Expr *Length = OASE->getLength(); 13306 if (Length == nullptr) { 13307 // For array sections of the form [1:] or [:], we would need to analyze 13308 // the lower bound... 13309 if (OASE->getColonLoc().isValid()) 13310 return false; 13311 13312 // This is an array subscript which has implicit length 1! 13313 SingleElement = true; 13314 ArraySizes.push_back(llvm::APSInt::get(1)); 13315 } else { 13316 Expr::EvalResult Result; 13317 if (!Length->EvaluateAsInt(Result, Context)) 13318 return false; 13319 13320 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13321 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13322 ArraySizes.push_back(ConstantLengthValue); 13323 } 13324 13325 // Get the base of this array section and walk up from there. 13326 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13327 13328 // We require length = 1 for all array sections except the right-most to 13329 // guarantee that the memory region is contiguous and has no holes in it. 13330 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13331 Length = TempOASE->getLength(); 13332 if (Length == nullptr) { 13333 // For array sections of the form [1:] or [:], we would need to analyze 13334 // the lower bound... 13335 if (OASE->getColonLoc().isValid()) 13336 return false; 13337 13338 // This is an array subscript which has implicit length 1! 13339 ArraySizes.push_back(llvm::APSInt::get(1)); 13340 } else { 13341 Expr::EvalResult Result; 13342 if (!Length->EvaluateAsInt(Result, Context)) 13343 return false; 13344 13345 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13346 if (ConstantLengthValue.getSExtValue() != 1) 13347 return false; 13348 13349 ArraySizes.push_back(ConstantLengthValue); 13350 } 13351 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13352 } 13353 13354 // If we have a single element, we don't need to add the implicit lengths. 13355 if (!SingleElement) { 13356 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13357 // Has implicit length 1! 13358 ArraySizes.push_back(llvm::APSInt::get(1)); 13359 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13360 } 13361 } 13362 13363 // This array section can be privatized as a single value or as a constant 13364 // sized array. 13365 return true; 13366 } 13367 13368 static bool actOnOMPReductionKindClause( 13369 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13370 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13371 SourceLocation ColonLoc, SourceLocation EndLoc, 13372 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13373 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13374 DeclarationName DN = ReductionId.getName(); 13375 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13376 BinaryOperatorKind BOK = BO_Comma; 13377 13378 ASTContext &Context = S.Context; 13379 // OpenMP [2.14.3.6, reduction clause] 13380 // C 13381 // reduction-identifier is either an identifier or one of the following 13382 // operators: +, -, *, &, |, ^, && and || 13383 // C++ 13384 // reduction-identifier is either an id-expression or one of the following 13385 // operators: +, -, *, &, |, ^, && and || 13386 switch (OOK) { 13387 case OO_Plus: 13388 case OO_Minus: 13389 BOK = BO_Add; 13390 break; 13391 case OO_Star: 13392 BOK = BO_Mul; 13393 break; 13394 case OO_Amp: 13395 BOK = BO_And; 13396 break; 13397 case OO_Pipe: 13398 BOK = BO_Or; 13399 break; 13400 case OO_Caret: 13401 BOK = BO_Xor; 13402 break; 13403 case OO_AmpAmp: 13404 BOK = BO_LAnd; 13405 break; 13406 case OO_PipePipe: 13407 BOK = BO_LOr; 13408 break; 13409 case OO_New: 13410 case OO_Delete: 13411 case OO_Array_New: 13412 case OO_Array_Delete: 13413 case OO_Slash: 13414 case OO_Percent: 13415 case OO_Tilde: 13416 case OO_Exclaim: 13417 case OO_Equal: 13418 case OO_Less: 13419 case OO_Greater: 13420 case OO_LessEqual: 13421 case OO_GreaterEqual: 13422 case OO_PlusEqual: 13423 case OO_MinusEqual: 13424 case OO_StarEqual: 13425 case OO_SlashEqual: 13426 case OO_PercentEqual: 13427 case OO_CaretEqual: 13428 case OO_AmpEqual: 13429 case OO_PipeEqual: 13430 case OO_LessLess: 13431 case OO_GreaterGreater: 13432 case OO_LessLessEqual: 13433 case OO_GreaterGreaterEqual: 13434 case OO_EqualEqual: 13435 case OO_ExclaimEqual: 13436 case OO_Spaceship: 13437 case OO_PlusPlus: 13438 case OO_MinusMinus: 13439 case OO_Comma: 13440 case OO_ArrowStar: 13441 case OO_Arrow: 13442 case OO_Call: 13443 case OO_Subscript: 13444 case OO_Conditional: 13445 case OO_Coawait: 13446 case NUM_OVERLOADED_OPERATORS: 13447 llvm_unreachable("Unexpected reduction identifier"); 13448 case OO_None: 13449 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13450 if (II->isStr("max")) 13451 BOK = BO_GT; 13452 else if (II->isStr("min")) 13453 BOK = BO_LT; 13454 } 13455 break; 13456 } 13457 SourceRange ReductionIdRange; 13458 if (ReductionIdScopeSpec.isValid()) 13459 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13460 else 13461 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13462 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13463 13464 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13465 bool FirstIter = true; 13466 for (Expr *RefExpr : VarList) { 13467 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13468 // OpenMP [2.1, C/C++] 13469 // A list item is a variable or array section, subject to the restrictions 13470 // specified in Section 2.4 on page 42 and in each of the sections 13471 // describing clauses and directives for which a list appears. 13472 // OpenMP [2.14.3.3, Restrictions, p.1] 13473 // A variable that is part of another variable (as an array or 13474 // structure element) cannot appear in a private clause. 13475 if (!FirstIter && IR != ER) 13476 ++IR; 13477 FirstIter = false; 13478 SourceLocation ELoc; 13479 SourceRange ERange; 13480 Expr *SimpleRefExpr = RefExpr; 13481 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13482 /*AllowArraySection=*/true); 13483 if (Res.second) { 13484 // Try to find 'declare reduction' corresponding construct before using 13485 // builtin/overloaded operators. 13486 QualType Type = Context.DependentTy; 13487 CXXCastPath BasePath; 13488 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13489 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13490 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13491 Expr *ReductionOp = nullptr; 13492 if (S.CurContext->isDependentContext() && 13493 (DeclareReductionRef.isUnset() || 13494 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13495 ReductionOp = DeclareReductionRef.get(); 13496 // It will be analyzed later. 13497 RD.push(RefExpr, ReductionOp); 13498 } 13499 ValueDecl *D = Res.first; 13500 if (!D) 13501 continue; 13502 13503 Expr *TaskgroupDescriptor = nullptr; 13504 QualType Type; 13505 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13506 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13507 if (ASE) { 13508 Type = ASE->getType().getNonReferenceType(); 13509 } else if (OASE) { 13510 QualType BaseType = 13511 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13512 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13513 Type = ATy->getElementType(); 13514 else 13515 Type = BaseType->getPointeeType(); 13516 Type = Type.getNonReferenceType(); 13517 } else { 13518 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13519 } 13520 auto *VD = dyn_cast<VarDecl>(D); 13521 13522 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13523 // A variable that appears in a private clause must not have an incomplete 13524 // type or a reference type. 13525 if (S.RequireCompleteType(ELoc, D->getType(), 13526 diag::err_omp_reduction_incomplete_type)) 13527 continue; 13528 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13529 // A list item that appears in a reduction clause must not be 13530 // const-qualified. 13531 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13532 /*AcceptIfMutable*/ false, ASE || OASE)) 13533 continue; 13534 13535 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13536 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13537 // If a list-item is a reference type then it must bind to the same object 13538 // for all threads of the team. 13539 if (!ASE && !OASE) { 13540 if (VD) { 13541 VarDecl *VDDef = VD->getDefinition(); 13542 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13543 DSARefChecker Check(Stack); 13544 if (Check.Visit(VDDef->getInit())) { 13545 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13546 << getOpenMPClauseName(ClauseKind) << ERange; 13547 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13548 continue; 13549 } 13550 } 13551 } 13552 13553 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13554 // in a Construct] 13555 // Variables with the predetermined data-sharing attributes may not be 13556 // listed in data-sharing attributes clauses, except for the cases 13557 // listed below. For these exceptions only, listing a predetermined 13558 // variable in a data-sharing attribute clause is allowed and overrides 13559 // the variable's predetermined data-sharing attributes. 13560 // OpenMP [2.14.3.6, Restrictions, p.3] 13561 // Any number of reduction clauses can be specified on the directive, 13562 // but a list item can appear only once in the reduction clauses for that 13563 // directive. 13564 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13565 if (DVar.CKind == OMPC_reduction) { 13566 S.Diag(ELoc, diag::err_omp_once_referenced) 13567 << getOpenMPClauseName(ClauseKind); 13568 if (DVar.RefExpr) 13569 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13570 continue; 13571 } 13572 if (DVar.CKind != OMPC_unknown) { 13573 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13574 << getOpenMPClauseName(DVar.CKind) 13575 << getOpenMPClauseName(OMPC_reduction); 13576 reportOriginalDsa(S, Stack, D, DVar); 13577 continue; 13578 } 13579 13580 // OpenMP [2.14.3.6, Restrictions, p.1] 13581 // A list item that appears in a reduction clause of a worksharing 13582 // construct must be shared in the parallel regions to which any of the 13583 // worksharing regions arising from the worksharing construct bind. 13584 if (isOpenMPWorksharingDirective(CurrDir) && 13585 !isOpenMPParallelDirective(CurrDir) && 13586 !isOpenMPTeamsDirective(CurrDir)) { 13587 DVar = Stack->getImplicitDSA(D, true); 13588 if (DVar.CKind != OMPC_shared) { 13589 S.Diag(ELoc, diag::err_omp_required_access) 13590 << getOpenMPClauseName(OMPC_reduction) 13591 << getOpenMPClauseName(OMPC_shared); 13592 reportOriginalDsa(S, Stack, D, DVar); 13593 continue; 13594 } 13595 } 13596 } 13597 13598 // Try to find 'declare reduction' corresponding construct before using 13599 // builtin/overloaded operators. 13600 CXXCastPath BasePath; 13601 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13602 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13603 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13604 if (DeclareReductionRef.isInvalid()) 13605 continue; 13606 if (S.CurContext->isDependentContext() && 13607 (DeclareReductionRef.isUnset() || 13608 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13609 RD.push(RefExpr, DeclareReductionRef.get()); 13610 continue; 13611 } 13612 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13613 // Not allowed reduction identifier is found. 13614 S.Diag(ReductionId.getBeginLoc(), 13615 diag::err_omp_unknown_reduction_identifier) 13616 << Type << ReductionIdRange; 13617 continue; 13618 } 13619 13620 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13621 // The type of a list item that appears in a reduction clause must be valid 13622 // for the reduction-identifier. For a max or min reduction in C, the type 13623 // of the list item must be an allowed arithmetic data type: char, int, 13624 // float, double, or _Bool, possibly modified with long, short, signed, or 13625 // unsigned. For a max or min reduction in C++, the type of the list item 13626 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13627 // double, or bool, possibly modified with long, short, signed, or unsigned. 13628 if (DeclareReductionRef.isUnset()) { 13629 if ((BOK == BO_GT || BOK == BO_LT) && 13630 !(Type->isScalarType() || 13631 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13632 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13633 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13634 if (!ASE && !OASE) { 13635 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13636 VarDecl::DeclarationOnly; 13637 S.Diag(D->getLocation(), 13638 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13639 << D; 13640 } 13641 continue; 13642 } 13643 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13644 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13645 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13646 << getOpenMPClauseName(ClauseKind); 13647 if (!ASE && !OASE) { 13648 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13649 VarDecl::DeclarationOnly; 13650 S.Diag(D->getLocation(), 13651 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13652 << D; 13653 } 13654 continue; 13655 } 13656 } 13657 13658 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13659 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13660 D->hasAttrs() ? &D->getAttrs() : nullptr); 13661 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13662 D->hasAttrs() ? &D->getAttrs() : nullptr); 13663 QualType PrivateTy = Type; 13664 13665 // Try if we can determine constant lengths for all array sections and avoid 13666 // the VLA. 13667 bool ConstantLengthOASE = false; 13668 if (OASE) { 13669 bool SingleElement; 13670 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13671 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13672 Context, OASE, SingleElement, ArraySizes); 13673 13674 // If we don't have a single element, we must emit a constant array type. 13675 if (ConstantLengthOASE && !SingleElement) { 13676 for (llvm::APSInt &Size : ArraySizes) 13677 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13678 ArrayType::Normal, 13679 /*IndexTypeQuals=*/0); 13680 } 13681 } 13682 13683 if ((OASE && !ConstantLengthOASE) || 13684 (!OASE && !ASE && 13685 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13686 if (!Context.getTargetInfo().isVLASupported()) { 13687 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13688 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13689 S.Diag(ELoc, diag::note_vla_unsupported); 13690 } else { 13691 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13692 S.targetDiag(ELoc, diag::note_vla_unsupported); 13693 } 13694 continue; 13695 } 13696 // For arrays/array sections only: 13697 // Create pseudo array type for private copy. The size for this array will 13698 // be generated during codegen. 13699 // For array subscripts or single variables Private Ty is the same as Type 13700 // (type of the variable or single array element). 13701 PrivateTy = Context.getVariableArrayType( 13702 Type, 13703 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13704 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13705 } else if (!ASE && !OASE && 13706 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13707 PrivateTy = D->getType().getNonReferenceType(); 13708 } 13709 // Private copy. 13710 VarDecl *PrivateVD = 13711 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13712 D->hasAttrs() ? &D->getAttrs() : nullptr, 13713 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13714 // Add initializer for private variable. 13715 Expr *Init = nullptr; 13716 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13717 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13718 if (DeclareReductionRef.isUsable()) { 13719 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13720 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13721 if (DRD->getInitializer()) { 13722 Init = DRDRef; 13723 RHSVD->setInit(DRDRef); 13724 RHSVD->setInitStyle(VarDecl::CallInit); 13725 } 13726 } else { 13727 switch (BOK) { 13728 case BO_Add: 13729 case BO_Xor: 13730 case BO_Or: 13731 case BO_LOr: 13732 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13733 if (Type->isScalarType() || Type->isAnyComplexType()) 13734 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13735 break; 13736 case BO_Mul: 13737 case BO_LAnd: 13738 if (Type->isScalarType() || Type->isAnyComplexType()) { 13739 // '*' and '&&' reduction ops - initializer is '1'. 13740 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13741 } 13742 break; 13743 case BO_And: { 13744 // '&' reduction op - initializer is '~0'. 13745 QualType OrigType = Type; 13746 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13747 Type = ComplexTy->getElementType(); 13748 if (Type->isRealFloatingType()) { 13749 llvm::APFloat InitValue = 13750 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13751 /*isIEEE=*/true); 13752 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13753 Type, ELoc); 13754 } else if (Type->isScalarType()) { 13755 uint64_t Size = Context.getTypeSize(Type); 13756 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13757 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13758 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13759 } 13760 if (Init && OrigType->isAnyComplexType()) { 13761 // Init = 0xFFFF + 0xFFFFi; 13762 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13763 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13764 } 13765 Type = OrigType; 13766 break; 13767 } 13768 case BO_LT: 13769 case BO_GT: { 13770 // 'min' reduction op - initializer is 'Largest representable number in 13771 // the reduction list item type'. 13772 // 'max' reduction op - initializer is 'Least representable number in 13773 // the reduction list item type'. 13774 if (Type->isIntegerType() || Type->isPointerType()) { 13775 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13776 uint64_t Size = Context.getTypeSize(Type); 13777 QualType IntTy = 13778 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13779 llvm::APInt InitValue = 13780 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13781 : llvm::APInt::getMinValue(Size) 13782 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13783 : llvm::APInt::getMaxValue(Size); 13784 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13785 if (Type->isPointerType()) { 13786 // Cast to pointer type. 13787 ExprResult CastExpr = S.BuildCStyleCastExpr( 13788 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13789 if (CastExpr.isInvalid()) 13790 continue; 13791 Init = CastExpr.get(); 13792 } 13793 } else if (Type->isRealFloatingType()) { 13794 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13795 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13796 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13797 Type, ELoc); 13798 } 13799 break; 13800 } 13801 case BO_PtrMemD: 13802 case BO_PtrMemI: 13803 case BO_MulAssign: 13804 case BO_Div: 13805 case BO_Rem: 13806 case BO_Sub: 13807 case BO_Shl: 13808 case BO_Shr: 13809 case BO_LE: 13810 case BO_GE: 13811 case BO_EQ: 13812 case BO_NE: 13813 case BO_Cmp: 13814 case BO_AndAssign: 13815 case BO_XorAssign: 13816 case BO_OrAssign: 13817 case BO_Assign: 13818 case BO_AddAssign: 13819 case BO_SubAssign: 13820 case BO_DivAssign: 13821 case BO_RemAssign: 13822 case BO_ShlAssign: 13823 case BO_ShrAssign: 13824 case BO_Comma: 13825 llvm_unreachable("Unexpected reduction operation"); 13826 } 13827 } 13828 if (Init && DeclareReductionRef.isUnset()) 13829 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13830 else if (!Init) 13831 S.ActOnUninitializedDecl(RHSVD); 13832 if (RHSVD->isInvalidDecl()) 13833 continue; 13834 if (!RHSVD->hasInit() && 13835 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13836 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13837 << Type << ReductionIdRange; 13838 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13839 VarDecl::DeclarationOnly; 13840 S.Diag(D->getLocation(), 13841 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13842 << D; 13843 continue; 13844 } 13845 // Store initializer for single element in private copy. Will be used during 13846 // codegen. 13847 PrivateVD->setInit(RHSVD->getInit()); 13848 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13849 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13850 ExprResult ReductionOp; 13851 if (DeclareReductionRef.isUsable()) { 13852 QualType RedTy = DeclareReductionRef.get()->getType(); 13853 QualType PtrRedTy = Context.getPointerType(RedTy); 13854 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13855 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13856 if (!BasePath.empty()) { 13857 LHS = S.DefaultLvalueConversion(LHS.get()); 13858 RHS = S.DefaultLvalueConversion(RHS.get()); 13859 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13860 CK_UncheckedDerivedToBase, LHS.get(), 13861 &BasePath, LHS.get()->getValueKind()); 13862 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13863 CK_UncheckedDerivedToBase, RHS.get(), 13864 &BasePath, RHS.get()->getValueKind()); 13865 } 13866 FunctionProtoType::ExtProtoInfo EPI; 13867 QualType Params[] = {PtrRedTy, PtrRedTy}; 13868 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13869 auto *OVE = new (Context) OpaqueValueExpr( 13870 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13871 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13872 Expr *Args[] = {LHS.get(), RHS.get()}; 13873 ReductionOp = 13874 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13875 } else { 13876 ReductionOp = S.BuildBinOp( 13877 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13878 if (ReductionOp.isUsable()) { 13879 if (BOK != BO_LT && BOK != BO_GT) { 13880 ReductionOp = 13881 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13882 BO_Assign, LHSDRE, ReductionOp.get()); 13883 } else { 13884 auto *ConditionalOp = new (Context) 13885 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13886 Type, VK_LValue, OK_Ordinary); 13887 ReductionOp = 13888 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13889 BO_Assign, LHSDRE, ConditionalOp); 13890 } 13891 if (ReductionOp.isUsable()) 13892 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13893 /*DiscardedValue*/ false); 13894 } 13895 if (!ReductionOp.isUsable()) 13896 continue; 13897 } 13898 13899 // OpenMP [2.15.4.6, Restrictions, p.2] 13900 // A list item that appears in an in_reduction clause of a task construct 13901 // must appear in a task_reduction clause of a construct associated with a 13902 // taskgroup region that includes the participating task in its taskgroup 13903 // set. The construct associated with the innermost region that meets this 13904 // condition must specify the same reduction-identifier as the in_reduction 13905 // clause. 13906 if (ClauseKind == OMPC_in_reduction) { 13907 SourceRange ParentSR; 13908 BinaryOperatorKind ParentBOK; 13909 const Expr *ParentReductionOp; 13910 Expr *ParentBOKTD, *ParentReductionOpTD; 13911 DSAStackTy::DSAVarData ParentBOKDSA = 13912 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13913 ParentBOKTD); 13914 DSAStackTy::DSAVarData ParentReductionOpDSA = 13915 Stack->getTopMostTaskgroupReductionData( 13916 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13917 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13918 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13919 if (!IsParentBOK && !IsParentReductionOp) { 13920 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13921 continue; 13922 } 13923 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13924 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13925 IsParentReductionOp) { 13926 bool EmitError = true; 13927 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13928 llvm::FoldingSetNodeID RedId, ParentRedId; 13929 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13930 DeclareReductionRef.get()->Profile(RedId, Context, 13931 /*Canonical=*/true); 13932 EmitError = RedId != ParentRedId; 13933 } 13934 if (EmitError) { 13935 S.Diag(ReductionId.getBeginLoc(), 13936 diag::err_omp_reduction_identifier_mismatch) 13937 << ReductionIdRange << RefExpr->getSourceRange(); 13938 S.Diag(ParentSR.getBegin(), 13939 diag::note_omp_previous_reduction_identifier) 13940 << ParentSR 13941 << (IsParentBOK ? ParentBOKDSA.RefExpr 13942 : ParentReductionOpDSA.RefExpr) 13943 ->getSourceRange(); 13944 continue; 13945 } 13946 } 13947 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13948 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13949 } 13950 13951 DeclRefExpr *Ref = nullptr; 13952 Expr *VarsExpr = RefExpr->IgnoreParens(); 13953 if (!VD && !S.CurContext->isDependentContext()) { 13954 if (ASE || OASE) { 13955 TransformExprToCaptures RebuildToCapture(S, D); 13956 VarsExpr = 13957 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13958 Ref = RebuildToCapture.getCapturedExpr(); 13959 } else { 13960 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13961 } 13962 if (!S.isOpenMPCapturedDecl(D)) { 13963 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13964 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13965 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13966 if (!RefRes.isUsable()) 13967 continue; 13968 ExprResult PostUpdateRes = 13969 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13970 RefRes.get()); 13971 if (!PostUpdateRes.isUsable()) 13972 continue; 13973 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13974 Stack->getCurrentDirective() == OMPD_taskgroup) { 13975 S.Diag(RefExpr->getExprLoc(), 13976 diag::err_omp_reduction_non_addressable_expression) 13977 << RefExpr->getSourceRange(); 13978 continue; 13979 } 13980 RD.ExprPostUpdates.emplace_back( 13981 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13982 } 13983 } 13984 } 13985 // All reduction items are still marked as reduction (to do not increase 13986 // code base size). 13987 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13988 if (CurrDir == OMPD_taskgroup) { 13989 if (DeclareReductionRef.isUsable()) 13990 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13991 DeclareReductionRef.get()); 13992 else 13993 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13994 } 13995 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13996 TaskgroupDescriptor); 13997 } 13998 return RD.Vars.empty(); 13999 } 14000 14001 OMPClause *Sema::ActOnOpenMPReductionClause( 14002 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14003 SourceLocation ColonLoc, SourceLocation EndLoc, 14004 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14005 ArrayRef<Expr *> UnresolvedReductions) { 14006 ReductionData RD(VarList.size()); 14007 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14008 StartLoc, LParenLoc, ColonLoc, EndLoc, 14009 ReductionIdScopeSpec, ReductionId, 14010 UnresolvedReductions, RD)) 14011 return nullptr; 14012 14013 return OMPReductionClause::Create( 14014 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14015 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14016 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14017 buildPreInits(Context, RD.ExprCaptures), 14018 buildPostUpdate(*this, RD.ExprPostUpdates)); 14019 } 14020 14021 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14022 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14023 SourceLocation ColonLoc, SourceLocation EndLoc, 14024 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14025 ArrayRef<Expr *> UnresolvedReductions) { 14026 ReductionData RD(VarList.size()); 14027 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14028 StartLoc, LParenLoc, ColonLoc, EndLoc, 14029 ReductionIdScopeSpec, ReductionId, 14030 UnresolvedReductions, RD)) 14031 return nullptr; 14032 14033 return OMPTaskReductionClause::Create( 14034 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14035 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14036 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14037 buildPreInits(Context, RD.ExprCaptures), 14038 buildPostUpdate(*this, RD.ExprPostUpdates)); 14039 } 14040 14041 OMPClause *Sema::ActOnOpenMPInReductionClause( 14042 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14043 SourceLocation ColonLoc, SourceLocation EndLoc, 14044 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14045 ArrayRef<Expr *> UnresolvedReductions) { 14046 ReductionData RD(VarList.size()); 14047 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14048 StartLoc, LParenLoc, ColonLoc, EndLoc, 14049 ReductionIdScopeSpec, ReductionId, 14050 UnresolvedReductions, RD)) 14051 return nullptr; 14052 14053 return OMPInReductionClause::Create( 14054 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14055 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14056 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14057 buildPreInits(Context, RD.ExprCaptures), 14058 buildPostUpdate(*this, RD.ExprPostUpdates)); 14059 } 14060 14061 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14062 SourceLocation LinLoc) { 14063 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14064 LinKind == OMPC_LINEAR_unknown) { 14065 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14066 return true; 14067 } 14068 return false; 14069 } 14070 14071 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14072 OpenMPLinearClauseKind LinKind, 14073 QualType Type) { 14074 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14075 // A variable must not have an incomplete type or a reference type. 14076 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14077 return true; 14078 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14079 !Type->isReferenceType()) { 14080 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14081 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14082 return true; 14083 } 14084 Type = Type.getNonReferenceType(); 14085 14086 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14087 // A variable that is privatized must not have a const-qualified type 14088 // unless it is of class type with a mutable member. This restriction does 14089 // not apply to the firstprivate clause. 14090 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14091 return true; 14092 14093 // A list item must be of integral or pointer type. 14094 Type = Type.getUnqualifiedType().getCanonicalType(); 14095 const auto *Ty = Type.getTypePtrOrNull(); 14096 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 14097 !Ty->isPointerType())) { 14098 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14099 if (D) { 14100 bool IsDecl = 14101 !VD || 14102 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14103 Diag(D->getLocation(), 14104 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14105 << D; 14106 } 14107 return true; 14108 } 14109 return false; 14110 } 14111 14112 OMPClause *Sema::ActOnOpenMPLinearClause( 14113 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14114 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14115 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14116 SmallVector<Expr *, 8> Vars; 14117 SmallVector<Expr *, 8> Privates; 14118 SmallVector<Expr *, 8> Inits; 14119 SmallVector<Decl *, 4> ExprCaptures; 14120 SmallVector<Expr *, 4> ExprPostUpdates; 14121 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14122 LinKind = OMPC_LINEAR_val; 14123 for (Expr *RefExpr : VarList) { 14124 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14125 SourceLocation ELoc; 14126 SourceRange ERange; 14127 Expr *SimpleRefExpr = RefExpr; 14128 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14129 if (Res.second) { 14130 // It will be analyzed later. 14131 Vars.push_back(RefExpr); 14132 Privates.push_back(nullptr); 14133 Inits.push_back(nullptr); 14134 } 14135 ValueDecl *D = Res.first; 14136 if (!D) 14137 continue; 14138 14139 QualType Type = D->getType(); 14140 auto *VD = dyn_cast<VarDecl>(D); 14141 14142 // OpenMP [2.14.3.7, linear clause] 14143 // A list-item cannot appear in more than one linear clause. 14144 // A list-item that appears in a linear clause cannot appear in any 14145 // other data-sharing attribute clause. 14146 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14147 if (DVar.RefExpr) { 14148 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14149 << getOpenMPClauseName(OMPC_linear); 14150 reportOriginalDsa(*this, DSAStack, D, DVar); 14151 continue; 14152 } 14153 14154 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14155 continue; 14156 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14157 14158 // Build private copy of original var. 14159 VarDecl *Private = 14160 buildVarDecl(*this, ELoc, Type, D->getName(), 14161 D->hasAttrs() ? &D->getAttrs() : nullptr, 14162 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14163 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14164 // Build var to save initial value. 14165 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14166 Expr *InitExpr; 14167 DeclRefExpr *Ref = nullptr; 14168 if (!VD && !CurContext->isDependentContext()) { 14169 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14170 if (!isOpenMPCapturedDecl(D)) { 14171 ExprCaptures.push_back(Ref->getDecl()); 14172 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14173 ExprResult RefRes = DefaultLvalueConversion(Ref); 14174 if (!RefRes.isUsable()) 14175 continue; 14176 ExprResult PostUpdateRes = 14177 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14178 SimpleRefExpr, RefRes.get()); 14179 if (!PostUpdateRes.isUsable()) 14180 continue; 14181 ExprPostUpdates.push_back( 14182 IgnoredValueConversions(PostUpdateRes.get()).get()); 14183 } 14184 } 14185 } 14186 if (LinKind == OMPC_LINEAR_uval) 14187 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14188 else 14189 InitExpr = VD ? SimpleRefExpr : Ref; 14190 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14191 /*DirectInit=*/false); 14192 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14193 14194 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14195 Vars.push_back((VD || CurContext->isDependentContext()) 14196 ? RefExpr->IgnoreParens() 14197 : Ref); 14198 Privates.push_back(PrivateRef); 14199 Inits.push_back(InitRef); 14200 } 14201 14202 if (Vars.empty()) 14203 return nullptr; 14204 14205 Expr *StepExpr = Step; 14206 Expr *CalcStepExpr = nullptr; 14207 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14208 !Step->isInstantiationDependent() && 14209 !Step->containsUnexpandedParameterPack()) { 14210 SourceLocation StepLoc = Step->getBeginLoc(); 14211 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14212 if (Val.isInvalid()) 14213 return nullptr; 14214 StepExpr = Val.get(); 14215 14216 // Build var to save the step value. 14217 VarDecl *SaveVar = 14218 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14219 ExprResult SaveRef = 14220 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14221 ExprResult CalcStep = 14222 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14223 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14224 14225 // Warn about zero linear step (it would be probably better specified as 14226 // making corresponding variables 'const'). 14227 llvm::APSInt Result; 14228 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14229 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14230 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14231 << (Vars.size() > 1); 14232 if (!IsConstant && CalcStep.isUsable()) { 14233 // Calculate the step beforehand instead of doing this on each iteration. 14234 // (This is not used if the number of iterations may be kfold-ed). 14235 CalcStepExpr = CalcStep.get(); 14236 } 14237 } 14238 14239 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14240 ColonLoc, EndLoc, Vars, Privates, Inits, 14241 StepExpr, CalcStepExpr, 14242 buildPreInits(Context, ExprCaptures), 14243 buildPostUpdate(*this, ExprPostUpdates)); 14244 } 14245 14246 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14247 Expr *NumIterations, Sema &SemaRef, 14248 Scope *S, DSAStackTy *Stack) { 14249 // Walk the vars and build update/final expressions for the CodeGen. 14250 SmallVector<Expr *, 8> Updates; 14251 SmallVector<Expr *, 8> Finals; 14252 SmallVector<Expr *, 8> UsedExprs; 14253 Expr *Step = Clause.getStep(); 14254 Expr *CalcStep = Clause.getCalcStep(); 14255 // OpenMP [2.14.3.7, linear clause] 14256 // If linear-step is not specified it is assumed to be 1. 14257 if (!Step) 14258 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14259 else if (CalcStep) 14260 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14261 bool HasErrors = false; 14262 auto CurInit = Clause.inits().begin(); 14263 auto CurPrivate = Clause.privates().begin(); 14264 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14265 for (Expr *RefExpr : Clause.varlists()) { 14266 SourceLocation ELoc; 14267 SourceRange ERange; 14268 Expr *SimpleRefExpr = RefExpr; 14269 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14270 ValueDecl *D = Res.first; 14271 if (Res.second || !D) { 14272 Updates.push_back(nullptr); 14273 Finals.push_back(nullptr); 14274 HasErrors = true; 14275 continue; 14276 } 14277 auto &&Info = Stack->isLoopControlVariable(D); 14278 // OpenMP [2.15.11, distribute simd Construct] 14279 // A list item may not appear in a linear clause, unless it is the loop 14280 // iteration variable. 14281 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14282 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14283 SemaRef.Diag(ELoc, 14284 diag::err_omp_linear_distribute_var_non_loop_iteration); 14285 Updates.push_back(nullptr); 14286 Finals.push_back(nullptr); 14287 HasErrors = true; 14288 continue; 14289 } 14290 Expr *InitExpr = *CurInit; 14291 14292 // Build privatized reference to the current linear var. 14293 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14294 Expr *CapturedRef; 14295 if (LinKind == OMPC_LINEAR_uval) 14296 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14297 else 14298 CapturedRef = 14299 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14300 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14301 /*RefersToCapture=*/true); 14302 14303 // Build update: Var = InitExpr + IV * Step 14304 ExprResult Update; 14305 if (!Info.first) 14306 Update = buildCounterUpdate( 14307 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14308 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14309 else 14310 Update = *CurPrivate; 14311 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14312 /*DiscardedValue*/ false); 14313 14314 // Build final: Var = InitExpr + NumIterations * Step 14315 ExprResult Final; 14316 if (!Info.first) 14317 Final = 14318 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14319 InitExpr, NumIterations, Step, /*Subtract=*/false, 14320 /*IsNonRectangularLB=*/false); 14321 else 14322 Final = *CurPrivate; 14323 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14324 /*DiscardedValue*/ false); 14325 14326 if (!Update.isUsable() || !Final.isUsable()) { 14327 Updates.push_back(nullptr); 14328 Finals.push_back(nullptr); 14329 UsedExprs.push_back(nullptr); 14330 HasErrors = true; 14331 } else { 14332 Updates.push_back(Update.get()); 14333 Finals.push_back(Final.get()); 14334 if (!Info.first) 14335 UsedExprs.push_back(SimpleRefExpr); 14336 } 14337 ++CurInit; 14338 ++CurPrivate; 14339 } 14340 if (Expr *S = Clause.getStep()) 14341 UsedExprs.push_back(S); 14342 // Fill the remaining part with the nullptr. 14343 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14344 Clause.setUpdates(Updates); 14345 Clause.setFinals(Finals); 14346 Clause.setUsedExprs(UsedExprs); 14347 return HasErrors; 14348 } 14349 14350 OMPClause *Sema::ActOnOpenMPAlignedClause( 14351 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14352 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14353 SmallVector<Expr *, 8> Vars; 14354 for (Expr *RefExpr : VarList) { 14355 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14356 SourceLocation ELoc; 14357 SourceRange ERange; 14358 Expr *SimpleRefExpr = RefExpr; 14359 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14360 if (Res.second) { 14361 // It will be analyzed later. 14362 Vars.push_back(RefExpr); 14363 } 14364 ValueDecl *D = Res.first; 14365 if (!D) 14366 continue; 14367 14368 QualType QType = D->getType(); 14369 auto *VD = dyn_cast<VarDecl>(D); 14370 14371 // OpenMP [2.8.1, simd construct, Restrictions] 14372 // The type of list items appearing in the aligned clause must be 14373 // array, pointer, reference to array, or reference to pointer. 14374 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14375 const Type *Ty = QType.getTypePtrOrNull(); 14376 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14377 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14378 << QType << getLangOpts().CPlusPlus << ERange; 14379 bool IsDecl = 14380 !VD || 14381 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14382 Diag(D->getLocation(), 14383 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14384 << D; 14385 continue; 14386 } 14387 14388 // OpenMP [2.8.1, simd construct, Restrictions] 14389 // A list-item cannot appear in more than one aligned clause. 14390 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14391 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 14392 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14393 << getOpenMPClauseName(OMPC_aligned); 14394 continue; 14395 } 14396 14397 DeclRefExpr *Ref = nullptr; 14398 if (!VD && isOpenMPCapturedDecl(D)) 14399 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14400 Vars.push_back(DefaultFunctionArrayConversion( 14401 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14402 .get()); 14403 } 14404 14405 // OpenMP [2.8.1, simd construct, Description] 14406 // The parameter of the aligned clause, alignment, must be a constant 14407 // positive integer expression. 14408 // If no optional parameter is specified, implementation-defined default 14409 // alignments for SIMD instructions on the target platforms are assumed. 14410 if (Alignment != nullptr) { 14411 ExprResult AlignResult = 14412 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14413 if (AlignResult.isInvalid()) 14414 return nullptr; 14415 Alignment = AlignResult.get(); 14416 } 14417 if (Vars.empty()) 14418 return nullptr; 14419 14420 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14421 EndLoc, Vars, Alignment); 14422 } 14423 14424 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14425 SourceLocation StartLoc, 14426 SourceLocation LParenLoc, 14427 SourceLocation EndLoc) { 14428 SmallVector<Expr *, 8> Vars; 14429 SmallVector<Expr *, 8> SrcExprs; 14430 SmallVector<Expr *, 8> DstExprs; 14431 SmallVector<Expr *, 8> AssignmentOps; 14432 for (Expr *RefExpr : VarList) { 14433 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14434 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14435 // It will be analyzed later. 14436 Vars.push_back(RefExpr); 14437 SrcExprs.push_back(nullptr); 14438 DstExprs.push_back(nullptr); 14439 AssignmentOps.push_back(nullptr); 14440 continue; 14441 } 14442 14443 SourceLocation ELoc = RefExpr->getExprLoc(); 14444 // OpenMP [2.1, C/C++] 14445 // A list item is a variable name. 14446 // OpenMP [2.14.4.1, Restrictions, p.1] 14447 // A list item that appears in a copyin clause must be threadprivate. 14448 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14449 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14450 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14451 << 0 << RefExpr->getSourceRange(); 14452 continue; 14453 } 14454 14455 Decl *D = DE->getDecl(); 14456 auto *VD = cast<VarDecl>(D); 14457 14458 QualType Type = VD->getType(); 14459 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14460 // It will be analyzed later. 14461 Vars.push_back(DE); 14462 SrcExprs.push_back(nullptr); 14463 DstExprs.push_back(nullptr); 14464 AssignmentOps.push_back(nullptr); 14465 continue; 14466 } 14467 14468 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14469 // A list item that appears in a copyin clause must be threadprivate. 14470 if (!DSAStack->isThreadPrivate(VD)) { 14471 Diag(ELoc, diag::err_omp_required_access) 14472 << getOpenMPClauseName(OMPC_copyin) 14473 << getOpenMPDirectiveName(OMPD_threadprivate); 14474 continue; 14475 } 14476 14477 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14478 // A variable of class type (or array thereof) that appears in a 14479 // copyin clause requires an accessible, unambiguous copy assignment 14480 // operator for the class type. 14481 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14482 VarDecl *SrcVD = 14483 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14484 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14485 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14486 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14487 VarDecl *DstVD = 14488 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14489 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14490 DeclRefExpr *PseudoDstExpr = 14491 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14492 // For arrays generate assignment operation for single element and replace 14493 // it by the original array element in CodeGen. 14494 ExprResult AssignmentOp = 14495 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14496 PseudoSrcExpr); 14497 if (AssignmentOp.isInvalid()) 14498 continue; 14499 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14500 /*DiscardedValue*/ false); 14501 if (AssignmentOp.isInvalid()) 14502 continue; 14503 14504 DSAStack->addDSA(VD, DE, OMPC_copyin); 14505 Vars.push_back(DE); 14506 SrcExprs.push_back(PseudoSrcExpr); 14507 DstExprs.push_back(PseudoDstExpr); 14508 AssignmentOps.push_back(AssignmentOp.get()); 14509 } 14510 14511 if (Vars.empty()) 14512 return nullptr; 14513 14514 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14515 SrcExprs, DstExprs, AssignmentOps); 14516 } 14517 14518 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14519 SourceLocation StartLoc, 14520 SourceLocation LParenLoc, 14521 SourceLocation EndLoc) { 14522 SmallVector<Expr *, 8> Vars; 14523 SmallVector<Expr *, 8> SrcExprs; 14524 SmallVector<Expr *, 8> DstExprs; 14525 SmallVector<Expr *, 8> AssignmentOps; 14526 for (Expr *RefExpr : VarList) { 14527 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14528 SourceLocation ELoc; 14529 SourceRange ERange; 14530 Expr *SimpleRefExpr = RefExpr; 14531 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14532 if (Res.second) { 14533 // It will be analyzed later. 14534 Vars.push_back(RefExpr); 14535 SrcExprs.push_back(nullptr); 14536 DstExprs.push_back(nullptr); 14537 AssignmentOps.push_back(nullptr); 14538 } 14539 ValueDecl *D = Res.first; 14540 if (!D) 14541 continue; 14542 14543 QualType Type = D->getType(); 14544 auto *VD = dyn_cast<VarDecl>(D); 14545 14546 // OpenMP [2.14.4.2, Restrictions, p.2] 14547 // A list item that appears in a copyprivate clause may not appear in a 14548 // private or firstprivate clause on the single construct. 14549 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14550 DSAStackTy::DSAVarData DVar = 14551 DSAStack->getTopDSA(D, /*FromParent=*/false); 14552 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14553 DVar.RefExpr) { 14554 Diag(ELoc, diag::err_omp_wrong_dsa) 14555 << getOpenMPClauseName(DVar.CKind) 14556 << getOpenMPClauseName(OMPC_copyprivate); 14557 reportOriginalDsa(*this, DSAStack, D, DVar); 14558 continue; 14559 } 14560 14561 // OpenMP [2.11.4.2, Restrictions, p.1] 14562 // All list items that appear in a copyprivate clause must be either 14563 // threadprivate or private in the enclosing context. 14564 if (DVar.CKind == OMPC_unknown) { 14565 DVar = DSAStack->getImplicitDSA(D, false); 14566 if (DVar.CKind == OMPC_shared) { 14567 Diag(ELoc, diag::err_omp_required_access) 14568 << getOpenMPClauseName(OMPC_copyprivate) 14569 << "threadprivate or private in the enclosing context"; 14570 reportOriginalDsa(*this, DSAStack, D, DVar); 14571 continue; 14572 } 14573 } 14574 } 14575 14576 // Variably modified types are not supported. 14577 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14578 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14579 << getOpenMPClauseName(OMPC_copyprivate) << Type 14580 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14581 bool IsDecl = 14582 !VD || 14583 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14584 Diag(D->getLocation(), 14585 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14586 << D; 14587 continue; 14588 } 14589 14590 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14591 // A variable of class type (or array thereof) that appears in a 14592 // copyin clause requires an accessible, unambiguous copy assignment 14593 // operator for the class type. 14594 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14595 .getUnqualifiedType(); 14596 VarDecl *SrcVD = 14597 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14598 D->hasAttrs() ? &D->getAttrs() : nullptr); 14599 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14600 VarDecl *DstVD = 14601 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14602 D->hasAttrs() ? &D->getAttrs() : nullptr); 14603 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14604 ExprResult AssignmentOp = BuildBinOp( 14605 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14606 if (AssignmentOp.isInvalid()) 14607 continue; 14608 AssignmentOp = 14609 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14610 if (AssignmentOp.isInvalid()) 14611 continue; 14612 14613 // No need to mark vars as copyprivate, they are already threadprivate or 14614 // implicitly private. 14615 assert(VD || isOpenMPCapturedDecl(D)); 14616 Vars.push_back( 14617 VD ? RefExpr->IgnoreParens() 14618 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14619 SrcExprs.push_back(PseudoSrcExpr); 14620 DstExprs.push_back(PseudoDstExpr); 14621 AssignmentOps.push_back(AssignmentOp.get()); 14622 } 14623 14624 if (Vars.empty()) 14625 return nullptr; 14626 14627 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14628 Vars, SrcExprs, DstExprs, AssignmentOps); 14629 } 14630 14631 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14632 SourceLocation StartLoc, 14633 SourceLocation LParenLoc, 14634 SourceLocation EndLoc) { 14635 if (VarList.empty()) 14636 return nullptr; 14637 14638 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14639 } 14640 14641 OMPClause * 14642 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14643 SourceLocation DepLoc, SourceLocation ColonLoc, 14644 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14645 SourceLocation LParenLoc, SourceLocation EndLoc) { 14646 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14647 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14648 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14649 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14650 return nullptr; 14651 } 14652 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14653 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14654 DepKind == OMPC_DEPEND_sink)) { 14655 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14656 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14657 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14658 /*Last=*/OMPC_DEPEND_unknown, Except) 14659 << getOpenMPClauseName(OMPC_depend); 14660 return nullptr; 14661 } 14662 SmallVector<Expr *, 8> Vars; 14663 DSAStackTy::OperatorOffsetTy OpsOffs; 14664 llvm::APSInt DepCounter(/*BitWidth=*/32); 14665 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14666 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14667 if (const Expr *OrderedCountExpr = 14668 DSAStack->getParentOrderedRegionParam().first) { 14669 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14670 TotalDepCount.setIsUnsigned(/*Val=*/true); 14671 } 14672 } 14673 for (Expr *RefExpr : VarList) { 14674 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14675 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14676 // It will be analyzed later. 14677 Vars.push_back(RefExpr); 14678 continue; 14679 } 14680 14681 SourceLocation ELoc = RefExpr->getExprLoc(); 14682 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14683 if (DepKind == OMPC_DEPEND_sink) { 14684 if (DSAStack->getParentOrderedRegionParam().first && 14685 DepCounter >= TotalDepCount) { 14686 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14687 continue; 14688 } 14689 ++DepCounter; 14690 // OpenMP [2.13.9, Summary] 14691 // depend(dependence-type : vec), where dependence-type is: 14692 // 'sink' and where vec is the iteration vector, which has the form: 14693 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14694 // where n is the value specified by the ordered clause in the loop 14695 // directive, xi denotes the loop iteration variable of the i-th nested 14696 // loop associated with the loop directive, and di is a constant 14697 // non-negative integer. 14698 if (CurContext->isDependentContext()) { 14699 // It will be analyzed later. 14700 Vars.push_back(RefExpr); 14701 continue; 14702 } 14703 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14704 OverloadedOperatorKind OOK = OO_None; 14705 SourceLocation OOLoc; 14706 Expr *LHS = SimpleExpr; 14707 Expr *RHS = nullptr; 14708 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14709 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14710 OOLoc = BO->getOperatorLoc(); 14711 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14712 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14713 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14714 OOK = OCE->getOperator(); 14715 OOLoc = OCE->getOperatorLoc(); 14716 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14717 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14718 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14719 OOK = MCE->getMethodDecl() 14720 ->getNameInfo() 14721 .getName() 14722 .getCXXOverloadedOperator(); 14723 OOLoc = MCE->getCallee()->getExprLoc(); 14724 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14725 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14726 } 14727 SourceLocation ELoc; 14728 SourceRange ERange; 14729 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14730 if (Res.second) { 14731 // It will be analyzed later. 14732 Vars.push_back(RefExpr); 14733 } 14734 ValueDecl *D = Res.first; 14735 if (!D) 14736 continue; 14737 14738 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14739 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14740 continue; 14741 } 14742 if (RHS) { 14743 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14744 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14745 if (RHSRes.isInvalid()) 14746 continue; 14747 } 14748 if (!CurContext->isDependentContext() && 14749 DSAStack->getParentOrderedRegionParam().first && 14750 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14751 const ValueDecl *VD = 14752 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14753 if (VD) 14754 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14755 << 1 << VD; 14756 else 14757 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14758 continue; 14759 } 14760 OpsOffs.emplace_back(RHS, OOK); 14761 } else { 14762 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14763 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14764 (ASE && 14765 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14766 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14767 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14768 << RefExpr->getSourceRange(); 14769 continue; 14770 } 14771 14772 ExprResult Res; 14773 { 14774 Sema::TentativeAnalysisScope Trap(*this); 14775 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14776 RefExpr->IgnoreParenImpCasts()); 14777 } 14778 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14779 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14780 << RefExpr->getSourceRange(); 14781 continue; 14782 } 14783 } 14784 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14785 } 14786 14787 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14788 TotalDepCount > VarList.size() && 14789 DSAStack->getParentOrderedRegionParam().first && 14790 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14791 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14792 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14793 } 14794 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14795 Vars.empty()) 14796 return nullptr; 14797 14798 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14799 DepKind, DepLoc, ColonLoc, Vars, 14800 TotalDepCount.getZExtValue()); 14801 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14802 DSAStack->isParentOrderedRegion()) 14803 DSAStack->addDoacrossDependClause(C, OpsOffs); 14804 return C; 14805 } 14806 14807 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14808 SourceLocation LParenLoc, 14809 SourceLocation EndLoc) { 14810 Expr *ValExpr = Device; 14811 Stmt *HelperValStmt = nullptr; 14812 14813 // OpenMP [2.9.1, Restrictions] 14814 // The device expression must evaluate to a non-negative integer value. 14815 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14816 /*StrictlyPositive=*/false)) 14817 return nullptr; 14818 14819 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14820 OpenMPDirectiveKind CaptureRegion = 14821 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14822 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14823 ValExpr = MakeFullExpr(ValExpr).get(); 14824 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14825 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14826 HelperValStmt = buildPreInits(Context, Captures); 14827 } 14828 14829 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14830 StartLoc, LParenLoc, EndLoc); 14831 } 14832 14833 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14834 DSAStackTy *Stack, QualType QTy, 14835 bool FullCheck = true) { 14836 NamedDecl *ND; 14837 if (QTy->isIncompleteType(&ND)) { 14838 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14839 return false; 14840 } 14841 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14842 !QTy.isTrivialType(SemaRef.Context)) 14843 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14844 return true; 14845 } 14846 14847 /// Return true if it can be proven that the provided array expression 14848 /// (array section or array subscript) does NOT specify the whole size of the 14849 /// array whose base type is \a BaseQTy. 14850 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14851 const Expr *E, 14852 QualType BaseQTy) { 14853 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14854 14855 // If this is an array subscript, it refers to the whole size if the size of 14856 // the dimension is constant and equals 1. Also, an array section assumes the 14857 // format of an array subscript if no colon is used. 14858 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14859 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14860 return ATy->getSize().getSExtValue() != 1; 14861 // Size can't be evaluated statically. 14862 return false; 14863 } 14864 14865 assert(OASE && "Expecting array section if not an array subscript."); 14866 const Expr *LowerBound = OASE->getLowerBound(); 14867 const Expr *Length = OASE->getLength(); 14868 14869 // If there is a lower bound that does not evaluates to zero, we are not 14870 // covering the whole dimension. 14871 if (LowerBound) { 14872 Expr::EvalResult Result; 14873 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14874 return false; // Can't get the integer value as a constant. 14875 14876 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14877 if (ConstLowerBound.getSExtValue()) 14878 return true; 14879 } 14880 14881 // If we don't have a length we covering the whole dimension. 14882 if (!Length) 14883 return false; 14884 14885 // If the base is a pointer, we don't have a way to get the size of the 14886 // pointee. 14887 if (BaseQTy->isPointerType()) 14888 return false; 14889 14890 // We can only check if the length is the same as the size of the dimension 14891 // if we have a constant array. 14892 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14893 if (!CATy) 14894 return false; 14895 14896 Expr::EvalResult Result; 14897 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14898 return false; // Can't get the integer value as a constant. 14899 14900 llvm::APSInt ConstLength = Result.Val.getInt(); 14901 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14902 } 14903 14904 // Return true if it can be proven that the provided array expression (array 14905 // section or array subscript) does NOT specify a single element of the array 14906 // whose base type is \a BaseQTy. 14907 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14908 const Expr *E, 14909 QualType BaseQTy) { 14910 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14911 14912 // An array subscript always refer to a single element. Also, an array section 14913 // assumes the format of an array subscript if no colon is used. 14914 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14915 return false; 14916 14917 assert(OASE && "Expecting array section if not an array subscript."); 14918 const Expr *Length = OASE->getLength(); 14919 14920 // If we don't have a length we have to check if the array has unitary size 14921 // for this dimension. Also, we should always expect a length if the base type 14922 // is pointer. 14923 if (!Length) { 14924 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14925 return ATy->getSize().getSExtValue() != 1; 14926 // We cannot assume anything. 14927 return false; 14928 } 14929 14930 // Check if the length evaluates to 1. 14931 Expr::EvalResult Result; 14932 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14933 return false; // Can't get the integer value as a constant. 14934 14935 llvm::APSInt ConstLength = Result.Val.getInt(); 14936 return ConstLength.getSExtValue() != 1; 14937 } 14938 14939 // Return the expression of the base of the mappable expression or null if it 14940 // cannot be determined and do all the necessary checks to see if the expression 14941 // is valid as a standalone mappable expression. In the process, record all the 14942 // components of the expression. 14943 static const Expr *checkMapClauseExpressionBase( 14944 Sema &SemaRef, Expr *E, 14945 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14946 OpenMPClauseKind CKind, bool NoDiagnose) { 14947 SourceLocation ELoc = E->getExprLoc(); 14948 SourceRange ERange = E->getSourceRange(); 14949 14950 // The base of elements of list in a map clause have to be either: 14951 // - a reference to variable or field. 14952 // - a member expression. 14953 // - an array expression. 14954 // 14955 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14956 // reference to 'r'. 14957 // 14958 // If we have: 14959 // 14960 // struct SS { 14961 // Bla S; 14962 // foo() { 14963 // #pragma omp target map (S.Arr[:12]); 14964 // } 14965 // } 14966 // 14967 // We want to retrieve the member expression 'this->S'; 14968 14969 const Expr *RelevantExpr = nullptr; 14970 14971 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14972 // If a list item is an array section, it must specify contiguous storage. 14973 // 14974 // For this restriction it is sufficient that we make sure only references 14975 // to variables or fields and array expressions, and that no array sections 14976 // exist except in the rightmost expression (unless they cover the whole 14977 // dimension of the array). E.g. these would be invalid: 14978 // 14979 // r.ArrS[3:5].Arr[6:7] 14980 // 14981 // r.ArrS[3:5].x 14982 // 14983 // but these would be valid: 14984 // r.ArrS[3].Arr[6:7] 14985 // 14986 // r.ArrS[3].x 14987 14988 bool AllowUnitySizeArraySection = true; 14989 bool AllowWholeSizeArraySection = true; 14990 14991 while (!RelevantExpr) { 14992 E = E->IgnoreParenImpCasts(); 14993 14994 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14995 if (!isa<VarDecl>(CurE->getDecl())) 14996 return nullptr; 14997 14998 RelevantExpr = CurE; 14999 15000 // If we got a reference to a declaration, we should not expect any array 15001 // section before that. 15002 AllowUnitySizeArraySection = false; 15003 AllowWholeSizeArraySection = false; 15004 15005 // Record the component. 15006 CurComponents.emplace_back(CurE, CurE->getDecl()); 15007 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 15008 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 15009 15010 if (isa<CXXThisExpr>(BaseE)) 15011 // We found a base expression: this->Val. 15012 RelevantExpr = CurE; 15013 else 15014 E = BaseE; 15015 15016 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 15017 if (!NoDiagnose) { 15018 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15019 << CurE->getSourceRange(); 15020 return nullptr; 15021 } 15022 if (RelevantExpr) 15023 return nullptr; 15024 continue; 15025 } 15026 15027 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 15028 15029 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15030 // A bit-field cannot appear in a map clause. 15031 // 15032 if (FD->isBitField()) { 15033 if (!NoDiagnose) { 15034 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15035 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 15036 return nullptr; 15037 } 15038 if (RelevantExpr) 15039 return nullptr; 15040 continue; 15041 } 15042 15043 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15044 // If the type of a list item is a reference to a type T then the type 15045 // will be considered to be T for all purposes of this clause. 15046 QualType CurType = BaseE->getType().getNonReferenceType(); 15047 15048 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15049 // A list item cannot be a variable that is a member of a structure with 15050 // a union type. 15051 // 15052 if (CurType->isUnionType()) { 15053 if (!NoDiagnose) { 15054 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15055 << CurE->getSourceRange(); 15056 return nullptr; 15057 } 15058 continue; 15059 } 15060 15061 // If we got a member expression, we should not expect any array section 15062 // before that: 15063 // 15064 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15065 // If a list item is an element of a structure, only the rightmost symbol 15066 // of the variable reference can be an array section. 15067 // 15068 AllowUnitySizeArraySection = false; 15069 AllowWholeSizeArraySection = false; 15070 15071 // Record the component. 15072 CurComponents.emplace_back(CurE, FD); 15073 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 15074 E = CurE->getBase()->IgnoreParenImpCasts(); 15075 15076 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15077 if (!NoDiagnose) { 15078 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15079 << 0 << CurE->getSourceRange(); 15080 return nullptr; 15081 } 15082 continue; 15083 } 15084 15085 // If we got an array subscript that express the whole dimension we 15086 // can have any array expressions before. If it only expressing part of 15087 // the dimension, we can only have unitary-size array expressions. 15088 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 15089 E->getType())) 15090 AllowWholeSizeArraySection = false; 15091 15092 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15093 Expr::EvalResult Result; 15094 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 15095 if (!Result.Val.getInt().isNullValue()) { 15096 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15097 diag::err_omp_invalid_map_this_expr); 15098 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15099 diag::note_omp_invalid_subscript_on_this_ptr_map); 15100 } 15101 } 15102 RelevantExpr = TE; 15103 } 15104 15105 // Record the component - we don't have any declaration associated. 15106 CurComponents.emplace_back(CurE, nullptr); 15107 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 15108 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15109 E = CurE->getBase()->IgnoreParenImpCasts(); 15110 15111 QualType CurType = 15112 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15113 15114 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15115 // If the type of a list item is a reference to a type T then the type 15116 // will be considered to be T for all purposes of this clause. 15117 if (CurType->isReferenceType()) 15118 CurType = CurType->getPointeeType(); 15119 15120 bool IsPointer = CurType->isAnyPointerType(); 15121 15122 if (!IsPointer && !CurType->isArrayType()) { 15123 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15124 << 0 << CurE->getSourceRange(); 15125 return nullptr; 15126 } 15127 15128 bool NotWhole = 15129 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 15130 bool NotUnity = 15131 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 15132 15133 if (AllowWholeSizeArraySection) { 15134 // Any array section is currently allowed. Allowing a whole size array 15135 // section implies allowing a unity array section as well. 15136 // 15137 // If this array section refers to the whole dimension we can still 15138 // accept other array sections before this one, except if the base is a 15139 // pointer. Otherwise, only unitary sections are accepted. 15140 if (NotWhole || IsPointer) 15141 AllowWholeSizeArraySection = false; 15142 } else if (AllowUnitySizeArraySection && NotUnity) { 15143 // A unity or whole array section is not allowed and that is not 15144 // compatible with the properties of the current array section. 15145 SemaRef.Diag( 15146 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15147 << CurE->getSourceRange(); 15148 return nullptr; 15149 } 15150 15151 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15152 Expr::EvalResult ResultR; 15153 Expr::EvalResult ResultL; 15154 if (CurE->getLength()->EvaluateAsInt(ResultR, 15155 SemaRef.getASTContext())) { 15156 if (!ResultR.Val.getInt().isOneValue()) { 15157 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15158 diag::err_omp_invalid_map_this_expr); 15159 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15160 diag::note_omp_invalid_length_on_this_ptr_mapping); 15161 } 15162 } 15163 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 15164 ResultL, SemaRef.getASTContext())) { 15165 if (!ResultL.Val.getInt().isNullValue()) { 15166 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15167 diag::err_omp_invalid_map_this_expr); 15168 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15169 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15170 } 15171 } 15172 RelevantExpr = TE; 15173 } 15174 15175 // Record the component - we don't have any declaration associated. 15176 CurComponents.emplace_back(CurE, nullptr); 15177 } else { 15178 if (!NoDiagnose) { 15179 // If nothing else worked, this is not a valid map clause expression. 15180 SemaRef.Diag( 15181 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15182 << ERange; 15183 } 15184 return nullptr; 15185 } 15186 } 15187 15188 return RelevantExpr; 15189 } 15190 15191 // Return true if expression E associated with value VD has conflicts with other 15192 // map information. 15193 static bool checkMapConflicts( 15194 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15195 bool CurrentRegionOnly, 15196 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15197 OpenMPClauseKind CKind) { 15198 assert(VD && E); 15199 SourceLocation ELoc = E->getExprLoc(); 15200 SourceRange ERange = E->getSourceRange(); 15201 15202 // In order to easily check the conflicts we need to match each component of 15203 // the expression under test with the components of the expressions that are 15204 // already in the stack. 15205 15206 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15207 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15208 "Map clause expression with unexpected base!"); 15209 15210 // Variables to help detecting enclosing problems in data environment nests. 15211 bool IsEnclosedByDataEnvironmentExpr = false; 15212 const Expr *EnclosingExpr = nullptr; 15213 15214 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15215 VD, CurrentRegionOnly, 15216 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15217 ERange, CKind, &EnclosingExpr, 15218 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15219 StackComponents, 15220 OpenMPClauseKind) { 15221 assert(!StackComponents.empty() && 15222 "Map clause expression with no components!"); 15223 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15224 "Map clause expression with unexpected base!"); 15225 (void)VD; 15226 15227 // The whole expression in the stack. 15228 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15229 15230 // Expressions must start from the same base. Here we detect at which 15231 // point both expressions diverge from each other and see if we can 15232 // detect if the memory referred to both expressions is contiguous and 15233 // do not overlap. 15234 auto CI = CurComponents.rbegin(); 15235 auto CE = CurComponents.rend(); 15236 auto SI = StackComponents.rbegin(); 15237 auto SE = StackComponents.rend(); 15238 for (; CI != CE && SI != SE; ++CI, ++SI) { 15239 15240 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15241 // At most one list item can be an array item derived from a given 15242 // variable in map clauses of the same construct. 15243 if (CurrentRegionOnly && 15244 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15245 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15246 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15247 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15248 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15249 diag::err_omp_multiple_array_items_in_map_clause) 15250 << CI->getAssociatedExpression()->getSourceRange(); 15251 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15252 diag::note_used_here) 15253 << SI->getAssociatedExpression()->getSourceRange(); 15254 return true; 15255 } 15256 15257 // Do both expressions have the same kind? 15258 if (CI->getAssociatedExpression()->getStmtClass() != 15259 SI->getAssociatedExpression()->getStmtClass()) 15260 break; 15261 15262 // Are we dealing with different variables/fields? 15263 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15264 break; 15265 } 15266 // Check if the extra components of the expressions in the enclosing 15267 // data environment are redundant for the current base declaration. 15268 // If they are, the maps completely overlap, which is legal. 15269 for (; SI != SE; ++SI) { 15270 QualType Type; 15271 if (const auto *ASE = 15272 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15273 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15274 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15275 SI->getAssociatedExpression())) { 15276 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15277 Type = 15278 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15279 } 15280 if (Type.isNull() || Type->isAnyPointerType() || 15281 checkArrayExpressionDoesNotReferToWholeSize( 15282 SemaRef, SI->getAssociatedExpression(), Type)) 15283 break; 15284 } 15285 15286 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15287 // List items of map clauses in the same construct must not share 15288 // original storage. 15289 // 15290 // If the expressions are exactly the same or one is a subset of the 15291 // other, it means they are sharing storage. 15292 if (CI == CE && SI == SE) { 15293 if (CurrentRegionOnly) { 15294 if (CKind == OMPC_map) { 15295 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15296 } else { 15297 assert(CKind == OMPC_to || CKind == OMPC_from); 15298 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15299 << ERange; 15300 } 15301 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15302 << RE->getSourceRange(); 15303 return true; 15304 } 15305 // If we find the same expression in the enclosing data environment, 15306 // that is legal. 15307 IsEnclosedByDataEnvironmentExpr = true; 15308 return false; 15309 } 15310 15311 QualType DerivedType = 15312 std::prev(CI)->getAssociatedDeclaration()->getType(); 15313 SourceLocation DerivedLoc = 15314 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15315 15316 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15317 // If the type of a list item is a reference to a type T then the type 15318 // will be considered to be T for all purposes of this clause. 15319 DerivedType = DerivedType.getNonReferenceType(); 15320 15321 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15322 // A variable for which the type is pointer and an array section 15323 // derived from that variable must not appear as list items of map 15324 // clauses of the same construct. 15325 // 15326 // Also, cover one of the cases in: 15327 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15328 // If any part of the original storage of a list item has corresponding 15329 // storage in the device data environment, all of the original storage 15330 // must have corresponding storage in the device data environment. 15331 // 15332 if (DerivedType->isAnyPointerType()) { 15333 if (CI == CE || SI == SE) { 15334 SemaRef.Diag( 15335 DerivedLoc, 15336 diag::err_omp_pointer_mapped_along_with_derived_section) 15337 << DerivedLoc; 15338 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15339 << RE->getSourceRange(); 15340 return true; 15341 } 15342 if (CI->getAssociatedExpression()->getStmtClass() != 15343 SI->getAssociatedExpression()->getStmtClass() || 15344 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15345 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15346 assert(CI != CE && SI != SE); 15347 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15348 << DerivedLoc; 15349 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15350 << RE->getSourceRange(); 15351 return true; 15352 } 15353 } 15354 15355 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15356 // List items of map clauses in the same construct must not share 15357 // original storage. 15358 // 15359 // An expression is a subset of the other. 15360 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15361 if (CKind == OMPC_map) { 15362 if (CI != CE || SI != SE) { 15363 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15364 // a pointer. 15365 auto Begin = 15366 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15367 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15368 auto It = Begin; 15369 while (It != End && !It->getAssociatedDeclaration()) 15370 std::advance(It, 1); 15371 assert(It != End && 15372 "Expected at least one component with the declaration."); 15373 if (It != Begin && It->getAssociatedDeclaration() 15374 ->getType() 15375 .getCanonicalType() 15376 ->isAnyPointerType()) { 15377 IsEnclosedByDataEnvironmentExpr = false; 15378 EnclosingExpr = nullptr; 15379 return false; 15380 } 15381 } 15382 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15383 } else { 15384 assert(CKind == OMPC_to || CKind == OMPC_from); 15385 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15386 << ERange; 15387 } 15388 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15389 << RE->getSourceRange(); 15390 return true; 15391 } 15392 15393 // The current expression uses the same base as other expression in the 15394 // data environment but does not contain it completely. 15395 if (!CurrentRegionOnly && SI != SE) 15396 EnclosingExpr = RE; 15397 15398 // The current expression is a subset of the expression in the data 15399 // environment. 15400 IsEnclosedByDataEnvironmentExpr |= 15401 (!CurrentRegionOnly && CI != CE && SI == SE); 15402 15403 return false; 15404 }); 15405 15406 if (CurrentRegionOnly) 15407 return FoundError; 15408 15409 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15410 // If any part of the original storage of a list item has corresponding 15411 // storage in the device data environment, all of the original storage must 15412 // have corresponding storage in the device data environment. 15413 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15414 // If a list item is an element of a structure, and a different element of 15415 // the structure has a corresponding list item in the device data environment 15416 // prior to a task encountering the construct associated with the map clause, 15417 // then the list item must also have a corresponding list item in the device 15418 // data environment prior to the task encountering the construct. 15419 // 15420 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15421 SemaRef.Diag(ELoc, 15422 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15423 << ERange; 15424 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15425 << EnclosingExpr->getSourceRange(); 15426 return true; 15427 } 15428 15429 return FoundError; 15430 } 15431 15432 // Look up the user-defined mapper given the mapper name and mapped type, and 15433 // build a reference to it. 15434 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15435 CXXScopeSpec &MapperIdScopeSpec, 15436 const DeclarationNameInfo &MapperId, 15437 QualType Type, 15438 Expr *UnresolvedMapper) { 15439 if (MapperIdScopeSpec.isInvalid()) 15440 return ExprError(); 15441 // Get the actual type for the array type. 15442 if (Type->isArrayType()) { 15443 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15444 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15445 } 15446 // Find all user-defined mappers with the given MapperId. 15447 SmallVector<UnresolvedSet<8>, 4> Lookups; 15448 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15449 Lookup.suppressDiagnostics(); 15450 if (S) { 15451 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15452 NamedDecl *D = Lookup.getRepresentativeDecl(); 15453 while (S && !S->isDeclScope(D)) 15454 S = S->getParent(); 15455 if (S) 15456 S = S->getParent(); 15457 Lookups.emplace_back(); 15458 Lookups.back().append(Lookup.begin(), Lookup.end()); 15459 Lookup.clear(); 15460 } 15461 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15462 // Extract the user-defined mappers with the given MapperId. 15463 Lookups.push_back(UnresolvedSet<8>()); 15464 for (NamedDecl *D : ULE->decls()) { 15465 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15466 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15467 Lookups.back().addDecl(DMD); 15468 } 15469 } 15470 // Defer the lookup for dependent types. The results will be passed through 15471 // UnresolvedMapper on instantiation. 15472 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15473 Type->isInstantiationDependentType() || 15474 Type->containsUnexpandedParameterPack() || 15475 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15476 return !D->isInvalidDecl() && 15477 (D->getType()->isDependentType() || 15478 D->getType()->isInstantiationDependentType() || 15479 D->getType()->containsUnexpandedParameterPack()); 15480 })) { 15481 UnresolvedSet<8> URS; 15482 for (const UnresolvedSet<8> &Set : Lookups) { 15483 if (Set.empty()) 15484 continue; 15485 URS.append(Set.begin(), Set.end()); 15486 } 15487 return UnresolvedLookupExpr::Create( 15488 SemaRef.Context, /*NamingClass=*/nullptr, 15489 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15490 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15491 } 15492 SourceLocation Loc = MapperId.getLoc(); 15493 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15494 // The type must be of struct, union or class type in C and C++ 15495 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15496 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15497 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15498 return ExprError(); 15499 } 15500 // Perform argument dependent lookup. 15501 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15502 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15503 // Return the first user-defined mapper with the desired type. 15504 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15505 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15506 if (!D->isInvalidDecl() && 15507 SemaRef.Context.hasSameType(D->getType(), Type)) 15508 return D; 15509 return nullptr; 15510 })) 15511 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15512 // Find the first user-defined mapper with a type derived from the desired 15513 // type. 15514 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15515 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15516 if (!D->isInvalidDecl() && 15517 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15518 !Type.isMoreQualifiedThan(D->getType())) 15519 return D; 15520 return nullptr; 15521 })) { 15522 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15523 /*DetectVirtual=*/false); 15524 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15525 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15526 VD->getType().getUnqualifiedType()))) { 15527 if (SemaRef.CheckBaseClassAccess( 15528 Loc, VD->getType(), Type, Paths.front(), 15529 /*DiagID=*/0) != Sema::AR_inaccessible) { 15530 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15531 } 15532 } 15533 } 15534 } 15535 // Report error if a mapper is specified, but cannot be found. 15536 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15537 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15538 << Type << MapperId.getName(); 15539 return ExprError(); 15540 } 15541 return ExprEmpty(); 15542 } 15543 15544 namespace { 15545 // Utility struct that gathers all the related lists associated with a mappable 15546 // expression. 15547 struct MappableVarListInfo { 15548 // The list of expressions. 15549 ArrayRef<Expr *> VarList; 15550 // The list of processed expressions. 15551 SmallVector<Expr *, 16> ProcessedVarList; 15552 // The mappble components for each expression. 15553 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15554 // The base declaration of the variable. 15555 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15556 // The reference to the user-defined mapper associated with every expression. 15557 SmallVector<Expr *, 16> UDMapperList; 15558 15559 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15560 // We have a list of components and base declarations for each entry in the 15561 // variable list. 15562 VarComponents.reserve(VarList.size()); 15563 VarBaseDeclarations.reserve(VarList.size()); 15564 } 15565 }; 15566 } 15567 15568 // Check the validity of the provided variable list for the provided clause kind 15569 // \a CKind. In the check process the valid expressions, mappable expression 15570 // components, variables, and user-defined mappers are extracted and used to 15571 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15572 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15573 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15574 static void checkMappableExpressionList( 15575 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15576 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15577 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15578 ArrayRef<Expr *> UnresolvedMappers, 15579 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15580 bool IsMapTypeImplicit = false) { 15581 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15582 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15583 "Unexpected clause kind with mappable expressions!"); 15584 15585 // If the identifier of user-defined mapper is not specified, it is "default". 15586 // We do not change the actual name in this clause to distinguish whether a 15587 // mapper is specified explicitly, i.e., it is not explicitly specified when 15588 // MapperId.getName() is empty. 15589 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15590 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15591 MapperId.setName(DeclNames.getIdentifier( 15592 &SemaRef.getASTContext().Idents.get("default"))); 15593 } 15594 15595 // Iterators to find the current unresolved mapper expression. 15596 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15597 bool UpdateUMIt = false; 15598 Expr *UnresolvedMapper = nullptr; 15599 15600 // Keep track of the mappable components and base declarations in this clause. 15601 // Each entry in the list is going to have a list of components associated. We 15602 // record each set of the components so that we can build the clause later on. 15603 // In the end we should have the same amount of declarations and component 15604 // lists. 15605 15606 for (Expr *RE : MVLI.VarList) { 15607 assert(RE && "Null expr in omp to/from/map clause"); 15608 SourceLocation ELoc = RE->getExprLoc(); 15609 15610 // Find the current unresolved mapper expression. 15611 if (UpdateUMIt && UMIt != UMEnd) { 15612 UMIt++; 15613 assert( 15614 UMIt != UMEnd && 15615 "Expect the size of UnresolvedMappers to match with that of VarList"); 15616 } 15617 UpdateUMIt = true; 15618 if (UMIt != UMEnd) 15619 UnresolvedMapper = *UMIt; 15620 15621 const Expr *VE = RE->IgnoreParenLValueCasts(); 15622 15623 if (VE->isValueDependent() || VE->isTypeDependent() || 15624 VE->isInstantiationDependent() || 15625 VE->containsUnexpandedParameterPack()) { 15626 // Try to find the associated user-defined mapper. 15627 ExprResult ER = buildUserDefinedMapperRef( 15628 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15629 VE->getType().getCanonicalType(), UnresolvedMapper); 15630 if (ER.isInvalid()) 15631 continue; 15632 MVLI.UDMapperList.push_back(ER.get()); 15633 // We can only analyze this information once the missing information is 15634 // resolved. 15635 MVLI.ProcessedVarList.push_back(RE); 15636 continue; 15637 } 15638 15639 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15640 15641 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15642 SemaRef.Diag(ELoc, 15643 diag::err_omp_expected_named_var_member_or_array_expression) 15644 << RE->getSourceRange(); 15645 continue; 15646 } 15647 15648 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15649 ValueDecl *CurDeclaration = nullptr; 15650 15651 // Obtain the array or member expression bases if required. Also, fill the 15652 // components array with all the components identified in the process. 15653 const Expr *BE = checkMapClauseExpressionBase( 15654 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15655 if (!BE) 15656 continue; 15657 15658 assert(!CurComponents.empty() && 15659 "Invalid mappable expression information."); 15660 15661 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15662 // Add store "this" pointer to class in DSAStackTy for future checking 15663 DSAS->addMappedClassesQualTypes(TE->getType()); 15664 // Try to find the associated user-defined mapper. 15665 ExprResult ER = buildUserDefinedMapperRef( 15666 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15667 VE->getType().getCanonicalType(), UnresolvedMapper); 15668 if (ER.isInvalid()) 15669 continue; 15670 MVLI.UDMapperList.push_back(ER.get()); 15671 // Skip restriction checking for variable or field declarations 15672 MVLI.ProcessedVarList.push_back(RE); 15673 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15674 MVLI.VarComponents.back().append(CurComponents.begin(), 15675 CurComponents.end()); 15676 MVLI.VarBaseDeclarations.push_back(nullptr); 15677 continue; 15678 } 15679 15680 // For the following checks, we rely on the base declaration which is 15681 // expected to be associated with the last component. The declaration is 15682 // expected to be a variable or a field (if 'this' is being mapped). 15683 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15684 assert(CurDeclaration && "Null decl on map clause."); 15685 assert( 15686 CurDeclaration->isCanonicalDecl() && 15687 "Expecting components to have associated only canonical declarations."); 15688 15689 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15690 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15691 15692 assert((VD || FD) && "Only variables or fields are expected here!"); 15693 (void)FD; 15694 15695 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15696 // threadprivate variables cannot appear in a map clause. 15697 // OpenMP 4.5 [2.10.5, target update Construct] 15698 // threadprivate variables cannot appear in a from clause. 15699 if (VD && DSAS->isThreadPrivate(VD)) { 15700 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15701 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15702 << getOpenMPClauseName(CKind); 15703 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15704 continue; 15705 } 15706 15707 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15708 // A list item cannot appear in both a map clause and a data-sharing 15709 // attribute clause on the same construct. 15710 15711 // Check conflicts with other map clause expressions. We check the conflicts 15712 // with the current construct separately from the enclosing data 15713 // environment, because the restrictions are different. We only have to 15714 // check conflicts across regions for the map clauses. 15715 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15716 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15717 break; 15718 if (CKind == OMPC_map && 15719 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15720 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15721 break; 15722 15723 // OpenMP 4.5 [2.10.5, target update Construct] 15724 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15725 // If the type of a list item is a reference to a type T then the type will 15726 // be considered to be T for all purposes of this clause. 15727 auto I = llvm::find_if( 15728 CurComponents, 15729 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15730 return MC.getAssociatedDeclaration(); 15731 }); 15732 assert(I != CurComponents.end() && "Null decl on map clause."); 15733 QualType Type = 15734 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15735 15736 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15737 // A list item in a to or from clause must have a mappable type. 15738 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15739 // A list item must have a mappable type. 15740 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15741 DSAS, Type)) 15742 continue; 15743 15744 if (CKind == OMPC_map) { 15745 // target enter data 15746 // OpenMP [2.10.2, Restrictions, p. 99] 15747 // A map-type must be specified in all map clauses and must be either 15748 // to or alloc. 15749 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15750 if (DKind == OMPD_target_enter_data && 15751 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15752 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15753 << (IsMapTypeImplicit ? 1 : 0) 15754 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15755 << getOpenMPDirectiveName(DKind); 15756 continue; 15757 } 15758 15759 // target exit_data 15760 // OpenMP [2.10.3, Restrictions, p. 102] 15761 // A map-type must be specified in all map clauses and must be either 15762 // from, release, or delete. 15763 if (DKind == OMPD_target_exit_data && 15764 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15765 MapType == OMPC_MAP_delete)) { 15766 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15767 << (IsMapTypeImplicit ? 1 : 0) 15768 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15769 << getOpenMPDirectiveName(DKind); 15770 continue; 15771 } 15772 15773 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15774 // A list item cannot appear in both a map clause and a data-sharing 15775 // attribute clause on the same construct 15776 // 15777 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15778 // A list item cannot appear in both a map clause and a data-sharing 15779 // attribute clause on the same construct unless the construct is a 15780 // combined construct. 15781 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15782 isOpenMPTargetExecutionDirective(DKind)) || 15783 DKind == OMPD_target)) { 15784 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15785 if (isOpenMPPrivate(DVar.CKind)) { 15786 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15787 << getOpenMPClauseName(DVar.CKind) 15788 << getOpenMPClauseName(OMPC_map) 15789 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15790 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15791 continue; 15792 } 15793 } 15794 } 15795 15796 // Try to find the associated user-defined mapper. 15797 ExprResult ER = buildUserDefinedMapperRef( 15798 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15799 Type.getCanonicalType(), UnresolvedMapper); 15800 if (ER.isInvalid()) 15801 continue; 15802 MVLI.UDMapperList.push_back(ER.get()); 15803 15804 // Save the current expression. 15805 MVLI.ProcessedVarList.push_back(RE); 15806 15807 // Store the components in the stack so that they can be used to check 15808 // against other clauses later on. 15809 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15810 /*WhereFoundClauseKind=*/OMPC_map); 15811 15812 // Save the components and declaration to create the clause. For purposes of 15813 // the clause creation, any component list that has has base 'this' uses 15814 // null as base declaration. 15815 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15816 MVLI.VarComponents.back().append(CurComponents.begin(), 15817 CurComponents.end()); 15818 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15819 : CurDeclaration); 15820 } 15821 } 15822 15823 OMPClause *Sema::ActOnOpenMPMapClause( 15824 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15825 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15826 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15827 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15828 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15829 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15830 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15831 OMPC_MAP_MODIFIER_unknown, 15832 OMPC_MAP_MODIFIER_unknown}; 15833 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15834 15835 // Process map-type-modifiers, flag errors for duplicate modifiers. 15836 unsigned Count = 0; 15837 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15838 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15839 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15840 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15841 continue; 15842 } 15843 assert(Count < OMPMapClause::NumberOfModifiers && 15844 "Modifiers exceed the allowed number of map type modifiers"); 15845 Modifiers[Count] = MapTypeModifiers[I]; 15846 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15847 ++Count; 15848 } 15849 15850 MappableVarListInfo MVLI(VarList); 15851 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15852 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15853 MapType, IsMapTypeImplicit); 15854 15855 // We need to produce a map clause even if we don't have variables so that 15856 // other diagnostics related with non-existing map clauses are accurate. 15857 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15858 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15859 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15860 MapperIdScopeSpec.getWithLocInContext(Context), 15861 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15862 } 15863 15864 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15865 TypeResult ParsedType) { 15866 assert(ParsedType.isUsable()); 15867 15868 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15869 if (ReductionType.isNull()) 15870 return QualType(); 15871 15872 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15873 // A type name in a declare reduction directive cannot be a function type, an 15874 // array type, a reference type, or a type qualified with const, volatile or 15875 // restrict. 15876 if (ReductionType.hasQualifiers()) { 15877 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15878 return QualType(); 15879 } 15880 15881 if (ReductionType->isFunctionType()) { 15882 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15883 return QualType(); 15884 } 15885 if (ReductionType->isReferenceType()) { 15886 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15887 return QualType(); 15888 } 15889 if (ReductionType->isArrayType()) { 15890 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15891 return QualType(); 15892 } 15893 return ReductionType; 15894 } 15895 15896 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15897 Scope *S, DeclContext *DC, DeclarationName Name, 15898 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15899 AccessSpecifier AS, Decl *PrevDeclInScope) { 15900 SmallVector<Decl *, 8> Decls; 15901 Decls.reserve(ReductionTypes.size()); 15902 15903 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15904 forRedeclarationInCurContext()); 15905 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15906 // A reduction-identifier may not be re-declared in the current scope for the 15907 // same type or for a type that is compatible according to the base language 15908 // rules. 15909 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15910 OMPDeclareReductionDecl *PrevDRD = nullptr; 15911 bool InCompoundScope = true; 15912 if (S != nullptr) { 15913 // Find previous declaration with the same name not referenced in other 15914 // declarations. 15915 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15916 InCompoundScope = 15917 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15918 LookupName(Lookup, S); 15919 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15920 /*AllowInlineNamespace=*/false); 15921 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15922 LookupResult::Filter Filter = Lookup.makeFilter(); 15923 while (Filter.hasNext()) { 15924 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15925 if (InCompoundScope) { 15926 auto I = UsedAsPrevious.find(PrevDecl); 15927 if (I == UsedAsPrevious.end()) 15928 UsedAsPrevious[PrevDecl] = false; 15929 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15930 UsedAsPrevious[D] = true; 15931 } 15932 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15933 PrevDecl->getLocation(); 15934 } 15935 Filter.done(); 15936 if (InCompoundScope) { 15937 for (const auto &PrevData : UsedAsPrevious) { 15938 if (!PrevData.second) { 15939 PrevDRD = PrevData.first; 15940 break; 15941 } 15942 } 15943 } 15944 } else if (PrevDeclInScope != nullptr) { 15945 auto *PrevDRDInScope = PrevDRD = 15946 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15947 do { 15948 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15949 PrevDRDInScope->getLocation(); 15950 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15951 } while (PrevDRDInScope != nullptr); 15952 } 15953 for (const auto &TyData : ReductionTypes) { 15954 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15955 bool Invalid = false; 15956 if (I != PreviousRedeclTypes.end()) { 15957 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15958 << TyData.first; 15959 Diag(I->second, diag::note_previous_definition); 15960 Invalid = true; 15961 } 15962 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15963 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15964 Name, TyData.first, PrevDRD); 15965 DC->addDecl(DRD); 15966 DRD->setAccess(AS); 15967 Decls.push_back(DRD); 15968 if (Invalid) 15969 DRD->setInvalidDecl(); 15970 else 15971 PrevDRD = DRD; 15972 } 15973 15974 return DeclGroupPtrTy::make( 15975 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15976 } 15977 15978 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15979 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15980 15981 // Enter new function scope. 15982 PushFunctionScope(); 15983 setFunctionHasBranchProtectedScope(); 15984 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15985 15986 if (S != nullptr) 15987 PushDeclContext(S, DRD); 15988 else 15989 CurContext = DRD; 15990 15991 PushExpressionEvaluationContext( 15992 ExpressionEvaluationContext::PotentiallyEvaluated); 15993 15994 QualType ReductionType = DRD->getType(); 15995 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15996 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15997 // uses semantics of argument handles by value, but it should be passed by 15998 // reference. C lang does not support references, so pass all parameters as 15999 // pointers. 16000 // Create 'T omp_in;' variable. 16001 VarDecl *OmpInParm = 16002 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16003 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16004 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16005 // uses semantics of argument handles by value, but it should be passed by 16006 // reference. C lang does not support references, so pass all parameters as 16007 // pointers. 16008 // Create 'T omp_out;' variable. 16009 VarDecl *OmpOutParm = 16010 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16011 if (S != nullptr) { 16012 PushOnScopeChains(OmpInParm, S); 16013 PushOnScopeChains(OmpOutParm, S); 16014 } else { 16015 DRD->addDecl(OmpInParm); 16016 DRD->addDecl(OmpOutParm); 16017 } 16018 Expr *InE = 16019 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16020 Expr *OutE = 16021 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16022 DRD->setCombinerData(InE, OutE); 16023 } 16024 16025 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16026 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16027 DiscardCleanupsInEvaluationContext(); 16028 PopExpressionEvaluationContext(); 16029 16030 PopDeclContext(); 16031 PopFunctionScopeInfo(); 16032 16033 if (Combiner != nullptr) 16034 DRD->setCombiner(Combiner); 16035 else 16036 DRD->setInvalidDecl(); 16037 } 16038 16039 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16040 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16041 16042 // Enter new function scope. 16043 PushFunctionScope(); 16044 setFunctionHasBranchProtectedScope(); 16045 16046 if (S != nullptr) 16047 PushDeclContext(S, DRD); 16048 else 16049 CurContext = DRD; 16050 16051 PushExpressionEvaluationContext( 16052 ExpressionEvaluationContext::PotentiallyEvaluated); 16053 16054 QualType ReductionType = DRD->getType(); 16055 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16056 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16057 // uses semantics of argument handles by value, but it should be passed by 16058 // reference. C lang does not support references, so pass all parameters as 16059 // pointers. 16060 // Create 'T omp_priv;' variable. 16061 VarDecl *OmpPrivParm = 16062 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16063 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16064 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16065 // uses semantics of argument handles by value, but it should be passed by 16066 // reference. C lang does not support references, so pass all parameters as 16067 // pointers. 16068 // Create 'T omp_orig;' variable. 16069 VarDecl *OmpOrigParm = 16070 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16071 if (S != nullptr) { 16072 PushOnScopeChains(OmpPrivParm, S); 16073 PushOnScopeChains(OmpOrigParm, S); 16074 } else { 16075 DRD->addDecl(OmpPrivParm); 16076 DRD->addDecl(OmpOrigParm); 16077 } 16078 Expr *OrigE = 16079 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16080 Expr *PrivE = 16081 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16082 DRD->setInitializerData(OrigE, PrivE); 16083 return OmpPrivParm; 16084 } 16085 16086 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16087 VarDecl *OmpPrivParm) { 16088 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16089 DiscardCleanupsInEvaluationContext(); 16090 PopExpressionEvaluationContext(); 16091 16092 PopDeclContext(); 16093 PopFunctionScopeInfo(); 16094 16095 if (Initializer != nullptr) { 16096 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16097 } else if (OmpPrivParm->hasInit()) { 16098 DRD->setInitializer(OmpPrivParm->getInit(), 16099 OmpPrivParm->isDirectInit() 16100 ? OMPDeclareReductionDecl::DirectInit 16101 : OMPDeclareReductionDecl::CopyInit); 16102 } else { 16103 DRD->setInvalidDecl(); 16104 } 16105 } 16106 16107 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16108 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16109 for (Decl *D : DeclReductions.get()) { 16110 if (IsValid) { 16111 if (S) 16112 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16113 /*AddToContext=*/false); 16114 } else { 16115 D->setInvalidDecl(); 16116 } 16117 } 16118 return DeclReductions; 16119 } 16120 16121 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16122 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16123 QualType T = TInfo->getType(); 16124 if (D.isInvalidType()) 16125 return true; 16126 16127 if (getLangOpts().CPlusPlus) { 16128 // Check that there are no default arguments (C++ only). 16129 CheckExtraCXXDefaultArguments(D); 16130 } 16131 16132 return CreateParsedType(T, TInfo); 16133 } 16134 16135 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16136 TypeResult ParsedType) { 16137 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16138 16139 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16140 assert(!MapperType.isNull() && "Expect valid mapper type"); 16141 16142 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16143 // The type must be of struct, union or class type in C and C++ 16144 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16145 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16146 return QualType(); 16147 } 16148 return MapperType; 16149 } 16150 16151 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16152 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16153 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16154 Decl *PrevDeclInScope) { 16155 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16156 forRedeclarationInCurContext()); 16157 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16158 // A mapper-identifier may not be redeclared in the current scope for the 16159 // same type or for a type that is compatible according to the base language 16160 // rules. 16161 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16162 OMPDeclareMapperDecl *PrevDMD = nullptr; 16163 bool InCompoundScope = true; 16164 if (S != nullptr) { 16165 // Find previous declaration with the same name not referenced in other 16166 // declarations. 16167 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16168 InCompoundScope = 16169 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16170 LookupName(Lookup, S); 16171 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16172 /*AllowInlineNamespace=*/false); 16173 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16174 LookupResult::Filter Filter = Lookup.makeFilter(); 16175 while (Filter.hasNext()) { 16176 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16177 if (InCompoundScope) { 16178 auto I = UsedAsPrevious.find(PrevDecl); 16179 if (I == UsedAsPrevious.end()) 16180 UsedAsPrevious[PrevDecl] = false; 16181 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16182 UsedAsPrevious[D] = true; 16183 } 16184 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16185 PrevDecl->getLocation(); 16186 } 16187 Filter.done(); 16188 if (InCompoundScope) { 16189 for (const auto &PrevData : UsedAsPrevious) { 16190 if (!PrevData.second) { 16191 PrevDMD = PrevData.first; 16192 break; 16193 } 16194 } 16195 } 16196 } else if (PrevDeclInScope) { 16197 auto *PrevDMDInScope = PrevDMD = 16198 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16199 do { 16200 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16201 PrevDMDInScope->getLocation(); 16202 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16203 } while (PrevDMDInScope != nullptr); 16204 } 16205 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16206 bool Invalid = false; 16207 if (I != PreviousRedeclTypes.end()) { 16208 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16209 << MapperType << Name; 16210 Diag(I->second, diag::note_previous_definition); 16211 Invalid = true; 16212 } 16213 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16214 MapperType, VN, PrevDMD); 16215 DC->addDecl(DMD); 16216 DMD->setAccess(AS); 16217 if (Invalid) 16218 DMD->setInvalidDecl(); 16219 16220 // Enter new function scope. 16221 PushFunctionScope(); 16222 setFunctionHasBranchProtectedScope(); 16223 16224 CurContext = DMD; 16225 16226 return DMD; 16227 } 16228 16229 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16230 Scope *S, 16231 QualType MapperType, 16232 SourceLocation StartLoc, 16233 DeclarationName VN) { 16234 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16235 if (S) 16236 PushOnScopeChains(VD, S); 16237 else 16238 DMD->addDecl(VD); 16239 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16240 DMD->setMapperVarRef(MapperVarRefExpr); 16241 } 16242 16243 Sema::DeclGroupPtrTy 16244 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16245 ArrayRef<OMPClause *> ClauseList) { 16246 PopDeclContext(); 16247 PopFunctionScopeInfo(); 16248 16249 if (D) { 16250 if (S) 16251 PushOnScopeChains(D, S, /*AddToContext=*/false); 16252 D->CreateClauses(Context, ClauseList); 16253 } 16254 16255 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16256 } 16257 16258 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16259 SourceLocation StartLoc, 16260 SourceLocation LParenLoc, 16261 SourceLocation EndLoc) { 16262 Expr *ValExpr = NumTeams; 16263 Stmt *HelperValStmt = nullptr; 16264 16265 // OpenMP [teams Constrcut, Restrictions] 16266 // The num_teams expression must evaluate to a positive integer value. 16267 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16268 /*StrictlyPositive=*/true)) 16269 return nullptr; 16270 16271 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16272 OpenMPDirectiveKind CaptureRegion = 16273 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 16274 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16275 ValExpr = MakeFullExpr(ValExpr).get(); 16276 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16277 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16278 HelperValStmt = buildPreInits(Context, Captures); 16279 } 16280 16281 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16282 StartLoc, LParenLoc, EndLoc); 16283 } 16284 16285 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16286 SourceLocation StartLoc, 16287 SourceLocation LParenLoc, 16288 SourceLocation EndLoc) { 16289 Expr *ValExpr = ThreadLimit; 16290 Stmt *HelperValStmt = nullptr; 16291 16292 // OpenMP [teams Constrcut, Restrictions] 16293 // The thread_limit expression must evaluate to a positive integer value. 16294 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16295 /*StrictlyPositive=*/true)) 16296 return nullptr; 16297 16298 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16299 OpenMPDirectiveKind CaptureRegion = 16300 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 16301 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16302 ValExpr = MakeFullExpr(ValExpr).get(); 16303 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16304 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16305 HelperValStmt = buildPreInits(Context, Captures); 16306 } 16307 16308 return new (Context) OMPThreadLimitClause( 16309 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16310 } 16311 16312 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16313 SourceLocation StartLoc, 16314 SourceLocation LParenLoc, 16315 SourceLocation EndLoc) { 16316 Expr *ValExpr = Priority; 16317 Stmt *HelperValStmt = nullptr; 16318 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16319 16320 // OpenMP [2.9.1, task Constrcut] 16321 // The priority-value is a non-negative numerical scalar expression. 16322 if (!isNonNegativeIntegerValue( 16323 ValExpr, *this, OMPC_priority, 16324 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16325 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16326 return nullptr; 16327 16328 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16329 StartLoc, LParenLoc, EndLoc); 16330 } 16331 16332 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16333 SourceLocation StartLoc, 16334 SourceLocation LParenLoc, 16335 SourceLocation EndLoc) { 16336 Expr *ValExpr = Grainsize; 16337 Stmt *HelperValStmt = nullptr; 16338 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16339 16340 // OpenMP [2.9.2, taskloop Constrcut] 16341 // The parameter of the grainsize clause must be a positive integer 16342 // expression. 16343 if (!isNonNegativeIntegerValue( 16344 ValExpr, *this, OMPC_grainsize, 16345 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16346 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16347 return nullptr; 16348 16349 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16350 StartLoc, LParenLoc, EndLoc); 16351 } 16352 16353 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16354 SourceLocation StartLoc, 16355 SourceLocation LParenLoc, 16356 SourceLocation EndLoc) { 16357 Expr *ValExpr = NumTasks; 16358 Stmt *HelperValStmt = nullptr; 16359 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16360 16361 // OpenMP [2.9.2, taskloop Constrcut] 16362 // The parameter of the num_tasks clause must be a positive integer 16363 // expression. 16364 if (!isNonNegativeIntegerValue( 16365 ValExpr, *this, OMPC_num_tasks, 16366 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16367 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16368 return nullptr; 16369 16370 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16371 StartLoc, LParenLoc, EndLoc); 16372 } 16373 16374 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16375 SourceLocation LParenLoc, 16376 SourceLocation EndLoc) { 16377 // OpenMP [2.13.2, critical construct, Description] 16378 // ... where hint-expression is an integer constant expression that evaluates 16379 // to a valid lock hint. 16380 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16381 if (HintExpr.isInvalid()) 16382 return nullptr; 16383 return new (Context) 16384 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16385 } 16386 16387 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16388 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16389 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16390 SourceLocation EndLoc) { 16391 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16392 std::string Values; 16393 Values += "'"; 16394 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16395 Values += "'"; 16396 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16397 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16398 return nullptr; 16399 } 16400 Expr *ValExpr = ChunkSize; 16401 Stmt *HelperValStmt = nullptr; 16402 if (ChunkSize) { 16403 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16404 !ChunkSize->isInstantiationDependent() && 16405 !ChunkSize->containsUnexpandedParameterPack()) { 16406 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16407 ExprResult Val = 16408 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16409 if (Val.isInvalid()) 16410 return nullptr; 16411 16412 ValExpr = Val.get(); 16413 16414 // OpenMP [2.7.1, Restrictions] 16415 // chunk_size must be a loop invariant integer expression with a positive 16416 // value. 16417 llvm::APSInt Result; 16418 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16419 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16420 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16421 << "dist_schedule" << ChunkSize->getSourceRange(); 16422 return nullptr; 16423 } 16424 } else if (getOpenMPCaptureRegionForClause( 16425 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 16426 OMPD_unknown && 16427 !CurContext->isDependentContext()) { 16428 ValExpr = MakeFullExpr(ValExpr).get(); 16429 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16430 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16431 HelperValStmt = buildPreInits(Context, Captures); 16432 } 16433 } 16434 } 16435 16436 return new (Context) 16437 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16438 Kind, ValExpr, HelperValStmt); 16439 } 16440 16441 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16442 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16443 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16444 SourceLocation KindLoc, SourceLocation EndLoc) { 16445 if (getLangOpts().OpenMP < 50) { 16446 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 16447 Kind != OMPC_DEFAULTMAP_scalar) { 16448 std::string Value; 16449 SourceLocation Loc; 16450 Value += "'"; 16451 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16452 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16453 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16454 Loc = MLoc; 16455 } else { 16456 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16457 OMPC_DEFAULTMAP_scalar); 16458 Loc = KindLoc; 16459 } 16460 Value += "'"; 16461 Diag(Loc, diag::err_omp_unexpected_clause_value) 16462 << Value << getOpenMPClauseName(OMPC_defaultmap); 16463 return nullptr; 16464 } 16465 } else { 16466 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 16467 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 16468 if (!isDefaultmapKind || !isDefaultmapModifier) { 16469 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 16470 "'firstprivate', 'none', 'default'"; 16471 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 16472 if (!isDefaultmapKind && isDefaultmapModifier) { 16473 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16474 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16475 } else if (isDefaultmapKind && !isDefaultmapModifier) { 16476 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16477 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16478 } else { 16479 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16480 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16481 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16482 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16483 } 16484 return nullptr; 16485 } 16486 16487 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 16488 // At most one defaultmap clause for each category can appear on the 16489 // directive. 16490 if (DSAStack->checkDefaultmapCategory(Kind)) { 16491 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 16492 return nullptr; 16493 } 16494 } 16495 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 16496 16497 return new (Context) 16498 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16499 } 16500 16501 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16502 DeclContext *CurLexicalContext = getCurLexicalContext(); 16503 if (!CurLexicalContext->isFileContext() && 16504 !CurLexicalContext->isExternCContext() && 16505 !CurLexicalContext->isExternCXXContext() && 16506 !isa<CXXRecordDecl>(CurLexicalContext) && 16507 !isa<ClassTemplateDecl>(CurLexicalContext) && 16508 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16509 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16510 Diag(Loc, diag::err_omp_region_not_file_context); 16511 return false; 16512 } 16513 ++DeclareTargetNestingLevel; 16514 return true; 16515 } 16516 16517 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16518 assert(DeclareTargetNestingLevel > 0 && 16519 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16520 --DeclareTargetNestingLevel; 16521 } 16522 16523 NamedDecl * 16524 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16525 const DeclarationNameInfo &Id, 16526 NamedDeclSetType &SameDirectiveDecls) { 16527 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16528 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16529 16530 if (Lookup.isAmbiguous()) 16531 return nullptr; 16532 Lookup.suppressDiagnostics(); 16533 16534 if (!Lookup.isSingleResult()) { 16535 VarOrFuncDeclFilterCCC CCC(*this); 16536 if (TypoCorrection Corrected = 16537 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16538 CTK_ErrorRecovery)) { 16539 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16540 << Id.getName()); 16541 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16542 return nullptr; 16543 } 16544 16545 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16546 return nullptr; 16547 } 16548 16549 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16550 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16551 !isa<FunctionTemplateDecl>(ND)) { 16552 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16553 return nullptr; 16554 } 16555 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16556 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16557 return ND; 16558 } 16559 16560 void Sema::ActOnOpenMPDeclareTargetName( 16561 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16562 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16563 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16564 isa<FunctionTemplateDecl>(ND)) && 16565 "Expected variable, function or function template."); 16566 16567 // Diagnose marking after use as it may lead to incorrect diagnosis and 16568 // codegen. 16569 if (LangOpts.OpenMP >= 50 && 16570 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16571 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16572 16573 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16574 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16575 if (DevTy.hasValue() && *DevTy != DT) { 16576 Diag(Loc, diag::err_omp_device_type_mismatch) 16577 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16578 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16579 return; 16580 } 16581 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16582 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16583 if (!Res) { 16584 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16585 SourceRange(Loc, Loc)); 16586 ND->addAttr(A); 16587 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16588 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16589 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16590 } else if (*Res != MT) { 16591 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16592 } 16593 } 16594 16595 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16596 Sema &SemaRef, Decl *D) { 16597 if (!D || !isa<VarDecl>(D)) 16598 return; 16599 auto *VD = cast<VarDecl>(D); 16600 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16601 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16602 if (SemaRef.LangOpts.OpenMP >= 50 && 16603 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16604 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16605 VD->hasGlobalStorage()) { 16606 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16607 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16608 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16609 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16610 // If a lambda declaration and definition appears between a 16611 // declare target directive and the matching end declare target 16612 // directive, all variables that are captured by the lambda 16613 // expression must also appear in a to clause. 16614 SemaRef.Diag(VD->getLocation(), 16615 diag::err_omp_lambda_capture_in_declare_target_not_to); 16616 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16617 << VD << 0 << SR; 16618 return; 16619 } 16620 } 16621 if (MapTy.hasValue()) 16622 return; 16623 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16624 SemaRef.Diag(SL, diag::note_used_here) << SR; 16625 } 16626 16627 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16628 Sema &SemaRef, DSAStackTy *Stack, 16629 ValueDecl *VD) { 16630 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16631 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16632 /*FullCheck=*/false); 16633 } 16634 16635 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16636 SourceLocation IdLoc) { 16637 if (!D || D->isInvalidDecl()) 16638 return; 16639 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16640 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16641 if (auto *VD = dyn_cast<VarDecl>(D)) { 16642 // Only global variables can be marked as declare target. 16643 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16644 !VD->isStaticDataMember()) 16645 return; 16646 // 2.10.6: threadprivate variable cannot appear in a declare target 16647 // directive. 16648 if (DSAStack->isThreadPrivate(VD)) { 16649 Diag(SL, diag::err_omp_threadprivate_in_target); 16650 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16651 return; 16652 } 16653 } 16654 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16655 D = FTD->getTemplatedDecl(); 16656 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16657 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16658 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16659 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16660 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16661 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16662 return; 16663 } 16664 // Mark the function as must be emitted for the device. 16665 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16666 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16667 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16668 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16669 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16670 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16671 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16672 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16673 } 16674 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16675 // Problem if any with var declared with incomplete type will be reported 16676 // as normal, so no need to check it here. 16677 if ((E || !VD->getType()->isIncompleteType()) && 16678 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16679 return; 16680 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16681 // Checking declaration inside declare target region. 16682 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16683 isa<FunctionTemplateDecl>(D)) { 16684 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16685 Context, OMPDeclareTargetDeclAttr::MT_To, 16686 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16687 D->addAttr(A); 16688 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16689 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16690 } 16691 return; 16692 } 16693 } 16694 if (!E) 16695 return; 16696 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16697 } 16698 16699 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16700 CXXScopeSpec &MapperIdScopeSpec, 16701 DeclarationNameInfo &MapperId, 16702 const OMPVarListLocTy &Locs, 16703 ArrayRef<Expr *> UnresolvedMappers) { 16704 MappableVarListInfo MVLI(VarList); 16705 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16706 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16707 if (MVLI.ProcessedVarList.empty()) 16708 return nullptr; 16709 16710 return OMPToClause::Create( 16711 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16712 MVLI.VarComponents, MVLI.UDMapperList, 16713 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16714 } 16715 16716 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16717 CXXScopeSpec &MapperIdScopeSpec, 16718 DeclarationNameInfo &MapperId, 16719 const OMPVarListLocTy &Locs, 16720 ArrayRef<Expr *> UnresolvedMappers) { 16721 MappableVarListInfo MVLI(VarList); 16722 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16723 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16724 if (MVLI.ProcessedVarList.empty()) 16725 return nullptr; 16726 16727 return OMPFromClause::Create( 16728 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16729 MVLI.VarComponents, MVLI.UDMapperList, 16730 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16731 } 16732 16733 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16734 const OMPVarListLocTy &Locs) { 16735 MappableVarListInfo MVLI(VarList); 16736 SmallVector<Expr *, 8> PrivateCopies; 16737 SmallVector<Expr *, 8> Inits; 16738 16739 for (Expr *RefExpr : VarList) { 16740 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16741 SourceLocation ELoc; 16742 SourceRange ERange; 16743 Expr *SimpleRefExpr = RefExpr; 16744 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16745 if (Res.second) { 16746 // It will be analyzed later. 16747 MVLI.ProcessedVarList.push_back(RefExpr); 16748 PrivateCopies.push_back(nullptr); 16749 Inits.push_back(nullptr); 16750 } 16751 ValueDecl *D = Res.first; 16752 if (!D) 16753 continue; 16754 16755 QualType Type = D->getType(); 16756 Type = Type.getNonReferenceType().getUnqualifiedType(); 16757 16758 auto *VD = dyn_cast<VarDecl>(D); 16759 16760 // Item should be a pointer or reference to pointer. 16761 if (!Type->isPointerType()) { 16762 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16763 << 0 << RefExpr->getSourceRange(); 16764 continue; 16765 } 16766 16767 // Build the private variable and the expression that refers to it. 16768 auto VDPrivate = 16769 buildVarDecl(*this, ELoc, Type, D->getName(), 16770 D->hasAttrs() ? &D->getAttrs() : nullptr, 16771 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16772 if (VDPrivate->isInvalidDecl()) 16773 continue; 16774 16775 CurContext->addDecl(VDPrivate); 16776 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16777 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16778 16779 // Add temporary variable to initialize the private copy of the pointer. 16780 VarDecl *VDInit = 16781 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16782 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16783 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16784 AddInitializerToDecl(VDPrivate, 16785 DefaultLvalueConversion(VDInitRefExpr).get(), 16786 /*DirectInit=*/false); 16787 16788 // If required, build a capture to implement the privatization initialized 16789 // with the current list item value. 16790 DeclRefExpr *Ref = nullptr; 16791 if (!VD) 16792 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16793 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16794 PrivateCopies.push_back(VDPrivateRefExpr); 16795 Inits.push_back(VDInitRefExpr); 16796 16797 // We need to add a data sharing attribute for this variable to make sure it 16798 // is correctly captured. A variable that shows up in a use_device_ptr has 16799 // similar properties of a first private variable. 16800 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16801 16802 // Create a mappable component for the list item. List items in this clause 16803 // only need a component. 16804 MVLI.VarBaseDeclarations.push_back(D); 16805 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16806 MVLI.VarComponents.back().push_back( 16807 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16808 } 16809 16810 if (MVLI.ProcessedVarList.empty()) 16811 return nullptr; 16812 16813 return OMPUseDevicePtrClause::Create( 16814 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16815 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16816 } 16817 16818 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16819 const OMPVarListLocTy &Locs) { 16820 MappableVarListInfo MVLI(VarList); 16821 for (Expr *RefExpr : VarList) { 16822 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16823 SourceLocation ELoc; 16824 SourceRange ERange; 16825 Expr *SimpleRefExpr = RefExpr; 16826 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16827 if (Res.second) { 16828 // It will be analyzed later. 16829 MVLI.ProcessedVarList.push_back(RefExpr); 16830 } 16831 ValueDecl *D = Res.first; 16832 if (!D) 16833 continue; 16834 16835 QualType Type = D->getType(); 16836 // item should be a pointer or array or reference to pointer or array 16837 if (!Type.getNonReferenceType()->isPointerType() && 16838 !Type.getNonReferenceType()->isArrayType()) { 16839 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16840 << 0 << RefExpr->getSourceRange(); 16841 continue; 16842 } 16843 16844 // Check if the declaration in the clause does not show up in any data 16845 // sharing attribute. 16846 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16847 if (isOpenMPPrivate(DVar.CKind)) { 16848 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16849 << getOpenMPClauseName(DVar.CKind) 16850 << getOpenMPClauseName(OMPC_is_device_ptr) 16851 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16852 reportOriginalDsa(*this, DSAStack, D, DVar); 16853 continue; 16854 } 16855 16856 const Expr *ConflictExpr; 16857 if (DSAStack->checkMappableExprComponentListsForDecl( 16858 D, /*CurrentRegionOnly=*/true, 16859 [&ConflictExpr]( 16860 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16861 OpenMPClauseKind) -> bool { 16862 ConflictExpr = R.front().getAssociatedExpression(); 16863 return true; 16864 })) { 16865 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16866 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16867 << ConflictExpr->getSourceRange(); 16868 continue; 16869 } 16870 16871 // Store the components in the stack so that they can be used to check 16872 // against other clauses later on. 16873 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16874 DSAStack->addMappableExpressionComponents( 16875 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16876 16877 // Record the expression we've just processed. 16878 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16879 16880 // Create a mappable component for the list item. List items in this clause 16881 // only need a component. We use a null declaration to signal fields in 16882 // 'this'. 16883 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16884 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16885 "Unexpected device pointer expression!"); 16886 MVLI.VarBaseDeclarations.push_back( 16887 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16888 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16889 MVLI.VarComponents.back().push_back(MC); 16890 } 16891 16892 if (MVLI.ProcessedVarList.empty()) 16893 return nullptr; 16894 16895 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16896 MVLI.VarBaseDeclarations, 16897 MVLI.VarComponents); 16898 } 16899 16900 OMPClause *Sema::ActOnOpenMPAllocateClause( 16901 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16902 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16903 if (Allocator) { 16904 // OpenMP [2.11.4 allocate Clause, Description] 16905 // allocator is an expression of omp_allocator_handle_t type. 16906 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16907 return nullptr; 16908 16909 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16910 if (AllocatorRes.isInvalid()) 16911 return nullptr; 16912 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16913 DSAStack->getOMPAllocatorHandleT(), 16914 Sema::AA_Initializing, 16915 /*AllowExplicit=*/true); 16916 if (AllocatorRes.isInvalid()) 16917 return nullptr; 16918 Allocator = AllocatorRes.get(); 16919 } else { 16920 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16921 // allocate clauses that appear on a target construct or on constructs in a 16922 // target region must specify an allocator expression unless a requires 16923 // directive with the dynamic_allocators clause is present in the same 16924 // compilation unit. 16925 if (LangOpts.OpenMPIsDevice && 16926 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16927 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16928 } 16929 // Analyze and build list of variables. 16930 SmallVector<Expr *, 8> Vars; 16931 for (Expr *RefExpr : VarList) { 16932 assert(RefExpr && "NULL expr in OpenMP private clause."); 16933 SourceLocation ELoc; 16934 SourceRange ERange; 16935 Expr *SimpleRefExpr = RefExpr; 16936 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16937 if (Res.second) { 16938 // It will be analyzed later. 16939 Vars.push_back(RefExpr); 16940 } 16941 ValueDecl *D = Res.first; 16942 if (!D) 16943 continue; 16944 16945 auto *VD = dyn_cast<VarDecl>(D); 16946 DeclRefExpr *Ref = nullptr; 16947 if (!VD && !CurContext->isDependentContext()) 16948 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16949 Vars.push_back((VD || CurContext->isDependentContext()) 16950 ? RefExpr->IgnoreParens() 16951 : Ref); 16952 } 16953 16954 if (Vars.empty()) 16955 return nullptr; 16956 16957 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16958 ColonLoc, EndLoc, Vars); 16959 } 16960