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/Basic/PartialDiagnostic.h" 27 #include "clang/Sema/Initialization.h" 28 #include "clang/Sema/Lookup.h" 29 #include "clang/Sema/Scope.h" 30 #include "clang/Sema/ScopeInfo.h" 31 #include "clang/Sema/SemaInternal.h" 32 #include "llvm/ADT/IndexedMap.h" 33 #include "llvm/ADT/PointerEmbeddedInt.h" 34 #include "llvm/Frontend/OpenMP/OMPConstants.h" 35 using namespace clang; 36 using namespace llvm::omp; 37 38 //===----------------------------------------------------------------------===// 39 // Stack of data-sharing attributes for variables 40 //===----------------------------------------------------------------------===// 41 42 static const Expr *checkMapClauseExpressionBase( 43 Sema &SemaRef, Expr *E, 44 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 45 OpenMPClauseKind CKind, bool NoDiagnose); 46 47 namespace { 48 /// Default data sharing attributes, which can be applied to directive. 49 enum DefaultDataSharingAttributes { 50 DSA_unspecified = 0, /// Data sharing attribute not specified. 51 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 52 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 53 }; 54 55 /// Stack for tracking declarations used in OpenMP directives and 56 /// clauses and their data-sharing attributes. 57 class DSAStackTy { 58 public: 59 struct DSAVarData { 60 OpenMPDirectiveKind DKind = OMPD_unknown; 61 OpenMPClauseKind CKind = OMPC_unknown; 62 const Expr *RefExpr = nullptr; 63 DeclRefExpr *PrivateCopy = nullptr; 64 SourceLocation ImplicitDSALoc; 65 DSAVarData() = default; 66 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 67 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 68 SourceLocation ImplicitDSALoc) 69 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 70 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 71 }; 72 using OperatorOffsetTy = 73 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 74 using DoacrossDependMapTy = 75 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 76 77 private: 78 struct DSAInfo { 79 OpenMPClauseKind Attributes = OMPC_unknown; 80 /// Pointer to a reference expression and a flag which shows that the 81 /// variable is marked as lastprivate(true) or not (false). 82 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 83 DeclRefExpr *PrivateCopy = nullptr; 84 }; 85 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 86 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 87 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 88 using LoopControlVariablesMapTy = 89 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 90 /// Struct that associates a component with the clause kind where they are 91 /// found. 92 struct MappedExprComponentTy { 93 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 94 OpenMPClauseKind Kind = OMPC_unknown; 95 }; 96 using MappedExprComponentsTy = 97 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 98 using CriticalsWithHintsTy = 99 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 100 struct ReductionData { 101 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 102 SourceRange ReductionRange; 103 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 104 ReductionData() = default; 105 void set(BinaryOperatorKind BO, SourceRange RR) { 106 ReductionRange = RR; 107 ReductionOp = BO; 108 } 109 void set(const Expr *RefExpr, SourceRange RR) { 110 ReductionRange = RR; 111 ReductionOp = RefExpr; 112 } 113 }; 114 using DeclReductionMapTy = 115 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 116 struct DefaultmapInfo { 117 OpenMPDefaultmapClauseModifier ImplicitBehavior = 118 OMPC_DEFAULTMAP_MODIFIER_unknown; 119 SourceLocation SLoc; 120 DefaultmapInfo() = default; 121 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 122 : ImplicitBehavior(M), SLoc(Loc) {} 123 }; 124 125 struct SharingMapTy { 126 DeclSAMapTy SharingMap; 127 DeclReductionMapTy ReductionMap; 128 AlignedMapTy AlignedMap; 129 MappedExprComponentsTy MappedExprComponents; 130 LoopControlVariablesMapTy LCVMap; 131 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 132 SourceLocation DefaultAttrLoc; 133 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 134 OpenMPDirectiveKind Directive = OMPD_unknown; 135 DeclarationNameInfo DirectiveName; 136 Scope *CurScope = nullptr; 137 SourceLocation ConstructLoc; 138 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 139 /// get the data (loop counters etc.) about enclosing loop-based construct. 140 /// This data is required during codegen. 141 DoacrossDependMapTy DoacrossDepends; 142 /// First argument (Expr *) contains optional argument of the 143 /// 'ordered' clause, the second one is true if the regions has 'ordered' 144 /// clause, false otherwise. 145 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 146 unsigned AssociatedLoops = 1; 147 bool HasMutipleLoops = false; 148 const Decl *PossiblyLoopCounter = nullptr; 149 bool NowaitRegion = false; 150 bool CancelRegion = false; 151 bool LoopStart = false; 152 bool BodyComplete = false; 153 SourceLocation InnerTeamsRegionLoc; 154 /// Reference to the taskgroup task_reduction reference expression. 155 Expr *TaskgroupReductionRef = nullptr; 156 llvm::DenseSet<QualType> MappedClassesQualTypes; 157 /// List of globals marked as declare target link in this target region 158 /// (isOpenMPTargetExecutionDirective(Directive) == true). 159 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 160 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 161 Scope *CurScope, SourceLocation Loc) 162 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 163 ConstructLoc(Loc) {} 164 SharingMapTy() = default; 165 }; 166 167 using StackTy = SmallVector<SharingMapTy, 4>; 168 169 /// Stack of used declaration and their data-sharing attributes. 170 DeclSAMapTy Threadprivates; 171 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 172 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 173 /// true, if check for DSA must be from parent directive, false, if 174 /// from current directive. 175 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 176 Sema &SemaRef; 177 bool ForceCapturing = false; 178 /// true if all the variables in the target executable directives must be 179 /// captured by reference. 180 bool ForceCaptureByReferenceInTargetExecutable = false; 181 CriticalsWithHintsTy Criticals; 182 unsigned IgnoredStackElements = 0; 183 184 /// Iterators over the stack iterate in order from innermost to outermost 185 /// directive. 186 using const_iterator = StackTy::const_reverse_iterator; 187 const_iterator begin() const { 188 return Stack.empty() ? const_iterator() 189 : Stack.back().first.rbegin() + IgnoredStackElements; 190 } 191 const_iterator end() const { 192 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 193 } 194 using iterator = StackTy::reverse_iterator; 195 iterator begin() { 196 return Stack.empty() ? iterator() 197 : Stack.back().first.rbegin() + IgnoredStackElements; 198 } 199 iterator end() { 200 return Stack.empty() ? iterator() : Stack.back().first.rend(); 201 } 202 203 // Convenience operations to get at the elements of the stack. 204 205 bool isStackEmpty() const { 206 return Stack.empty() || 207 Stack.back().second != CurrentNonCapturingFunctionScope || 208 Stack.back().first.size() <= IgnoredStackElements; 209 } 210 size_t getStackSize() const { 211 return isStackEmpty() ? 0 212 : Stack.back().first.size() - IgnoredStackElements; 213 } 214 215 SharingMapTy *getTopOfStackOrNull() { 216 size_t Size = getStackSize(); 217 if (Size == 0) 218 return nullptr; 219 return &Stack.back().first[Size - 1]; 220 } 221 const SharingMapTy *getTopOfStackOrNull() const { 222 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 223 } 224 SharingMapTy &getTopOfStack() { 225 assert(!isStackEmpty() && "no current directive"); 226 return *getTopOfStackOrNull(); 227 } 228 const SharingMapTy &getTopOfStack() const { 229 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 230 } 231 232 SharingMapTy *getSecondOnStackOrNull() { 233 size_t Size = getStackSize(); 234 if (Size <= 1) 235 return nullptr; 236 return &Stack.back().first[Size - 2]; 237 } 238 const SharingMapTy *getSecondOnStackOrNull() const { 239 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 240 } 241 242 /// Get the stack element at a certain level (previously returned by 243 /// \c getNestingLevel). 244 /// 245 /// Note that nesting levels count from outermost to innermost, and this is 246 /// the reverse of our iteration order where new inner levels are pushed at 247 /// the front of the stack. 248 SharingMapTy &getStackElemAtLevel(unsigned Level) { 249 assert(Level < getStackSize() && "no such stack element"); 250 return Stack.back().first[Level]; 251 } 252 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 253 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 254 } 255 256 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 257 258 /// Checks if the variable is a local for OpenMP region. 259 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 260 261 /// Vector of previously declared requires directives 262 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 263 /// omp_allocator_handle_t type. 264 QualType OMPAllocatorHandleT; 265 /// Expression for the predefined allocators. 266 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 267 nullptr}; 268 /// Vector of previously encountered target directives 269 SmallVector<SourceLocation, 2> TargetLocations; 270 271 public: 272 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 273 274 /// Sets omp_allocator_handle_t type. 275 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 276 /// Gets omp_allocator_handle_t type. 277 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 278 /// Sets the given default allocator. 279 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 280 Expr *Allocator) { 281 OMPPredefinedAllocators[AllocatorKind] = Allocator; 282 } 283 /// Returns the specified default allocator. 284 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 285 return OMPPredefinedAllocators[AllocatorKind]; 286 } 287 288 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 289 OpenMPClauseKind getClauseParsingMode() const { 290 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 291 return ClauseKindMode; 292 } 293 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 294 295 bool isBodyComplete() const { 296 const SharingMapTy *Top = getTopOfStackOrNull(); 297 return Top && Top->BodyComplete; 298 } 299 void setBodyComplete() { 300 getTopOfStack().BodyComplete = true; 301 } 302 303 bool isForceVarCapturing() const { return ForceCapturing; } 304 void setForceVarCapturing(bool V) { ForceCapturing = V; } 305 306 void setForceCaptureByReferenceInTargetExecutable(bool V) { 307 ForceCaptureByReferenceInTargetExecutable = V; 308 } 309 bool isForceCaptureByReferenceInTargetExecutable() const { 310 return ForceCaptureByReferenceInTargetExecutable; 311 } 312 313 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 314 Scope *CurScope, SourceLocation Loc) { 315 assert(!IgnoredStackElements && 316 "cannot change stack while ignoring elements"); 317 if (Stack.empty() || 318 Stack.back().second != CurrentNonCapturingFunctionScope) 319 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 320 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 321 Stack.back().first.back().DefaultAttrLoc = Loc; 322 } 323 324 void pop() { 325 assert(!IgnoredStackElements && 326 "cannot change stack while ignoring elements"); 327 assert(!Stack.back().first.empty() && 328 "Data-sharing attributes stack is empty!"); 329 Stack.back().first.pop_back(); 330 } 331 332 /// RAII object to temporarily leave the scope of a directive when we want to 333 /// logically operate in its parent. 334 class ParentDirectiveScope { 335 DSAStackTy &Self; 336 bool Active; 337 public: 338 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 339 : Self(Self), Active(false) { 340 if (Activate) 341 enable(); 342 } 343 ~ParentDirectiveScope() { disable(); } 344 void disable() { 345 if (Active) { 346 --Self.IgnoredStackElements; 347 Active = false; 348 } 349 } 350 void enable() { 351 if (!Active) { 352 ++Self.IgnoredStackElements; 353 Active = true; 354 } 355 } 356 }; 357 358 /// Marks that we're started loop parsing. 359 void loopInit() { 360 assert(isOpenMPLoopDirective(getCurrentDirective()) && 361 "Expected loop-based directive."); 362 getTopOfStack().LoopStart = true; 363 } 364 /// Start capturing of the variables in the loop context. 365 void loopStart() { 366 assert(isOpenMPLoopDirective(getCurrentDirective()) && 367 "Expected loop-based directive."); 368 getTopOfStack().LoopStart = false; 369 } 370 /// true, if variables are captured, false otherwise. 371 bool isLoopStarted() const { 372 assert(isOpenMPLoopDirective(getCurrentDirective()) && 373 "Expected loop-based directive."); 374 return !getTopOfStack().LoopStart; 375 } 376 /// Marks (or clears) declaration as possibly loop counter. 377 void resetPossibleLoopCounter(const Decl *D = nullptr) { 378 getTopOfStack().PossiblyLoopCounter = 379 D ? D->getCanonicalDecl() : D; 380 } 381 /// Gets the possible loop counter decl. 382 const Decl *getPossiblyLoopCunter() const { 383 return getTopOfStack().PossiblyLoopCounter; 384 } 385 /// Start new OpenMP region stack in new non-capturing function. 386 void pushFunction() { 387 assert(!IgnoredStackElements && 388 "cannot change stack while ignoring elements"); 389 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 390 assert(!isa<CapturingScopeInfo>(CurFnScope)); 391 CurrentNonCapturingFunctionScope = CurFnScope; 392 } 393 /// Pop region stack for non-capturing function. 394 void popFunction(const FunctionScopeInfo *OldFSI) { 395 assert(!IgnoredStackElements && 396 "cannot change stack while ignoring elements"); 397 if (!Stack.empty() && Stack.back().second == OldFSI) { 398 assert(Stack.back().first.empty()); 399 Stack.pop_back(); 400 } 401 CurrentNonCapturingFunctionScope = nullptr; 402 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 403 if (!isa<CapturingScopeInfo>(FSI)) { 404 CurrentNonCapturingFunctionScope = FSI; 405 break; 406 } 407 } 408 } 409 410 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 411 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 412 } 413 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 414 getCriticalWithHint(const DeclarationNameInfo &Name) const { 415 auto I = Criticals.find(Name.getAsString()); 416 if (I != Criticals.end()) 417 return I->second; 418 return std::make_pair(nullptr, llvm::APSInt()); 419 } 420 /// If 'aligned' declaration for given variable \a D was not seen yet, 421 /// add it and return NULL; otherwise return previous occurrence's expression 422 /// for diagnostics. 423 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 424 425 /// Register specified variable as loop control variable. 426 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 427 /// Check if the specified variable is a loop control variable for 428 /// current region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 432 /// Check if the specified variable is a loop control variable for 433 /// parent region. 434 /// \return The index of the loop control variable in the list of associated 435 /// for-loops (from outer to inner). 436 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 437 /// Get the loop control variable for the I-th loop (or nullptr) in 438 /// parent directive. 439 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 440 441 /// Adds explicit data sharing attribute to the specified declaration. 442 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 443 DeclRefExpr *PrivateCopy = nullptr); 444 445 /// Adds additional information for the reduction items with the reduction id 446 /// represented as an operator. 447 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 448 BinaryOperatorKind BOK); 449 /// Adds additional information for the reduction items with the reduction id 450 /// represented as reduction identifier. 451 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 452 const Expr *ReductionRef); 453 /// Returns the location and reduction operation from the innermost parent 454 /// region for the given \p D. 455 const DSAVarData 456 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 457 BinaryOperatorKind &BOK, 458 Expr *&TaskgroupDescriptor) const; 459 /// Returns the location and reduction operation from the innermost parent 460 /// region for the given \p D. 461 const DSAVarData 462 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 463 const Expr *&ReductionRef, 464 Expr *&TaskgroupDescriptor) const; 465 /// Return reduction reference expression for the current taskgroup. 466 Expr *getTaskgroupReductionRef() const { 467 assert(getTopOfStack().Directive == OMPD_taskgroup && 468 "taskgroup reference expression requested for non taskgroup " 469 "directive."); 470 return getTopOfStack().TaskgroupReductionRef; 471 } 472 /// Checks if the given \p VD declaration is actually a taskgroup reduction 473 /// descriptor variable at the \p Level of OpenMP regions. 474 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 475 return getStackElemAtLevel(Level).TaskgroupReductionRef && 476 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 477 ->getDecl() == VD; 478 } 479 480 /// Returns data sharing attributes from top of the stack for the 481 /// specified declaration. 482 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 483 /// Returns data-sharing attributes for the specified declaration. 484 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 485 /// Checks if the specified variables has data-sharing attributes which 486 /// match specified \a CPred predicate in any directive which matches \a DPred 487 /// predicate. 488 const DSAVarData 489 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 490 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 491 bool FromParent) const; 492 /// Checks if the specified variables has data-sharing attributes which 493 /// match specified \a CPred predicate in any innermost directive which 494 /// matches \a DPred predicate. 495 const DSAVarData 496 hasInnermostDSA(ValueDecl *D, 497 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 498 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 499 bool FromParent) const; 500 /// Checks if the specified variables has explicit data-sharing 501 /// attributes which match specified \a CPred predicate at the specified 502 /// OpenMP region. 503 bool hasExplicitDSA(const ValueDecl *D, 504 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 505 unsigned Level, bool NotLastprivate = false) const; 506 507 /// Returns true if the directive at level \Level matches in the 508 /// specified \a DPred predicate. 509 bool hasExplicitDirective( 510 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 511 unsigned Level) const; 512 513 /// Finds a directive which matches specified \a DPred predicate. 514 bool hasDirective( 515 const llvm::function_ref<bool( 516 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 517 DPred, 518 bool FromParent) const; 519 520 /// Returns currently analyzed directive. 521 OpenMPDirectiveKind getCurrentDirective() const { 522 const SharingMapTy *Top = getTopOfStackOrNull(); 523 return Top ? Top->Directive : OMPD_unknown; 524 } 525 /// Returns directive kind at specified level. 526 OpenMPDirectiveKind getDirective(unsigned Level) const { 527 assert(!isStackEmpty() && "No directive at specified level."); 528 return getStackElemAtLevel(Level).Directive; 529 } 530 /// Returns the capture region at the specified level. 531 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 532 unsigned OpenMPCaptureLevel) const { 533 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 534 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 535 return CaptureRegions[OpenMPCaptureLevel]; 536 } 537 /// Returns parent directive. 538 OpenMPDirectiveKind getParentDirective() const { 539 const SharingMapTy *Parent = getSecondOnStackOrNull(); 540 return Parent ? Parent->Directive : OMPD_unknown; 541 } 542 543 /// Add requires decl to internal vector 544 void addRequiresDecl(OMPRequiresDecl *RD) { 545 RequiresDecls.push_back(RD); 546 } 547 548 /// Checks if the defined 'requires' directive has specified type of clause. 549 template <typename ClauseType> 550 bool hasRequiresDeclWithClause() { 551 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 552 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 553 return isa<ClauseType>(C); 554 }); 555 }); 556 } 557 558 /// Checks for a duplicate clause amongst previously declared requires 559 /// directives 560 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 561 bool IsDuplicate = false; 562 for (OMPClause *CNew : ClauseList) { 563 for (const OMPRequiresDecl *D : RequiresDecls) { 564 for (const OMPClause *CPrev : D->clauselists()) { 565 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 566 SemaRef.Diag(CNew->getBeginLoc(), 567 diag::err_omp_requires_clause_redeclaration) 568 << getOpenMPClauseName(CNew->getClauseKind()); 569 SemaRef.Diag(CPrev->getBeginLoc(), 570 diag::note_omp_requires_previous_clause) 571 << getOpenMPClauseName(CPrev->getClauseKind()); 572 IsDuplicate = true; 573 } 574 } 575 } 576 } 577 return IsDuplicate; 578 } 579 580 /// Add location of previously encountered target to internal vector 581 void addTargetDirLocation(SourceLocation LocStart) { 582 TargetLocations.push_back(LocStart); 583 } 584 585 // Return previously encountered target region locations. 586 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 587 return TargetLocations; 588 } 589 590 /// Set default data sharing attribute to none. 591 void setDefaultDSANone(SourceLocation Loc) { 592 getTopOfStack().DefaultAttr = DSA_none; 593 getTopOfStack().DefaultAttrLoc = Loc; 594 } 595 /// Set default data sharing attribute to shared. 596 void setDefaultDSAShared(SourceLocation Loc) { 597 getTopOfStack().DefaultAttr = DSA_shared; 598 getTopOfStack().DefaultAttrLoc = Loc; 599 } 600 /// Set default data mapping attribute to Modifier:Kind 601 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 602 OpenMPDefaultmapClauseKind Kind, 603 SourceLocation Loc) { 604 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 605 DMI.ImplicitBehavior = M; 606 DMI.SLoc = Loc; 607 } 608 /// Check whether the implicit-behavior has been set in defaultmap 609 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 610 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 611 OMPC_DEFAULTMAP_MODIFIER_unknown; 612 } 613 614 DefaultDataSharingAttributes getDefaultDSA() const { 615 return isStackEmpty() ? DSA_unspecified 616 : getTopOfStack().DefaultAttr; 617 } 618 SourceLocation getDefaultDSALocation() const { 619 return isStackEmpty() ? SourceLocation() 620 : getTopOfStack().DefaultAttrLoc; 621 } 622 OpenMPDefaultmapClauseModifier 623 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 624 return isStackEmpty() 625 ? OMPC_DEFAULTMAP_MODIFIER_unknown 626 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 627 } 628 OpenMPDefaultmapClauseModifier 629 getDefaultmapModifierAtLevel(unsigned Level, 630 OpenMPDefaultmapClauseKind Kind) const { 631 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 632 } 633 bool isDefaultmapCapturedByRef(unsigned Level, 634 OpenMPDefaultmapClauseKind Kind) const { 635 OpenMPDefaultmapClauseModifier M = 636 getDefaultmapModifierAtLevel(Level, Kind); 637 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 638 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 639 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 640 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 641 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 642 } 643 return true; 644 } 645 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 646 OpenMPDefaultmapClauseKind Kind) { 647 switch (Kind) { 648 case OMPC_DEFAULTMAP_scalar: 649 case OMPC_DEFAULTMAP_pointer: 650 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 651 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 652 (M == OMPC_DEFAULTMAP_MODIFIER_default); 653 case OMPC_DEFAULTMAP_aggregate: 654 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 655 default: 656 break; 657 } 658 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 659 } 660 bool mustBeFirstprivateAtLevel(unsigned Level, 661 OpenMPDefaultmapClauseKind Kind) const { 662 OpenMPDefaultmapClauseModifier M = 663 getDefaultmapModifierAtLevel(Level, Kind); 664 return mustBeFirstprivateBase(M, Kind); 665 } 666 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 667 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 668 return mustBeFirstprivateBase(M, Kind); 669 } 670 671 /// Checks if the specified variable is a threadprivate. 672 bool isThreadPrivate(VarDecl *D) { 673 const DSAVarData DVar = getTopDSA(D, false); 674 return isOpenMPThreadPrivate(DVar.CKind); 675 } 676 677 /// Marks current region as ordered (it has an 'ordered' clause). 678 void setOrderedRegion(bool IsOrdered, const Expr *Param, 679 OMPOrderedClause *Clause) { 680 if (IsOrdered) 681 getTopOfStack().OrderedRegion.emplace(Param, Clause); 682 else 683 getTopOfStack().OrderedRegion.reset(); 684 } 685 /// Returns true, if region is ordered (has associated 'ordered' clause), 686 /// false - otherwise. 687 bool isOrderedRegion() const { 688 if (const SharingMapTy *Top = getTopOfStackOrNull()) 689 return Top->OrderedRegion.hasValue(); 690 return false; 691 } 692 /// Returns optional parameter for the ordered region. 693 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 694 if (const SharingMapTy *Top = getTopOfStackOrNull()) 695 if (Top->OrderedRegion.hasValue()) 696 return Top->OrderedRegion.getValue(); 697 return std::make_pair(nullptr, nullptr); 698 } 699 /// Returns true, if parent region is ordered (has associated 700 /// 'ordered' clause), false - otherwise. 701 bool isParentOrderedRegion() const { 702 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 703 return Parent->OrderedRegion.hasValue(); 704 return false; 705 } 706 /// Returns optional parameter for the ordered region. 707 std::pair<const Expr *, OMPOrderedClause *> 708 getParentOrderedRegionParam() const { 709 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 710 if (Parent->OrderedRegion.hasValue()) 711 return Parent->OrderedRegion.getValue(); 712 return std::make_pair(nullptr, nullptr); 713 } 714 /// Marks current region as nowait (it has a 'nowait' clause). 715 void setNowaitRegion(bool IsNowait = true) { 716 getTopOfStack().NowaitRegion = IsNowait; 717 } 718 /// Returns true, if parent region is nowait (has associated 719 /// 'nowait' clause), false - otherwise. 720 bool isParentNowaitRegion() const { 721 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 722 return Parent->NowaitRegion; 723 return false; 724 } 725 /// Marks parent region as cancel region. 726 void setParentCancelRegion(bool Cancel = true) { 727 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 728 Parent->CancelRegion |= Cancel; 729 } 730 /// Return true if current region has inner cancel construct. 731 bool isCancelRegion() const { 732 const SharingMapTy *Top = getTopOfStackOrNull(); 733 return Top ? Top->CancelRegion : false; 734 } 735 736 /// Set collapse value for the region. 737 void setAssociatedLoops(unsigned Val) { 738 getTopOfStack().AssociatedLoops = Val; 739 if (Val > 1) 740 getTopOfStack().HasMutipleLoops = true; 741 } 742 /// Return collapse value for region. 743 unsigned getAssociatedLoops() const { 744 const SharingMapTy *Top = getTopOfStackOrNull(); 745 return Top ? Top->AssociatedLoops : 0; 746 } 747 /// Returns true if the construct is associated with multiple loops. 748 bool hasMutipleLoops() const { 749 const SharingMapTy *Top = getTopOfStackOrNull(); 750 return Top ? Top->HasMutipleLoops : false; 751 } 752 753 /// Marks current target region as one with closely nested teams 754 /// region. 755 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 756 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 757 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 758 } 759 /// Returns true, if current region has closely nested teams region. 760 bool hasInnerTeamsRegion() const { 761 return getInnerTeamsRegionLoc().isValid(); 762 } 763 /// Returns location of the nested teams region (if any). 764 SourceLocation getInnerTeamsRegionLoc() const { 765 const SharingMapTy *Top = getTopOfStackOrNull(); 766 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 767 } 768 769 Scope *getCurScope() const { 770 const SharingMapTy *Top = getTopOfStackOrNull(); 771 return Top ? Top->CurScope : nullptr; 772 } 773 SourceLocation getConstructLoc() const { 774 const SharingMapTy *Top = getTopOfStackOrNull(); 775 return Top ? Top->ConstructLoc : SourceLocation(); 776 } 777 778 /// Do the check specified in \a Check to all component lists and return true 779 /// if any issue is found. 780 bool checkMappableExprComponentListsForDecl( 781 const ValueDecl *VD, bool CurrentRegionOnly, 782 const llvm::function_ref< 783 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 784 OpenMPClauseKind)> 785 Check) const { 786 if (isStackEmpty()) 787 return false; 788 auto SI = begin(); 789 auto SE = end(); 790 791 if (SI == SE) 792 return false; 793 794 if (CurrentRegionOnly) 795 SE = std::next(SI); 796 else 797 std::advance(SI, 1); 798 799 for (; SI != SE; ++SI) { 800 auto MI = SI->MappedExprComponents.find(VD); 801 if (MI != SI->MappedExprComponents.end()) 802 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 803 MI->second.Components) 804 if (Check(L, MI->second.Kind)) 805 return true; 806 } 807 return false; 808 } 809 810 /// Do the check specified in \a Check to all component lists at a given level 811 /// and return true if any issue is found. 812 bool checkMappableExprComponentListsForDeclAtLevel( 813 const ValueDecl *VD, unsigned Level, 814 const llvm::function_ref< 815 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 816 OpenMPClauseKind)> 817 Check) const { 818 if (getStackSize() <= Level) 819 return false; 820 821 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 822 auto MI = StackElem.MappedExprComponents.find(VD); 823 if (MI != StackElem.MappedExprComponents.end()) 824 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 825 MI->second.Components) 826 if (Check(L, MI->second.Kind)) 827 return true; 828 return false; 829 } 830 831 /// Create a new mappable expression component list associated with a given 832 /// declaration and initialize it with the provided list of components. 833 void addMappableExpressionComponents( 834 const ValueDecl *VD, 835 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 836 OpenMPClauseKind WhereFoundClauseKind) { 837 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 838 // Create new entry and append the new components there. 839 MEC.Components.resize(MEC.Components.size() + 1); 840 MEC.Components.back().append(Components.begin(), Components.end()); 841 MEC.Kind = WhereFoundClauseKind; 842 } 843 844 unsigned getNestingLevel() const { 845 assert(!isStackEmpty()); 846 return getStackSize() - 1; 847 } 848 void addDoacrossDependClause(OMPDependClause *C, 849 const OperatorOffsetTy &OpsOffs) { 850 SharingMapTy *Parent = getSecondOnStackOrNull(); 851 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 852 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 853 } 854 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 855 getDoacrossDependClauses() const { 856 const SharingMapTy &StackElem = getTopOfStack(); 857 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 858 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 859 return llvm::make_range(Ref.begin(), Ref.end()); 860 } 861 return llvm::make_range(StackElem.DoacrossDepends.end(), 862 StackElem.DoacrossDepends.end()); 863 } 864 865 // Store types of classes which have been explicitly mapped 866 void addMappedClassesQualTypes(QualType QT) { 867 SharingMapTy &StackElem = getTopOfStack(); 868 StackElem.MappedClassesQualTypes.insert(QT); 869 } 870 871 // Return set of mapped classes types 872 bool isClassPreviouslyMapped(QualType QT) const { 873 const SharingMapTy &StackElem = getTopOfStack(); 874 return StackElem.MappedClassesQualTypes.count(QT) != 0; 875 } 876 877 /// Adds global declare target to the parent target region. 878 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 879 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 880 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 881 "Expected declare target link global."); 882 for (auto &Elem : *this) { 883 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 884 Elem.DeclareTargetLinkVarDecls.push_back(E); 885 return; 886 } 887 } 888 } 889 890 /// Returns the list of globals with declare target link if current directive 891 /// is target. 892 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 893 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 894 "Expected target executable directive."); 895 return getTopOfStack().DeclareTargetLinkVarDecls; 896 } 897 }; 898 899 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 900 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 901 } 902 903 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 904 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 905 DKind == OMPD_unknown; 906 } 907 908 } // namespace 909 910 static const Expr *getExprAsWritten(const Expr *E) { 911 if (const auto *FE = dyn_cast<FullExpr>(E)) 912 E = FE->getSubExpr(); 913 914 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 915 E = MTE->getSubExpr(); 916 917 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 918 E = Binder->getSubExpr(); 919 920 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 921 E = ICE->getSubExprAsWritten(); 922 return E->IgnoreParens(); 923 } 924 925 static Expr *getExprAsWritten(Expr *E) { 926 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 927 } 928 929 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 930 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 931 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 932 D = ME->getMemberDecl(); 933 const auto *VD = dyn_cast<VarDecl>(D); 934 const auto *FD = dyn_cast<FieldDecl>(D); 935 if (VD != nullptr) { 936 VD = VD->getCanonicalDecl(); 937 D = VD; 938 } else { 939 assert(FD); 940 FD = FD->getCanonicalDecl(); 941 D = FD; 942 } 943 return D; 944 } 945 946 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 947 return const_cast<ValueDecl *>( 948 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 949 } 950 951 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 952 ValueDecl *D) const { 953 D = getCanonicalDecl(D); 954 auto *VD = dyn_cast<VarDecl>(D); 955 const auto *FD = dyn_cast<FieldDecl>(D); 956 DSAVarData DVar; 957 if (Iter == end()) { 958 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 959 // in a region but not in construct] 960 // File-scope or namespace-scope variables referenced in called routines 961 // in the region are shared unless they appear in a threadprivate 962 // directive. 963 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 964 DVar.CKind = OMPC_shared; 965 966 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 967 // in a region but not in construct] 968 // Variables with static storage duration that are declared in called 969 // routines in the region are shared. 970 if (VD && VD->hasGlobalStorage()) 971 DVar.CKind = OMPC_shared; 972 973 // Non-static data members are shared by default. 974 if (FD) 975 DVar.CKind = OMPC_shared; 976 977 return DVar; 978 } 979 980 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 981 // in a Construct, C/C++, predetermined, p.1] 982 // Variables with automatic storage duration that are declared in a scope 983 // inside the construct are private. 984 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 985 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 986 DVar.CKind = OMPC_private; 987 return DVar; 988 } 989 990 DVar.DKind = Iter->Directive; 991 // Explicitly specified attributes and local variables with predetermined 992 // attributes. 993 if (Iter->SharingMap.count(D)) { 994 const DSAInfo &Data = Iter->SharingMap.lookup(D); 995 DVar.RefExpr = Data.RefExpr.getPointer(); 996 DVar.PrivateCopy = Data.PrivateCopy; 997 DVar.CKind = Data.Attributes; 998 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 999 return DVar; 1000 } 1001 1002 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1003 // in a Construct, C/C++, implicitly determined, p.1] 1004 // In a parallel or task construct, the data-sharing attributes of these 1005 // variables are determined by the default clause, if present. 1006 switch (Iter->DefaultAttr) { 1007 case DSA_shared: 1008 DVar.CKind = OMPC_shared; 1009 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1010 return DVar; 1011 case DSA_none: 1012 return DVar; 1013 case DSA_unspecified: 1014 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1015 // in a Construct, implicitly determined, p.2] 1016 // In a parallel construct, if no default clause is present, these 1017 // variables are shared. 1018 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1019 if ((isOpenMPParallelDirective(DVar.DKind) && 1020 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1021 isOpenMPTeamsDirective(DVar.DKind)) { 1022 DVar.CKind = OMPC_shared; 1023 return DVar; 1024 } 1025 1026 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1027 // in a Construct, implicitly determined, p.4] 1028 // In a task construct, if no default clause is present, a variable that in 1029 // the enclosing context is determined to be shared by all implicit tasks 1030 // bound to the current team is shared. 1031 if (isOpenMPTaskingDirective(DVar.DKind)) { 1032 DSAVarData DVarTemp; 1033 const_iterator I = Iter, E = end(); 1034 do { 1035 ++I; 1036 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1037 // Referenced in a Construct, implicitly determined, p.6] 1038 // In a task construct, if no default clause is present, a variable 1039 // whose data-sharing attribute is not determined by the rules above is 1040 // firstprivate. 1041 DVarTemp = getDSA(I, D); 1042 if (DVarTemp.CKind != OMPC_shared) { 1043 DVar.RefExpr = nullptr; 1044 DVar.CKind = OMPC_firstprivate; 1045 return DVar; 1046 } 1047 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1048 DVar.CKind = 1049 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1050 return DVar; 1051 } 1052 } 1053 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1054 // in a Construct, implicitly determined, p.3] 1055 // For constructs other than task, if no default clause is present, these 1056 // variables inherit their data-sharing attributes from the enclosing 1057 // context. 1058 return getDSA(++Iter, D); 1059 } 1060 1061 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1062 const Expr *NewDE) { 1063 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1064 D = getCanonicalDecl(D); 1065 SharingMapTy &StackElem = getTopOfStack(); 1066 auto It = StackElem.AlignedMap.find(D); 1067 if (It == StackElem.AlignedMap.end()) { 1068 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1069 StackElem.AlignedMap[D] = NewDE; 1070 return nullptr; 1071 } 1072 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1073 return It->second; 1074 } 1075 1076 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1077 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1078 D = getCanonicalDecl(D); 1079 SharingMapTy &StackElem = getTopOfStack(); 1080 StackElem.LCVMap.try_emplace( 1081 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1082 } 1083 1084 const DSAStackTy::LCDeclInfo 1085 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1086 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1087 D = getCanonicalDecl(D); 1088 const SharingMapTy &StackElem = getTopOfStack(); 1089 auto It = StackElem.LCVMap.find(D); 1090 if (It != StackElem.LCVMap.end()) 1091 return It->second; 1092 return {0, nullptr}; 1093 } 1094 1095 const DSAStackTy::LCDeclInfo 1096 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1097 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1098 assert(Parent && "Data-sharing attributes stack is empty"); 1099 D = getCanonicalDecl(D); 1100 auto It = Parent->LCVMap.find(D); 1101 if (It != Parent->LCVMap.end()) 1102 return It->second; 1103 return {0, nullptr}; 1104 } 1105 1106 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1107 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1108 assert(Parent && "Data-sharing attributes stack is empty"); 1109 if (Parent->LCVMap.size() < I) 1110 return nullptr; 1111 for (const auto &Pair : Parent->LCVMap) 1112 if (Pair.second.first == I) 1113 return Pair.first; 1114 return nullptr; 1115 } 1116 1117 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1118 DeclRefExpr *PrivateCopy) { 1119 D = getCanonicalDecl(D); 1120 if (A == OMPC_threadprivate) { 1121 DSAInfo &Data = Threadprivates[D]; 1122 Data.Attributes = A; 1123 Data.RefExpr.setPointer(E); 1124 Data.PrivateCopy = nullptr; 1125 } else { 1126 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1127 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1128 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1129 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1130 (isLoopControlVariable(D).first && A == OMPC_private)); 1131 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1132 Data.RefExpr.setInt(/*IntVal=*/true); 1133 return; 1134 } 1135 const bool IsLastprivate = 1136 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1137 Data.Attributes = A; 1138 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1139 Data.PrivateCopy = PrivateCopy; 1140 if (PrivateCopy) { 1141 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1142 Data.Attributes = A; 1143 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1144 Data.PrivateCopy = nullptr; 1145 } 1146 } 1147 } 1148 1149 /// Build a variable declaration for OpenMP loop iteration variable. 1150 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1151 StringRef Name, const AttrVec *Attrs = nullptr, 1152 DeclRefExpr *OrigRef = nullptr) { 1153 DeclContext *DC = SemaRef.CurContext; 1154 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1155 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1156 auto *Decl = 1157 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1158 if (Attrs) { 1159 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1160 I != E; ++I) 1161 Decl->addAttr(*I); 1162 } 1163 Decl->setImplicit(); 1164 if (OrigRef) { 1165 Decl->addAttr( 1166 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1167 } 1168 return Decl; 1169 } 1170 1171 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1172 SourceLocation Loc, 1173 bool RefersToCapture = false) { 1174 D->setReferenced(); 1175 D->markUsed(S.Context); 1176 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1177 SourceLocation(), D, RefersToCapture, Loc, Ty, 1178 VK_LValue); 1179 } 1180 1181 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1182 BinaryOperatorKind BOK) { 1183 D = getCanonicalDecl(D); 1184 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1185 assert( 1186 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1187 "Additional reduction info may be specified only for reduction items."); 1188 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1189 assert(ReductionData.ReductionRange.isInvalid() && 1190 getTopOfStack().Directive == OMPD_taskgroup && 1191 "Additional reduction info may be specified only once for reduction " 1192 "items."); 1193 ReductionData.set(BOK, SR); 1194 Expr *&TaskgroupReductionRef = 1195 getTopOfStack().TaskgroupReductionRef; 1196 if (!TaskgroupReductionRef) { 1197 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1198 SemaRef.Context.VoidPtrTy, ".task_red."); 1199 TaskgroupReductionRef = 1200 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1201 } 1202 } 1203 1204 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1205 const Expr *ReductionRef) { 1206 D = getCanonicalDecl(D); 1207 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1208 assert( 1209 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1210 "Additional reduction info may be specified only for reduction items."); 1211 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1212 assert(ReductionData.ReductionRange.isInvalid() && 1213 getTopOfStack().Directive == OMPD_taskgroup && 1214 "Additional reduction info may be specified only once for reduction " 1215 "items."); 1216 ReductionData.set(ReductionRef, SR); 1217 Expr *&TaskgroupReductionRef = 1218 getTopOfStack().TaskgroupReductionRef; 1219 if (!TaskgroupReductionRef) { 1220 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1221 SemaRef.Context.VoidPtrTy, ".task_red."); 1222 TaskgroupReductionRef = 1223 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1224 } 1225 } 1226 1227 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1228 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1229 Expr *&TaskgroupDescriptor) const { 1230 D = getCanonicalDecl(D); 1231 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1232 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1233 const DSAInfo &Data = I->SharingMap.lookup(D); 1234 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1235 continue; 1236 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1237 if (!ReductionData.ReductionOp || 1238 ReductionData.ReductionOp.is<const Expr *>()) 1239 return DSAVarData(); 1240 SR = ReductionData.ReductionRange; 1241 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1242 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1243 "expression for the descriptor is not " 1244 "set."); 1245 TaskgroupDescriptor = I->TaskgroupReductionRef; 1246 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1247 Data.PrivateCopy, I->DefaultAttrLoc); 1248 } 1249 return DSAVarData(); 1250 } 1251 1252 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1253 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1254 Expr *&TaskgroupDescriptor) const { 1255 D = getCanonicalDecl(D); 1256 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1257 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1258 const DSAInfo &Data = I->SharingMap.lookup(D); 1259 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1260 continue; 1261 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1262 if (!ReductionData.ReductionOp || 1263 !ReductionData.ReductionOp.is<const Expr *>()) 1264 return DSAVarData(); 1265 SR = ReductionData.ReductionRange; 1266 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1267 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1268 "expression for the descriptor is not " 1269 "set."); 1270 TaskgroupDescriptor = I->TaskgroupReductionRef; 1271 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1272 Data.PrivateCopy, I->DefaultAttrLoc); 1273 } 1274 return DSAVarData(); 1275 } 1276 1277 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1278 D = D->getCanonicalDecl(); 1279 for (const_iterator E = end(); I != E; ++I) { 1280 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1281 isOpenMPTargetExecutionDirective(I->Directive)) { 1282 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1283 Scope *CurScope = getCurScope(); 1284 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1285 CurScope = CurScope->getParent(); 1286 return CurScope != TopScope; 1287 } 1288 } 1289 return false; 1290 } 1291 1292 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1293 bool AcceptIfMutable = true, 1294 bool *IsClassType = nullptr) { 1295 ASTContext &Context = SemaRef.getASTContext(); 1296 Type = Type.getNonReferenceType().getCanonicalType(); 1297 bool IsConstant = Type.isConstant(Context); 1298 Type = Context.getBaseElementType(Type); 1299 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1300 ? Type->getAsCXXRecordDecl() 1301 : nullptr; 1302 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1303 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1304 RD = CTD->getTemplatedDecl(); 1305 if (IsClassType) 1306 *IsClassType = RD; 1307 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1308 RD->hasDefinition() && RD->hasMutableFields()); 1309 } 1310 1311 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1312 QualType Type, OpenMPClauseKind CKind, 1313 SourceLocation ELoc, 1314 bool AcceptIfMutable = true, 1315 bool ListItemNotVar = false) { 1316 ASTContext &Context = SemaRef.getASTContext(); 1317 bool IsClassType; 1318 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1319 unsigned Diag = ListItemNotVar 1320 ? diag::err_omp_const_list_item 1321 : IsClassType ? diag::err_omp_const_not_mutable_variable 1322 : diag::err_omp_const_variable; 1323 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1324 if (!ListItemNotVar && D) { 1325 const VarDecl *VD = dyn_cast<VarDecl>(D); 1326 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1327 VarDecl::DeclarationOnly; 1328 SemaRef.Diag(D->getLocation(), 1329 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1330 << D; 1331 } 1332 return true; 1333 } 1334 return false; 1335 } 1336 1337 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1338 bool FromParent) { 1339 D = getCanonicalDecl(D); 1340 DSAVarData DVar; 1341 1342 auto *VD = dyn_cast<VarDecl>(D); 1343 auto TI = Threadprivates.find(D); 1344 if (TI != Threadprivates.end()) { 1345 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1346 DVar.CKind = OMPC_threadprivate; 1347 return DVar; 1348 } 1349 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1350 DVar.RefExpr = buildDeclRefExpr( 1351 SemaRef, VD, D->getType().getNonReferenceType(), 1352 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1353 DVar.CKind = OMPC_threadprivate; 1354 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1355 return DVar; 1356 } 1357 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1358 // in a Construct, C/C++, predetermined, p.1] 1359 // Variables appearing in threadprivate directives are threadprivate. 1360 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1361 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1362 SemaRef.getLangOpts().OpenMPUseTLS && 1363 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1364 (VD && VD->getStorageClass() == SC_Register && 1365 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1366 DVar.RefExpr = buildDeclRefExpr( 1367 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1368 DVar.CKind = OMPC_threadprivate; 1369 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1370 return DVar; 1371 } 1372 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1373 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1374 !isLoopControlVariable(D).first) { 1375 const_iterator IterTarget = 1376 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1377 return isOpenMPTargetExecutionDirective(Data.Directive); 1378 }); 1379 if (IterTarget != end()) { 1380 const_iterator ParentIterTarget = IterTarget + 1; 1381 for (const_iterator Iter = begin(); 1382 Iter != ParentIterTarget; ++Iter) { 1383 if (isOpenMPLocal(VD, Iter)) { 1384 DVar.RefExpr = 1385 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1386 D->getLocation()); 1387 DVar.CKind = OMPC_threadprivate; 1388 return DVar; 1389 } 1390 } 1391 if (!isClauseParsingMode() || IterTarget != begin()) { 1392 auto DSAIter = IterTarget->SharingMap.find(D); 1393 if (DSAIter != IterTarget->SharingMap.end() && 1394 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1395 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1396 DVar.CKind = OMPC_threadprivate; 1397 return DVar; 1398 } 1399 const_iterator End = end(); 1400 if (!SemaRef.isOpenMPCapturedByRef( 1401 D, std::distance(ParentIterTarget, End), 1402 /*OpenMPCaptureLevel=*/0)) { 1403 DVar.RefExpr = 1404 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1405 IterTarget->ConstructLoc); 1406 DVar.CKind = OMPC_threadprivate; 1407 return DVar; 1408 } 1409 } 1410 } 1411 } 1412 1413 if (isStackEmpty()) 1414 // Not in OpenMP execution region and top scope was already checked. 1415 return DVar; 1416 1417 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1418 // in a Construct, C/C++, predetermined, p.4] 1419 // Static data members are shared. 1420 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1421 // in a Construct, C/C++, predetermined, p.7] 1422 // Variables with static storage duration that are declared in a scope 1423 // inside the construct are shared. 1424 if (VD && VD->isStaticDataMember()) { 1425 // Check for explicitly specified attributes. 1426 const_iterator I = begin(); 1427 const_iterator EndI = end(); 1428 if (FromParent && I != EndI) 1429 ++I; 1430 auto It = I->SharingMap.find(D); 1431 if (It != I->SharingMap.end()) { 1432 const DSAInfo &Data = It->getSecond(); 1433 DVar.RefExpr = Data.RefExpr.getPointer(); 1434 DVar.PrivateCopy = Data.PrivateCopy; 1435 DVar.CKind = Data.Attributes; 1436 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1437 DVar.DKind = I->Directive; 1438 return DVar; 1439 } 1440 1441 DVar.CKind = OMPC_shared; 1442 return DVar; 1443 } 1444 1445 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1446 // The predetermined shared attribute for const-qualified types having no 1447 // mutable members was removed after OpenMP 3.1. 1448 if (SemaRef.LangOpts.OpenMP <= 31) { 1449 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1450 // in a Construct, C/C++, predetermined, p.6] 1451 // Variables with const qualified type having no mutable member are 1452 // shared. 1453 if (isConstNotMutableType(SemaRef, D->getType())) { 1454 // Variables with const-qualified type having no mutable member may be 1455 // listed in a firstprivate clause, even if they are static data members. 1456 DSAVarData DVarTemp = hasInnermostDSA( 1457 D, 1458 [](OpenMPClauseKind C) { 1459 return C == OMPC_firstprivate || C == OMPC_shared; 1460 }, 1461 MatchesAlways, FromParent); 1462 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1463 return DVarTemp; 1464 1465 DVar.CKind = OMPC_shared; 1466 return DVar; 1467 } 1468 } 1469 1470 // Explicitly specified attributes and local variables with predetermined 1471 // attributes. 1472 const_iterator I = begin(); 1473 const_iterator EndI = end(); 1474 if (FromParent && I != EndI) 1475 ++I; 1476 auto It = I->SharingMap.find(D); 1477 if (It != I->SharingMap.end()) { 1478 const DSAInfo &Data = It->getSecond(); 1479 DVar.RefExpr = Data.RefExpr.getPointer(); 1480 DVar.PrivateCopy = Data.PrivateCopy; 1481 DVar.CKind = Data.Attributes; 1482 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1483 DVar.DKind = I->Directive; 1484 } 1485 1486 return DVar; 1487 } 1488 1489 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1490 bool FromParent) const { 1491 if (isStackEmpty()) { 1492 const_iterator I; 1493 return getDSA(I, D); 1494 } 1495 D = getCanonicalDecl(D); 1496 const_iterator StartI = begin(); 1497 const_iterator EndI = end(); 1498 if (FromParent && StartI != EndI) 1499 ++StartI; 1500 return getDSA(StartI, D); 1501 } 1502 1503 const DSAStackTy::DSAVarData 1504 DSAStackTy::hasDSA(ValueDecl *D, 1505 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1506 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1507 bool FromParent) const { 1508 if (isStackEmpty()) 1509 return {}; 1510 D = getCanonicalDecl(D); 1511 const_iterator I = begin(); 1512 const_iterator EndI = end(); 1513 if (FromParent && I != EndI) 1514 ++I; 1515 for (; I != EndI; ++I) { 1516 if (!DPred(I->Directive) && 1517 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1518 continue; 1519 const_iterator NewI = I; 1520 DSAVarData DVar = getDSA(NewI, D); 1521 if (I == NewI && CPred(DVar.CKind)) 1522 return DVar; 1523 } 1524 return {}; 1525 } 1526 1527 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1528 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1529 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1530 bool FromParent) const { 1531 if (isStackEmpty()) 1532 return {}; 1533 D = getCanonicalDecl(D); 1534 const_iterator StartI = begin(); 1535 const_iterator EndI = end(); 1536 if (FromParent && StartI != EndI) 1537 ++StartI; 1538 if (StartI == EndI || !DPred(StartI->Directive)) 1539 return {}; 1540 const_iterator NewI = StartI; 1541 DSAVarData DVar = getDSA(NewI, D); 1542 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1543 } 1544 1545 bool DSAStackTy::hasExplicitDSA( 1546 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1547 unsigned Level, bool NotLastprivate) const { 1548 if (getStackSize() <= Level) 1549 return false; 1550 D = getCanonicalDecl(D); 1551 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1552 auto I = StackElem.SharingMap.find(D); 1553 if (I != StackElem.SharingMap.end() && 1554 I->getSecond().RefExpr.getPointer() && 1555 CPred(I->getSecond().Attributes) && 1556 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1557 return true; 1558 // Check predetermined rules for the loop control variables. 1559 auto LI = StackElem.LCVMap.find(D); 1560 if (LI != StackElem.LCVMap.end()) 1561 return CPred(OMPC_private); 1562 return false; 1563 } 1564 1565 bool DSAStackTy::hasExplicitDirective( 1566 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1567 unsigned Level) const { 1568 if (getStackSize() <= Level) 1569 return false; 1570 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1571 return DPred(StackElem.Directive); 1572 } 1573 1574 bool DSAStackTy::hasDirective( 1575 const llvm::function_ref<bool(OpenMPDirectiveKind, 1576 const DeclarationNameInfo &, SourceLocation)> 1577 DPred, 1578 bool FromParent) const { 1579 // We look only in the enclosing region. 1580 size_t Skip = FromParent ? 2 : 1; 1581 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1582 I != E; ++I) { 1583 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1584 return true; 1585 } 1586 return false; 1587 } 1588 1589 void Sema::InitDataSharingAttributesStack() { 1590 VarDataSharingAttributesStack = new DSAStackTy(*this); 1591 } 1592 1593 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1594 1595 void Sema::pushOpenMPFunctionRegion() { 1596 DSAStack->pushFunction(); 1597 } 1598 1599 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1600 DSAStack->popFunction(OldFSI); 1601 } 1602 1603 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1604 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1605 "Expected OpenMP device compilation."); 1606 return !S.isInOpenMPTargetExecutionDirective() && 1607 !S.isInOpenMPDeclareTargetContext(); 1608 } 1609 1610 namespace { 1611 /// Status of the function emission on the host/device. 1612 enum class FunctionEmissionStatus { 1613 Emitted, 1614 Discarded, 1615 Unknown, 1616 }; 1617 } // anonymous namespace 1618 1619 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1620 unsigned DiagID) { 1621 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1622 "Expected OpenMP device compilation."); 1623 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1624 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1625 switch (FES) { 1626 case FunctionEmissionStatus::Emitted: 1627 Kind = DeviceDiagBuilder::K_Immediate; 1628 break; 1629 case FunctionEmissionStatus::Unknown: 1630 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1631 : DeviceDiagBuilder::K_Immediate; 1632 break; 1633 case FunctionEmissionStatus::TemplateDiscarded: 1634 case FunctionEmissionStatus::OMPDiscarded: 1635 Kind = DeviceDiagBuilder::K_Nop; 1636 break; 1637 case FunctionEmissionStatus::CUDADiscarded: 1638 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1639 break; 1640 } 1641 1642 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1643 } 1644 1645 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1646 unsigned DiagID) { 1647 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1648 "Expected OpenMP host compilation."); 1649 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1650 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1651 switch (FES) { 1652 case FunctionEmissionStatus::Emitted: 1653 Kind = DeviceDiagBuilder::K_Immediate; 1654 break; 1655 case FunctionEmissionStatus::Unknown: 1656 Kind = DeviceDiagBuilder::K_Deferred; 1657 break; 1658 case FunctionEmissionStatus::TemplateDiscarded: 1659 case FunctionEmissionStatus::OMPDiscarded: 1660 case FunctionEmissionStatus::CUDADiscarded: 1661 Kind = DeviceDiagBuilder::K_Nop; 1662 break; 1663 } 1664 1665 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1666 } 1667 1668 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1669 bool CheckForDelayedContext) { 1670 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1671 "Expected OpenMP device compilation."); 1672 assert(Callee && "Callee may not be null."); 1673 Callee = Callee->getMostRecentDecl(); 1674 FunctionDecl *Caller = getCurFunctionDecl(); 1675 1676 // host only function are not available on the device. 1677 if (Caller) { 1678 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1679 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1680 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1681 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1682 "CUDADiscarded unexpected in OpenMP device function check"); 1683 if ((CallerS == FunctionEmissionStatus::Emitted || 1684 (!isOpenMPDeviceDelayedContext(*this) && 1685 CallerS == FunctionEmissionStatus::Unknown)) && 1686 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1687 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1688 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1689 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1690 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1691 diag::note_omp_marked_device_type_here) 1692 << HostDevTy; 1693 return; 1694 } 1695 } 1696 // If the caller is known-emitted, mark the callee as known-emitted. 1697 // Otherwise, mark the call in our call graph so we can traverse it later. 1698 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1699 (!Caller && !CheckForDelayedContext) || 1700 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1701 markKnownEmitted(*this, Caller, Callee, Loc, 1702 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1703 return CheckForDelayedContext && 1704 S.getEmissionStatus(FD) == 1705 FunctionEmissionStatus::Emitted; 1706 }); 1707 else if (Caller) 1708 DeviceCallGraph[Caller].insert({Callee, Loc}); 1709 } 1710 1711 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1712 bool CheckCaller) { 1713 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1714 "Expected OpenMP host compilation."); 1715 assert(Callee && "Callee may not be null."); 1716 Callee = Callee->getMostRecentDecl(); 1717 FunctionDecl *Caller = getCurFunctionDecl(); 1718 1719 // device only function are not available on the host. 1720 if (Caller) { 1721 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1722 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1723 assert( 1724 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1725 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1726 "CUDADiscarded unexpected in OpenMP host function check"); 1727 if (CallerS == FunctionEmissionStatus::Emitted && 1728 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1729 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1730 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1731 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1732 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1733 diag::note_omp_marked_device_type_here) 1734 << NoHostDevTy; 1735 return; 1736 } 1737 } 1738 // If the caller is known-emitted, mark the callee as known-emitted. 1739 // Otherwise, mark the call in our call graph so we can traverse it later. 1740 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1741 if ((!CheckCaller && !Caller) || 1742 (Caller && 1743 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1744 markKnownEmitted( 1745 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1746 return CheckCaller && 1747 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1748 }); 1749 else if (Caller) 1750 DeviceCallGraph[Caller].insert({Callee, Loc}); 1751 } 1752 } 1753 1754 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1755 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1756 "OpenMP device compilation mode is expected."); 1757 QualType Ty = E->getType(); 1758 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1759 ((Ty->isFloat128Type() || 1760 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1761 !Context.getTargetInfo().hasFloat128Type()) || 1762 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1763 !Context.getTargetInfo().hasInt128Type())) 1764 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1765 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1766 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1767 } 1768 1769 static OpenMPDefaultmapClauseKind 1770 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1771 if (LO.OpenMP <= 45) { 1772 if (VD->getType().getNonReferenceType()->isScalarType()) 1773 return OMPC_DEFAULTMAP_scalar; 1774 return OMPC_DEFAULTMAP_aggregate; 1775 } 1776 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1777 return OMPC_DEFAULTMAP_pointer; 1778 if (VD->getType().getNonReferenceType()->isScalarType()) 1779 return OMPC_DEFAULTMAP_scalar; 1780 return OMPC_DEFAULTMAP_aggregate; 1781 } 1782 1783 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1784 unsigned OpenMPCaptureLevel) const { 1785 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1786 1787 ASTContext &Ctx = getASTContext(); 1788 bool IsByRef = true; 1789 1790 // Find the directive that is associated with the provided scope. 1791 D = cast<ValueDecl>(D->getCanonicalDecl()); 1792 QualType Ty = D->getType(); 1793 1794 bool IsVariableUsedInMapClause = false; 1795 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1796 // This table summarizes how a given variable should be passed to the device 1797 // given its type and the clauses where it appears. This table is based on 1798 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1799 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1800 // 1801 // ========================================================================= 1802 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1803 // | |(tofrom:scalar)| | pvt | | | | 1804 // ========================================================================= 1805 // | scl | | | | - | | bycopy| 1806 // | scl | | - | x | - | - | bycopy| 1807 // | scl | | x | - | - | - | null | 1808 // | scl | x | | | - | | byref | 1809 // | scl | x | - | x | - | - | bycopy| 1810 // | scl | x | x | - | - | - | null | 1811 // | scl | | - | - | - | x | byref | 1812 // | scl | x | - | - | - | x | byref | 1813 // 1814 // | agg | n.a. | | | - | | byref | 1815 // | agg | n.a. | - | x | - | - | byref | 1816 // | agg | n.a. | x | - | - | - | null | 1817 // | agg | n.a. | - | - | - | x | byref | 1818 // | agg | n.a. | - | - | - | x[] | byref | 1819 // 1820 // | ptr | n.a. | | | - | | bycopy| 1821 // | ptr | n.a. | - | x | - | - | bycopy| 1822 // | ptr | n.a. | x | - | - | - | null | 1823 // | ptr | n.a. | - | - | - | x | byref | 1824 // | ptr | n.a. | - | - | - | x[] | bycopy| 1825 // | ptr | n.a. | - | - | x | | bycopy| 1826 // | ptr | n.a. | - | - | x | x | bycopy| 1827 // | ptr | n.a. | - | - | x | x[] | bycopy| 1828 // ========================================================================= 1829 // Legend: 1830 // scl - scalar 1831 // ptr - pointer 1832 // agg - aggregate 1833 // x - applies 1834 // - - invalid in this combination 1835 // [] - mapped with an array section 1836 // byref - should be mapped by reference 1837 // byval - should be mapped by value 1838 // null - initialize a local variable to null on the device 1839 // 1840 // Observations: 1841 // - All scalar declarations that show up in a map clause have to be passed 1842 // by reference, because they may have been mapped in the enclosing data 1843 // environment. 1844 // - If the scalar value does not fit the size of uintptr, it has to be 1845 // passed by reference, regardless the result in the table above. 1846 // - For pointers mapped by value that have either an implicit map or an 1847 // array section, the runtime library may pass the NULL value to the 1848 // device instead of the value passed to it by the compiler. 1849 1850 if (Ty->isReferenceType()) 1851 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1852 1853 // Locate map clauses and see if the variable being captured is referred to 1854 // in any of those clauses. Here we only care about variables, not fields, 1855 // because fields are part of aggregates. 1856 bool IsVariableAssociatedWithSection = false; 1857 1858 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1859 D, Level, 1860 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1861 OMPClauseMappableExprCommon::MappableExprComponentListRef 1862 MapExprComponents, 1863 OpenMPClauseKind WhereFoundClauseKind) { 1864 // Only the map clause information influences how a variable is 1865 // captured. E.g. is_device_ptr does not require changing the default 1866 // behavior. 1867 if (WhereFoundClauseKind != OMPC_map) 1868 return false; 1869 1870 auto EI = MapExprComponents.rbegin(); 1871 auto EE = MapExprComponents.rend(); 1872 1873 assert(EI != EE && "Invalid map expression!"); 1874 1875 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1876 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1877 1878 ++EI; 1879 if (EI == EE) 1880 return false; 1881 1882 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1883 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1884 isa<MemberExpr>(EI->getAssociatedExpression())) { 1885 IsVariableAssociatedWithSection = true; 1886 // There is nothing more we need to know about this variable. 1887 return true; 1888 } 1889 1890 // Keep looking for more map info. 1891 return false; 1892 }); 1893 1894 if (IsVariableUsedInMapClause) { 1895 // If variable is identified in a map clause it is always captured by 1896 // reference except if it is a pointer that is dereferenced somehow. 1897 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1898 } else { 1899 // By default, all the data that has a scalar type is mapped by copy 1900 // (except for reduction variables). 1901 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1902 IsByRef = 1903 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1904 !Ty->isAnyPointerType()) || 1905 !Ty->isScalarType() || 1906 DSAStack->isDefaultmapCapturedByRef( 1907 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1908 DSAStack->hasExplicitDSA( 1909 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1910 } 1911 } 1912 1913 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1914 IsByRef = 1915 ((IsVariableUsedInMapClause && 1916 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1917 OMPD_target) || 1918 !DSAStack->hasExplicitDSA( 1919 D, 1920 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1921 Level, /*NotLastprivate=*/true)) && 1922 // If the variable is artificial and must be captured by value - try to 1923 // capture by value. 1924 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1925 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1926 } 1927 1928 // When passing data by copy, we need to make sure it fits the uintptr size 1929 // and alignment, because the runtime library only deals with uintptr types. 1930 // If it does not fit the uintptr size, we need to pass the data by reference 1931 // instead. 1932 if (!IsByRef && 1933 (Ctx.getTypeSizeInChars(Ty) > 1934 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1935 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1936 IsByRef = true; 1937 } 1938 1939 return IsByRef; 1940 } 1941 1942 unsigned Sema::getOpenMPNestingLevel() const { 1943 assert(getLangOpts().OpenMP); 1944 return DSAStack->getNestingLevel(); 1945 } 1946 1947 bool Sema::isInOpenMPTargetExecutionDirective() const { 1948 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1949 !DSAStack->isClauseParsingMode()) || 1950 DSAStack->hasDirective( 1951 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1952 SourceLocation) -> bool { 1953 return isOpenMPTargetExecutionDirective(K); 1954 }, 1955 false); 1956 } 1957 1958 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1959 unsigned StopAt) { 1960 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1961 D = getCanonicalDecl(D); 1962 1963 auto *VD = dyn_cast<VarDecl>(D); 1964 // Do not capture constexpr variables. 1965 if (VD && VD->isConstexpr()) 1966 return nullptr; 1967 1968 // If we want to determine whether the variable should be captured from the 1969 // perspective of the current capturing scope, and we've already left all the 1970 // capturing scopes of the top directive on the stack, check from the 1971 // perspective of its parent directive (if any) instead. 1972 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1973 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1974 1975 // If we are attempting to capture a global variable in a directive with 1976 // 'target' we return true so that this global is also mapped to the device. 1977 // 1978 if (VD && !VD->hasLocalStorage() && 1979 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1980 if (isInOpenMPDeclareTargetContext()) { 1981 // Try to mark variable as declare target if it is used in capturing 1982 // regions. 1983 if (LangOpts.OpenMP <= 45 && 1984 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1985 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1986 return nullptr; 1987 } else if (isInOpenMPTargetExecutionDirective()) { 1988 // If the declaration is enclosed in a 'declare target' directive, 1989 // then it should not be captured. 1990 // 1991 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1992 return nullptr; 1993 return VD; 1994 } 1995 } 1996 1997 if (CheckScopeInfo) { 1998 bool OpenMPFound = false; 1999 for (unsigned I = StopAt + 1; I > 0; --I) { 2000 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2001 if(!isa<CapturingScopeInfo>(FSI)) 2002 return nullptr; 2003 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2004 if (RSI->CapRegionKind == CR_OpenMP) { 2005 OpenMPFound = true; 2006 break; 2007 } 2008 } 2009 if (!OpenMPFound) 2010 return nullptr; 2011 } 2012 2013 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2014 (!DSAStack->isClauseParsingMode() || 2015 DSAStack->getParentDirective() != OMPD_unknown)) { 2016 auto &&Info = DSAStack->isLoopControlVariable(D); 2017 if (Info.first || 2018 (VD && VD->hasLocalStorage() && 2019 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2020 (VD && DSAStack->isForceVarCapturing())) 2021 return VD ? VD : Info.second; 2022 DSAStackTy::DSAVarData DVarPrivate = 2023 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2024 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2025 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2026 // Threadprivate variables must not be captured. 2027 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2028 return nullptr; 2029 // The variable is not private or it is the variable in the directive with 2030 // default(none) clause and not used in any clause. 2031 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2032 [](OpenMPDirectiveKind) { return true; }, 2033 DSAStack->isClauseParsingMode()); 2034 if (DVarPrivate.CKind != OMPC_unknown || 2035 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2036 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2037 } 2038 return nullptr; 2039 } 2040 2041 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2042 unsigned Level) const { 2043 SmallVector<OpenMPDirectiveKind, 4> Regions; 2044 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2045 FunctionScopesIndex -= Regions.size(); 2046 } 2047 2048 void Sema::startOpenMPLoop() { 2049 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2050 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2051 DSAStack->loopInit(); 2052 } 2053 2054 void Sema::startOpenMPCXXRangeFor() { 2055 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2056 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2057 DSAStack->resetPossibleLoopCounter(); 2058 DSAStack->loopStart(); 2059 } 2060 } 2061 2062 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2063 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2064 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2065 if (DSAStack->getAssociatedLoops() > 0 && 2066 !DSAStack->isLoopStarted()) { 2067 DSAStack->resetPossibleLoopCounter(D); 2068 DSAStack->loopStart(); 2069 return true; 2070 } 2071 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2072 DSAStack->isLoopControlVariable(D).first) && 2073 !DSAStack->hasExplicitDSA( 2074 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2075 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2076 return true; 2077 } 2078 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2079 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2080 DSAStack->isForceVarCapturing() && 2081 !DSAStack->hasExplicitDSA( 2082 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2083 return true; 2084 } 2085 return DSAStack->hasExplicitDSA( 2086 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2087 (DSAStack->isClauseParsingMode() && 2088 DSAStack->getClauseParsingMode() == OMPC_private) || 2089 // Consider taskgroup reduction descriptor variable a private to avoid 2090 // possible capture in the region. 2091 (DSAStack->hasExplicitDirective( 2092 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2093 Level) && 2094 DSAStack->isTaskgroupReductionRef(D, Level)); 2095 } 2096 2097 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2098 unsigned Level) { 2099 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2100 D = getCanonicalDecl(D); 2101 OpenMPClauseKind OMPC = OMPC_unknown; 2102 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2103 const unsigned NewLevel = I - 1; 2104 if (DSAStack->hasExplicitDSA(D, 2105 [&OMPC](const OpenMPClauseKind K) { 2106 if (isOpenMPPrivate(K)) { 2107 OMPC = K; 2108 return true; 2109 } 2110 return false; 2111 }, 2112 NewLevel)) 2113 break; 2114 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2115 D, NewLevel, 2116 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2117 OpenMPClauseKind) { return true; })) { 2118 OMPC = OMPC_map; 2119 break; 2120 } 2121 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2122 NewLevel)) { 2123 OMPC = OMPC_map; 2124 if (DSAStack->mustBeFirstprivateAtLevel( 2125 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2126 OMPC = OMPC_firstprivate; 2127 break; 2128 } 2129 } 2130 if (OMPC != OMPC_unknown) 2131 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2132 } 2133 2134 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2135 unsigned Level) const { 2136 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2137 // Return true if the current level is no longer enclosed in a target region. 2138 2139 const auto *VD = dyn_cast<VarDecl>(D); 2140 return VD && !VD->hasLocalStorage() && 2141 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2142 Level); 2143 } 2144 2145 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2146 2147 void Sema::finalizeOpenMPDelayedAnalysis() { 2148 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2149 // Diagnose implicit declare target functions and their callees. 2150 for (const auto &CallerCallees : DeviceCallGraph) { 2151 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2152 OMPDeclareTargetDeclAttr::getDeviceType( 2153 CallerCallees.getFirst()->getMostRecentDecl()); 2154 // Ignore host functions during device analyzis. 2155 if (LangOpts.OpenMPIsDevice && DevTy && 2156 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2157 continue; 2158 // Ignore nohost functions during host analyzis. 2159 if (!LangOpts.OpenMPIsDevice && DevTy && 2160 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2161 continue; 2162 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2163 &Callee : CallerCallees.getSecond()) { 2164 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2165 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2166 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2167 if (LangOpts.OpenMPIsDevice && DevTy && 2168 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2169 // Diagnose host function called during device codegen. 2170 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2171 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2172 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2173 << HostDevTy << 0; 2174 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2175 diag::note_omp_marked_device_type_here) 2176 << HostDevTy; 2177 continue; 2178 } 2179 if (!LangOpts.OpenMPIsDevice && DevTy && 2180 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2181 // Diagnose nohost function called during host codegen. 2182 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2183 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2184 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2185 << NoHostDevTy << 1; 2186 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2187 diag::note_omp_marked_device_type_here) 2188 << NoHostDevTy; 2189 continue; 2190 } 2191 } 2192 } 2193 } 2194 2195 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2196 const DeclarationNameInfo &DirName, 2197 Scope *CurScope, SourceLocation Loc) { 2198 DSAStack->push(DKind, DirName, CurScope, Loc); 2199 PushExpressionEvaluationContext( 2200 ExpressionEvaluationContext::PotentiallyEvaluated); 2201 } 2202 2203 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2204 DSAStack->setClauseParsingMode(K); 2205 } 2206 2207 void Sema::EndOpenMPClause() { 2208 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2209 } 2210 2211 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2212 ArrayRef<OMPClause *> Clauses); 2213 2214 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2215 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2216 // A variable of class type (or array thereof) that appears in a lastprivate 2217 // clause requires an accessible, unambiguous default constructor for the 2218 // class type, unless the list item is also specified in a firstprivate 2219 // clause. 2220 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2221 for (OMPClause *C : D->clauses()) { 2222 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2223 SmallVector<Expr *, 8> PrivateCopies; 2224 for (Expr *DE : Clause->varlists()) { 2225 if (DE->isValueDependent() || DE->isTypeDependent()) { 2226 PrivateCopies.push_back(nullptr); 2227 continue; 2228 } 2229 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2230 auto *VD = cast<VarDecl>(DRE->getDecl()); 2231 QualType Type = VD->getType().getNonReferenceType(); 2232 const DSAStackTy::DSAVarData DVar = 2233 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2234 if (DVar.CKind == OMPC_lastprivate) { 2235 // Generate helper private variable and initialize it with the 2236 // default value. The address of the original variable is replaced 2237 // by the address of the new private variable in CodeGen. This new 2238 // variable is not added to IdResolver, so the code in the OpenMP 2239 // region uses original variable for proper diagnostics. 2240 VarDecl *VDPrivate = buildVarDecl( 2241 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2242 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2243 ActOnUninitializedDecl(VDPrivate); 2244 if (VDPrivate->isInvalidDecl()) { 2245 PrivateCopies.push_back(nullptr); 2246 continue; 2247 } 2248 PrivateCopies.push_back(buildDeclRefExpr( 2249 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2250 } else { 2251 // The variable is also a firstprivate, so initialization sequence 2252 // for private copy is generated already. 2253 PrivateCopies.push_back(nullptr); 2254 } 2255 } 2256 Clause->setPrivateCopies(PrivateCopies); 2257 } 2258 } 2259 // Check allocate clauses. 2260 if (!CurContext->isDependentContext()) 2261 checkAllocateClauses(*this, DSAStack, D->clauses()); 2262 } 2263 2264 DSAStack->pop(); 2265 DiscardCleanupsInEvaluationContext(); 2266 PopExpressionEvaluationContext(); 2267 } 2268 2269 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2270 Expr *NumIterations, Sema &SemaRef, 2271 Scope *S, DSAStackTy *Stack); 2272 2273 namespace { 2274 2275 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2276 private: 2277 Sema &SemaRef; 2278 2279 public: 2280 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2281 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2282 NamedDecl *ND = Candidate.getCorrectionDecl(); 2283 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2284 return VD->hasGlobalStorage() && 2285 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2286 SemaRef.getCurScope()); 2287 } 2288 return false; 2289 } 2290 2291 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2292 return std::make_unique<VarDeclFilterCCC>(*this); 2293 } 2294 2295 }; 2296 2297 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2298 private: 2299 Sema &SemaRef; 2300 2301 public: 2302 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2303 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2304 NamedDecl *ND = Candidate.getCorrectionDecl(); 2305 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2306 isa<FunctionDecl>(ND))) { 2307 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2308 SemaRef.getCurScope()); 2309 } 2310 return false; 2311 } 2312 2313 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2314 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2315 } 2316 }; 2317 2318 } // namespace 2319 2320 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2321 CXXScopeSpec &ScopeSpec, 2322 const DeclarationNameInfo &Id, 2323 OpenMPDirectiveKind Kind) { 2324 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2325 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2326 2327 if (Lookup.isAmbiguous()) 2328 return ExprError(); 2329 2330 VarDecl *VD; 2331 if (!Lookup.isSingleResult()) { 2332 VarDeclFilterCCC CCC(*this); 2333 if (TypoCorrection Corrected = 2334 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2335 CTK_ErrorRecovery)) { 2336 diagnoseTypo(Corrected, 2337 PDiag(Lookup.empty() 2338 ? diag::err_undeclared_var_use_suggest 2339 : diag::err_omp_expected_var_arg_suggest) 2340 << Id.getName()); 2341 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2342 } else { 2343 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2344 : diag::err_omp_expected_var_arg) 2345 << Id.getName(); 2346 return ExprError(); 2347 } 2348 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2349 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2350 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2351 return ExprError(); 2352 } 2353 Lookup.suppressDiagnostics(); 2354 2355 // OpenMP [2.9.2, Syntax, C/C++] 2356 // Variables must be file-scope, namespace-scope, or static block-scope. 2357 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2358 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2359 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2360 bool IsDecl = 2361 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2362 Diag(VD->getLocation(), 2363 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2364 << VD; 2365 return ExprError(); 2366 } 2367 2368 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2369 NamedDecl *ND = CanonicalVD; 2370 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2371 // A threadprivate directive for file-scope variables must appear outside 2372 // any definition or declaration. 2373 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2374 !getCurLexicalContext()->isTranslationUnit()) { 2375 Diag(Id.getLoc(), diag::err_omp_var_scope) 2376 << getOpenMPDirectiveName(Kind) << VD; 2377 bool IsDecl = 2378 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2379 Diag(VD->getLocation(), 2380 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2381 << VD; 2382 return ExprError(); 2383 } 2384 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2385 // A threadprivate directive for static class member variables must appear 2386 // in the class definition, in the same scope in which the member 2387 // variables are declared. 2388 if (CanonicalVD->isStaticDataMember() && 2389 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2390 Diag(Id.getLoc(), diag::err_omp_var_scope) 2391 << getOpenMPDirectiveName(Kind) << VD; 2392 bool IsDecl = 2393 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2394 Diag(VD->getLocation(), 2395 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2396 << VD; 2397 return ExprError(); 2398 } 2399 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2400 // A threadprivate directive for namespace-scope variables must appear 2401 // outside any definition or declaration other than the namespace 2402 // definition itself. 2403 if (CanonicalVD->getDeclContext()->isNamespace() && 2404 (!getCurLexicalContext()->isFileContext() || 2405 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2406 Diag(Id.getLoc(), diag::err_omp_var_scope) 2407 << getOpenMPDirectiveName(Kind) << VD; 2408 bool IsDecl = 2409 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2410 Diag(VD->getLocation(), 2411 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2412 << VD; 2413 return ExprError(); 2414 } 2415 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2416 // A threadprivate directive for static block-scope variables must appear 2417 // in the scope of the variable and not in a nested scope. 2418 if (CanonicalVD->isLocalVarDecl() && CurScope && 2419 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2420 Diag(Id.getLoc(), diag::err_omp_var_scope) 2421 << getOpenMPDirectiveName(Kind) << VD; 2422 bool IsDecl = 2423 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2424 Diag(VD->getLocation(), 2425 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2426 << VD; 2427 return ExprError(); 2428 } 2429 2430 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2431 // A threadprivate directive must lexically precede all references to any 2432 // of the variables in its list. 2433 if (Kind == OMPD_threadprivate && VD->isUsed() && 2434 !DSAStack->isThreadPrivate(VD)) { 2435 Diag(Id.getLoc(), diag::err_omp_var_used) 2436 << getOpenMPDirectiveName(Kind) << VD; 2437 return ExprError(); 2438 } 2439 2440 QualType ExprType = VD->getType().getNonReferenceType(); 2441 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2442 SourceLocation(), VD, 2443 /*RefersToEnclosingVariableOrCapture=*/false, 2444 Id.getLoc(), ExprType, VK_LValue); 2445 } 2446 2447 Sema::DeclGroupPtrTy 2448 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2449 ArrayRef<Expr *> VarList) { 2450 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2451 CurContext->addDecl(D); 2452 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2453 } 2454 return nullptr; 2455 } 2456 2457 namespace { 2458 class LocalVarRefChecker final 2459 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2460 Sema &SemaRef; 2461 2462 public: 2463 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2464 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2465 if (VD->hasLocalStorage()) { 2466 SemaRef.Diag(E->getBeginLoc(), 2467 diag::err_omp_local_var_in_threadprivate_init) 2468 << E->getSourceRange(); 2469 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2470 << VD << VD->getSourceRange(); 2471 return true; 2472 } 2473 } 2474 return false; 2475 } 2476 bool VisitStmt(const Stmt *S) { 2477 for (const Stmt *Child : S->children()) { 2478 if (Child && Visit(Child)) 2479 return true; 2480 } 2481 return false; 2482 } 2483 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2484 }; 2485 } // namespace 2486 2487 OMPThreadPrivateDecl * 2488 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2489 SmallVector<Expr *, 8> Vars; 2490 for (Expr *RefExpr : VarList) { 2491 auto *DE = cast<DeclRefExpr>(RefExpr); 2492 auto *VD = cast<VarDecl>(DE->getDecl()); 2493 SourceLocation ILoc = DE->getExprLoc(); 2494 2495 // Mark variable as used. 2496 VD->setReferenced(); 2497 VD->markUsed(Context); 2498 2499 QualType QType = VD->getType(); 2500 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2501 // It will be analyzed later. 2502 Vars.push_back(DE); 2503 continue; 2504 } 2505 2506 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2507 // A threadprivate variable must not have an incomplete type. 2508 if (RequireCompleteType(ILoc, VD->getType(), 2509 diag::err_omp_threadprivate_incomplete_type)) { 2510 continue; 2511 } 2512 2513 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2514 // A threadprivate variable must not have a reference type. 2515 if (VD->getType()->isReferenceType()) { 2516 Diag(ILoc, diag::err_omp_ref_type_arg) 2517 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2518 bool IsDecl = 2519 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2520 Diag(VD->getLocation(), 2521 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2522 << VD; 2523 continue; 2524 } 2525 2526 // Check if this is a TLS variable. If TLS is not being supported, produce 2527 // the corresponding diagnostic. 2528 if ((VD->getTLSKind() != VarDecl::TLS_None && 2529 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2530 getLangOpts().OpenMPUseTLS && 2531 getASTContext().getTargetInfo().isTLSSupported())) || 2532 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2533 !VD->isLocalVarDecl())) { 2534 Diag(ILoc, diag::err_omp_var_thread_local) 2535 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2536 bool IsDecl = 2537 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2538 Diag(VD->getLocation(), 2539 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2540 << VD; 2541 continue; 2542 } 2543 2544 // Check if initial value of threadprivate variable reference variable with 2545 // local storage (it is not supported by runtime). 2546 if (const Expr *Init = VD->getAnyInitializer()) { 2547 LocalVarRefChecker Checker(*this); 2548 if (Checker.Visit(Init)) 2549 continue; 2550 } 2551 2552 Vars.push_back(RefExpr); 2553 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2554 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2555 Context, SourceRange(Loc, Loc))); 2556 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2557 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2558 } 2559 OMPThreadPrivateDecl *D = nullptr; 2560 if (!Vars.empty()) { 2561 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2562 Vars); 2563 D->setAccess(AS_public); 2564 } 2565 return D; 2566 } 2567 2568 static OMPAllocateDeclAttr::AllocatorTypeTy 2569 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2570 if (!Allocator) 2571 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2572 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2573 Allocator->isInstantiationDependent() || 2574 Allocator->containsUnexpandedParameterPack()) 2575 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2576 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2577 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2578 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2579 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2580 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2581 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2582 llvm::FoldingSetNodeID AEId, DAEId; 2583 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2584 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2585 if (AEId == DAEId) { 2586 AllocatorKindRes = AllocatorKind; 2587 break; 2588 } 2589 } 2590 return AllocatorKindRes; 2591 } 2592 2593 static bool checkPreviousOMPAllocateAttribute( 2594 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2595 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2596 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2597 return false; 2598 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2599 Expr *PrevAllocator = A->getAllocator(); 2600 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2601 getAllocatorKind(S, Stack, PrevAllocator); 2602 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2603 if (AllocatorsMatch && 2604 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2605 Allocator && PrevAllocator) { 2606 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2607 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2608 llvm::FoldingSetNodeID AEId, PAEId; 2609 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2610 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2611 AllocatorsMatch = AEId == PAEId; 2612 } 2613 if (!AllocatorsMatch) { 2614 SmallString<256> AllocatorBuffer; 2615 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2616 if (Allocator) 2617 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2618 SmallString<256> PrevAllocatorBuffer; 2619 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2620 if (PrevAllocator) 2621 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2622 S.getPrintingPolicy()); 2623 2624 SourceLocation AllocatorLoc = 2625 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2626 SourceRange AllocatorRange = 2627 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2628 SourceLocation PrevAllocatorLoc = 2629 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2630 SourceRange PrevAllocatorRange = 2631 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2632 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2633 << (Allocator ? 1 : 0) << AllocatorStream.str() 2634 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2635 << AllocatorRange; 2636 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2637 << PrevAllocatorRange; 2638 return true; 2639 } 2640 return false; 2641 } 2642 2643 static void 2644 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2645 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2646 Expr *Allocator, SourceRange SR) { 2647 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2648 return; 2649 if (Allocator && 2650 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2651 Allocator->isInstantiationDependent() || 2652 Allocator->containsUnexpandedParameterPack())) 2653 return; 2654 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2655 Allocator, SR); 2656 VD->addAttr(A); 2657 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2658 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2659 } 2660 2661 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2662 SourceLocation Loc, ArrayRef<Expr *> VarList, 2663 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2664 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2665 Expr *Allocator = nullptr; 2666 if (Clauses.empty()) { 2667 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2668 // allocate directives that appear in a target region must specify an 2669 // allocator clause unless a requires directive with the dynamic_allocators 2670 // clause is present in the same compilation unit. 2671 if (LangOpts.OpenMPIsDevice && 2672 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2673 targetDiag(Loc, diag::err_expected_allocator_clause); 2674 } else { 2675 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2676 } 2677 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2678 getAllocatorKind(*this, DSAStack, Allocator); 2679 SmallVector<Expr *, 8> Vars; 2680 for (Expr *RefExpr : VarList) { 2681 auto *DE = cast<DeclRefExpr>(RefExpr); 2682 auto *VD = cast<VarDecl>(DE->getDecl()); 2683 2684 // Check if this is a TLS variable or global register. 2685 if (VD->getTLSKind() != VarDecl::TLS_None || 2686 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2687 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2688 !VD->isLocalVarDecl())) 2689 continue; 2690 2691 // If the used several times in the allocate directive, the same allocator 2692 // must be used. 2693 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2694 AllocatorKind, Allocator)) 2695 continue; 2696 2697 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2698 // If a list item has a static storage type, the allocator expression in the 2699 // allocator clause must be a constant expression that evaluates to one of 2700 // the predefined memory allocator values. 2701 if (Allocator && VD->hasGlobalStorage()) { 2702 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2703 Diag(Allocator->getExprLoc(), 2704 diag::err_omp_expected_predefined_allocator) 2705 << Allocator->getSourceRange(); 2706 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2707 VarDecl::DeclarationOnly; 2708 Diag(VD->getLocation(), 2709 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2710 << VD; 2711 continue; 2712 } 2713 } 2714 2715 Vars.push_back(RefExpr); 2716 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2717 DE->getSourceRange()); 2718 } 2719 if (Vars.empty()) 2720 return nullptr; 2721 if (!Owner) 2722 Owner = getCurLexicalContext(); 2723 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2724 D->setAccess(AS_public); 2725 Owner->addDecl(D); 2726 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2727 } 2728 2729 Sema::DeclGroupPtrTy 2730 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2731 ArrayRef<OMPClause *> ClauseList) { 2732 OMPRequiresDecl *D = nullptr; 2733 if (!CurContext->isFileContext()) { 2734 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2735 } else { 2736 D = CheckOMPRequiresDecl(Loc, ClauseList); 2737 if (D) { 2738 CurContext->addDecl(D); 2739 DSAStack->addRequiresDecl(D); 2740 } 2741 } 2742 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2743 } 2744 2745 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2746 ArrayRef<OMPClause *> ClauseList) { 2747 /// For target specific clauses, the requires directive cannot be 2748 /// specified after the handling of any of the target regions in the 2749 /// current compilation unit. 2750 ArrayRef<SourceLocation> TargetLocations = 2751 DSAStack->getEncounteredTargetLocs(); 2752 if (!TargetLocations.empty()) { 2753 for (const OMPClause *CNew : ClauseList) { 2754 // Check if any of the requires clauses affect target regions. 2755 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2756 isa<OMPUnifiedAddressClause>(CNew) || 2757 isa<OMPReverseOffloadClause>(CNew) || 2758 isa<OMPDynamicAllocatorsClause>(CNew)) { 2759 Diag(Loc, diag::err_omp_target_before_requires) 2760 << getOpenMPClauseName(CNew->getClauseKind()); 2761 for (SourceLocation TargetLoc : TargetLocations) { 2762 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2763 } 2764 } 2765 } 2766 } 2767 2768 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2769 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2770 ClauseList); 2771 return nullptr; 2772 } 2773 2774 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2775 const ValueDecl *D, 2776 const DSAStackTy::DSAVarData &DVar, 2777 bool IsLoopIterVar = false) { 2778 if (DVar.RefExpr) { 2779 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2780 << getOpenMPClauseName(DVar.CKind); 2781 return; 2782 } 2783 enum { 2784 PDSA_StaticMemberShared, 2785 PDSA_StaticLocalVarShared, 2786 PDSA_LoopIterVarPrivate, 2787 PDSA_LoopIterVarLinear, 2788 PDSA_LoopIterVarLastprivate, 2789 PDSA_ConstVarShared, 2790 PDSA_GlobalVarShared, 2791 PDSA_TaskVarFirstprivate, 2792 PDSA_LocalVarPrivate, 2793 PDSA_Implicit 2794 } Reason = PDSA_Implicit; 2795 bool ReportHint = false; 2796 auto ReportLoc = D->getLocation(); 2797 auto *VD = dyn_cast<VarDecl>(D); 2798 if (IsLoopIterVar) { 2799 if (DVar.CKind == OMPC_private) 2800 Reason = PDSA_LoopIterVarPrivate; 2801 else if (DVar.CKind == OMPC_lastprivate) 2802 Reason = PDSA_LoopIterVarLastprivate; 2803 else 2804 Reason = PDSA_LoopIterVarLinear; 2805 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2806 DVar.CKind == OMPC_firstprivate) { 2807 Reason = PDSA_TaskVarFirstprivate; 2808 ReportLoc = DVar.ImplicitDSALoc; 2809 } else if (VD && VD->isStaticLocal()) 2810 Reason = PDSA_StaticLocalVarShared; 2811 else if (VD && VD->isStaticDataMember()) 2812 Reason = PDSA_StaticMemberShared; 2813 else if (VD && VD->isFileVarDecl()) 2814 Reason = PDSA_GlobalVarShared; 2815 else if (D->getType().isConstant(SemaRef.getASTContext())) 2816 Reason = PDSA_ConstVarShared; 2817 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2818 ReportHint = true; 2819 Reason = PDSA_LocalVarPrivate; 2820 } 2821 if (Reason != PDSA_Implicit) { 2822 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2823 << Reason << ReportHint 2824 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2825 } else if (DVar.ImplicitDSALoc.isValid()) { 2826 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2827 << getOpenMPClauseName(DVar.CKind); 2828 } 2829 } 2830 2831 static OpenMPMapClauseKind 2832 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 2833 bool IsAggregateOrDeclareTarget) { 2834 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 2835 switch (M) { 2836 case OMPC_DEFAULTMAP_MODIFIER_alloc: 2837 Kind = OMPC_MAP_alloc; 2838 break; 2839 case OMPC_DEFAULTMAP_MODIFIER_to: 2840 Kind = OMPC_MAP_to; 2841 break; 2842 case OMPC_DEFAULTMAP_MODIFIER_from: 2843 Kind = OMPC_MAP_from; 2844 break; 2845 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 2846 Kind = OMPC_MAP_tofrom; 2847 break; 2848 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 2849 case OMPC_DEFAULTMAP_MODIFIER_last: 2850 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2851 case OMPC_DEFAULTMAP_MODIFIER_none: 2852 case OMPC_DEFAULTMAP_MODIFIER_default: 2853 case OMPC_DEFAULTMAP_MODIFIER_unknown: 2854 // IsAggregateOrDeclareTarget could be true if: 2855 // 1. the implicit behavior for aggregate is tofrom 2856 // 2. it's a declare target link 2857 if (IsAggregateOrDeclareTarget) { 2858 Kind = OMPC_MAP_tofrom; 2859 break; 2860 } 2861 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2862 } 2863 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 2864 return Kind; 2865 } 2866 2867 namespace { 2868 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2869 DSAStackTy *Stack; 2870 Sema &SemaRef; 2871 bool ErrorFound = false; 2872 bool TryCaptureCXXThisMembers = false; 2873 CapturedStmt *CS = nullptr; 2874 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2875 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 2876 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2877 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2878 2879 void VisitSubCaptures(OMPExecutableDirective *S) { 2880 // Check implicitly captured variables. 2881 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2882 return; 2883 visitSubCaptures(S->getInnermostCapturedStmt()); 2884 // Try to capture inner this->member references to generate correct mappings 2885 // and diagnostics. 2886 if (TryCaptureCXXThisMembers || 2887 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2888 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2889 [](const CapturedStmt::Capture &C) { 2890 return C.capturesThis(); 2891 }))) { 2892 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2893 TryCaptureCXXThisMembers = true; 2894 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2895 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2896 } 2897 } 2898 2899 public: 2900 void VisitDeclRefExpr(DeclRefExpr *E) { 2901 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 2902 E->isValueDependent() || E->containsUnexpandedParameterPack() || 2903 E->isInstantiationDependent()) 2904 return; 2905 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2906 // Check the datasharing rules for the expressions in the clauses. 2907 if (!CS) { 2908 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2909 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2910 Visit(CED->getInit()); 2911 return; 2912 } 2913 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2914 // Do not analyze internal variables and do not enclose them into 2915 // implicit clauses. 2916 return; 2917 VD = VD->getCanonicalDecl(); 2918 // Skip internally declared variables. 2919 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2920 return; 2921 2922 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2923 // Check if the variable has explicit DSA set and stop analysis if it so. 2924 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2925 return; 2926 2927 // Skip internally declared static variables. 2928 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2929 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2930 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2931 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2932 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2933 return; 2934 2935 SourceLocation ELoc = E->getExprLoc(); 2936 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2937 // The default(none) clause requires that each variable that is referenced 2938 // in the construct, and does not have a predetermined data-sharing 2939 // attribute, must have its data-sharing attribute explicitly determined 2940 // by being listed in a data-sharing attribute clause. 2941 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2942 isImplicitOrExplicitTaskingRegion(DKind) && 2943 VarsWithInheritedDSA.count(VD) == 0) { 2944 VarsWithInheritedDSA[VD] = E; 2945 return; 2946 } 2947 2948 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 2949 // If implicit-behavior is none, each variable referenced in the 2950 // construct that does not have a predetermined data-sharing attribute 2951 // and does not appear in a to or link clause on a declare target 2952 // directive must be listed in a data-mapping attribute clause, a 2953 // data-haring attribute clause (including a data-sharing attribute 2954 // clause on a combined construct where target. is one of the 2955 // constituent constructs), or an is_device_ptr clause. 2956 OpenMPDefaultmapClauseKind ClauseKind = 2957 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 2958 if (SemaRef.getLangOpts().OpenMP >= 50) { 2959 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 2960 OMPC_DEFAULTMAP_MODIFIER_none; 2961 if (DVar.CKind == OMPC_unknown && IsModifierNone && 2962 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 2963 // Only check for data-mapping attribute and is_device_ptr here 2964 // since we have already make sure that the declaration does not 2965 // have a data-sharing attribute above 2966 if (!Stack->checkMappableExprComponentListsForDecl( 2967 VD, /*CurrentRegionOnly=*/true, 2968 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 2969 MapExprComponents, 2970 OpenMPClauseKind) { 2971 auto MI = MapExprComponents.rbegin(); 2972 auto ME = MapExprComponents.rend(); 2973 return MI != ME && MI->getAssociatedDeclaration() == VD; 2974 })) { 2975 VarsWithInheritedDSA[VD] = E; 2976 return; 2977 } 2978 } 2979 } 2980 2981 if (isOpenMPTargetExecutionDirective(DKind) && 2982 !Stack->isLoopControlVariable(VD).first) { 2983 if (!Stack->checkMappableExprComponentListsForDecl( 2984 VD, /*CurrentRegionOnly=*/true, 2985 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2986 StackComponents, 2987 OpenMPClauseKind) { 2988 // Variable is used if it has been marked as an array, array 2989 // section or the variable iself. 2990 return StackComponents.size() == 1 || 2991 std::all_of( 2992 std::next(StackComponents.rbegin()), 2993 StackComponents.rend(), 2994 [](const OMPClauseMappableExprCommon:: 2995 MappableComponent &MC) { 2996 return MC.getAssociatedDeclaration() == 2997 nullptr && 2998 (isa<OMPArraySectionExpr>( 2999 MC.getAssociatedExpression()) || 3000 isa<ArraySubscriptExpr>( 3001 MC.getAssociatedExpression())); 3002 }); 3003 })) { 3004 bool IsFirstprivate = false; 3005 // By default lambdas are captured as firstprivates. 3006 if (const auto *RD = 3007 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3008 IsFirstprivate = RD->isLambda(); 3009 IsFirstprivate = 3010 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3011 if (IsFirstprivate) { 3012 ImplicitFirstprivate.emplace_back(E); 3013 } else { 3014 OpenMPDefaultmapClauseModifier M = 3015 Stack->getDefaultmapModifier(ClauseKind); 3016 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3017 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3018 ImplicitMap[Kind].emplace_back(E); 3019 } 3020 return; 3021 } 3022 } 3023 3024 // OpenMP [2.9.3.6, Restrictions, p.2] 3025 // A list item that appears in a reduction clause of the innermost 3026 // enclosing worksharing or parallel construct may not be accessed in an 3027 // explicit task. 3028 DVar = Stack->hasInnermostDSA( 3029 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3030 [](OpenMPDirectiveKind K) { 3031 return isOpenMPParallelDirective(K) || 3032 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3033 }, 3034 /*FromParent=*/true); 3035 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3036 ErrorFound = true; 3037 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3038 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3039 return; 3040 } 3041 3042 // Define implicit data-sharing attributes for task. 3043 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3044 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3045 !Stack->isLoopControlVariable(VD).first) { 3046 ImplicitFirstprivate.push_back(E); 3047 return; 3048 } 3049 3050 // Store implicitly used globals with declare target link for parent 3051 // target. 3052 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3053 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3054 Stack->addToParentTargetRegionLinkGlobals(E); 3055 return; 3056 } 3057 } 3058 } 3059 void VisitMemberExpr(MemberExpr *E) { 3060 if (E->isTypeDependent() || E->isValueDependent() || 3061 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3062 return; 3063 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3064 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3065 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 3066 if (!FD) 3067 return; 3068 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3069 // Check if the variable has explicit DSA set and stop analysis if it 3070 // so. 3071 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3072 return; 3073 3074 if (isOpenMPTargetExecutionDirective(DKind) && 3075 !Stack->isLoopControlVariable(FD).first && 3076 !Stack->checkMappableExprComponentListsForDecl( 3077 FD, /*CurrentRegionOnly=*/true, 3078 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3079 StackComponents, 3080 OpenMPClauseKind) { 3081 return isa<CXXThisExpr>( 3082 cast<MemberExpr>( 3083 StackComponents.back().getAssociatedExpression()) 3084 ->getBase() 3085 ->IgnoreParens()); 3086 })) { 3087 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3088 // A bit-field cannot appear in a map clause. 3089 // 3090 if (FD->isBitField()) 3091 return; 3092 3093 // Check to see if the member expression is referencing a class that 3094 // has already been explicitly mapped 3095 if (Stack->isClassPreviouslyMapped(TE->getType())) 3096 return; 3097 3098 OpenMPDefaultmapClauseModifier Modifier = 3099 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3100 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3101 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3102 ImplicitMap[Kind].emplace_back(E); 3103 return; 3104 } 3105 3106 SourceLocation ELoc = E->getExprLoc(); 3107 // OpenMP [2.9.3.6, Restrictions, p.2] 3108 // A list item that appears in a reduction clause of the innermost 3109 // enclosing worksharing or parallel construct may not be accessed in 3110 // an explicit task. 3111 DVar = Stack->hasInnermostDSA( 3112 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3113 [](OpenMPDirectiveKind K) { 3114 return isOpenMPParallelDirective(K) || 3115 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3116 }, 3117 /*FromParent=*/true); 3118 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3119 ErrorFound = true; 3120 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3121 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3122 return; 3123 } 3124 3125 // Define implicit data-sharing attributes for task. 3126 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3127 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3128 !Stack->isLoopControlVariable(FD).first) { 3129 // Check if there is a captured expression for the current field in the 3130 // region. Do not mark it as firstprivate unless there is no captured 3131 // expression. 3132 // TODO: try to make it firstprivate. 3133 if (DVar.CKind != OMPC_unknown) 3134 ImplicitFirstprivate.push_back(E); 3135 } 3136 return; 3137 } 3138 if (isOpenMPTargetExecutionDirective(DKind)) { 3139 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3140 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3141 /*NoDiagnose=*/true)) 3142 return; 3143 const auto *VD = cast<ValueDecl>( 3144 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3145 if (!Stack->checkMappableExprComponentListsForDecl( 3146 VD, /*CurrentRegionOnly=*/true, 3147 [&CurComponents]( 3148 OMPClauseMappableExprCommon::MappableExprComponentListRef 3149 StackComponents, 3150 OpenMPClauseKind) { 3151 auto CCI = CurComponents.rbegin(); 3152 auto CCE = CurComponents.rend(); 3153 for (const auto &SC : llvm::reverse(StackComponents)) { 3154 // Do both expressions have the same kind? 3155 if (CCI->getAssociatedExpression()->getStmtClass() != 3156 SC.getAssociatedExpression()->getStmtClass()) 3157 if (!(isa<OMPArraySectionExpr>( 3158 SC.getAssociatedExpression()) && 3159 isa<ArraySubscriptExpr>( 3160 CCI->getAssociatedExpression()))) 3161 return false; 3162 3163 const Decl *CCD = CCI->getAssociatedDeclaration(); 3164 const Decl *SCD = SC.getAssociatedDeclaration(); 3165 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3166 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3167 if (SCD != CCD) 3168 return false; 3169 std::advance(CCI, 1); 3170 if (CCI == CCE) 3171 break; 3172 } 3173 return true; 3174 })) { 3175 Visit(E->getBase()); 3176 } 3177 } else if (!TryCaptureCXXThisMembers) { 3178 Visit(E->getBase()); 3179 } 3180 } 3181 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3182 for (OMPClause *C : S->clauses()) { 3183 // Skip analysis of arguments of implicitly defined firstprivate clause 3184 // for task|target directives. 3185 // Skip analysis of arguments of implicitly defined map clause for target 3186 // directives. 3187 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3188 C->isImplicit())) { 3189 for (Stmt *CC : C->children()) { 3190 if (CC) 3191 Visit(CC); 3192 } 3193 } 3194 } 3195 // Check implicitly captured variables. 3196 VisitSubCaptures(S); 3197 } 3198 void VisitStmt(Stmt *S) { 3199 for (Stmt *C : S->children()) { 3200 if (C) { 3201 // Check implicitly captured variables in the task-based directives to 3202 // check if they must be firstprivatized. 3203 Visit(C); 3204 } 3205 } 3206 } 3207 3208 void visitSubCaptures(CapturedStmt *S) { 3209 for (const CapturedStmt::Capture &Cap : S->captures()) { 3210 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3211 continue; 3212 VarDecl *VD = Cap.getCapturedVar(); 3213 // Do not try to map the variable if it or its sub-component was mapped 3214 // already. 3215 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3216 Stack->checkMappableExprComponentListsForDecl( 3217 VD, /*CurrentRegionOnly=*/true, 3218 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3219 OpenMPClauseKind) { return true; })) 3220 continue; 3221 DeclRefExpr *DRE = buildDeclRefExpr( 3222 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3223 Cap.getLocation(), /*RefersToCapture=*/true); 3224 Visit(DRE); 3225 } 3226 } 3227 bool isErrorFound() const { return ErrorFound; } 3228 ArrayRef<Expr *> getImplicitFirstprivate() const { 3229 return ImplicitFirstprivate; 3230 } 3231 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3232 return ImplicitMap[Kind]; 3233 } 3234 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3235 return VarsWithInheritedDSA; 3236 } 3237 3238 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3239 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3240 // Process declare target link variables for the target directives. 3241 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3242 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3243 Visit(E); 3244 } 3245 } 3246 }; 3247 } // namespace 3248 3249 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3250 switch (DKind) { 3251 case OMPD_parallel: 3252 case OMPD_parallel_for: 3253 case OMPD_parallel_for_simd: 3254 case OMPD_parallel_sections: 3255 case OMPD_parallel_master: 3256 case OMPD_teams: 3257 case OMPD_teams_distribute: 3258 case OMPD_teams_distribute_simd: { 3259 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3260 QualType KmpInt32PtrTy = 3261 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3262 Sema::CapturedParamNameType Params[] = { 3263 std::make_pair(".global_tid.", KmpInt32PtrTy), 3264 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3265 std::make_pair(StringRef(), QualType()) // __context with shared vars 3266 }; 3267 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3268 Params); 3269 break; 3270 } 3271 case OMPD_target_teams: 3272 case OMPD_target_parallel: 3273 case OMPD_target_parallel_for: 3274 case OMPD_target_parallel_for_simd: 3275 case OMPD_target_teams_distribute: 3276 case OMPD_target_teams_distribute_simd: { 3277 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3278 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3279 QualType KmpInt32PtrTy = 3280 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3281 QualType Args[] = {VoidPtrTy}; 3282 FunctionProtoType::ExtProtoInfo EPI; 3283 EPI.Variadic = true; 3284 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3285 Sema::CapturedParamNameType Params[] = { 3286 std::make_pair(".global_tid.", KmpInt32Ty), 3287 std::make_pair(".part_id.", KmpInt32PtrTy), 3288 std::make_pair(".privates.", VoidPtrTy), 3289 std::make_pair( 3290 ".copy_fn.", 3291 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3292 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3293 std::make_pair(StringRef(), QualType()) // __context with shared vars 3294 }; 3295 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3296 Params, /*OpenMPCaptureLevel=*/0); 3297 // Mark this captured region as inlined, because we don't use outlined 3298 // function directly. 3299 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3300 AlwaysInlineAttr::CreateImplicit( 3301 Context, {}, AttributeCommonInfo::AS_Keyword, 3302 AlwaysInlineAttr::Keyword_forceinline)); 3303 Sema::CapturedParamNameType ParamsTarget[] = { 3304 std::make_pair(StringRef(), QualType()) // __context with shared vars 3305 }; 3306 // Start a captured region for 'target' with no implicit parameters. 3307 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3308 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3309 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3310 std::make_pair(".global_tid.", KmpInt32PtrTy), 3311 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3312 std::make_pair(StringRef(), QualType()) // __context with shared vars 3313 }; 3314 // Start a captured region for 'teams' or 'parallel'. Both regions have 3315 // the same implicit parameters. 3316 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3317 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3318 break; 3319 } 3320 case OMPD_target: 3321 case OMPD_target_simd: { 3322 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3323 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3324 QualType KmpInt32PtrTy = 3325 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3326 QualType Args[] = {VoidPtrTy}; 3327 FunctionProtoType::ExtProtoInfo EPI; 3328 EPI.Variadic = true; 3329 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3330 Sema::CapturedParamNameType Params[] = { 3331 std::make_pair(".global_tid.", KmpInt32Ty), 3332 std::make_pair(".part_id.", KmpInt32PtrTy), 3333 std::make_pair(".privates.", VoidPtrTy), 3334 std::make_pair( 3335 ".copy_fn.", 3336 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3337 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3338 std::make_pair(StringRef(), QualType()) // __context with shared vars 3339 }; 3340 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3341 Params, /*OpenMPCaptureLevel=*/0); 3342 // Mark this captured region as inlined, because we don't use outlined 3343 // function directly. 3344 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3345 AlwaysInlineAttr::CreateImplicit( 3346 Context, {}, AttributeCommonInfo::AS_Keyword, 3347 AlwaysInlineAttr::Keyword_forceinline)); 3348 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3349 std::make_pair(StringRef(), QualType()), 3350 /*OpenMPCaptureLevel=*/1); 3351 break; 3352 } 3353 case OMPD_simd: 3354 case OMPD_for: 3355 case OMPD_for_simd: 3356 case OMPD_sections: 3357 case OMPD_section: 3358 case OMPD_single: 3359 case OMPD_master: 3360 case OMPD_critical: 3361 case OMPD_taskgroup: 3362 case OMPD_distribute: 3363 case OMPD_distribute_simd: 3364 case OMPD_ordered: 3365 case OMPD_atomic: 3366 case OMPD_target_data: { 3367 Sema::CapturedParamNameType Params[] = { 3368 std::make_pair(StringRef(), QualType()) // __context with shared vars 3369 }; 3370 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3371 Params); 3372 break; 3373 } 3374 case OMPD_task: { 3375 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3376 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3377 QualType KmpInt32PtrTy = 3378 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3379 QualType Args[] = {VoidPtrTy}; 3380 FunctionProtoType::ExtProtoInfo EPI; 3381 EPI.Variadic = true; 3382 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3383 Sema::CapturedParamNameType Params[] = { 3384 std::make_pair(".global_tid.", KmpInt32Ty), 3385 std::make_pair(".part_id.", KmpInt32PtrTy), 3386 std::make_pair(".privates.", VoidPtrTy), 3387 std::make_pair( 3388 ".copy_fn.", 3389 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3390 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3391 std::make_pair(StringRef(), QualType()) // __context with shared vars 3392 }; 3393 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3394 Params); 3395 // Mark this captured region as inlined, because we don't use outlined 3396 // function directly. 3397 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3398 AlwaysInlineAttr::CreateImplicit( 3399 Context, {}, AttributeCommonInfo::AS_Keyword, 3400 AlwaysInlineAttr::Keyword_forceinline)); 3401 break; 3402 } 3403 case OMPD_taskloop: 3404 case OMPD_taskloop_simd: 3405 case OMPD_master_taskloop: 3406 case OMPD_master_taskloop_simd: { 3407 QualType KmpInt32Ty = 3408 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3409 .withConst(); 3410 QualType KmpUInt64Ty = 3411 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3412 .withConst(); 3413 QualType KmpInt64Ty = 3414 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3415 .withConst(); 3416 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3417 QualType KmpInt32PtrTy = 3418 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3419 QualType Args[] = {VoidPtrTy}; 3420 FunctionProtoType::ExtProtoInfo EPI; 3421 EPI.Variadic = true; 3422 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3423 Sema::CapturedParamNameType Params[] = { 3424 std::make_pair(".global_tid.", KmpInt32Ty), 3425 std::make_pair(".part_id.", KmpInt32PtrTy), 3426 std::make_pair(".privates.", VoidPtrTy), 3427 std::make_pair( 3428 ".copy_fn.", 3429 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3430 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3431 std::make_pair(".lb.", KmpUInt64Ty), 3432 std::make_pair(".ub.", KmpUInt64Ty), 3433 std::make_pair(".st.", KmpInt64Ty), 3434 std::make_pair(".liter.", KmpInt32Ty), 3435 std::make_pair(".reductions.", VoidPtrTy), 3436 std::make_pair(StringRef(), QualType()) // __context with shared vars 3437 }; 3438 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3439 Params); 3440 // Mark this captured region as inlined, because we don't use outlined 3441 // function directly. 3442 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3443 AlwaysInlineAttr::CreateImplicit( 3444 Context, {}, AttributeCommonInfo::AS_Keyword, 3445 AlwaysInlineAttr::Keyword_forceinline)); 3446 break; 3447 } 3448 case OMPD_parallel_master_taskloop: 3449 case OMPD_parallel_master_taskloop_simd: { 3450 QualType KmpInt32Ty = 3451 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3452 .withConst(); 3453 QualType KmpUInt64Ty = 3454 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3455 .withConst(); 3456 QualType KmpInt64Ty = 3457 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3458 .withConst(); 3459 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3460 QualType KmpInt32PtrTy = 3461 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3462 Sema::CapturedParamNameType ParamsParallel[] = { 3463 std::make_pair(".global_tid.", KmpInt32PtrTy), 3464 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3465 std::make_pair(StringRef(), QualType()) // __context with shared vars 3466 }; 3467 // Start a captured region for 'parallel'. 3468 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3469 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3470 QualType Args[] = {VoidPtrTy}; 3471 FunctionProtoType::ExtProtoInfo EPI; 3472 EPI.Variadic = true; 3473 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3474 Sema::CapturedParamNameType Params[] = { 3475 std::make_pair(".global_tid.", KmpInt32Ty), 3476 std::make_pair(".part_id.", KmpInt32PtrTy), 3477 std::make_pair(".privates.", VoidPtrTy), 3478 std::make_pair( 3479 ".copy_fn.", 3480 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3481 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3482 std::make_pair(".lb.", KmpUInt64Ty), 3483 std::make_pair(".ub.", KmpUInt64Ty), 3484 std::make_pair(".st.", KmpInt64Ty), 3485 std::make_pair(".liter.", KmpInt32Ty), 3486 std::make_pair(".reductions.", VoidPtrTy), 3487 std::make_pair(StringRef(), QualType()) // __context with shared vars 3488 }; 3489 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3490 Params, /*OpenMPCaptureLevel=*/2); 3491 // Mark this captured region as inlined, because we don't use outlined 3492 // function directly. 3493 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3494 AlwaysInlineAttr::CreateImplicit( 3495 Context, {}, AttributeCommonInfo::AS_Keyword, 3496 AlwaysInlineAttr::Keyword_forceinline)); 3497 break; 3498 } 3499 case OMPD_distribute_parallel_for_simd: 3500 case OMPD_distribute_parallel_for: { 3501 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3502 QualType KmpInt32PtrTy = 3503 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3504 Sema::CapturedParamNameType Params[] = { 3505 std::make_pair(".global_tid.", KmpInt32PtrTy), 3506 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3507 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3508 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3509 std::make_pair(StringRef(), QualType()) // __context with shared vars 3510 }; 3511 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3512 Params); 3513 break; 3514 } 3515 case OMPD_target_teams_distribute_parallel_for: 3516 case OMPD_target_teams_distribute_parallel_for_simd: { 3517 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3518 QualType KmpInt32PtrTy = 3519 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3520 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3521 3522 QualType Args[] = {VoidPtrTy}; 3523 FunctionProtoType::ExtProtoInfo EPI; 3524 EPI.Variadic = true; 3525 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3526 Sema::CapturedParamNameType Params[] = { 3527 std::make_pair(".global_tid.", KmpInt32Ty), 3528 std::make_pair(".part_id.", KmpInt32PtrTy), 3529 std::make_pair(".privates.", VoidPtrTy), 3530 std::make_pair( 3531 ".copy_fn.", 3532 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3533 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3534 std::make_pair(StringRef(), QualType()) // __context with shared vars 3535 }; 3536 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3537 Params, /*OpenMPCaptureLevel=*/0); 3538 // Mark this captured region as inlined, because we don't use outlined 3539 // function directly. 3540 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3541 AlwaysInlineAttr::CreateImplicit( 3542 Context, {}, AttributeCommonInfo::AS_Keyword, 3543 AlwaysInlineAttr::Keyword_forceinline)); 3544 Sema::CapturedParamNameType ParamsTarget[] = { 3545 std::make_pair(StringRef(), QualType()) // __context with shared vars 3546 }; 3547 // Start a captured region for 'target' with no implicit parameters. 3548 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3549 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3550 3551 Sema::CapturedParamNameType ParamsTeams[] = { 3552 std::make_pair(".global_tid.", KmpInt32PtrTy), 3553 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3554 std::make_pair(StringRef(), QualType()) // __context with shared vars 3555 }; 3556 // Start a captured region for 'target' with no implicit parameters. 3557 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3558 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3559 3560 Sema::CapturedParamNameType ParamsParallel[] = { 3561 std::make_pair(".global_tid.", KmpInt32PtrTy), 3562 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3563 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3564 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3565 std::make_pair(StringRef(), QualType()) // __context with shared vars 3566 }; 3567 // Start a captured region for 'teams' or 'parallel'. Both regions have 3568 // the same implicit parameters. 3569 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3570 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3571 break; 3572 } 3573 3574 case OMPD_teams_distribute_parallel_for: 3575 case OMPD_teams_distribute_parallel_for_simd: { 3576 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3577 QualType KmpInt32PtrTy = 3578 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3579 3580 Sema::CapturedParamNameType ParamsTeams[] = { 3581 std::make_pair(".global_tid.", KmpInt32PtrTy), 3582 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3583 std::make_pair(StringRef(), QualType()) // __context with shared vars 3584 }; 3585 // Start a captured region for 'target' with no implicit parameters. 3586 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3587 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3588 3589 Sema::CapturedParamNameType ParamsParallel[] = { 3590 std::make_pair(".global_tid.", KmpInt32PtrTy), 3591 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3592 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3593 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3594 std::make_pair(StringRef(), QualType()) // __context with shared vars 3595 }; 3596 // Start a captured region for 'teams' or 'parallel'. Both regions have 3597 // the same implicit parameters. 3598 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3599 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3600 break; 3601 } 3602 case OMPD_target_update: 3603 case OMPD_target_enter_data: 3604 case OMPD_target_exit_data: { 3605 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3606 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3607 QualType KmpInt32PtrTy = 3608 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3609 QualType Args[] = {VoidPtrTy}; 3610 FunctionProtoType::ExtProtoInfo EPI; 3611 EPI.Variadic = true; 3612 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3613 Sema::CapturedParamNameType Params[] = { 3614 std::make_pair(".global_tid.", KmpInt32Ty), 3615 std::make_pair(".part_id.", KmpInt32PtrTy), 3616 std::make_pair(".privates.", VoidPtrTy), 3617 std::make_pair( 3618 ".copy_fn.", 3619 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3620 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3621 std::make_pair(StringRef(), QualType()) // __context with shared vars 3622 }; 3623 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3624 Params); 3625 // Mark this captured region as inlined, because we don't use outlined 3626 // function directly. 3627 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3628 AlwaysInlineAttr::CreateImplicit( 3629 Context, {}, AttributeCommonInfo::AS_Keyword, 3630 AlwaysInlineAttr::Keyword_forceinline)); 3631 break; 3632 } 3633 case OMPD_threadprivate: 3634 case OMPD_allocate: 3635 case OMPD_taskyield: 3636 case OMPD_barrier: 3637 case OMPD_taskwait: 3638 case OMPD_cancellation_point: 3639 case OMPD_cancel: 3640 case OMPD_flush: 3641 case OMPD_declare_reduction: 3642 case OMPD_declare_mapper: 3643 case OMPD_declare_simd: 3644 case OMPD_declare_target: 3645 case OMPD_end_declare_target: 3646 case OMPD_requires: 3647 case OMPD_declare_variant: 3648 llvm_unreachable("OpenMP Directive is not allowed"); 3649 case OMPD_unknown: 3650 llvm_unreachable("Unknown OpenMP directive"); 3651 } 3652 } 3653 3654 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3655 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3656 } 3657 3658 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3659 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3660 getOpenMPCaptureRegions(CaptureRegions, DKind); 3661 return CaptureRegions.size(); 3662 } 3663 3664 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3665 Expr *CaptureExpr, bool WithInit, 3666 bool AsExpression) { 3667 assert(CaptureExpr); 3668 ASTContext &C = S.getASTContext(); 3669 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3670 QualType Ty = Init->getType(); 3671 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3672 if (S.getLangOpts().CPlusPlus) { 3673 Ty = C.getLValueReferenceType(Ty); 3674 } else { 3675 Ty = C.getPointerType(Ty); 3676 ExprResult Res = 3677 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3678 if (!Res.isUsable()) 3679 return nullptr; 3680 Init = Res.get(); 3681 } 3682 WithInit = true; 3683 } 3684 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3685 CaptureExpr->getBeginLoc()); 3686 if (!WithInit) 3687 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3688 S.CurContext->addHiddenDecl(CED); 3689 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3690 return CED; 3691 } 3692 3693 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3694 bool WithInit) { 3695 OMPCapturedExprDecl *CD; 3696 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3697 CD = cast<OMPCapturedExprDecl>(VD); 3698 else 3699 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3700 /*AsExpression=*/false); 3701 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3702 CaptureExpr->getExprLoc()); 3703 } 3704 3705 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3706 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3707 if (!Ref) { 3708 OMPCapturedExprDecl *CD = buildCaptureDecl( 3709 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3710 /*WithInit=*/true, /*AsExpression=*/true); 3711 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3712 CaptureExpr->getExprLoc()); 3713 } 3714 ExprResult Res = Ref; 3715 if (!S.getLangOpts().CPlusPlus && 3716 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3717 Ref->getType()->isPointerType()) { 3718 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3719 if (!Res.isUsable()) 3720 return ExprError(); 3721 } 3722 return S.DefaultLvalueConversion(Res.get()); 3723 } 3724 3725 namespace { 3726 // OpenMP directives parsed in this section are represented as a 3727 // CapturedStatement with an associated statement. If a syntax error 3728 // is detected during the parsing of the associated statement, the 3729 // compiler must abort processing and close the CapturedStatement. 3730 // 3731 // Combined directives such as 'target parallel' have more than one 3732 // nested CapturedStatements. This RAII ensures that we unwind out 3733 // of all the nested CapturedStatements when an error is found. 3734 class CaptureRegionUnwinderRAII { 3735 private: 3736 Sema &S; 3737 bool &ErrorFound; 3738 OpenMPDirectiveKind DKind = OMPD_unknown; 3739 3740 public: 3741 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3742 OpenMPDirectiveKind DKind) 3743 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3744 ~CaptureRegionUnwinderRAII() { 3745 if (ErrorFound) { 3746 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3747 while (--ThisCaptureLevel >= 0) 3748 S.ActOnCapturedRegionError(); 3749 } 3750 } 3751 }; 3752 } // namespace 3753 3754 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3755 // Capture variables captured by reference in lambdas for target-based 3756 // directives. 3757 if (!CurContext->isDependentContext() && 3758 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3759 isOpenMPTargetDataManagementDirective( 3760 DSAStack->getCurrentDirective()))) { 3761 QualType Type = V->getType(); 3762 if (const auto *RD = Type.getCanonicalType() 3763 .getNonReferenceType() 3764 ->getAsCXXRecordDecl()) { 3765 bool SavedForceCaptureByReferenceInTargetExecutable = 3766 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3767 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3768 /*V=*/true); 3769 if (RD->isLambda()) { 3770 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3771 FieldDecl *ThisCapture; 3772 RD->getCaptureFields(Captures, ThisCapture); 3773 for (const LambdaCapture &LC : RD->captures()) { 3774 if (LC.getCaptureKind() == LCK_ByRef) { 3775 VarDecl *VD = LC.getCapturedVar(); 3776 DeclContext *VDC = VD->getDeclContext(); 3777 if (!VDC->Encloses(CurContext)) 3778 continue; 3779 MarkVariableReferenced(LC.getLocation(), VD); 3780 } else if (LC.getCaptureKind() == LCK_This) { 3781 QualType ThisTy = getCurrentThisType(); 3782 if (!ThisTy.isNull() && 3783 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3784 CheckCXXThisCapture(LC.getLocation()); 3785 } 3786 } 3787 } 3788 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3789 SavedForceCaptureByReferenceInTargetExecutable); 3790 } 3791 } 3792 } 3793 3794 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3795 ArrayRef<OMPClause *> Clauses) { 3796 bool ErrorFound = false; 3797 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3798 *this, ErrorFound, DSAStack->getCurrentDirective()); 3799 if (!S.isUsable()) { 3800 ErrorFound = true; 3801 return StmtError(); 3802 } 3803 3804 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3805 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3806 OMPOrderedClause *OC = nullptr; 3807 OMPScheduleClause *SC = nullptr; 3808 SmallVector<const OMPLinearClause *, 4> LCs; 3809 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3810 // This is required for proper codegen. 3811 for (OMPClause *Clause : Clauses) { 3812 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3813 Clause->getClauseKind() == OMPC_in_reduction) { 3814 // Capture taskgroup task_reduction descriptors inside the tasking regions 3815 // with the corresponding in_reduction items. 3816 auto *IRC = cast<OMPInReductionClause>(Clause); 3817 for (Expr *E : IRC->taskgroup_descriptors()) 3818 if (E) 3819 MarkDeclarationsReferencedInExpr(E); 3820 } 3821 if (isOpenMPPrivate(Clause->getClauseKind()) || 3822 Clause->getClauseKind() == OMPC_copyprivate || 3823 (getLangOpts().OpenMPUseTLS && 3824 getASTContext().getTargetInfo().isTLSSupported() && 3825 Clause->getClauseKind() == OMPC_copyin)) { 3826 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3827 // Mark all variables in private list clauses as used in inner region. 3828 for (Stmt *VarRef : Clause->children()) { 3829 if (auto *E = cast_or_null<Expr>(VarRef)) { 3830 MarkDeclarationsReferencedInExpr(E); 3831 } 3832 } 3833 DSAStack->setForceVarCapturing(/*V=*/false); 3834 } else if (CaptureRegions.size() > 1 || 3835 CaptureRegions.back() != OMPD_unknown) { 3836 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3837 PICs.push_back(C); 3838 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3839 if (Expr *E = C->getPostUpdateExpr()) 3840 MarkDeclarationsReferencedInExpr(E); 3841 } 3842 } 3843 if (Clause->getClauseKind() == OMPC_schedule) 3844 SC = cast<OMPScheduleClause>(Clause); 3845 else if (Clause->getClauseKind() == OMPC_ordered) 3846 OC = cast<OMPOrderedClause>(Clause); 3847 else if (Clause->getClauseKind() == OMPC_linear) 3848 LCs.push_back(cast<OMPLinearClause>(Clause)); 3849 } 3850 // OpenMP, 2.7.1 Loop Construct, Restrictions 3851 // The nonmonotonic modifier cannot be specified if an ordered clause is 3852 // specified. 3853 if (SC && 3854 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3855 SC->getSecondScheduleModifier() == 3856 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3857 OC) { 3858 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3859 ? SC->getFirstScheduleModifierLoc() 3860 : SC->getSecondScheduleModifierLoc(), 3861 diag::err_omp_schedule_nonmonotonic_ordered) 3862 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3863 ErrorFound = true; 3864 } 3865 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3866 for (const OMPLinearClause *C : LCs) { 3867 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3868 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3869 } 3870 ErrorFound = true; 3871 } 3872 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3873 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3874 OC->getNumForLoops()) { 3875 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3876 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3877 ErrorFound = true; 3878 } 3879 if (ErrorFound) { 3880 return StmtError(); 3881 } 3882 StmtResult SR = S; 3883 unsigned CompletedRegions = 0; 3884 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3885 // Mark all variables in private list clauses as used in inner region. 3886 // Required for proper codegen of combined directives. 3887 // TODO: add processing for other clauses. 3888 if (ThisCaptureRegion != OMPD_unknown) { 3889 for (const clang::OMPClauseWithPreInit *C : PICs) { 3890 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3891 // Find the particular capture region for the clause if the 3892 // directive is a combined one with multiple capture regions. 3893 // If the directive is not a combined one, the capture region 3894 // associated with the clause is OMPD_unknown and is generated 3895 // only once. 3896 if (CaptureRegion == ThisCaptureRegion || 3897 CaptureRegion == OMPD_unknown) { 3898 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3899 for (Decl *D : DS->decls()) 3900 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3901 } 3902 } 3903 } 3904 } 3905 if (++CompletedRegions == CaptureRegions.size()) 3906 DSAStack->setBodyComplete(); 3907 SR = ActOnCapturedRegionEnd(SR.get()); 3908 } 3909 return SR; 3910 } 3911 3912 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3913 OpenMPDirectiveKind CancelRegion, 3914 SourceLocation StartLoc) { 3915 // CancelRegion is only needed for cancel and cancellation_point. 3916 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3917 return false; 3918 3919 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3920 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3921 return false; 3922 3923 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3924 << getOpenMPDirectiveName(CancelRegion); 3925 return true; 3926 } 3927 3928 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3929 OpenMPDirectiveKind CurrentRegion, 3930 const DeclarationNameInfo &CurrentName, 3931 OpenMPDirectiveKind CancelRegion, 3932 SourceLocation StartLoc) { 3933 if (Stack->getCurScope()) { 3934 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3935 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3936 bool NestingProhibited = false; 3937 bool CloseNesting = true; 3938 bool OrphanSeen = false; 3939 enum { 3940 NoRecommend, 3941 ShouldBeInParallelRegion, 3942 ShouldBeInOrderedRegion, 3943 ShouldBeInTargetRegion, 3944 ShouldBeInTeamsRegion 3945 } Recommend = NoRecommend; 3946 if (isOpenMPSimdDirective(ParentRegion) && 3947 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 3948 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 3949 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 3950 // OpenMP [2.16, Nesting of Regions] 3951 // OpenMP constructs may not be nested inside a simd region. 3952 // OpenMP [2.8.1,simd Construct, Restrictions] 3953 // An ordered construct with the simd clause is the only OpenMP 3954 // construct that can appear in the simd region. 3955 // Allowing a SIMD construct nested in another SIMD construct is an 3956 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3957 // message. 3958 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 3959 // The only OpenMP constructs that can be encountered during execution of 3960 // a simd region are the atomic construct, the loop construct, the simd 3961 // construct and the ordered construct with the simd clause. 3962 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3963 ? diag::err_omp_prohibited_region_simd 3964 : diag::warn_omp_nesting_simd) 3965 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 3966 return CurrentRegion != OMPD_simd; 3967 } 3968 if (ParentRegion == OMPD_atomic) { 3969 // OpenMP [2.16, Nesting of Regions] 3970 // OpenMP constructs may not be nested inside an atomic region. 3971 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3972 return true; 3973 } 3974 if (CurrentRegion == OMPD_section) { 3975 // OpenMP [2.7.2, sections Construct, Restrictions] 3976 // Orphaned section directives are prohibited. That is, the section 3977 // directives must appear within the sections construct and must not be 3978 // encountered elsewhere in the sections region. 3979 if (ParentRegion != OMPD_sections && 3980 ParentRegion != OMPD_parallel_sections) { 3981 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3982 << (ParentRegion != OMPD_unknown) 3983 << getOpenMPDirectiveName(ParentRegion); 3984 return true; 3985 } 3986 return false; 3987 } 3988 // Allow some constructs (except teams and cancellation constructs) to be 3989 // orphaned (they could be used in functions, called from OpenMP regions 3990 // with the required preconditions). 3991 if (ParentRegion == OMPD_unknown && 3992 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3993 CurrentRegion != OMPD_cancellation_point && 3994 CurrentRegion != OMPD_cancel) 3995 return false; 3996 if (CurrentRegion == OMPD_cancellation_point || 3997 CurrentRegion == OMPD_cancel) { 3998 // OpenMP [2.16, Nesting of Regions] 3999 // A cancellation point construct for which construct-type-clause is 4000 // taskgroup must be nested inside a task construct. A cancellation 4001 // point construct for which construct-type-clause is not taskgroup must 4002 // be closely nested inside an OpenMP construct that matches the type 4003 // specified in construct-type-clause. 4004 // A cancel construct for which construct-type-clause is taskgroup must be 4005 // nested inside a task construct. A cancel construct for which 4006 // construct-type-clause is not taskgroup must be closely nested inside an 4007 // OpenMP construct that matches the type specified in 4008 // construct-type-clause. 4009 NestingProhibited = 4010 !((CancelRegion == OMPD_parallel && 4011 (ParentRegion == OMPD_parallel || 4012 ParentRegion == OMPD_target_parallel)) || 4013 (CancelRegion == OMPD_for && 4014 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4015 ParentRegion == OMPD_target_parallel_for || 4016 ParentRegion == OMPD_distribute_parallel_for || 4017 ParentRegion == OMPD_teams_distribute_parallel_for || 4018 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4019 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 4020 (CancelRegion == OMPD_sections && 4021 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4022 ParentRegion == OMPD_parallel_sections))); 4023 OrphanSeen = ParentRegion == OMPD_unknown; 4024 } else if (CurrentRegion == OMPD_master) { 4025 // OpenMP [2.16, Nesting of Regions] 4026 // A master region may not be closely nested inside a worksharing, 4027 // atomic, or explicit task region. 4028 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4029 isOpenMPTaskingDirective(ParentRegion); 4030 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4031 // OpenMP [2.16, Nesting of Regions] 4032 // A critical region may not be nested (closely or otherwise) inside a 4033 // critical region with the same name. Note that this restriction is not 4034 // sufficient to prevent deadlock. 4035 SourceLocation PreviousCriticalLoc; 4036 bool DeadLock = Stack->hasDirective( 4037 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4038 const DeclarationNameInfo &DNI, 4039 SourceLocation Loc) { 4040 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4041 PreviousCriticalLoc = Loc; 4042 return true; 4043 } 4044 return false; 4045 }, 4046 false /* skip top directive */); 4047 if (DeadLock) { 4048 SemaRef.Diag(StartLoc, 4049 diag::err_omp_prohibited_region_critical_same_name) 4050 << CurrentName.getName(); 4051 if (PreviousCriticalLoc.isValid()) 4052 SemaRef.Diag(PreviousCriticalLoc, 4053 diag::note_omp_previous_critical_region); 4054 return true; 4055 } 4056 } else if (CurrentRegion == OMPD_barrier) { 4057 // OpenMP [2.16, Nesting of Regions] 4058 // A barrier region may not be closely nested inside a worksharing, 4059 // explicit task, critical, ordered, atomic, or master region. 4060 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4061 isOpenMPTaskingDirective(ParentRegion) || 4062 ParentRegion == OMPD_master || 4063 ParentRegion == OMPD_parallel_master || 4064 ParentRegion == OMPD_critical || 4065 ParentRegion == OMPD_ordered; 4066 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4067 !isOpenMPParallelDirective(CurrentRegion) && 4068 !isOpenMPTeamsDirective(CurrentRegion)) { 4069 // OpenMP [2.16, Nesting of Regions] 4070 // A worksharing region may not be closely nested inside a worksharing, 4071 // explicit task, critical, ordered, atomic, or master region. 4072 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4073 isOpenMPTaskingDirective(ParentRegion) || 4074 ParentRegion == OMPD_master || 4075 ParentRegion == OMPD_parallel_master || 4076 ParentRegion == OMPD_critical || 4077 ParentRegion == OMPD_ordered; 4078 Recommend = ShouldBeInParallelRegion; 4079 } else if (CurrentRegion == OMPD_ordered) { 4080 // OpenMP [2.16, Nesting of Regions] 4081 // An ordered region may not be closely nested inside a critical, 4082 // atomic, or explicit task region. 4083 // An ordered region must be closely nested inside a loop region (or 4084 // parallel loop region) with an ordered clause. 4085 // OpenMP [2.8.1,simd Construct, Restrictions] 4086 // An ordered construct with the simd clause is the only OpenMP construct 4087 // that can appear in the simd region. 4088 NestingProhibited = ParentRegion == OMPD_critical || 4089 isOpenMPTaskingDirective(ParentRegion) || 4090 !(isOpenMPSimdDirective(ParentRegion) || 4091 Stack->isParentOrderedRegion()); 4092 Recommend = ShouldBeInOrderedRegion; 4093 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4094 // OpenMP [2.16, Nesting of Regions] 4095 // If specified, a teams construct must be contained within a target 4096 // construct. 4097 NestingProhibited = 4098 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4099 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4100 ParentRegion != OMPD_target); 4101 OrphanSeen = ParentRegion == OMPD_unknown; 4102 Recommend = ShouldBeInTargetRegion; 4103 } 4104 if (!NestingProhibited && 4105 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4106 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4107 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4108 // OpenMP [2.16, Nesting of Regions] 4109 // distribute, parallel, parallel sections, parallel workshare, and the 4110 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4111 // constructs that can be closely nested in the teams region. 4112 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4113 !isOpenMPDistributeDirective(CurrentRegion); 4114 Recommend = ShouldBeInParallelRegion; 4115 } 4116 if (!NestingProhibited && 4117 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4118 // OpenMP 4.5 [2.17 Nesting of Regions] 4119 // The region associated with the distribute construct must be strictly 4120 // nested inside a teams region 4121 NestingProhibited = 4122 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4123 Recommend = ShouldBeInTeamsRegion; 4124 } 4125 if (!NestingProhibited && 4126 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4127 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4128 // OpenMP 4.5 [2.17 Nesting of Regions] 4129 // If a target, target update, target data, target enter data, or 4130 // target exit data construct is encountered during execution of a 4131 // target region, the behavior is unspecified. 4132 NestingProhibited = Stack->hasDirective( 4133 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4134 SourceLocation) { 4135 if (isOpenMPTargetExecutionDirective(K)) { 4136 OffendingRegion = K; 4137 return true; 4138 } 4139 return false; 4140 }, 4141 false /* don't skip top directive */); 4142 CloseNesting = false; 4143 } 4144 if (NestingProhibited) { 4145 if (OrphanSeen) { 4146 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4147 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4148 } else { 4149 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4150 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4151 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4152 } 4153 return true; 4154 } 4155 } 4156 return false; 4157 } 4158 4159 struct Kind2Unsigned { 4160 using argument_type = OpenMPDirectiveKind; 4161 unsigned operator()(argument_type DK) { return unsigned(DK); } 4162 }; 4163 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4164 ArrayRef<OMPClause *> Clauses, 4165 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4166 bool ErrorFound = false; 4167 unsigned NamedModifiersNumber = 0; 4168 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4169 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4170 SmallVector<SourceLocation, 4> NameModifierLoc; 4171 for (const OMPClause *C : Clauses) { 4172 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4173 // At most one if clause without a directive-name-modifier can appear on 4174 // the directive. 4175 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4176 if (FoundNameModifiers[CurNM]) { 4177 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4178 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4179 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4180 ErrorFound = true; 4181 } else if (CurNM != OMPD_unknown) { 4182 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4183 ++NamedModifiersNumber; 4184 } 4185 FoundNameModifiers[CurNM] = IC; 4186 if (CurNM == OMPD_unknown) 4187 continue; 4188 // Check if the specified name modifier is allowed for the current 4189 // directive. 4190 // At most one if clause with the particular directive-name-modifier can 4191 // appear on the directive. 4192 bool MatchFound = false; 4193 for (auto NM : AllowedNameModifiers) { 4194 if (CurNM == NM) { 4195 MatchFound = true; 4196 break; 4197 } 4198 } 4199 if (!MatchFound) { 4200 S.Diag(IC->getNameModifierLoc(), 4201 diag::err_omp_wrong_if_directive_name_modifier) 4202 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4203 ErrorFound = true; 4204 } 4205 } 4206 } 4207 // If any if clause on the directive includes a directive-name-modifier then 4208 // all if clauses on the directive must include a directive-name-modifier. 4209 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4210 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4211 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4212 diag::err_omp_no_more_if_clause); 4213 } else { 4214 std::string Values; 4215 std::string Sep(", "); 4216 unsigned AllowedCnt = 0; 4217 unsigned TotalAllowedNum = 4218 AllowedNameModifiers.size() - NamedModifiersNumber; 4219 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4220 ++Cnt) { 4221 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4222 if (!FoundNameModifiers[NM]) { 4223 Values += "'"; 4224 Values += getOpenMPDirectiveName(NM); 4225 Values += "'"; 4226 if (AllowedCnt + 2 == TotalAllowedNum) 4227 Values += " or "; 4228 else if (AllowedCnt + 1 != TotalAllowedNum) 4229 Values += Sep; 4230 ++AllowedCnt; 4231 } 4232 } 4233 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4234 diag::err_omp_unnamed_if_clause) 4235 << (TotalAllowedNum > 1) << Values; 4236 } 4237 for (SourceLocation Loc : NameModifierLoc) { 4238 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4239 } 4240 ErrorFound = true; 4241 } 4242 return ErrorFound; 4243 } 4244 4245 static std::pair<ValueDecl *, bool> 4246 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4247 SourceRange &ERange, bool AllowArraySection = false) { 4248 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4249 RefExpr->containsUnexpandedParameterPack()) 4250 return std::make_pair(nullptr, true); 4251 4252 // OpenMP [3.1, C/C++] 4253 // A list item is a variable name. 4254 // OpenMP [2.9.3.3, Restrictions, p.1] 4255 // A variable that is part of another variable (as an array or 4256 // structure element) cannot appear in a private clause. 4257 RefExpr = RefExpr->IgnoreParens(); 4258 enum { 4259 NoArrayExpr = -1, 4260 ArraySubscript = 0, 4261 OMPArraySection = 1 4262 } IsArrayExpr = NoArrayExpr; 4263 if (AllowArraySection) { 4264 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4265 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4266 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4267 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4268 RefExpr = Base; 4269 IsArrayExpr = ArraySubscript; 4270 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4271 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4272 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4273 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4274 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4275 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4276 RefExpr = Base; 4277 IsArrayExpr = OMPArraySection; 4278 } 4279 } 4280 ELoc = RefExpr->getExprLoc(); 4281 ERange = RefExpr->getSourceRange(); 4282 RefExpr = RefExpr->IgnoreParenImpCasts(); 4283 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4284 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4285 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4286 (S.getCurrentThisType().isNull() || !ME || 4287 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4288 !isa<FieldDecl>(ME->getMemberDecl()))) { 4289 if (IsArrayExpr != NoArrayExpr) { 4290 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4291 << ERange; 4292 } else { 4293 S.Diag(ELoc, 4294 AllowArraySection 4295 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4296 : diag::err_omp_expected_var_name_member_expr) 4297 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4298 } 4299 return std::make_pair(nullptr, false); 4300 } 4301 return std::make_pair( 4302 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4303 } 4304 4305 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4306 ArrayRef<OMPClause *> Clauses) { 4307 assert(!S.CurContext->isDependentContext() && 4308 "Expected non-dependent context."); 4309 auto AllocateRange = 4310 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4311 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4312 DeclToCopy; 4313 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4314 return isOpenMPPrivate(C->getClauseKind()); 4315 }); 4316 for (OMPClause *Cl : PrivateRange) { 4317 MutableArrayRef<Expr *>::iterator I, It, Et; 4318 if (Cl->getClauseKind() == OMPC_private) { 4319 auto *PC = cast<OMPPrivateClause>(Cl); 4320 I = PC->private_copies().begin(); 4321 It = PC->varlist_begin(); 4322 Et = PC->varlist_end(); 4323 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4324 auto *PC = cast<OMPFirstprivateClause>(Cl); 4325 I = PC->private_copies().begin(); 4326 It = PC->varlist_begin(); 4327 Et = PC->varlist_end(); 4328 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4329 auto *PC = cast<OMPLastprivateClause>(Cl); 4330 I = PC->private_copies().begin(); 4331 It = PC->varlist_begin(); 4332 Et = PC->varlist_end(); 4333 } else if (Cl->getClauseKind() == OMPC_linear) { 4334 auto *PC = cast<OMPLinearClause>(Cl); 4335 I = PC->privates().begin(); 4336 It = PC->varlist_begin(); 4337 Et = PC->varlist_end(); 4338 } else if (Cl->getClauseKind() == OMPC_reduction) { 4339 auto *PC = cast<OMPReductionClause>(Cl); 4340 I = PC->privates().begin(); 4341 It = PC->varlist_begin(); 4342 Et = PC->varlist_end(); 4343 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4344 auto *PC = cast<OMPTaskReductionClause>(Cl); 4345 I = PC->privates().begin(); 4346 It = PC->varlist_begin(); 4347 Et = PC->varlist_end(); 4348 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4349 auto *PC = cast<OMPInReductionClause>(Cl); 4350 I = PC->privates().begin(); 4351 It = PC->varlist_begin(); 4352 Et = PC->varlist_end(); 4353 } else { 4354 llvm_unreachable("Expected private clause."); 4355 } 4356 for (Expr *E : llvm::make_range(It, Et)) { 4357 if (!*I) { 4358 ++I; 4359 continue; 4360 } 4361 SourceLocation ELoc; 4362 SourceRange ERange; 4363 Expr *SimpleRefExpr = E; 4364 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4365 /*AllowArraySection=*/true); 4366 DeclToCopy.try_emplace(Res.first, 4367 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4368 ++I; 4369 } 4370 } 4371 for (OMPClause *C : AllocateRange) { 4372 auto *AC = cast<OMPAllocateClause>(C); 4373 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4374 getAllocatorKind(S, Stack, AC->getAllocator()); 4375 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4376 // For task, taskloop or target directives, allocation requests to memory 4377 // allocators with the trait access set to thread result in unspecified 4378 // behavior. 4379 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4380 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4381 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4382 S.Diag(AC->getAllocator()->getExprLoc(), 4383 diag::warn_omp_allocate_thread_on_task_target_directive) 4384 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4385 } 4386 for (Expr *E : AC->varlists()) { 4387 SourceLocation ELoc; 4388 SourceRange ERange; 4389 Expr *SimpleRefExpr = E; 4390 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4391 ValueDecl *VD = Res.first; 4392 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4393 if (!isOpenMPPrivate(Data.CKind)) { 4394 S.Diag(E->getExprLoc(), 4395 diag::err_omp_expected_private_copy_for_allocate); 4396 continue; 4397 } 4398 VarDecl *PrivateVD = DeclToCopy[VD]; 4399 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4400 AllocatorKind, AC->getAllocator())) 4401 continue; 4402 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4403 E->getSourceRange()); 4404 } 4405 } 4406 } 4407 4408 StmtResult Sema::ActOnOpenMPExecutableDirective( 4409 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4410 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4411 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4412 StmtResult Res = StmtError(); 4413 // First check CancelRegion which is then used in checkNestingOfRegions. 4414 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4415 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4416 StartLoc)) 4417 return StmtError(); 4418 4419 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4420 VarsWithInheritedDSAType VarsWithInheritedDSA; 4421 bool ErrorFound = false; 4422 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4423 if (AStmt && !CurContext->isDependentContext()) { 4424 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4425 4426 // Check default data sharing attributes for referenced variables. 4427 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4428 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4429 Stmt *S = AStmt; 4430 while (--ThisCaptureLevel >= 0) 4431 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4432 DSAChecker.Visit(S); 4433 if (!isOpenMPTargetDataManagementDirective(Kind) && 4434 !isOpenMPTaskingDirective(Kind)) { 4435 // Visit subcaptures to generate implicit clauses for captured vars. 4436 auto *CS = cast<CapturedStmt>(AStmt); 4437 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4438 getOpenMPCaptureRegions(CaptureRegions, Kind); 4439 // Ignore outer tasking regions for target directives. 4440 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4441 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4442 DSAChecker.visitSubCaptures(CS); 4443 } 4444 if (DSAChecker.isErrorFound()) 4445 return StmtError(); 4446 // Generate list of implicitly defined firstprivate variables. 4447 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4448 4449 SmallVector<Expr *, 4> ImplicitFirstprivates( 4450 DSAChecker.getImplicitFirstprivate().begin(), 4451 DSAChecker.getImplicitFirstprivate().end()); 4452 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4453 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4454 ArrayRef<Expr *> ImplicitMap = 4455 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4456 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4457 } 4458 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4459 for (OMPClause *C : Clauses) { 4460 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4461 for (Expr *E : IRC->taskgroup_descriptors()) 4462 if (E) 4463 ImplicitFirstprivates.emplace_back(E); 4464 } 4465 } 4466 if (!ImplicitFirstprivates.empty()) { 4467 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4468 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4469 SourceLocation())) { 4470 ClausesWithImplicit.push_back(Implicit); 4471 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4472 ImplicitFirstprivates.size(); 4473 } else { 4474 ErrorFound = true; 4475 } 4476 } 4477 int ClauseKindCnt = -1; 4478 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4479 ++ClauseKindCnt; 4480 if (ImplicitMap.empty()) 4481 continue; 4482 CXXScopeSpec MapperIdScopeSpec; 4483 DeclarationNameInfo MapperId; 4484 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4485 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4486 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4487 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4488 ImplicitMap, OMPVarListLocTy())) { 4489 ClausesWithImplicit.emplace_back(Implicit); 4490 ErrorFound |= 4491 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4492 } else { 4493 ErrorFound = true; 4494 } 4495 } 4496 } 4497 4498 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4499 switch (Kind) { 4500 case OMPD_parallel: 4501 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4502 EndLoc); 4503 AllowedNameModifiers.push_back(OMPD_parallel); 4504 break; 4505 case OMPD_simd: 4506 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4507 VarsWithInheritedDSA); 4508 if (LangOpts.OpenMP >= 50) 4509 AllowedNameModifiers.push_back(OMPD_simd); 4510 break; 4511 case OMPD_for: 4512 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4513 VarsWithInheritedDSA); 4514 break; 4515 case OMPD_for_simd: 4516 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4517 EndLoc, VarsWithInheritedDSA); 4518 if (LangOpts.OpenMP >= 50) 4519 AllowedNameModifiers.push_back(OMPD_simd); 4520 break; 4521 case OMPD_sections: 4522 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4523 EndLoc); 4524 break; 4525 case OMPD_section: 4526 assert(ClausesWithImplicit.empty() && 4527 "No clauses are allowed for 'omp section' directive"); 4528 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4529 break; 4530 case OMPD_single: 4531 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4532 EndLoc); 4533 break; 4534 case OMPD_master: 4535 assert(ClausesWithImplicit.empty() && 4536 "No clauses are allowed for 'omp master' directive"); 4537 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4538 break; 4539 case OMPD_critical: 4540 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4541 StartLoc, EndLoc); 4542 break; 4543 case OMPD_parallel_for: 4544 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4545 EndLoc, VarsWithInheritedDSA); 4546 AllowedNameModifiers.push_back(OMPD_parallel); 4547 break; 4548 case OMPD_parallel_for_simd: 4549 Res = ActOnOpenMPParallelForSimdDirective( 4550 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4551 AllowedNameModifiers.push_back(OMPD_parallel); 4552 if (LangOpts.OpenMP >= 50) 4553 AllowedNameModifiers.push_back(OMPD_simd); 4554 break; 4555 case OMPD_parallel_master: 4556 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4557 StartLoc, EndLoc); 4558 AllowedNameModifiers.push_back(OMPD_parallel); 4559 break; 4560 case OMPD_parallel_sections: 4561 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4562 StartLoc, EndLoc); 4563 AllowedNameModifiers.push_back(OMPD_parallel); 4564 break; 4565 case OMPD_task: 4566 Res = 4567 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4568 AllowedNameModifiers.push_back(OMPD_task); 4569 break; 4570 case OMPD_taskyield: 4571 assert(ClausesWithImplicit.empty() && 4572 "No clauses are allowed for 'omp taskyield' directive"); 4573 assert(AStmt == nullptr && 4574 "No associated statement allowed for 'omp taskyield' directive"); 4575 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4576 break; 4577 case OMPD_barrier: 4578 assert(ClausesWithImplicit.empty() && 4579 "No clauses are allowed for 'omp barrier' directive"); 4580 assert(AStmt == nullptr && 4581 "No associated statement allowed for 'omp barrier' directive"); 4582 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4583 break; 4584 case OMPD_taskwait: 4585 assert(ClausesWithImplicit.empty() && 4586 "No clauses are allowed for 'omp taskwait' directive"); 4587 assert(AStmt == nullptr && 4588 "No associated statement allowed for 'omp taskwait' directive"); 4589 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4590 break; 4591 case OMPD_taskgroup: 4592 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4593 EndLoc); 4594 break; 4595 case OMPD_flush: 4596 assert(AStmt == nullptr && 4597 "No associated statement allowed for 'omp flush' directive"); 4598 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4599 break; 4600 case OMPD_ordered: 4601 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4602 EndLoc); 4603 break; 4604 case OMPD_atomic: 4605 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4606 EndLoc); 4607 break; 4608 case OMPD_teams: 4609 Res = 4610 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4611 break; 4612 case OMPD_target: 4613 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4614 EndLoc); 4615 AllowedNameModifiers.push_back(OMPD_target); 4616 break; 4617 case OMPD_target_parallel: 4618 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4619 StartLoc, EndLoc); 4620 AllowedNameModifiers.push_back(OMPD_target); 4621 AllowedNameModifiers.push_back(OMPD_parallel); 4622 break; 4623 case OMPD_target_parallel_for: 4624 Res = ActOnOpenMPTargetParallelForDirective( 4625 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4626 AllowedNameModifiers.push_back(OMPD_target); 4627 AllowedNameModifiers.push_back(OMPD_parallel); 4628 break; 4629 case OMPD_cancellation_point: 4630 assert(ClausesWithImplicit.empty() && 4631 "No clauses are allowed for 'omp cancellation point' directive"); 4632 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4633 "cancellation point' directive"); 4634 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4635 break; 4636 case OMPD_cancel: 4637 assert(AStmt == nullptr && 4638 "No associated statement allowed for 'omp cancel' directive"); 4639 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4640 CancelRegion); 4641 AllowedNameModifiers.push_back(OMPD_cancel); 4642 break; 4643 case OMPD_target_data: 4644 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4645 EndLoc); 4646 AllowedNameModifiers.push_back(OMPD_target_data); 4647 break; 4648 case OMPD_target_enter_data: 4649 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4650 EndLoc, AStmt); 4651 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4652 break; 4653 case OMPD_target_exit_data: 4654 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4655 EndLoc, AStmt); 4656 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4657 break; 4658 case OMPD_taskloop: 4659 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4660 EndLoc, VarsWithInheritedDSA); 4661 AllowedNameModifiers.push_back(OMPD_taskloop); 4662 break; 4663 case OMPD_taskloop_simd: 4664 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4665 EndLoc, VarsWithInheritedDSA); 4666 AllowedNameModifiers.push_back(OMPD_taskloop); 4667 if (LangOpts.OpenMP >= 50) 4668 AllowedNameModifiers.push_back(OMPD_simd); 4669 break; 4670 case OMPD_master_taskloop: 4671 Res = ActOnOpenMPMasterTaskLoopDirective( 4672 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4673 AllowedNameModifiers.push_back(OMPD_taskloop); 4674 break; 4675 case OMPD_master_taskloop_simd: 4676 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4677 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4678 AllowedNameModifiers.push_back(OMPD_taskloop); 4679 if (LangOpts.OpenMP >= 50) 4680 AllowedNameModifiers.push_back(OMPD_simd); 4681 break; 4682 case OMPD_parallel_master_taskloop: 4683 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4684 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4685 AllowedNameModifiers.push_back(OMPD_taskloop); 4686 AllowedNameModifiers.push_back(OMPD_parallel); 4687 break; 4688 case OMPD_parallel_master_taskloop_simd: 4689 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4690 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4691 AllowedNameModifiers.push_back(OMPD_taskloop); 4692 AllowedNameModifiers.push_back(OMPD_parallel); 4693 if (LangOpts.OpenMP >= 50) 4694 AllowedNameModifiers.push_back(OMPD_simd); 4695 break; 4696 case OMPD_distribute: 4697 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4698 EndLoc, VarsWithInheritedDSA); 4699 break; 4700 case OMPD_target_update: 4701 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4702 EndLoc, AStmt); 4703 AllowedNameModifiers.push_back(OMPD_target_update); 4704 break; 4705 case OMPD_distribute_parallel_for: 4706 Res = ActOnOpenMPDistributeParallelForDirective( 4707 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4708 AllowedNameModifiers.push_back(OMPD_parallel); 4709 break; 4710 case OMPD_distribute_parallel_for_simd: 4711 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4712 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4713 AllowedNameModifiers.push_back(OMPD_parallel); 4714 if (LangOpts.OpenMP >= 50) 4715 AllowedNameModifiers.push_back(OMPD_simd); 4716 break; 4717 case OMPD_distribute_simd: 4718 Res = ActOnOpenMPDistributeSimdDirective( 4719 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4720 if (LangOpts.OpenMP >= 50) 4721 AllowedNameModifiers.push_back(OMPD_simd); 4722 break; 4723 case OMPD_target_parallel_for_simd: 4724 Res = ActOnOpenMPTargetParallelForSimdDirective( 4725 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4726 AllowedNameModifiers.push_back(OMPD_target); 4727 AllowedNameModifiers.push_back(OMPD_parallel); 4728 if (LangOpts.OpenMP >= 50) 4729 AllowedNameModifiers.push_back(OMPD_simd); 4730 break; 4731 case OMPD_target_simd: 4732 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4733 EndLoc, VarsWithInheritedDSA); 4734 AllowedNameModifiers.push_back(OMPD_target); 4735 if (LangOpts.OpenMP >= 50) 4736 AllowedNameModifiers.push_back(OMPD_simd); 4737 break; 4738 case OMPD_teams_distribute: 4739 Res = ActOnOpenMPTeamsDistributeDirective( 4740 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4741 break; 4742 case OMPD_teams_distribute_simd: 4743 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4744 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4745 if (LangOpts.OpenMP >= 50) 4746 AllowedNameModifiers.push_back(OMPD_simd); 4747 break; 4748 case OMPD_teams_distribute_parallel_for_simd: 4749 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4750 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4751 AllowedNameModifiers.push_back(OMPD_parallel); 4752 if (LangOpts.OpenMP >= 50) 4753 AllowedNameModifiers.push_back(OMPD_simd); 4754 break; 4755 case OMPD_teams_distribute_parallel_for: 4756 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4757 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4758 AllowedNameModifiers.push_back(OMPD_parallel); 4759 break; 4760 case OMPD_target_teams: 4761 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4762 EndLoc); 4763 AllowedNameModifiers.push_back(OMPD_target); 4764 break; 4765 case OMPD_target_teams_distribute: 4766 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4767 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4768 AllowedNameModifiers.push_back(OMPD_target); 4769 break; 4770 case OMPD_target_teams_distribute_parallel_for: 4771 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4772 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4773 AllowedNameModifiers.push_back(OMPD_target); 4774 AllowedNameModifiers.push_back(OMPD_parallel); 4775 break; 4776 case OMPD_target_teams_distribute_parallel_for_simd: 4777 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4778 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4779 AllowedNameModifiers.push_back(OMPD_target); 4780 AllowedNameModifiers.push_back(OMPD_parallel); 4781 break; 4782 case OMPD_target_teams_distribute_simd: 4783 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4784 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4785 AllowedNameModifiers.push_back(OMPD_target); 4786 break; 4787 case OMPD_declare_target: 4788 case OMPD_end_declare_target: 4789 case OMPD_threadprivate: 4790 case OMPD_allocate: 4791 case OMPD_declare_reduction: 4792 case OMPD_declare_mapper: 4793 case OMPD_declare_simd: 4794 case OMPD_requires: 4795 case OMPD_declare_variant: 4796 llvm_unreachable("OpenMP Directive is not allowed"); 4797 case OMPD_unknown: 4798 llvm_unreachable("Unknown OpenMP directive"); 4799 } 4800 4801 ErrorFound = Res.isInvalid() || ErrorFound; 4802 4803 // Check variables in the clauses if default(none) was specified. 4804 if (DSAStack->getDefaultDSA() == DSA_none) { 4805 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4806 for (OMPClause *C : Clauses) { 4807 switch (C->getClauseKind()) { 4808 case OMPC_num_threads: 4809 case OMPC_dist_schedule: 4810 // Do not analyse if no parent teams directive. 4811 if (isOpenMPTeamsDirective(Kind)) 4812 break; 4813 continue; 4814 case OMPC_if: 4815 if (isOpenMPTeamsDirective(Kind) && 4816 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4817 break; 4818 if (isOpenMPParallelDirective(Kind) && 4819 isOpenMPTaskLoopDirective(Kind) && 4820 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 4821 break; 4822 continue; 4823 case OMPC_schedule: 4824 break; 4825 case OMPC_grainsize: 4826 case OMPC_num_tasks: 4827 case OMPC_final: 4828 case OMPC_priority: 4829 // Do not analyze if no parent parallel directive. 4830 if (isOpenMPParallelDirective(Kind)) 4831 break; 4832 continue; 4833 case OMPC_ordered: 4834 case OMPC_device: 4835 case OMPC_num_teams: 4836 case OMPC_thread_limit: 4837 case OMPC_hint: 4838 case OMPC_collapse: 4839 case OMPC_safelen: 4840 case OMPC_simdlen: 4841 case OMPC_default: 4842 case OMPC_proc_bind: 4843 case OMPC_private: 4844 case OMPC_firstprivate: 4845 case OMPC_lastprivate: 4846 case OMPC_shared: 4847 case OMPC_reduction: 4848 case OMPC_task_reduction: 4849 case OMPC_in_reduction: 4850 case OMPC_linear: 4851 case OMPC_aligned: 4852 case OMPC_copyin: 4853 case OMPC_copyprivate: 4854 case OMPC_nowait: 4855 case OMPC_untied: 4856 case OMPC_mergeable: 4857 case OMPC_allocate: 4858 case OMPC_read: 4859 case OMPC_write: 4860 case OMPC_update: 4861 case OMPC_capture: 4862 case OMPC_seq_cst: 4863 case OMPC_depend: 4864 case OMPC_threads: 4865 case OMPC_simd: 4866 case OMPC_map: 4867 case OMPC_nogroup: 4868 case OMPC_defaultmap: 4869 case OMPC_to: 4870 case OMPC_from: 4871 case OMPC_use_device_ptr: 4872 case OMPC_is_device_ptr: 4873 continue; 4874 case OMPC_allocator: 4875 case OMPC_flush: 4876 case OMPC_threadprivate: 4877 case OMPC_uniform: 4878 case OMPC_unknown: 4879 case OMPC_unified_address: 4880 case OMPC_unified_shared_memory: 4881 case OMPC_reverse_offload: 4882 case OMPC_dynamic_allocators: 4883 case OMPC_atomic_default_mem_order: 4884 case OMPC_device_type: 4885 case OMPC_match: 4886 llvm_unreachable("Unexpected clause"); 4887 } 4888 for (Stmt *CC : C->children()) { 4889 if (CC) 4890 DSAChecker.Visit(CC); 4891 } 4892 } 4893 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4894 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4895 } 4896 for (const auto &P : VarsWithInheritedDSA) { 4897 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4898 continue; 4899 ErrorFound = true; 4900 if (DSAStack->getDefaultDSA() == DSA_none) { 4901 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4902 << P.first << P.second->getSourceRange(); 4903 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4904 } else if (getLangOpts().OpenMP >= 50) { 4905 Diag(P.second->getExprLoc(), 4906 diag::err_omp_defaultmap_no_attr_for_variable) 4907 << P.first << P.second->getSourceRange(); 4908 Diag(DSAStack->getDefaultDSALocation(), 4909 diag::note_omp_defaultmap_attr_none); 4910 } 4911 } 4912 4913 if (!AllowedNameModifiers.empty()) 4914 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4915 ErrorFound; 4916 4917 if (ErrorFound) 4918 return StmtError(); 4919 4920 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4921 Res.getAs<OMPExecutableDirective>() 4922 ->getStructuredBlock() 4923 ->setIsOMPStructuredBlock(true); 4924 } 4925 4926 if (!CurContext->isDependentContext() && 4927 isOpenMPTargetExecutionDirective(Kind) && 4928 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4929 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4930 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4931 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4932 // Register target to DSA Stack. 4933 DSAStack->addTargetDirLocation(StartLoc); 4934 } 4935 4936 return Res; 4937 } 4938 4939 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4940 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4941 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4942 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4943 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4944 assert(Aligneds.size() == Alignments.size()); 4945 assert(Linears.size() == LinModifiers.size()); 4946 assert(Linears.size() == Steps.size()); 4947 if (!DG || DG.get().isNull()) 4948 return DeclGroupPtrTy(); 4949 4950 const int SimdId = 0; 4951 if (!DG.get().isSingleDecl()) { 4952 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4953 << SimdId; 4954 return DG; 4955 } 4956 Decl *ADecl = DG.get().getSingleDecl(); 4957 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4958 ADecl = FTD->getTemplatedDecl(); 4959 4960 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4961 if (!FD) { 4962 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4963 return DeclGroupPtrTy(); 4964 } 4965 4966 // OpenMP [2.8.2, declare simd construct, Description] 4967 // The parameter of the simdlen clause must be a constant positive integer 4968 // expression. 4969 ExprResult SL; 4970 if (Simdlen) 4971 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4972 // OpenMP [2.8.2, declare simd construct, Description] 4973 // The special this pointer can be used as if was one of the arguments to the 4974 // function in any of the linear, aligned, or uniform clauses. 4975 // The uniform clause declares one or more arguments to have an invariant 4976 // value for all concurrent invocations of the function in the execution of a 4977 // single SIMD loop. 4978 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4979 const Expr *UniformedLinearThis = nullptr; 4980 for (const Expr *E : Uniforms) { 4981 E = E->IgnoreParenImpCasts(); 4982 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4983 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4984 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4985 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4986 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4987 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4988 continue; 4989 } 4990 if (isa<CXXThisExpr>(E)) { 4991 UniformedLinearThis = E; 4992 continue; 4993 } 4994 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4995 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4996 } 4997 // OpenMP [2.8.2, declare simd construct, Description] 4998 // The aligned clause declares that the object to which each list item points 4999 // is aligned to the number of bytes expressed in the optional parameter of 5000 // the aligned clause. 5001 // The special this pointer can be used as if was one of the arguments to the 5002 // function in any of the linear, aligned, or uniform clauses. 5003 // The type of list items appearing in the aligned clause must be array, 5004 // pointer, reference to array, or reference to pointer. 5005 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5006 const Expr *AlignedThis = nullptr; 5007 for (const Expr *E : Aligneds) { 5008 E = E->IgnoreParenImpCasts(); 5009 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5010 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5011 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5012 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5013 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5014 ->getCanonicalDecl() == CanonPVD) { 5015 // OpenMP [2.8.1, simd construct, Restrictions] 5016 // A list-item cannot appear in more than one aligned clause. 5017 if (AlignedArgs.count(CanonPVD) > 0) { 5018 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 5019 << 1 << E->getSourceRange(); 5020 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5021 diag::note_omp_explicit_dsa) 5022 << getOpenMPClauseName(OMPC_aligned); 5023 continue; 5024 } 5025 AlignedArgs[CanonPVD] = E; 5026 QualType QTy = PVD->getType() 5027 .getNonReferenceType() 5028 .getUnqualifiedType() 5029 .getCanonicalType(); 5030 const Type *Ty = QTy.getTypePtrOrNull(); 5031 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5032 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5033 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5034 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5035 } 5036 continue; 5037 } 5038 } 5039 if (isa<CXXThisExpr>(E)) { 5040 if (AlignedThis) { 5041 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 5042 << 2 << E->getSourceRange(); 5043 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5044 << getOpenMPClauseName(OMPC_aligned); 5045 } 5046 AlignedThis = E; 5047 continue; 5048 } 5049 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5050 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5051 } 5052 // The optional parameter of the aligned clause, alignment, must be a constant 5053 // positive integer expression. If no optional parameter is specified, 5054 // implementation-defined default alignments for SIMD instructions on the 5055 // target platforms are assumed. 5056 SmallVector<const Expr *, 4> NewAligns; 5057 for (Expr *E : Alignments) { 5058 ExprResult Align; 5059 if (E) 5060 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5061 NewAligns.push_back(Align.get()); 5062 } 5063 // OpenMP [2.8.2, declare simd construct, Description] 5064 // The linear clause declares one or more list items to be private to a SIMD 5065 // lane and to have a linear relationship with respect to the iteration space 5066 // of a loop. 5067 // The special this pointer can be used as if was one of the arguments to the 5068 // function in any of the linear, aligned, or uniform clauses. 5069 // When a linear-step expression is specified in a linear clause it must be 5070 // either a constant integer expression or an integer-typed parameter that is 5071 // specified in a uniform clause on the directive. 5072 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5073 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5074 auto MI = LinModifiers.begin(); 5075 for (const Expr *E : Linears) { 5076 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5077 ++MI; 5078 E = E->IgnoreParenImpCasts(); 5079 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5080 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5081 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5082 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5083 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5084 ->getCanonicalDecl() == CanonPVD) { 5085 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5086 // A list-item cannot appear in more than one linear clause. 5087 if (LinearArgs.count(CanonPVD) > 0) { 5088 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5089 << getOpenMPClauseName(OMPC_linear) 5090 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5091 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5092 diag::note_omp_explicit_dsa) 5093 << getOpenMPClauseName(OMPC_linear); 5094 continue; 5095 } 5096 // Each argument can appear in at most one uniform or linear clause. 5097 if (UniformedArgs.count(CanonPVD) > 0) { 5098 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5099 << getOpenMPClauseName(OMPC_linear) 5100 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5101 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5102 diag::note_omp_explicit_dsa) 5103 << getOpenMPClauseName(OMPC_uniform); 5104 continue; 5105 } 5106 LinearArgs[CanonPVD] = E; 5107 if (E->isValueDependent() || E->isTypeDependent() || 5108 E->isInstantiationDependent() || 5109 E->containsUnexpandedParameterPack()) 5110 continue; 5111 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5112 PVD->getOriginalType()); 5113 continue; 5114 } 5115 } 5116 if (isa<CXXThisExpr>(E)) { 5117 if (UniformedLinearThis) { 5118 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5119 << getOpenMPClauseName(OMPC_linear) 5120 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5121 << E->getSourceRange(); 5122 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5123 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5124 : OMPC_linear); 5125 continue; 5126 } 5127 UniformedLinearThis = E; 5128 if (E->isValueDependent() || E->isTypeDependent() || 5129 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5130 continue; 5131 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5132 E->getType()); 5133 continue; 5134 } 5135 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5136 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5137 } 5138 Expr *Step = nullptr; 5139 Expr *NewStep = nullptr; 5140 SmallVector<Expr *, 4> NewSteps; 5141 for (Expr *E : Steps) { 5142 // Skip the same step expression, it was checked already. 5143 if (Step == E || !E) { 5144 NewSteps.push_back(E ? NewStep : nullptr); 5145 continue; 5146 } 5147 Step = E; 5148 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5149 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5150 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5151 if (UniformedArgs.count(CanonPVD) == 0) { 5152 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5153 << Step->getSourceRange(); 5154 } else if (E->isValueDependent() || E->isTypeDependent() || 5155 E->isInstantiationDependent() || 5156 E->containsUnexpandedParameterPack() || 5157 CanonPVD->getType()->hasIntegerRepresentation()) { 5158 NewSteps.push_back(Step); 5159 } else { 5160 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5161 << Step->getSourceRange(); 5162 } 5163 continue; 5164 } 5165 NewStep = Step; 5166 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5167 !Step->isInstantiationDependent() && 5168 !Step->containsUnexpandedParameterPack()) { 5169 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5170 .get(); 5171 if (NewStep) 5172 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5173 } 5174 NewSteps.push_back(NewStep); 5175 } 5176 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5177 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5178 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5179 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5180 const_cast<Expr **>(Linears.data()), Linears.size(), 5181 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5182 NewSteps.data(), NewSteps.size(), SR); 5183 ADecl->addAttr(NewAttr); 5184 return DG; 5185 } 5186 5187 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5188 QualType NewType) { 5189 assert(NewType->isFunctionProtoType() && 5190 "Expected function type with prototype."); 5191 assert(FD->getType()->isFunctionNoProtoType() && 5192 "Expected function with type with no prototype."); 5193 assert(FDWithProto->getType()->isFunctionProtoType() && 5194 "Expected function with prototype."); 5195 // Synthesize parameters with the same types. 5196 FD->setType(NewType); 5197 SmallVector<ParmVarDecl *, 16> Params; 5198 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5199 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5200 SourceLocation(), nullptr, P->getType(), 5201 /*TInfo=*/nullptr, SC_None, nullptr); 5202 Param->setScopeInfo(0, Params.size()); 5203 Param->setImplicit(); 5204 Params.push_back(Param); 5205 } 5206 5207 FD->setParams(Params); 5208 } 5209 5210 Optional<std::pair<FunctionDecl *, Expr *>> 5211 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5212 Expr *VariantRef, SourceRange SR) { 5213 if (!DG || DG.get().isNull()) 5214 return None; 5215 5216 const int VariantId = 1; 5217 // Must be applied only to single decl. 5218 if (!DG.get().isSingleDecl()) { 5219 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5220 << VariantId << SR; 5221 return None; 5222 } 5223 Decl *ADecl = DG.get().getSingleDecl(); 5224 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5225 ADecl = FTD->getTemplatedDecl(); 5226 5227 // Decl must be a function. 5228 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5229 if (!FD) { 5230 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5231 << VariantId << SR; 5232 return None; 5233 } 5234 5235 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5236 return FD->hasAttrs() && 5237 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5238 FD->hasAttr<TargetAttr>()); 5239 }; 5240 // OpenMP is not compatible with CPU-specific attributes. 5241 if (HasMultiVersionAttributes(FD)) { 5242 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5243 << SR; 5244 return None; 5245 } 5246 5247 // Allow #pragma omp declare variant only if the function is not used. 5248 if (FD->isUsed(false)) 5249 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5250 << FD->getLocation(); 5251 5252 // Check if the function was emitted already. 5253 const FunctionDecl *Definition; 5254 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5255 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5256 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5257 << FD->getLocation(); 5258 5259 // The VariantRef must point to function. 5260 if (!VariantRef) { 5261 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5262 return None; 5263 } 5264 5265 // Do not check templates, wait until instantiation. 5266 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5267 VariantRef->containsUnexpandedParameterPack() || 5268 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5269 return std::make_pair(FD, VariantRef); 5270 5271 // Convert VariantRef expression to the type of the original function to 5272 // resolve possible conflicts. 5273 ExprResult VariantRefCast; 5274 if (LangOpts.CPlusPlus) { 5275 QualType FnPtrType; 5276 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5277 if (Method && !Method->isStatic()) { 5278 const Type *ClassType = 5279 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5280 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5281 ExprResult ER; 5282 { 5283 // Build adrr_of unary op to correctly handle type checks for member 5284 // functions. 5285 Sema::TentativeAnalysisScope Trap(*this); 5286 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5287 VariantRef); 5288 } 5289 if (!ER.isUsable()) { 5290 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5291 << VariantId << VariantRef->getSourceRange(); 5292 return None; 5293 } 5294 VariantRef = ER.get(); 5295 } else { 5296 FnPtrType = Context.getPointerType(FD->getType()); 5297 } 5298 ImplicitConversionSequence ICS = 5299 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5300 /*SuppressUserConversions=*/false, 5301 /*AllowExplicit=*/false, 5302 /*InOverloadResolution=*/false, 5303 /*CStyle=*/false, 5304 /*AllowObjCWritebackConversion=*/false); 5305 if (ICS.isFailure()) { 5306 Diag(VariantRef->getExprLoc(), 5307 diag::err_omp_declare_variant_incompat_types) 5308 << VariantRef->getType() 5309 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5310 << VariantRef->getSourceRange(); 5311 return None; 5312 } 5313 VariantRefCast = PerformImplicitConversion( 5314 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5315 if (!VariantRefCast.isUsable()) 5316 return None; 5317 // Drop previously built artificial addr_of unary op for member functions. 5318 if (Method && !Method->isStatic()) { 5319 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5320 if (auto *UO = dyn_cast<UnaryOperator>( 5321 PossibleAddrOfVariantRef->IgnoreImplicit())) 5322 VariantRefCast = UO->getSubExpr(); 5323 } 5324 } else { 5325 VariantRefCast = VariantRef; 5326 } 5327 5328 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5329 if (!ER.isUsable() || 5330 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5331 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5332 << VariantId << VariantRef->getSourceRange(); 5333 return None; 5334 } 5335 5336 // The VariantRef must point to function. 5337 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5338 if (!DRE) { 5339 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5340 << VariantId << VariantRef->getSourceRange(); 5341 return None; 5342 } 5343 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5344 if (!NewFD) { 5345 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5346 << VariantId << VariantRef->getSourceRange(); 5347 return None; 5348 } 5349 5350 // Check if function types are compatible in C. 5351 if (!LangOpts.CPlusPlus) { 5352 QualType NewType = 5353 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5354 if (NewType.isNull()) { 5355 Diag(VariantRef->getExprLoc(), 5356 diag::err_omp_declare_variant_incompat_types) 5357 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5358 return None; 5359 } 5360 if (NewType->isFunctionProtoType()) { 5361 if (FD->getType()->isFunctionNoProtoType()) 5362 setPrototype(*this, FD, NewFD, NewType); 5363 else if (NewFD->getType()->isFunctionNoProtoType()) 5364 setPrototype(*this, NewFD, FD, NewType); 5365 } 5366 } 5367 5368 // Check if variant function is not marked with declare variant directive. 5369 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5370 Diag(VariantRef->getExprLoc(), 5371 diag::warn_omp_declare_variant_marked_as_declare_variant) 5372 << VariantRef->getSourceRange(); 5373 SourceRange SR = 5374 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5375 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5376 return None; 5377 } 5378 5379 enum DoesntSupport { 5380 VirtFuncs = 1, 5381 Constructors = 3, 5382 Destructors = 4, 5383 DeletedFuncs = 5, 5384 DefaultedFuncs = 6, 5385 ConstexprFuncs = 7, 5386 ConstevalFuncs = 8, 5387 }; 5388 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5389 if (CXXFD->isVirtual()) { 5390 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5391 << VirtFuncs; 5392 return None; 5393 } 5394 5395 if (isa<CXXConstructorDecl>(FD)) { 5396 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5397 << Constructors; 5398 return None; 5399 } 5400 5401 if (isa<CXXDestructorDecl>(FD)) { 5402 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5403 << Destructors; 5404 return None; 5405 } 5406 } 5407 5408 if (FD->isDeleted()) { 5409 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5410 << DeletedFuncs; 5411 return None; 5412 } 5413 5414 if (FD->isDefaulted()) { 5415 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5416 << DefaultedFuncs; 5417 return None; 5418 } 5419 5420 if (FD->isConstexpr()) { 5421 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5422 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5423 return None; 5424 } 5425 5426 // Check general compatibility. 5427 if (areMultiversionVariantFunctionsCompatible( 5428 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5429 PartialDiagnosticAt(SourceLocation(), 5430 PartialDiagnostic::NullDiagnostic()), 5431 PartialDiagnosticAt( 5432 VariantRef->getExprLoc(), 5433 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5434 PartialDiagnosticAt(VariantRef->getExprLoc(), 5435 PDiag(diag::err_omp_declare_variant_diff) 5436 << FD->getLocation()), 5437 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5438 /*CLinkageMayDiffer=*/true)) 5439 return None; 5440 return std::make_pair(FD, cast<Expr>(DRE)); 5441 } 5442 5443 void Sema::ActOnOpenMPDeclareVariantDirective( 5444 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5445 ArrayRef<OMPCtxSelectorData> Data) { 5446 if (Data.empty()) 5447 return; 5448 SmallVector<Expr *, 4> CtxScores; 5449 SmallVector<unsigned, 4> CtxSets; 5450 SmallVector<unsigned, 4> Ctxs; 5451 SmallVector<StringRef, 4> ImplVendors, DeviceKinds; 5452 bool IsError = false; 5453 for (const OMPCtxSelectorData &D : Data) { 5454 OpenMPContextSelectorSetKind CtxSet = D.CtxSet; 5455 OpenMPContextSelectorKind Ctx = D.Ctx; 5456 if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown) 5457 return; 5458 Expr *Score = nullptr; 5459 if (D.Score.isUsable()) { 5460 Score = D.Score.get(); 5461 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5462 !Score->isInstantiationDependent() && 5463 !Score->containsUnexpandedParameterPack()) { 5464 Score = 5465 PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score) 5466 .get(); 5467 if (Score) 5468 Score = VerifyIntegerConstantExpression(Score).get(); 5469 } 5470 } else { 5471 // OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors. 5472 // The kind, arch, and isa selectors are given the values 2^l, 2^(l+1) and 5473 // 2^(l+2), respectively, where l is the number of traits in the construct 5474 // set. 5475 // TODO: implement correct logic for isa and arch traits. 5476 // TODO: take the construct context set into account when it is 5477 // implemented. 5478 int L = 0; // Currently set the number of traits in construct set to 0, 5479 // since the construct trait set in not supported yet. 5480 if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind) 5481 Score = ActOnIntegerConstant(SourceLocation(), std::pow(2, L)).get(); 5482 else 5483 Score = ActOnIntegerConstant(SourceLocation(), 0).get(); 5484 } 5485 switch (Ctx) { 5486 case OMP_CTX_vendor: 5487 assert(CtxSet == OMP_CTX_SET_implementation && 5488 "Expected implementation context selector set."); 5489 ImplVendors.append(D.Names.begin(), D.Names.end()); 5490 break; 5491 case OMP_CTX_kind: 5492 assert(CtxSet == OMP_CTX_SET_device && 5493 "Expected device context selector set."); 5494 DeviceKinds.append(D.Names.begin(), D.Names.end()); 5495 break; 5496 case OMP_CTX_unknown: 5497 llvm_unreachable("Unknown context selector kind."); 5498 } 5499 IsError = IsError || !Score; 5500 CtxSets.push_back(CtxSet); 5501 Ctxs.push_back(Ctx); 5502 CtxScores.push_back(Score); 5503 } 5504 if (!IsError) { 5505 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5506 Context, VariantRef, CtxScores.begin(), CtxScores.size(), 5507 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(), 5508 ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(), 5509 DeviceKinds.size(), SR); 5510 FD->addAttr(NewAttr); 5511 } 5512 } 5513 5514 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5515 FunctionDecl *Func, 5516 bool MightBeOdrUse) { 5517 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5518 5519 if (!Func->isDependentContext() && Func->hasAttrs()) { 5520 for (OMPDeclareVariantAttr *A : 5521 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5522 // TODO: add checks for active OpenMP context where possible. 5523 Expr *VariantRef = A->getVariantFuncRef(); 5524 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5525 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5526 if (!F->isDefined() && F->isTemplateInstantiation()) 5527 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5528 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5529 } 5530 } 5531 } 5532 5533 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5534 Stmt *AStmt, 5535 SourceLocation StartLoc, 5536 SourceLocation EndLoc) { 5537 if (!AStmt) 5538 return StmtError(); 5539 5540 auto *CS = cast<CapturedStmt>(AStmt); 5541 // 1.2.2 OpenMP Language Terminology 5542 // Structured block - An executable statement with a single entry at the 5543 // top and a single exit at the bottom. 5544 // The point of exit cannot be a branch out of the structured block. 5545 // longjmp() and throw() must not violate the entry/exit criteria. 5546 CS->getCapturedDecl()->setNothrow(); 5547 5548 setFunctionHasBranchProtectedScope(); 5549 5550 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5551 DSAStack->isCancelRegion()); 5552 } 5553 5554 namespace { 5555 /// Iteration space of a single for loop. 5556 struct LoopIterationSpace final { 5557 /// True if the condition operator is the strict compare operator (<, > or 5558 /// !=). 5559 bool IsStrictCompare = false; 5560 /// Condition of the loop. 5561 Expr *PreCond = nullptr; 5562 /// This expression calculates the number of iterations in the loop. 5563 /// It is always possible to calculate it before starting the loop. 5564 Expr *NumIterations = nullptr; 5565 /// The loop counter variable. 5566 Expr *CounterVar = nullptr; 5567 /// Private loop counter variable. 5568 Expr *PrivateCounterVar = nullptr; 5569 /// This is initializer for the initial value of #CounterVar. 5570 Expr *CounterInit = nullptr; 5571 /// This is step for the #CounterVar used to generate its update: 5572 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5573 Expr *CounterStep = nullptr; 5574 /// Should step be subtracted? 5575 bool Subtract = false; 5576 /// Source range of the loop init. 5577 SourceRange InitSrcRange; 5578 /// Source range of the loop condition. 5579 SourceRange CondSrcRange; 5580 /// Source range of the loop increment. 5581 SourceRange IncSrcRange; 5582 /// Minimum value that can have the loop control variable. Used to support 5583 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5584 /// since only such variables can be used in non-loop invariant expressions. 5585 Expr *MinValue = nullptr; 5586 /// Maximum value that can have the loop control variable. Used to support 5587 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5588 /// since only such variables can be used in non-loop invariant expressions. 5589 Expr *MaxValue = nullptr; 5590 /// true, if the lower bound depends on the outer loop control var. 5591 bool IsNonRectangularLB = false; 5592 /// true, if the upper bound depends on the outer loop control var. 5593 bool IsNonRectangularUB = false; 5594 /// Index of the loop this loop depends on and forms non-rectangular loop 5595 /// nest. 5596 unsigned LoopDependentIdx = 0; 5597 /// Final condition for the non-rectangular loop nest support. It is used to 5598 /// check that the number of iterations for this particular counter must be 5599 /// finished. 5600 Expr *FinalCondition = nullptr; 5601 }; 5602 5603 /// Helper class for checking canonical form of the OpenMP loops and 5604 /// extracting iteration space of each loop in the loop nest, that will be used 5605 /// for IR generation. 5606 class OpenMPIterationSpaceChecker { 5607 /// Reference to Sema. 5608 Sema &SemaRef; 5609 /// Data-sharing stack. 5610 DSAStackTy &Stack; 5611 /// A location for diagnostics (when there is no some better location). 5612 SourceLocation DefaultLoc; 5613 /// A location for diagnostics (when increment is not compatible). 5614 SourceLocation ConditionLoc; 5615 /// A source location for referring to loop init later. 5616 SourceRange InitSrcRange; 5617 /// A source location for referring to condition later. 5618 SourceRange ConditionSrcRange; 5619 /// A source location for referring to increment later. 5620 SourceRange IncrementSrcRange; 5621 /// Loop variable. 5622 ValueDecl *LCDecl = nullptr; 5623 /// Reference to loop variable. 5624 Expr *LCRef = nullptr; 5625 /// Lower bound (initializer for the var). 5626 Expr *LB = nullptr; 5627 /// Upper bound. 5628 Expr *UB = nullptr; 5629 /// Loop step (increment). 5630 Expr *Step = nullptr; 5631 /// This flag is true when condition is one of: 5632 /// Var < UB 5633 /// Var <= UB 5634 /// UB > Var 5635 /// UB >= Var 5636 /// This will have no value when the condition is != 5637 llvm::Optional<bool> TestIsLessOp; 5638 /// This flag is true when condition is strict ( < or > ). 5639 bool TestIsStrictOp = false; 5640 /// This flag is true when step is subtracted on each iteration. 5641 bool SubtractStep = false; 5642 /// The outer loop counter this loop depends on (if any). 5643 const ValueDecl *DepDecl = nullptr; 5644 /// Contains number of loop (starts from 1) on which loop counter init 5645 /// expression of this loop depends on. 5646 Optional<unsigned> InitDependOnLC; 5647 /// Contains number of loop (starts from 1) on which loop counter condition 5648 /// expression of this loop depends on. 5649 Optional<unsigned> CondDependOnLC; 5650 /// Checks if the provide statement depends on the loop counter. 5651 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5652 /// Original condition required for checking of the exit condition for 5653 /// non-rectangular loop. 5654 Expr *Condition = nullptr; 5655 5656 public: 5657 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5658 SourceLocation DefaultLoc) 5659 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5660 ConditionLoc(DefaultLoc) {} 5661 /// Check init-expr for canonical loop form and save loop counter 5662 /// variable - #Var and its initialization value - #LB. 5663 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5664 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5665 /// for less/greater and for strict/non-strict comparison. 5666 bool checkAndSetCond(Expr *S); 5667 /// Check incr-expr for canonical loop form and return true if it 5668 /// does not conform, otherwise save loop step (#Step). 5669 bool checkAndSetInc(Expr *S); 5670 /// Return the loop counter variable. 5671 ValueDecl *getLoopDecl() const { return LCDecl; } 5672 /// Return the reference expression to loop counter variable. 5673 Expr *getLoopDeclRefExpr() const { return LCRef; } 5674 /// Source range of the loop init. 5675 SourceRange getInitSrcRange() const { return InitSrcRange; } 5676 /// Source range of the loop condition. 5677 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5678 /// Source range of the loop increment. 5679 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5680 /// True if the step should be subtracted. 5681 bool shouldSubtractStep() const { return SubtractStep; } 5682 /// True, if the compare operator is strict (<, > or !=). 5683 bool isStrictTestOp() const { return TestIsStrictOp; } 5684 /// Build the expression to calculate the number of iterations. 5685 Expr *buildNumIterations( 5686 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5687 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5688 /// Build the precondition expression for the loops. 5689 Expr * 5690 buildPreCond(Scope *S, Expr *Cond, 5691 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5692 /// Build reference expression to the counter be used for codegen. 5693 DeclRefExpr * 5694 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5695 DSAStackTy &DSA) const; 5696 /// Build reference expression to the private counter be used for 5697 /// codegen. 5698 Expr *buildPrivateCounterVar() const; 5699 /// Build initialization of the counter be used for codegen. 5700 Expr *buildCounterInit() const; 5701 /// Build step of the counter be used for codegen. 5702 Expr *buildCounterStep() const; 5703 /// Build loop data with counter value for depend clauses in ordered 5704 /// directives. 5705 Expr * 5706 buildOrderedLoopData(Scope *S, Expr *Counter, 5707 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5708 SourceLocation Loc, Expr *Inc = nullptr, 5709 OverloadedOperatorKind OOK = OO_Amp); 5710 /// Builds the minimum value for the loop counter. 5711 std::pair<Expr *, Expr *> buildMinMaxValues( 5712 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5713 /// Builds final condition for the non-rectangular loops. 5714 Expr *buildFinalCondition(Scope *S) const; 5715 /// Return true if any expression is dependent. 5716 bool dependent() const; 5717 /// Returns true if the initializer forms non-rectangular loop. 5718 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5719 /// Returns true if the condition forms non-rectangular loop. 5720 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5721 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5722 unsigned getLoopDependentIdx() const { 5723 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5724 } 5725 5726 private: 5727 /// Check the right-hand side of an assignment in the increment 5728 /// expression. 5729 bool checkAndSetIncRHS(Expr *RHS); 5730 /// Helper to set loop counter variable and its initializer. 5731 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5732 bool EmitDiags); 5733 /// Helper to set upper bound. 5734 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5735 SourceRange SR, SourceLocation SL); 5736 /// Helper to set loop increment. 5737 bool setStep(Expr *NewStep, bool Subtract); 5738 }; 5739 5740 bool OpenMPIterationSpaceChecker::dependent() const { 5741 if (!LCDecl) { 5742 assert(!LB && !UB && !Step); 5743 return false; 5744 } 5745 return LCDecl->getType()->isDependentType() || 5746 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5747 (Step && Step->isValueDependent()); 5748 } 5749 5750 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5751 Expr *NewLCRefExpr, 5752 Expr *NewLB, bool EmitDiags) { 5753 // State consistency checking to ensure correct usage. 5754 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5755 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5756 if (!NewLCDecl || !NewLB) 5757 return true; 5758 LCDecl = getCanonicalDecl(NewLCDecl); 5759 LCRef = NewLCRefExpr; 5760 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5761 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5762 if ((Ctor->isCopyOrMoveConstructor() || 5763 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5764 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5765 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5766 LB = NewLB; 5767 if (EmitDiags) 5768 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5769 return false; 5770 } 5771 5772 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5773 llvm::Optional<bool> LessOp, 5774 bool StrictOp, SourceRange SR, 5775 SourceLocation SL) { 5776 // State consistency checking to ensure correct usage. 5777 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5778 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5779 if (!NewUB) 5780 return true; 5781 UB = NewUB; 5782 if (LessOp) 5783 TestIsLessOp = LessOp; 5784 TestIsStrictOp = StrictOp; 5785 ConditionSrcRange = SR; 5786 ConditionLoc = SL; 5787 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5788 return false; 5789 } 5790 5791 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5792 // State consistency checking to ensure correct usage. 5793 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5794 if (!NewStep) 5795 return true; 5796 if (!NewStep->isValueDependent()) { 5797 // Check that the step is integer expression. 5798 SourceLocation StepLoc = NewStep->getBeginLoc(); 5799 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5800 StepLoc, getExprAsWritten(NewStep)); 5801 if (Val.isInvalid()) 5802 return true; 5803 NewStep = Val.get(); 5804 5805 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5806 // If test-expr is of form var relational-op b and relational-op is < or 5807 // <= then incr-expr must cause var to increase on each iteration of the 5808 // loop. If test-expr is of form var relational-op b and relational-op is 5809 // > or >= then incr-expr must cause var to decrease on each iteration of 5810 // the loop. 5811 // If test-expr is of form b relational-op var and relational-op is < or 5812 // <= then incr-expr must cause var to decrease on each iteration of the 5813 // loop. If test-expr is of form b relational-op var and relational-op is 5814 // > or >= then incr-expr must cause var to increase on each iteration of 5815 // the loop. 5816 llvm::APSInt Result; 5817 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5818 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5819 bool IsConstNeg = 5820 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5821 bool IsConstPos = 5822 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5823 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5824 5825 // != with increment is treated as <; != with decrement is treated as > 5826 if (!TestIsLessOp.hasValue()) 5827 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5828 if (UB && (IsConstZero || 5829 (TestIsLessOp.getValue() ? 5830 (IsConstNeg || (IsUnsigned && Subtract)) : 5831 (IsConstPos || (IsUnsigned && !Subtract))))) { 5832 SemaRef.Diag(NewStep->getExprLoc(), 5833 diag::err_omp_loop_incr_not_compatible) 5834 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5835 SemaRef.Diag(ConditionLoc, 5836 diag::note_omp_loop_cond_requres_compatible_incr) 5837 << TestIsLessOp.getValue() << ConditionSrcRange; 5838 return true; 5839 } 5840 if (TestIsLessOp.getValue() == Subtract) { 5841 NewStep = 5842 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5843 .get(); 5844 Subtract = !Subtract; 5845 } 5846 } 5847 5848 Step = NewStep; 5849 SubtractStep = Subtract; 5850 return false; 5851 } 5852 5853 namespace { 5854 /// Checker for the non-rectangular loops. Checks if the initializer or 5855 /// condition expression references loop counter variable. 5856 class LoopCounterRefChecker final 5857 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5858 Sema &SemaRef; 5859 DSAStackTy &Stack; 5860 const ValueDecl *CurLCDecl = nullptr; 5861 const ValueDecl *DepDecl = nullptr; 5862 const ValueDecl *PrevDepDecl = nullptr; 5863 bool IsInitializer = true; 5864 unsigned BaseLoopId = 0; 5865 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5866 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5867 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5868 << (IsInitializer ? 0 : 1); 5869 return false; 5870 } 5871 const auto &&Data = Stack.isLoopControlVariable(VD); 5872 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5873 // The type of the loop iterator on which we depend may not have a random 5874 // access iterator type. 5875 if (Data.first && VD->getType()->isRecordType()) { 5876 SmallString<128> Name; 5877 llvm::raw_svector_ostream OS(Name); 5878 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5879 /*Qualified=*/true); 5880 SemaRef.Diag(E->getExprLoc(), 5881 diag::err_omp_wrong_dependency_iterator_type) 5882 << OS.str(); 5883 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5884 return false; 5885 } 5886 if (Data.first && 5887 (DepDecl || (PrevDepDecl && 5888 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5889 if (!DepDecl && PrevDepDecl) 5890 DepDecl = PrevDepDecl; 5891 SmallString<128> Name; 5892 llvm::raw_svector_ostream OS(Name); 5893 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5894 /*Qualified=*/true); 5895 SemaRef.Diag(E->getExprLoc(), 5896 diag::err_omp_invariant_or_linear_dependency) 5897 << OS.str(); 5898 return false; 5899 } 5900 if (Data.first) { 5901 DepDecl = VD; 5902 BaseLoopId = Data.first; 5903 } 5904 return Data.first; 5905 } 5906 5907 public: 5908 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5909 const ValueDecl *VD = E->getDecl(); 5910 if (isa<VarDecl>(VD)) 5911 return checkDecl(E, VD); 5912 return false; 5913 } 5914 bool VisitMemberExpr(const MemberExpr *E) { 5915 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5916 const ValueDecl *VD = E->getMemberDecl(); 5917 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5918 return checkDecl(E, VD); 5919 } 5920 return false; 5921 } 5922 bool VisitStmt(const Stmt *S) { 5923 bool Res = false; 5924 for (const Stmt *Child : S->children()) 5925 Res = (Child && Visit(Child)) || Res; 5926 return Res; 5927 } 5928 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5929 const ValueDecl *CurLCDecl, bool IsInitializer, 5930 const ValueDecl *PrevDepDecl = nullptr) 5931 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5932 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5933 unsigned getBaseLoopId() const { 5934 assert(CurLCDecl && "Expected loop dependency."); 5935 return BaseLoopId; 5936 } 5937 const ValueDecl *getDepDecl() const { 5938 assert(CurLCDecl && "Expected loop dependency."); 5939 return DepDecl; 5940 } 5941 }; 5942 } // namespace 5943 5944 Optional<unsigned> 5945 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5946 bool IsInitializer) { 5947 // Check for the non-rectangular loops. 5948 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5949 DepDecl); 5950 if (LoopStmtChecker.Visit(S)) { 5951 DepDecl = LoopStmtChecker.getDepDecl(); 5952 return LoopStmtChecker.getBaseLoopId(); 5953 } 5954 return llvm::None; 5955 } 5956 5957 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5958 // Check init-expr for canonical loop form and save loop counter 5959 // variable - #Var and its initialization value - #LB. 5960 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5961 // var = lb 5962 // integer-type var = lb 5963 // random-access-iterator-type var = lb 5964 // pointer-type var = lb 5965 // 5966 if (!S) { 5967 if (EmitDiags) { 5968 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5969 } 5970 return true; 5971 } 5972 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5973 if (!ExprTemp->cleanupsHaveSideEffects()) 5974 S = ExprTemp->getSubExpr(); 5975 5976 InitSrcRange = S->getSourceRange(); 5977 if (Expr *E = dyn_cast<Expr>(S)) 5978 S = E->IgnoreParens(); 5979 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5980 if (BO->getOpcode() == BO_Assign) { 5981 Expr *LHS = BO->getLHS()->IgnoreParens(); 5982 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5983 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5984 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5985 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5986 EmitDiags); 5987 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5988 } 5989 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5990 if (ME->isArrow() && 5991 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5992 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5993 EmitDiags); 5994 } 5995 } 5996 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5997 if (DS->isSingleDecl()) { 5998 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5999 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6000 // Accept non-canonical init form here but emit ext. warning. 6001 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6002 SemaRef.Diag(S->getBeginLoc(), 6003 diag::ext_omp_loop_not_canonical_init) 6004 << S->getSourceRange(); 6005 return setLCDeclAndLB( 6006 Var, 6007 buildDeclRefExpr(SemaRef, Var, 6008 Var->getType().getNonReferenceType(), 6009 DS->getBeginLoc()), 6010 Var->getInit(), EmitDiags); 6011 } 6012 } 6013 } 6014 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6015 if (CE->getOperator() == OO_Equal) { 6016 Expr *LHS = CE->getArg(0); 6017 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6018 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6019 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6020 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6021 EmitDiags); 6022 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6023 } 6024 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6025 if (ME->isArrow() && 6026 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6027 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6028 EmitDiags); 6029 } 6030 } 6031 } 6032 6033 if (dependent() || SemaRef.CurContext->isDependentContext()) 6034 return false; 6035 if (EmitDiags) { 6036 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6037 << S->getSourceRange(); 6038 } 6039 return true; 6040 } 6041 6042 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6043 /// variable (which may be the loop variable) if possible. 6044 static const ValueDecl *getInitLCDecl(const Expr *E) { 6045 if (!E) 6046 return nullptr; 6047 E = getExprAsWritten(E); 6048 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6049 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6050 if ((Ctor->isCopyOrMoveConstructor() || 6051 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6052 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6053 E = CE->getArg(0)->IgnoreParenImpCasts(); 6054 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6055 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6056 return getCanonicalDecl(VD); 6057 } 6058 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6059 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6060 return getCanonicalDecl(ME->getMemberDecl()); 6061 return nullptr; 6062 } 6063 6064 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6065 // Check test-expr for canonical form, save upper-bound UB, flags for 6066 // less/greater and for strict/non-strict comparison. 6067 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6068 // var relational-op b 6069 // b relational-op var 6070 // 6071 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6072 if (!S) { 6073 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6074 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6075 return true; 6076 } 6077 Condition = S; 6078 S = getExprAsWritten(S); 6079 SourceLocation CondLoc = S->getBeginLoc(); 6080 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6081 if (BO->isRelationalOp()) { 6082 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6083 return setUB(BO->getRHS(), 6084 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6085 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6086 BO->getSourceRange(), BO->getOperatorLoc()); 6087 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6088 return setUB(BO->getLHS(), 6089 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6090 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6091 BO->getSourceRange(), BO->getOperatorLoc()); 6092 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6093 return setUB( 6094 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6095 /*LessOp=*/llvm::None, 6096 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6097 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6098 if (CE->getNumArgs() == 2) { 6099 auto Op = CE->getOperator(); 6100 switch (Op) { 6101 case OO_Greater: 6102 case OO_GreaterEqual: 6103 case OO_Less: 6104 case OO_LessEqual: 6105 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6106 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6107 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6108 CE->getOperatorLoc()); 6109 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6110 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6111 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6112 CE->getOperatorLoc()); 6113 break; 6114 case OO_ExclaimEqual: 6115 if (IneqCondIsCanonical) 6116 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6117 : CE->getArg(0), 6118 /*LessOp=*/llvm::None, 6119 /*StrictOp=*/true, CE->getSourceRange(), 6120 CE->getOperatorLoc()); 6121 break; 6122 default: 6123 break; 6124 } 6125 } 6126 } 6127 if (dependent() || SemaRef.CurContext->isDependentContext()) 6128 return false; 6129 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6130 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6131 return true; 6132 } 6133 6134 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6135 // RHS of canonical loop form increment can be: 6136 // var + incr 6137 // incr + var 6138 // var - incr 6139 // 6140 RHS = RHS->IgnoreParenImpCasts(); 6141 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6142 if (BO->isAdditiveOp()) { 6143 bool IsAdd = BO->getOpcode() == BO_Add; 6144 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6145 return setStep(BO->getRHS(), !IsAdd); 6146 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6147 return setStep(BO->getLHS(), /*Subtract=*/false); 6148 } 6149 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6150 bool IsAdd = CE->getOperator() == OO_Plus; 6151 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6152 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6153 return setStep(CE->getArg(1), !IsAdd); 6154 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6155 return setStep(CE->getArg(0), /*Subtract=*/false); 6156 } 6157 } 6158 if (dependent() || SemaRef.CurContext->isDependentContext()) 6159 return false; 6160 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6161 << RHS->getSourceRange() << LCDecl; 6162 return true; 6163 } 6164 6165 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6166 // Check incr-expr for canonical loop form and return true if it 6167 // does not conform. 6168 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6169 // ++var 6170 // var++ 6171 // --var 6172 // var-- 6173 // var += incr 6174 // var -= incr 6175 // var = var + incr 6176 // var = incr + var 6177 // var = var - incr 6178 // 6179 if (!S) { 6180 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6181 return true; 6182 } 6183 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6184 if (!ExprTemp->cleanupsHaveSideEffects()) 6185 S = ExprTemp->getSubExpr(); 6186 6187 IncrementSrcRange = S->getSourceRange(); 6188 S = S->IgnoreParens(); 6189 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6190 if (UO->isIncrementDecrementOp() && 6191 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6192 return setStep(SemaRef 6193 .ActOnIntegerConstant(UO->getBeginLoc(), 6194 (UO->isDecrementOp() ? -1 : 1)) 6195 .get(), 6196 /*Subtract=*/false); 6197 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6198 switch (BO->getOpcode()) { 6199 case BO_AddAssign: 6200 case BO_SubAssign: 6201 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6202 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6203 break; 6204 case BO_Assign: 6205 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6206 return checkAndSetIncRHS(BO->getRHS()); 6207 break; 6208 default: 6209 break; 6210 } 6211 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6212 switch (CE->getOperator()) { 6213 case OO_PlusPlus: 6214 case OO_MinusMinus: 6215 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6216 return setStep(SemaRef 6217 .ActOnIntegerConstant( 6218 CE->getBeginLoc(), 6219 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6220 .get(), 6221 /*Subtract=*/false); 6222 break; 6223 case OO_PlusEqual: 6224 case OO_MinusEqual: 6225 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6226 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6227 break; 6228 case OO_Equal: 6229 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6230 return checkAndSetIncRHS(CE->getArg(1)); 6231 break; 6232 default: 6233 break; 6234 } 6235 } 6236 if (dependent() || SemaRef.CurContext->isDependentContext()) 6237 return false; 6238 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6239 << S->getSourceRange() << LCDecl; 6240 return true; 6241 } 6242 6243 static ExprResult 6244 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6245 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6246 if (SemaRef.CurContext->isDependentContext()) 6247 return ExprResult(Capture); 6248 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6249 return SemaRef.PerformImplicitConversion( 6250 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6251 /*AllowExplicit=*/true); 6252 auto I = Captures.find(Capture); 6253 if (I != Captures.end()) 6254 return buildCapture(SemaRef, Capture, I->second); 6255 DeclRefExpr *Ref = nullptr; 6256 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6257 Captures[Capture] = Ref; 6258 return Res; 6259 } 6260 6261 /// Build the expression to calculate the number of iterations. 6262 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6263 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6264 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6265 ExprResult Diff; 6266 QualType VarType = LCDecl->getType().getNonReferenceType(); 6267 if (VarType->isIntegerType() || VarType->isPointerType() || 6268 SemaRef.getLangOpts().CPlusPlus) { 6269 Expr *LBVal = LB; 6270 Expr *UBVal = UB; 6271 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6272 // max(LB(MinVal), LB(MaxVal)) 6273 if (InitDependOnLC) { 6274 const LoopIterationSpace &IS = 6275 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6276 InitDependOnLC.getValueOr( 6277 CondDependOnLC.getValueOr(0))]; 6278 if (!IS.MinValue || !IS.MaxValue) 6279 return nullptr; 6280 // OuterVar = Min 6281 ExprResult MinValue = 6282 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6283 if (!MinValue.isUsable()) 6284 return nullptr; 6285 6286 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6287 IS.CounterVar, MinValue.get()); 6288 if (!LBMinVal.isUsable()) 6289 return nullptr; 6290 // OuterVar = Min, LBVal 6291 LBMinVal = 6292 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6293 if (!LBMinVal.isUsable()) 6294 return nullptr; 6295 // (OuterVar = Min, LBVal) 6296 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6297 if (!LBMinVal.isUsable()) 6298 return nullptr; 6299 6300 // OuterVar = Max 6301 ExprResult MaxValue = 6302 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6303 if (!MaxValue.isUsable()) 6304 return nullptr; 6305 6306 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6307 IS.CounterVar, MaxValue.get()); 6308 if (!LBMaxVal.isUsable()) 6309 return nullptr; 6310 // OuterVar = Max, LBVal 6311 LBMaxVal = 6312 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6313 if (!LBMaxVal.isUsable()) 6314 return nullptr; 6315 // (OuterVar = Max, LBVal) 6316 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6317 if (!LBMaxVal.isUsable()) 6318 return nullptr; 6319 6320 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6321 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6322 if (!LBMin || !LBMax) 6323 return nullptr; 6324 // LB(MinVal) < LB(MaxVal) 6325 ExprResult MinLessMaxRes = 6326 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6327 if (!MinLessMaxRes.isUsable()) 6328 return nullptr; 6329 Expr *MinLessMax = 6330 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6331 if (!MinLessMax) 6332 return nullptr; 6333 if (TestIsLessOp.getValue()) { 6334 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6335 // LB(MaxVal)) 6336 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6337 MinLessMax, LBMin, LBMax); 6338 if (!MinLB.isUsable()) 6339 return nullptr; 6340 LBVal = MinLB.get(); 6341 } else { 6342 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6343 // LB(MaxVal)) 6344 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6345 MinLessMax, LBMax, LBMin); 6346 if (!MaxLB.isUsable()) 6347 return nullptr; 6348 LBVal = MaxLB.get(); 6349 } 6350 } 6351 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6352 // min(UB(MinVal), UB(MaxVal)) 6353 if (CondDependOnLC) { 6354 const LoopIterationSpace &IS = 6355 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6356 InitDependOnLC.getValueOr( 6357 CondDependOnLC.getValueOr(0))]; 6358 if (!IS.MinValue || !IS.MaxValue) 6359 return nullptr; 6360 // OuterVar = Min 6361 ExprResult MinValue = 6362 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6363 if (!MinValue.isUsable()) 6364 return nullptr; 6365 6366 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6367 IS.CounterVar, MinValue.get()); 6368 if (!UBMinVal.isUsable()) 6369 return nullptr; 6370 // OuterVar = Min, UBVal 6371 UBMinVal = 6372 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6373 if (!UBMinVal.isUsable()) 6374 return nullptr; 6375 // (OuterVar = Min, UBVal) 6376 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6377 if (!UBMinVal.isUsable()) 6378 return nullptr; 6379 6380 // OuterVar = Max 6381 ExprResult MaxValue = 6382 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6383 if (!MaxValue.isUsable()) 6384 return nullptr; 6385 6386 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6387 IS.CounterVar, MaxValue.get()); 6388 if (!UBMaxVal.isUsable()) 6389 return nullptr; 6390 // OuterVar = Max, UBVal 6391 UBMaxVal = 6392 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6393 if (!UBMaxVal.isUsable()) 6394 return nullptr; 6395 // (OuterVar = Max, UBVal) 6396 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6397 if (!UBMaxVal.isUsable()) 6398 return nullptr; 6399 6400 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6401 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6402 if (!UBMin || !UBMax) 6403 return nullptr; 6404 // UB(MinVal) > UB(MaxVal) 6405 ExprResult MinGreaterMaxRes = 6406 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6407 if (!MinGreaterMaxRes.isUsable()) 6408 return nullptr; 6409 Expr *MinGreaterMax = 6410 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6411 if (!MinGreaterMax) 6412 return nullptr; 6413 if (TestIsLessOp.getValue()) { 6414 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6415 // UB(MaxVal)) 6416 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6417 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6418 if (!MaxUB.isUsable()) 6419 return nullptr; 6420 UBVal = MaxUB.get(); 6421 } else { 6422 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6423 // UB(MaxVal)) 6424 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6425 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6426 if (!MinUB.isUsable()) 6427 return nullptr; 6428 UBVal = MinUB.get(); 6429 } 6430 } 6431 // Upper - Lower 6432 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6433 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6434 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6435 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6436 if (!Upper || !Lower) 6437 return nullptr; 6438 6439 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6440 6441 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6442 // BuildBinOp already emitted error, this one is to point user to upper 6443 // and lower bound, and to tell what is passed to 'operator-'. 6444 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6445 << Upper->getSourceRange() << Lower->getSourceRange(); 6446 return nullptr; 6447 } 6448 } 6449 6450 if (!Diff.isUsable()) 6451 return nullptr; 6452 6453 // Upper - Lower [- 1] 6454 if (TestIsStrictOp) 6455 Diff = SemaRef.BuildBinOp( 6456 S, DefaultLoc, BO_Sub, Diff.get(), 6457 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6458 if (!Diff.isUsable()) 6459 return nullptr; 6460 6461 // Upper - Lower [- 1] + Step 6462 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6463 if (!NewStep.isUsable()) 6464 return nullptr; 6465 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6466 if (!Diff.isUsable()) 6467 return nullptr; 6468 6469 // Parentheses (for dumping/debugging purposes only). 6470 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6471 if (!Diff.isUsable()) 6472 return nullptr; 6473 6474 // (Upper - Lower [- 1] + Step) / Step 6475 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6476 if (!Diff.isUsable()) 6477 return nullptr; 6478 6479 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6480 QualType Type = Diff.get()->getType(); 6481 ASTContext &C = SemaRef.Context; 6482 bool UseVarType = VarType->hasIntegerRepresentation() && 6483 C.getTypeSize(Type) > C.getTypeSize(VarType); 6484 if (!Type->isIntegerType() || UseVarType) { 6485 unsigned NewSize = 6486 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6487 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6488 : Type->hasSignedIntegerRepresentation(); 6489 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6490 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6491 Diff = SemaRef.PerformImplicitConversion( 6492 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6493 if (!Diff.isUsable()) 6494 return nullptr; 6495 } 6496 } 6497 if (LimitedType) { 6498 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6499 if (NewSize != C.getTypeSize(Type)) { 6500 if (NewSize < C.getTypeSize(Type)) { 6501 assert(NewSize == 64 && "incorrect loop var size"); 6502 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6503 << InitSrcRange << ConditionSrcRange; 6504 } 6505 QualType NewType = C.getIntTypeForBitwidth( 6506 NewSize, Type->hasSignedIntegerRepresentation() || 6507 C.getTypeSize(Type) < NewSize); 6508 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6509 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6510 Sema::AA_Converting, true); 6511 if (!Diff.isUsable()) 6512 return nullptr; 6513 } 6514 } 6515 } 6516 6517 return Diff.get(); 6518 } 6519 6520 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6521 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6522 // Do not build for iterators, they cannot be used in non-rectangular loop 6523 // nests. 6524 if (LCDecl->getType()->isRecordType()) 6525 return std::make_pair(nullptr, nullptr); 6526 // If we subtract, the min is in the condition, otherwise the min is in the 6527 // init value. 6528 Expr *MinExpr = nullptr; 6529 Expr *MaxExpr = nullptr; 6530 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6531 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6532 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6533 : CondDependOnLC.hasValue(); 6534 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6535 : InitDependOnLC.hasValue(); 6536 Expr *Lower = 6537 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6538 Expr *Upper = 6539 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6540 if (!Upper || !Lower) 6541 return std::make_pair(nullptr, nullptr); 6542 6543 if (TestIsLessOp.getValue()) 6544 MinExpr = Lower; 6545 else 6546 MaxExpr = Upper; 6547 6548 // Build minimum/maximum value based on number of iterations. 6549 ExprResult Diff; 6550 QualType VarType = LCDecl->getType().getNonReferenceType(); 6551 6552 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6553 if (!Diff.isUsable()) 6554 return std::make_pair(nullptr, nullptr); 6555 6556 // Upper - Lower [- 1] 6557 if (TestIsStrictOp) 6558 Diff = SemaRef.BuildBinOp( 6559 S, DefaultLoc, BO_Sub, Diff.get(), 6560 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6561 if (!Diff.isUsable()) 6562 return std::make_pair(nullptr, nullptr); 6563 6564 // Upper - Lower [- 1] + Step 6565 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6566 if (!NewStep.isUsable()) 6567 return std::make_pair(nullptr, nullptr); 6568 6569 // Parentheses (for dumping/debugging purposes only). 6570 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6571 if (!Diff.isUsable()) 6572 return std::make_pair(nullptr, nullptr); 6573 6574 // (Upper - Lower [- 1]) / Step 6575 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6576 if (!Diff.isUsable()) 6577 return std::make_pair(nullptr, nullptr); 6578 6579 // ((Upper - Lower [- 1]) / Step) * Step 6580 // Parentheses (for dumping/debugging purposes only). 6581 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6582 if (!Diff.isUsable()) 6583 return std::make_pair(nullptr, nullptr); 6584 6585 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6586 if (!Diff.isUsable()) 6587 return std::make_pair(nullptr, nullptr); 6588 6589 // Convert to the original type or ptrdiff_t, if original type is pointer. 6590 if (!VarType->isAnyPointerType() && 6591 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6592 Diff = SemaRef.PerformImplicitConversion( 6593 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6594 } else if (VarType->isAnyPointerType() && 6595 !SemaRef.Context.hasSameType( 6596 Diff.get()->getType(), 6597 SemaRef.Context.getUnsignedPointerDiffType())) { 6598 Diff = SemaRef.PerformImplicitConversion( 6599 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6600 Sema::AA_Converting, /*AllowExplicit=*/true); 6601 } 6602 if (!Diff.isUsable()) 6603 return std::make_pair(nullptr, nullptr); 6604 6605 // Parentheses (for dumping/debugging purposes only). 6606 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6607 if (!Diff.isUsable()) 6608 return std::make_pair(nullptr, nullptr); 6609 6610 if (TestIsLessOp.getValue()) { 6611 // MinExpr = Lower; 6612 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6613 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6614 if (!Diff.isUsable()) 6615 return std::make_pair(nullptr, nullptr); 6616 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6617 if (!Diff.isUsable()) 6618 return std::make_pair(nullptr, nullptr); 6619 MaxExpr = Diff.get(); 6620 } else { 6621 // MaxExpr = Upper; 6622 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6623 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6624 if (!Diff.isUsable()) 6625 return std::make_pair(nullptr, nullptr); 6626 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6627 if (!Diff.isUsable()) 6628 return std::make_pair(nullptr, nullptr); 6629 MinExpr = Diff.get(); 6630 } 6631 6632 return std::make_pair(MinExpr, MaxExpr); 6633 } 6634 6635 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6636 if (InitDependOnLC || CondDependOnLC) 6637 return Condition; 6638 return nullptr; 6639 } 6640 6641 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6642 Scope *S, Expr *Cond, 6643 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6644 // Do not build a precondition when the condition/initialization is dependent 6645 // to prevent pessimistic early loop exit. 6646 // TODO: this can be improved by calculating min/max values but not sure that 6647 // it will be very effective. 6648 if (CondDependOnLC || InitDependOnLC) 6649 return SemaRef.PerformImplicitConversion( 6650 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6651 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6652 /*AllowExplicit=*/true).get(); 6653 6654 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6655 Sema::TentativeAnalysisScope Trap(SemaRef); 6656 6657 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6658 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6659 if (!NewLB.isUsable() || !NewUB.isUsable()) 6660 return nullptr; 6661 6662 ExprResult CondExpr = 6663 SemaRef.BuildBinOp(S, DefaultLoc, 6664 TestIsLessOp.getValue() ? 6665 (TestIsStrictOp ? BO_LT : BO_LE) : 6666 (TestIsStrictOp ? BO_GT : BO_GE), 6667 NewLB.get(), NewUB.get()); 6668 if (CondExpr.isUsable()) { 6669 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6670 SemaRef.Context.BoolTy)) 6671 CondExpr = SemaRef.PerformImplicitConversion( 6672 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6673 /*AllowExplicit=*/true); 6674 } 6675 6676 // Otherwise use original loop condition and evaluate it in runtime. 6677 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6678 } 6679 6680 /// Build reference expression to the counter be used for codegen. 6681 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6682 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6683 DSAStackTy &DSA) const { 6684 auto *VD = dyn_cast<VarDecl>(LCDecl); 6685 if (!VD) { 6686 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6687 DeclRefExpr *Ref = buildDeclRefExpr( 6688 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6689 const DSAStackTy::DSAVarData Data = 6690 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6691 // If the loop control decl is explicitly marked as private, do not mark it 6692 // as captured again. 6693 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6694 Captures.insert(std::make_pair(LCRef, Ref)); 6695 return Ref; 6696 } 6697 return cast<DeclRefExpr>(LCRef); 6698 } 6699 6700 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6701 if (LCDecl && !LCDecl->isInvalidDecl()) { 6702 QualType Type = LCDecl->getType().getNonReferenceType(); 6703 VarDecl *PrivateVar = buildVarDecl( 6704 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6705 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6706 isa<VarDecl>(LCDecl) 6707 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6708 : nullptr); 6709 if (PrivateVar->isInvalidDecl()) 6710 return nullptr; 6711 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6712 } 6713 return nullptr; 6714 } 6715 6716 /// Build initialization of the counter to be used for codegen. 6717 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6718 6719 /// Build step of the counter be used for codegen. 6720 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6721 6722 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6723 Scope *S, Expr *Counter, 6724 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6725 Expr *Inc, OverloadedOperatorKind OOK) { 6726 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6727 if (!Cnt) 6728 return nullptr; 6729 if (Inc) { 6730 assert((OOK == OO_Plus || OOK == OO_Minus) && 6731 "Expected only + or - operations for depend clauses."); 6732 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6733 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6734 if (!Cnt) 6735 return nullptr; 6736 } 6737 ExprResult Diff; 6738 QualType VarType = LCDecl->getType().getNonReferenceType(); 6739 if (VarType->isIntegerType() || VarType->isPointerType() || 6740 SemaRef.getLangOpts().CPlusPlus) { 6741 // Upper - Lower 6742 Expr *Upper = TestIsLessOp.getValue() 6743 ? Cnt 6744 : tryBuildCapture(SemaRef, UB, Captures).get(); 6745 Expr *Lower = TestIsLessOp.getValue() 6746 ? tryBuildCapture(SemaRef, LB, Captures).get() 6747 : Cnt; 6748 if (!Upper || !Lower) 6749 return nullptr; 6750 6751 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6752 6753 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6754 // BuildBinOp already emitted error, this one is to point user to upper 6755 // and lower bound, and to tell what is passed to 'operator-'. 6756 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6757 << Upper->getSourceRange() << Lower->getSourceRange(); 6758 return nullptr; 6759 } 6760 } 6761 6762 if (!Diff.isUsable()) 6763 return nullptr; 6764 6765 // Parentheses (for dumping/debugging purposes only). 6766 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6767 if (!Diff.isUsable()) 6768 return nullptr; 6769 6770 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6771 if (!NewStep.isUsable()) 6772 return nullptr; 6773 // (Upper - Lower) / Step 6774 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6775 if (!Diff.isUsable()) 6776 return nullptr; 6777 6778 return Diff.get(); 6779 } 6780 } // namespace 6781 6782 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6783 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6784 assert(Init && "Expected loop in canonical form."); 6785 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6786 if (AssociatedLoops > 0 && 6787 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6788 DSAStack->loopStart(); 6789 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6790 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6791 if (ValueDecl *D = ISC.getLoopDecl()) { 6792 auto *VD = dyn_cast<VarDecl>(D); 6793 DeclRefExpr *PrivateRef = nullptr; 6794 if (!VD) { 6795 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6796 VD = Private; 6797 } else { 6798 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6799 /*WithInit=*/false); 6800 VD = cast<VarDecl>(PrivateRef->getDecl()); 6801 } 6802 } 6803 DSAStack->addLoopControlVariable(D, VD); 6804 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6805 if (LD != D->getCanonicalDecl()) { 6806 DSAStack->resetPossibleLoopCounter(); 6807 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6808 MarkDeclarationsReferencedInExpr( 6809 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6810 Var->getType().getNonLValueExprType(Context), 6811 ForLoc, /*RefersToCapture=*/true)); 6812 } 6813 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6814 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6815 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6816 // associated for-loop of a simd construct with just one associated 6817 // for-loop may be listed in a linear clause with a constant-linear-step 6818 // that is the increment of the associated for-loop. The loop iteration 6819 // variable(s) in the associated for-loop(s) of a for or parallel for 6820 // construct may be listed in a private or lastprivate clause. 6821 DSAStackTy::DSAVarData DVar = 6822 DSAStack->getTopDSA(D, /*FromParent=*/false); 6823 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6824 // is declared in the loop and it is predetermined as a private. 6825 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6826 OpenMPClauseKind PredeterminedCKind = 6827 isOpenMPSimdDirective(DKind) 6828 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6829 : OMPC_private; 6830 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6831 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6832 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6833 DVar.CKind != OMPC_private))) || 6834 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6835 DKind == OMPD_master_taskloop || 6836 DKind == OMPD_parallel_master_taskloop || 6837 isOpenMPDistributeDirective(DKind)) && 6838 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6839 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6840 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6841 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6842 << getOpenMPClauseName(DVar.CKind) 6843 << getOpenMPDirectiveName(DKind) 6844 << getOpenMPClauseName(PredeterminedCKind); 6845 if (DVar.RefExpr == nullptr) 6846 DVar.CKind = PredeterminedCKind; 6847 reportOriginalDsa(*this, DSAStack, D, DVar, 6848 /*IsLoopIterVar=*/true); 6849 } else if (LoopDeclRefExpr) { 6850 // Make the loop iteration variable private (for worksharing 6851 // constructs), linear (for simd directives with the only one 6852 // associated loop) or lastprivate (for simd directives with several 6853 // collapsed or ordered loops). 6854 if (DVar.CKind == OMPC_unknown) 6855 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6856 PrivateRef); 6857 } 6858 } 6859 } 6860 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6861 } 6862 } 6863 6864 /// Called on a for stmt to check and extract its iteration space 6865 /// for further processing (such as collapsing). 6866 static bool checkOpenMPIterationSpace( 6867 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6868 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6869 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6870 Expr *OrderedLoopCountExpr, 6871 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6872 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6873 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6874 // OpenMP [2.9.1, Canonical Loop Form] 6875 // for (init-expr; test-expr; incr-expr) structured-block 6876 // for (range-decl: range-expr) structured-block 6877 auto *For = dyn_cast_or_null<ForStmt>(S); 6878 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6879 // Ranged for is supported only in OpenMP 5.0. 6880 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6881 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6882 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6883 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6884 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6885 if (TotalNestedLoopCount > 1) { 6886 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6887 SemaRef.Diag(DSA.getConstructLoc(), 6888 diag::note_omp_collapse_ordered_expr) 6889 << 2 << CollapseLoopCountExpr->getSourceRange() 6890 << OrderedLoopCountExpr->getSourceRange(); 6891 else if (CollapseLoopCountExpr) 6892 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6893 diag::note_omp_collapse_ordered_expr) 6894 << 0 << CollapseLoopCountExpr->getSourceRange(); 6895 else 6896 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6897 diag::note_omp_collapse_ordered_expr) 6898 << 1 << OrderedLoopCountExpr->getSourceRange(); 6899 } 6900 return true; 6901 } 6902 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6903 "No loop body."); 6904 6905 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6906 For ? For->getForLoc() : CXXFor->getForLoc()); 6907 6908 // Check init. 6909 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6910 if (ISC.checkAndSetInit(Init)) 6911 return true; 6912 6913 bool HasErrors = false; 6914 6915 // Check loop variable's type. 6916 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6917 // OpenMP [2.6, Canonical Loop Form] 6918 // Var is one of the following: 6919 // A variable of signed or unsigned integer type. 6920 // For C++, a variable of a random access iterator type. 6921 // For C, a variable of a pointer type. 6922 QualType VarType = LCDecl->getType().getNonReferenceType(); 6923 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6924 !VarType->isPointerType() && 6925 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6926 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6927 << SemaRef.getLangOpts().CPlusPlus; 6928 HasErrors = true; 6929 } 6930 6931 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6932 // a Construct 6933 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6934 // parallel for construct is (are) private. 6935 // The loop iteration variable in the associated for-loop of a simd 6936 // construct with just one associated for-loop is linear with a 6937 // constant-linear-step that is the increment of the associated for-loop. 6938 // Exclude loop var from the list of variables with implicitly defined data 6939 // sharing attributes. 6940 VarsWithImplicitDSA.erase(LCDecl); 6941 6942 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6943 6944 // Check test-expr. 6945 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6946 6947 // Check incr-expr. 6948 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6949 } 6950 6951 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6952 return HasErrors; 6953 6954 // Build the loop's iteration space representation. 6955 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6956 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6957 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6958 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6959 (isOpenMPWorksharingDirective(DKind) || 6960 isOpenMPTaskLoopDirective(DKind) || 6961 isOpenMPDistributeDirective(DKind)), 6962 Captures); 6963 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6964 ISC.buildCounterVar(Captures, DSA); 6965 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6966 ISC.buildPrivateCounterVar(); 6967 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6968 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6969 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6970 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6971 ISC.getConditionSrcRange(); 6972 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6973 ISC.getIncrementSrcRange(); 6974 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6975 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6976 ISC.isStrictTestOp(); 6977 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6978 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6979 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6980 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6981 ISC.buildFinalCondition(DSA.getCurScope()); 6982 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6983 ISC.doesInitDependOnLC(); 6984 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6985 ISC.doesCondDependOnLC(); 6986 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6987 ISC.getLoopDependentIdx(); 6988 6989 HasErrors |= 6990 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6991 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6992 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6993 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6994 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6995 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6996 if (!HasErrors && DSA.isOrderedRegion()) { 6997 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6998 if (CurrentNestedLoopCount < 6999 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7000 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7001 CurrentNestedLoopCount, 7002 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7003 DSA.getOrderedRegionParam().second->setLoopCounter( 7004 CurrentNestedLoopCount, 7005 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7006 } 7007 } 7008 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7009 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7010 // Erroneous case - clause has some problems. 7011 continue; 7012 } 7013 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7014 Pair.second.size() <= CurrentNestedLoopCount) { 7015 // Erroneous case - clause has some problems. 7016 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7017 continue; 7018 } 7019 Expr *CntValue; 7020 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7021 CntValue = ISC.buildOrderedLoopData( 7022 DSA.getCurScope(), 7023 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7024 Pair.first->getDependencyLoc()); 7025 else 7026 CntValue = ISC.buildOrderedLoopData( 7027 DSA.getCurScope(), 7028 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7029 Pair.first->getDependencyLoc(), 7030 Pair.second[CurrentNestedLoopCount].first, 7031 Pair.second[CurrentNestedLoopCount].second); 7032 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7033 } 7034 } 7035 7036 return HasErrors; 7037 } 7038 7039 /// Build 'VarRef = Start. 7040 static ExprResult 7041 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7042 ExprResult Start, bool IsNonRectangularLB, 7043 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7044 // Build 'VarRef = Start. 7045 ExprResult NewStart = IsNonRectangularLB 7046 ? Start.get() 7047 : tryBuildCapture(SemaRef, Start.get(), Captures); 7048 if (!NewStart.isUsable()) 7049 return ExprError(); 7050 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7051 VarRef.get()->getType())) { 7052 NewStart = SemaRef.PerformImplicitConversion( 7053 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7054 /*AllowExplicit=*/true); 7055 if (!NewStart.isUsable()) 7056 return ExprError(); 7057 } 7058 7059 ExprResult Init = 7060 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7061 return Init; 7062 } 7063 7064 /// Build 'VarRef = Start + Iter * Step'. 7065 static ExprResult buildCounterUpdate( 7066 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7067 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7068 bool IsNonRectangularLB, 7069 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7070 // Add parentheses (for debugging purposes only). 7071 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7072 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7073 !Step.isUsable()) 7074 return ExprError(); 7075 7076 ExprResult NewStep = Step; 7077 if (Captures) 7078 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7079 if (NewStep.isInvalid()) 7080 return ExprError(); 7081 ExprResult Update = 7082 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7083 if (!Update.isUsable()) 7084 return ExprError(); 7085 7086 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7087 // 'VarRef = Start (+|-) Iter * Step'. 7088 if (!Start.isUsable()) 7089 return ExprError(); 7090 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7091 if (!NewStart.isUsable()) 7092 return ExprError(); 7093 if (Captures && !IsNonRectangularLB) 7094 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7095 if (NewStart.isInvalid()) 7096 return ExprError(); 7097 7098 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7099 ExprResult SavedUpdate = Update; 7100 ExprResult UpdateVal; 7101 if (VarRef.get()->getType()->isOverloadableType() || 7102 NewStart.get()->getType()->isOverloadableType() || 7103 Update.get()->getType()->isOverloadableType()) { 7104 Sema::TentativeAnalysisScope Trap(SemaRef); 7105 7106 Update = 7107 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7108 if (Update.isUsable()) { 7109 UpdateVal = 7110 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7111 VarRef.get(), SavedUpdate.get()); 7112 if (UpdateVal.isUsable()) { 7113 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7114 UpdateVal.get()); 7115 } 7116 } 7117 } 7118 7119 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7120 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7121 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7122 NewStart.get(), SavedUpdate.get()); 7123 if (!Update.isUsable()) 7124 return ExprError(); 7125 7126 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7127 VarRef.get()->getType())) { 7128 Update = SemaRef.PerformImplicitConversion( 7129 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7130 if (!Update.isUsable()) 7131 return ExprError(); 7132 } 7133 7134 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7135 } 7136 return Update; 7137 } 7138 7139 /// Convert integer expression \a E to make it have at least \a Bits 7140 /// bits. 7141 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7142 if (E == nullptr) 7143 return ExprError(); 7144 ASTContext &C = SemaRef.Context; 7145 QualType OldType = E->getType(); 7146 unsigned HasBits = C.getTypeSize(OldType); 7147 if (HasBits >= Bits) 7148 return ExprResult(E); 7149 // OK to convert to signed, because new type has more bits than old. 7150 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7151 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7152 true); 7153 } 7154 7155 /// Check if the given expression \a E is a constant integer that fits 7156 /// into \a Bits bits. 7157 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7158 if (E == nullptr) 7159 return false; 7160 llvm::APSInt Result; 7161 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7162 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7163 return false; 7164 } 7165 7166 /// Build preinits statement for the given declarations. 7167 static Stmt *buildPreInits(ASTContext &Context, 7168 MutableArrayRef<Decl *> PreInits) { 7169 if (!PreInits.empty()) { 7170 return new (Context) DeclStmt( 7171 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7172 SourceLocation(), SourceLocation()); 7173 } 7174 return nullptr; 7175 } 7176 7177 /// Build preinits statement for the given declarations. 7178 static Stmt * 7179 buildPreInits(ASTContext &Context, 7180 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7181 if (!Captures.empty()) { 7182 SmallVector<Decl *, 16> PreInits; 7183 for (const auto &Pair : Captures) 7184 PreInits.push_back(Pair.second->getDecl()); 7185 return buildPreInits(Context, PreInits); 7186 } 7187 return nullptr; 7188 } 7189 7190 /// Build postupdate expression for the given list of postupdates expressions. 7191 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7192 Expr *PostUpdate = nullptr; 7193 if (!PostUpdates.empty()) { 7194 for (Expr *E : PostUpdates) { 7195 Expr *ConvE = S.BuildCStyleCastExpr( 7196 E->getExprLoc(), 7197 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7198 E->getExprLoc(), E) 7199 .get(); 7200 PostUpdate = PostUpdate 7201 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7202 PostUpdate, ConvE) 7203 .get() 7204 : ConvE; 7205 } 7206 } 7207 return PostUpdate; 7208 } 7209 7210 /// Called on a for stmt to check itself and nested loops (if any). 7211 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7212 /// number of collapsed loops otherwise. 7213 static unsigned 7214 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7215 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7216 DSAStackTy &DSA, 7217 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7218 OMPLoopDirective::HelperExprs &Built) { 7219 unsigned NestedLoopCount = 1; 7220 if (CollapseLoopCountExpr) { 7221 // Found 'collapse' clause - calculate collapse number. 7222 Expr::EvalResult Result; 7223 if (!CollapseLoopCountExpr->isValueDependent() && 7224 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7225 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7226 } else { 7227 Built.clear(/*Size=*/1); 7228 return 1; 7229 } 7230 } 7231 unsigned OrderedLoopCount = 1; 7232 if (OrderedLoopCountExpr) { 7233 // Found 'ordered' clause - calculate collapse number. 7234 Expr::EvalResult EVResult; 7235 if (!OrderedLoopCountExpr->isValueDependent() && 7236 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7237 SemaRef.getASTContext())) { 7238 llvm::APSInt Result = EVResult.Val.getInt(); 7239 if (Result.getLimitedValue() < NestedLoopCount) { 7240 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7241 diag::err_omp_wrong_ordered_loop_count) 7242 << OrderedLoopCountExpr->getSourceRange(); 7243 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7244 diag::note_collapse_loop_count) 7245 << CollapseLoopCountExpr->getSourceRange(); 7246 } 7247 OrderedLoopCount = Result.getLimitedValue(); 7248 } else { 7249 Built.clear(/*Size=*/1); 7250 return 1; 7251 } 7252 } 7253 // This is helper routine for loop directives (e.g., 'for', 'simd', 7254 // 'for simd', etc.). 7255 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7256 SmallVector<LoopIterationSpace, 4> IterSpaces( 7257 std::max(OrderedLoopCount, NestedLoopCount)); 7258 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7259 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7260 if (checkOpenMPIterationSpace( 7261 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7262 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7263 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7264 return 0; 7265 // Move on to the next nested for loop, or to the loop body. 7266 // OpenMP [2.8.1, simd construct, Restrictions] 7267 // All loops associated with the construct must be perfectly nested; that 7268 // is, there must be no intervening code nor any OpenMP directive between 7269 // any two loops. 7270 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7271 CurStmt = For->getBody(); 7272 } else { 7273 assert(isa<CXXForRangeStmt>(CurStmt) && 7274 "Expected canonical for or range-based for loops."); 7275 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7276 } 7277 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7278 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7279 } 7280 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7281 if (checkOpenMPIterationSpace( 7282 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7283 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7284 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7285 return 0; 7286 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7287 // Handle initialization of captured loop iterator variables. 7288 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7289 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7290 Captures[DRE] = DRE; 7291 } 7292 } 7293 // Move on to the next nested for loop, or to the loop body. 7294 // OpenMP [2.8.1, simd construct, Restrictions] 7295 // All loops associated with the construct must be perfectly nested; that 7296 // is, there must be no intervening code nor any OpenMP directive between 7297 // any two loops. 7298 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7299 CurStmt = For->getBody(); 7300 } else { 7301 assert(isa<CXXForRangeStmt>(CurStmt) && 7302 "Expected canonical for or range-based for loops."); 7303 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7304 } 7305 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7306 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7307 } 7308 7309 Built.clear(/* size */ NestedLoopCount); 7310 7311 if (SemaRef.CurContext->isDependentContext()) 7312 return NestedLoopCount; 7313 7314 // An example of what is generated for the following code: 7315 // 7316 // #pragma omp simd collapse(2) ordered(2) 7317 // for (i = 0; i < NI; ++i) 7318 // for (k = 0; k < NK; ++k) 7319 // for (j = J0; j < NJ; j+=2) { 7320 // <loop body> 7321 // } 7322 // 7323 // We generate the code below. 7324 // Note: the loop body may be outlined in CodeGen. 7325 // Note: some counters may be C++ classes, operator- is used to find number of 7326 // iterations and operator+= to calculate counter value. 7327 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7328 // or i64 is currently supported). 7329 // 7330 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7331 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7332 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7333 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7334 // // similar updates for vars in clauses (e.g. 'linear') 7335 // <loop body (using local i and j)> 7336 // } 7337 // i = NI; // assign final values of counters 7338 // j = NJ; 7339 // 7340 7341 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7342 // the iteration counts of the collapsed for loops. 7343 // Precondition tests if there is at least one iteration (all conditions are 7344 // true). 7345 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7346 Expr *N0 = IterSpaces[0].NumIterations; 7347 ExprResult LastIteration32 = 7348 widenIterationCount(/*Bits=*/32, 7349 SemaRef 7350 .PerformImplicitConversion( 7351 N0->IgnoreImpCasts(), N0->getType(), 7352 Sema::AA_Converting, /*AllowExplicit=*/true) 7353 .get(), 7354 SemaRef); 7355 ExprResult LastIteration64 = widenIterationCount( 7356 /*Bits=*/64, 7357 SemaRef 7358 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7359 Sema::AA_Converting, 7360 /*AllowExplicit=*/true) 7361 .get(), 7362 SemaRef); 7363 7364 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7365 return NestedLoopCount; 7366 7367 ASTContext &C = SemaRef.Context; 7368 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7369 7370 Scope *CurScope = DSA.getCurScope(); 7371 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7372 if (PreCond.isUsable()) { 7373 PreCond = 7374 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7375 PreCond.get(), IterSpaces[Cnt].PreCond); 7376 } 7377 Expr *N = IterSpaces[Cnt].NumIterations; 7378 SourceLocation Loc = N->getExprLoc(); 7379 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7380 if (LastIteration32.isUsable()) 7381 LastIteration32 = SemaRef.BuildBinOp( 7382 CurScope, Loc, BO_Mul, LastIteration32.get(), 7383 SemaRef 7384 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7385 Sema::AA_Converting, 7386 /*AllowExplicit=*/true) 7387 .get()); 7388 if (LastIteration64.isUsable()) 7389 LastIteration64 = SemaRef.BuildBinOp( 7390 CurScope, Loc, BO_Mul, LastIteration64.get(), 7391 SemaRef 7392 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7393 Sema::AA_Converting, 7394 /*AllowExplicit=*/true) 7395 .get()); 7396 } 7397 7398 // Choose either the 32-bit or 64-bit version. 7399 ExprResult LastIteration = LastIteration64; 7400 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7401 (LastIteration32.isUsable() && 7402 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7403 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7404 fitsInto( 7405 /*Bits=*/32, 7406 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7407 LastIteration64.get(), SemaRef)))) 7408 LastIteration = LastIteration32; 7409 QualType VType = LastIteration.get()->getType(); 7410 QualType RealVType = VType; 7411 QualType StrideVType = VType; 7412 if (isOpenMPTaskLoopDirective(DKind)) { 7413 VType = 7414 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7415 StrideVType = 7416 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7417 } 7418 7419 if (!LastIteration.isUsable()) 7420 return 0; 7421 7422 // Save the number of iterations. 7423 ExprResult NumIterations = LastIteration; 7424 { 7425 LastIteration = SemaRef.BuildBinOp( 7426 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7427 LastIteration.get(), 7428 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7429 if (!LastIteration.isUsable()) 7430 return 0; 7431 } 7432 7433 // Calculate the last iteration number beforehand instead of doing this on 7434 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7435 llvm::APSInt Result; 7436 bool IsConstant = 7437 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7438 ExprResult CalcLastIteration; 7439 if (!IsConstant) { 7440 ExprResult SaveRef = 7441 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7442 LastIteration = SaveRef; 7443 7444 // Prepare SaveRef + 1. 7445 NumIterations = SemaRef.BuildBinOp( 7446 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7447 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7448 if (!NumIterations.isUsable()) 7449 return 0; 7450 } 7451 7452 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7453 7454 // Build variables passed into runtime, necessary for worksharing directives. 7455 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7456 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7457 isOpenMPDistributeDirective(DKind)) { 7458 // Lower bound variable, initialized with zero. 7459 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7460 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7461 SemaRef.AddInitializerToDecl(LBDecl, 7462 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7463 /*DirectInit*/ false); 7464 7465 // Upper bound variable, initialized with last iteration number. 7466 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7467 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7468 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7469 /*DirectInit*/ false); 7470 7471 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7472 // This will be used to implement clause 'lastprivate'. 7473 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7474 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7475 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7476 SemaRef.AddInitializerToDecl(ILDecl, 7477 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7478 /*DirectInit*/ false); 7479 7480 // Stride variable returned by runtime (we initialize it to 1 by default). 7481 VarDecl *STDecl = 7482 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7483 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7484 SemaRef.AddInitializerToDecl(STDecl, 7485 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7486 /*DirectInit*/ false); 7487 7488 // Build expression: UB = min(UB, LastIteration) 7489 // It is necessary for CodeGen of directives with static scheduling. 7490 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7491 UB.get(), LastIteration.get()); 7492 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7493 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7494 LastIteration.get(), UB.get()); 7495 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7496 CondOp.get()); 7497 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7498 7499 // If we have a combined directive that combines 'distribute', 'for' or 7500 // 'simd' we need to be able to access the bounds of the schedule of the 7501 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7502 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7503 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7504 // Lower bound variable, initialized with zero. 7505 VarDecl *CombLBDecl = 7506 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7507 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7508 SemaRef.AddInitializerToDecl( 7509 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7510 /*DirectInit*/ false); 7511 7512 // Upper bound variable, initialized with last iteration number. 7513 VarDecl *CombUBDecl = 7514 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7515 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7516 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7517 /*DirectInit*/ false); 7518 7519 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7520 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7521 ExprResult CombCondOp = 7522 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7523 LastIteration.get(), CombUB.get()); 7524 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7525 CombCondOp.get()); 7526 CombEUB = 7527 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7528 7529 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7530 // We expect to have at least 2 more parameters than the 'parallel' 7531 // directive does - the lower and upper bounds of the previous schedule. 7532 assert(CD->getNumParams() >= 4 && 7533 "Unexpected number of parameters in loop combined directive"); 7534 7535 // Set the proper type for the bounds given what we learned from the 7536 // enclosed loops. 7537 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7538 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7539 7540 // Previous lower and upper bounds are obtained from the region 7541 // parameters. 7542 PrevLB = 7543 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7544 PrevUB = 7545 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7546 } 7547 } 7548 7549 // Build the iteration variable and its initialization before loop. 7550 ExprResult IV; 7551 ExprResult Init, CombInit; 7552 { 7553 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7554 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7555 Expr *RHS = 7556 (isOpenMPWorksharingDirective(DKind) || 7557 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7558 ? LB.get() 7559 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7560 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7561 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7562 7563 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7564 Expr *CombRHS = 7565 (isOpenMPWorksharingDirective(DKind) || 7566 isOpenMPTaskLoopDirective(DKind) || 7567 isOpenMPDistributeDirective(DKind)) 7568 ? CombLB.get() 7569 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7570 CombInit = 7571 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7572 CombInit = 7573 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7574 } 7575 } 7576 7577 bool UseStrictCompare = 7578 RealVType->hasUnsignedIntegerRepresentation() && 7579 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7580 return LIS.IsStrictCompare; 7581 }); 7582 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7583 // unsigned IV)) for worksharing loops. 7584 SourceLocation CondLoc = AStmt->getBeginLoc(); 7585 Expr *BoundUB = UB.get(); 7586 if (UseStrictCompare) { 7587 BoundUB = 7588 SemaRef 7589 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7590 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7591 .get(); 7592 BoundUB = 7593 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7594 } 7595 ExprResult Cond = 7596 (isOpenMPWorksharingDirective(DKind) || 7597 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7598 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7599 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7600 BoundUB) 7601 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7602 NumIterations.get()); 7603 ExprResult CombDistCond; 7604 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7605 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7606 NumIterations.get()); 7607 } 7608 7609 ExprResult CombCond; 7610 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7611 Expr *BoundCombUB = CombUB.get(); 7612 if (UseStrictCompare) { 7613 BoundCombUB = 7614 SemaRef 7615 .BuildBinOp( 7616 CurScope, CondLoc, BO_Add, BoundCombUB, 7617 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7618 .get(); 7619 BoundCombUB = 7620 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7621 .get(); 7622 } 7623 CombCond = 7624 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7625 IV.get(), BoundCombUB); 7626 } 7627 // Loop increment (IV = IV + 1) 7628 SourceLocation IncLoc = AStmt->getBeginLoc(); 7629 ExprResult Inc = 7630 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7631 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7632 if (!Inc.isUsable()) 7633 return 0; 7634 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7635 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7636 if (!Inc.isUsable()) 7637 return 0; 7638 7639 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7640 // Used for directives with static scheduling. 7641 // In combined construct, add combined version that use CombLB and CombUB 7642 // base variables for the update 7643 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7644 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7645 isOpenMPDistributeDirective(DKind)) { 7646 // LB + ST 7647 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7648 if (!NextLB.isUsable()) 7649 return 0; 7650 // LB = LB + ST 7651 NextLB = 7652 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7653 NextLB = 7654 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7655 if (!NextLB.isUsable()) 7656 return 0; 7657 // UB + ST 7658 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7659 if (!NextUB.isUsable()) 7660 return 0; 7661 // UB = UB + ST 7662 NextUB = 7663 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7664 NextUB = 7665 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7666 if (!NextUB.isUsable()) 7667 return 0; 7668 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7669 CombNextLB = 7670 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7671 if (!NextLB.isUsable()) 7672 return 0; 7673 // LB = LB + ST 7674 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7675 CombNextLB.get()); 7676 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7677 /*DiscardedValue*/ false); 7678 if (!CombNextLB.isUsable()) 7679 return 0; 7680 // UB + ST 7681 CombNextUB = 7682 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7683 if (!CombNextUB.isUsable()) 7684 return 0; 7685 // UB = UB + ST 7686 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7687 CombNextUB.get()); 7688 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7689 /*DiscardedValue*/ false); 7690 if (!CombNextUB.isUsable()) 7691 return 0; 7692 } 7693 } 7694 7695 // Create increment expression for distribute loop when combined in a same 7696 // directive with for as IV = IV + ST; ensure upper bound expression based 7697 // on PrevUB instead of NumIterations - used to implement 'for' when found 7698 // in combination with 'distribute', like in 'distribute parallel for' 7699 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7700 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7701 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7702 DistCond = SemaRef.BuildBinOp( 7703 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7704 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7705 7706 DistInc = 7707 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7708 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7709 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7710 DistInc.get()); 7711 DistInc = 7712 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7713 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7714 7715 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7716 // construct 7717 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7718 ExprResult IsUBGreater = 7719 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7720 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7721 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7722 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7723 CondOp.get()); 7724 PrevEUB = 7725 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7726 7727 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7728 // parallel for is in combination with a distribute directive with 7729 // schedule(static, 1) 7730 Expr *BoundPrevUB = PrevUB.get(); 7731 if (UseStrictCompare) { 7732 BoundPrevUB = 7733 SemaRef 7734 .BuildBinOp( 7735 CurScope, CondLoc, BO_Add, BoundPrevUB, 7736 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7737 .get(); 7738 BoundPrevUB = 7739 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7740 .get(); 7741 } 7742 ParForInDistCond = 7743 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7744 IV.get(), BoundPrevUB); 7745 } 7746 7747 // Build updates and final values of the loop counters. 7748 bool HasErrors = false; 7749 Built.Counters.resize(NestedLoopCount); 7750 Built.Inits.resize(NestedLoopCount); 7751 Built.Updates.resize(NestedLoopCount); 7752 Built.Finals.resize(NestedLoopCount); 7753 Built.DependentCounters.resize(NestedLoopCount); 7754 Built.DependentInits.resize(NestedLoopCount); 7755 Built.FinalsConditions.resize(NestedLoopCount); 7756 { 7757 // We implement the following algorithm for obtaining the 7758 // original loop iteration variable values based on the 7759 // value of the collapsed loop iteration variable IV. 7760 // 7761 // Let n+1 be the number of collapsed loops in the nest. 7762 // Iteration variables (I0, I1, .... In) 7763 // Iteration counts (N0, N1, ... Nn) 7764 // 7765 // Acc = IV; 7766 // 7767 // To compute Ik for loop k, 0 <= k <= n, generate: 7768 // Prod = N(k+1) * N(k+2) * ... * Nn; 7769 // Ik = Acc / Prod; 7770 // Acc -= Ik * Prod; 7771 // 7772 ExprResult Acc = IV; 7773 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7774 LoopIterationSpace &IS = IterSpaces[Cnt]; 7775 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7776 ExprResult Iter; 7777 7778 // Compute prod 7779 ExprResult Prod = 7780 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7781 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7782 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7783 IterSpaces[K].NumIterations); 7784 7785 // Iter = Acc / Prod 7786 // If there is at least one more inner loop to avoid 7787 // multiplication by 1. 7788 if (Cnt + 1 < NestedLoopCount) 7789 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7790 Acc.get(), Prod.get()); 7791 else 7792 Iter = Acc; 7793 if (!Iter.isUsable()) { 7794 HasErrors = true; 7795 break; 7796 } 7797 7798 // Update Acc: 7799 // Acc -= Iter * Prod 7800 // Check if there is at least one more inner loop to avoid 7801 // multiplication by 1. 7802 if (Cnt + 1 < NestedLoopCount) 7803 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7804 Iter.get(), Prod.get()); 7805 else 7806 Prod = Iter; 7807 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7808 Acc.get(), Prod.get()); 7809 7810 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7811 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7812 DeclRefExpr *CounterVar = buildDeclRefExpr( 7813 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7814 /*RefersToCapture=*/true); 7815 ExprResult Init = 7816 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7817 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7818 if (!Init.isUsable()) { 7819 HasErrors = true; 7820 break; 7821 } 7822 ExprResult Update = buildCounterUpdate( 7823 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7824 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7825 if (!Update.isUsable()) { 7826 HasErrors = true; 7827 break; 7828 } 7829 7830 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7831 ExprResult Final = 7832 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7833 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7834 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7835 if (!Final.isUsable()) { 7836 HasErrors = true; 7837 break; 7838 } 7839 7840 if (!Update.isUsable() || !Final.isUsable()) { 7841 HasErrors = true; 7842 break; 7843 } 7844 // Save results 7845 Built.Counters[Cnt] = IS.CounterVar; 7846 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7847 Built.Inits[Cnt] = Init.get(); 7848 Built.Updates[Cnt] = Update.get(); 7849 Built.Finals[Cnt] = Final.get(); 7850 Built.DependentCounters[Cnt] = nullptr; 7851 Built.DependentInits[Cnt] = nullptr; 7852 Built.FinalsConditions[Cnt] = nullptr; 7853 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7854 Built.DependentCounters[Cnt] = 7855 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7856 Built.DependentInits[Cnt] = 7857 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7858 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7859 } 7860 } 7861 } 7862 7863 if (HasErrors) 7864 return 0; 7865 7866 // Save results 7867 Built.IterationVarRef = IV.get(); 7868 Built.LastIteration = LastIteration.get(); 7869 Built.NumIterations = NumIterations.get(); 7870 Built.CalcLastIteration = SemaRef 7871 .ActOnFinishFullExpr(CalcLastIteration.get(), 7872 /*DiscardedValue=*/false) 7873 .get(); 7874 Built.PreCond = PreCond.get(); 7875 Built.PreInits = buildPreInits(C, Captures); 7876 Built.Cond = Cond.get(); 7877 Built.Init = Init.get(); 7878 Built.Inc = Inc.get(); 7879 Built.LB = LB.get(); 7880 Built.UB = UB.get(); 7881 Built.IL = IL.get(); 7882 Built.ST = ST.get(); 7883 Built.EUB = EUB.get(); 7884 Built.NLB = NextLB.get(); 7885 Built.NUB = NextUB.get(); 7886 Built.PrevLB = PrevLB.get(); 7887 Built.PrevUB = PrevUB.get(); 7888 Built.DistInc = DistInc.get(); 7889 Built.PrevEUB = PrevEUB.get(); 7890 Built.DistCombinedFields.LB = CombLB.get(); 7891 Built.DistCombinedFields.UB = CombUB.get(); 7892 Built.DistCombinedFields.EUB = CombEUB.get(); 7893 Built.DistCombinedFields.Init = CombInit.get(); 7894 Built.DistCombinedFields.Cond = CombCond.get(); 7895 Built.DistCombinedFields.NLB = CombNextLB.get(); 7896 Built.DistCombinedFields.NUB = CombNextUB.get(); 7897 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7898 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7899 7900 return NestedLoopCount; 7901 } 7902 7903 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7904 auto CollapseClauses = 7905 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7906 if (CollapseClauses.begin() != CollapseClauses.end()) 7907 return (*CollapseClauses.begin())->getNumForLoops(); 7908 return nullptr; 7909 } 7910 7911 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7912 auto OrderedClauses = 7913 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7914 if (OrderedClauses.begin() != OrderedClauses.end()) 7915 return (*OrderedClauses.begin())->getNumForLoops(); 7916 return nullptr; 7917 } 7918 7919 static bool checkSimdlenSafelenSpecified(Sema &S, 7920 const ArrayRef<OMPClause *> Clauses) { 7921 const OMPSafelenClause *Safelen = nullptr; 7922 const OMPSimdlenClause *Simdlen = nullptr; 7923 7924 for (const OMPClause *Clause : Clauses) { 7925 if (Clause->getClauseKind() == OMPC_safelen) 7926 Safelen = cast<OMPSafelenClause>(Clause); 7927 else if (Clause->getClauseKind() == OMPC_simdlen) 7928 Simdlen = cast<OMPSimdlenClause>(Clause); 7929 if (Safelen && Simdlen) 7930 break; 7931 } 7932 7933 if (Simdlen && Safelen) { 7934 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7935 const Expr *SafelenLength = Safelen->getSafelen(); 7936 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7937 SimdlenLength->isInstantiationDependent() || 7938 SimdlenLength->containsUnexpandedParameterPack()) 7939 return false; 7940 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7941 SafelenLength->isInstantiationDependent() || 7942 SafelenLength->containsUnexpandedParameterPack()) 7943 return false; 7944 Expr::EvalResult SimdlenResult, SafelenResult; 7945 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7946 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7947 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7948 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7949 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7950 // If both simdlen and safelen clauses are specified, the value of the 7951 // simdlen parameter must be less than or equal to the value of the safelen 7952 // parameter. 7953 if (SimdlenRes > SafelenRes) { 7954 S.Diag(SimdlenLength->getExprLoc(), 7955 diag::err_omp_wrong_simdlen_safelen_values) 7956 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7957 return true; 7958 } 7959 } 7960 return false; 7961 } 7962 7963 StmtResult 7964 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7965 SourceLocation StartLoc, SourceLocation EndLoc, 7966 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7967 if (!AStmt) 7968 return StmtError(); 7969 7970 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7971 OMPLoopDirective::HelperExprs B; 7972 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7973 // define the nested loops number. 7974 unsigned NestedLoopCount = checkOpenMPLoop( 7975 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7976 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7977 if (NestedLoopCount == 0) 7978 return StmtError(); 7979 7980 assert((CurContext->isDependentContext() || B.builtAll()) && 7981 "omp simd loop exprs were not built"); 7982 7983 if (!CurContext->isDependentContext()) { 7984 // Finalize the clauses that need pre-built expressions for CodeGen. 7985 for (OMPClause *C : Clauses) { 7986 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7987 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7988 B.NumIterations, *this, CurScope, 7989 DSAStack)) 7990 return StmtError(); 7991 } 7992 } 7993 7994 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7995 return StmtError(); 7996 7997 setFunctionHasBranchProtectedScope(); 7998 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7999 Clauses, AStmt, B); 8000 } 8001 8002 StmtResult 8003 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8004 SourceLocation StartLoc, SourceLocation EndLoc, 8005 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8006 if (!AStmt) 8007 return StmtError(); 8008 8009 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8010 OMPLoopDirective::HelperExprs B; 8011 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8012 // define the nested loops number. 8013 unsigned NestedLoopCount = checkOpenMPLoop( 8014 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8015 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8016 if (NestedLoopCount == 0) 8017 return StmtError(); 8018 8019 assert((CurContext->isDependentContext() || B.builtAll()) && 8020 "omp for loop exprs were not built"); 8021 8022 if (!CurContext->isDependentContext()) { 8023 // Finalize the clauses that need pre-built expressions for CodeGen. 8024 for (OMPClause *C : Clauses) { 8025 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8026 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8027 B.NumIterations, *this, CurScope, 8028 DSAStack)) 8029 return StmtError(); 8030 } 8031 } 8032 8033 setFunctionHasBranchProtectedScope(); 8034 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8035 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8036 } 8037 8038 StmtResult Sema::ActOnOpenMPForSimdDirective( 8039 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8040 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8041 if (!AStmt) 8042 return StmtError(); 8043 8044 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8045 OMPLoopDirective::HelperExprs B; 8046 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8047 // define the nested loops number. 8048 unsigned NestedLoopCount = 8049 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8050 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8051 VarsWithImplicitDSA, B); 8052 if (NestedLoopCount == 0) 8053 return StmtError(); 8054 8055 assert((CurContext->isDependentContext() || B.builtAll()) && 8056 "omp for simd loop exprs were not built"); 8057 8058 if (!CurContext->isDependentContext()) { 8059 // Finalize the clauses that need pre-built expressions for CodeGen. 8060 for (OMPClause *C : Clauses) { 8061 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8062 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8063 B.NumIterations, *this, CurScope, 8064 DSAStack)) 8065 return StmtError(); 8066 } 8067 } 8068 8069 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8070 return StmtError(); 8071 8072 setFunctionHasBranchProtectedScope(); 8073 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8074 Clauses, AStmt, B); 8075 } 8076 8077 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8078 Stmt *AStmt, 8079 SourceLocation StartLoc, 8080 SourceLocation EndLoc) { 8081 if (!AStmt) 8082 return StmtError(); 8083 8084 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8085 auto BaseStmt = AStmt; 8086 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8087 BaseStmt = CS->getCapturedStmt(); 8088 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8089 auto S = C->children(); 8090 if (S.begin() == S.end()) 8091 return StmtError(); 8092 // All associated statements must be '#pragma omp section' except for 8093 // the first one. 8094 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8095 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8096 if (SectionStmt) 8097 Diag(SectionStmt->getBeginLoc(), 8098 diag::err_omp_sections_substmt_not_section); 8099 return StmtError(); 8100 } 8101 cast<OMPSectionDirective>(SectionStmt) 8102 ->setHasCancel(DSAStack->isCancelRegion()); 8103 } 8104 } else { 8105 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8106 return StmtError(); 8107 } 8108 8109 setFunctionHasBranchProtectedScope(); 8110 8111 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8112 DSAStack->isCancelRegion()); 8113 } 8114 8115 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8116 SourceLocation StartLoc, 8117 SourceLocation EndLoc) { 8118 if (!AStmt) 8119 return StmtError(); 8120 8121 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8122 8123 setFunctionHasBranchProtectedScope(); 8124 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8125 8126 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8127 DSAStack->isCancelRegion()); 8128 } 8129 8130 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8131 Stmt *AStmt, 8132 SourceLocation StartLoc, 8133 SourceLocation EndLoc) { 8134 if (!AStmt) 8135 return StmtError(); 8136 8137 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8138 8139 setFunctionHasBranchProtectedScope(); 8140 8141 // OpenMP [2.7.3, single Construct, Restrictions] 8142 // The copyprivate clause must not be used with the nowait clause. 8143 const OMPClause *Nowait = nullptr; 8144 const OMPClause *Copyprivate = nullptr; 8145 for (const OMPClause *Clause : Clauses) { 8146 if (Clause->getClauseKind() == OMPC_nowait) 8147 Nowait = Clause; 8148 else if (Clause->getClauseKind() == OMPC_copyprivate) 8149 Copyprivate = Clause; 8150 if (Copyprivate && Nowait) { 8151 Diag(Copyprivate->getBeginLoc(), 8152 diag::err_omp_single_copyprivate_with_nowait); 8153 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8154 return StmtError(); 8155 } 8156 } 8157 8158 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8159 } 8160 8161 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8162 SourceLocation StartLoc, 8163 SourceLocation EndLoc) { 8164 if (!AStmt) 8165 return StmtError(); 8166 8167 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8168 8169 setFunctionHasBranchProtectedScope(); 8170 8171 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8172 } 8173 8174 StmtResult Sema::ActOnOpenMPCriticalDirective( 8175 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8176 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8177 if (!AStmt) 8178 return StmtError(); 8179 8180 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8181 8182 bool ErrorFound = false; 8183 llvm::APSInt Hint; 8184 SourceLocation HintLoc; 8185 bool DependentHint = false; 8186 for (const OMPClause *C : Clauses) { 8187 if (C->getClauseKind() == OMPC_hint) { 8188 if (!DirName.getName()) { 8189 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8190 ErrorFound = true; 8191 } 8192 Expr *E = cast<OMPHintClause>(C)->getHint(); 8193 if (E->isTypeDependent() || E->isValueDependent() || 8194 E->isInstantiationDependent()) { 8195 DependentHint = true; 8196 } else { 8197 Hint = E->EvaluateKnownConstInt(Context); 8198 HintLoc = C->getBeginLoc(); 8199 } 8200 } 8201 } 8202 if (ErrorFound) 8203 return StmtError(); 8204 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8205 if (Pair.first && DirName.getName() && !DependentHint) { 8206 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8207 Diag(StartLoc, diag::err_omp_critical_with_hint); 8208 if (HintLoc.isValid()) 8209 Diag(HintLoc, diag::note_omp_critical_hint_here) 8210 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8211 else 8212 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8213 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8214 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8215 << 1 8216 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8217 /*Radix=*/10, /*Signed=*/false); 8218 } else { 8219 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8220 } 8221 } 8222 } 8223 8224 setFunctionHasBranchProtectedScope(); 8225 8226 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8227 Clauses, AStmt); 8228 if (!Pair.first && DirName.getName() && !DependentHint) 8229 DSAStack->addCriticalWithHint(Dir, Hint); 8230 return Dir; 8231 } 8232 8233 StmtResult Sema::ActOnOpenMPParallelForDirective( 8234 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8235 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8236 if (!AStmt) 8237 return StmtError(); 8238 8239 auto *CS = cast<CapturedStmt>(AStmt); 8240 // 1.2.2 OpenMP Language Terminology 8241 // Structured block - An executable statement with a single entry at the 8242 // top and a single exit at the bottom. 8243 // The point of exit cannot be a branch out of the structured block. 8244 // longjmp() and throw() must not violate the entry/exit criteria. 8245 CS->getCapturedDecl()->setNothrow(); 8246 8247 OMPLoopDirective::HelperExprs B; 8248 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8249 // define the nested loops number. 8250 unsigned NestedLoopCount = 8251 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8252 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8253 VarsWithImplicitDSA, B); 8254 if (NestedLoopCount == 0) 8255 return StmtError(); 8256 8257 assert((CurContext->isDependentContext() || B.builtAll()) && 8258 "omp parallel for loop exprs were not built"); 8259 8260 if (!CurContext->isDependentContext()) { 8261 // Finalize the clauses that need pre-built expressions for CodeGen. 8262 for (OMPClause *C : Clauses) { 8263 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8264 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8265 B.NumIterations, *this, CurScope, 8266 DSAStack)) 8267 return StmtError(); 8268 } 8269 } 8270 8271 setFunctionHasBranchProtectedScope(); 8272 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8273 NestedLoopCount, Clauses, AStmt, B, 8274 DSAStack->isCancelRegion()); 8275 } 8276 8277 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8278 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8279 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8280 if (!AStmt) 8281 return StmtError(); 8282 8283 auto *CS = cast<CapturedStmt>(AStmt); 8284 // 1.2.2 OpenMP Language Terminology 8285 // Structured block - An executable statement with a single entry at the 8286 // top and a single exit at the bottom. 8287 // The point of exit cannot be a branch out of the structured block. 8288 // longjmp() and throw() must not violate the entry/exit criteria. 8289 CS->getCapturedDecl()->setNothrow(); 8290 8291 OMPLoopDirective::HelperExprs B; 8292 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8293 // define the nested loops number. 8294 unsigned NestedLoopCount = 8295 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8296 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8297 VarsWithImplicitDSA, B); 8298 if (NestedLoopCount == 0) 8299 return StmtError(); 8300 8301 if (!CurContext->isDependentContext()) { 8302 // Finalize the clauses that need pre-built expressions for CodeGen. 8303 for (OMPClause *C : Clauses) { 8304 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8305 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8306 B.NumIterations, *this, CurScope, 8307 DSAStack)) 8308 return StmtError(); 8309 } 8310 } 8311 8312 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8313 return StmtError(); 8314 8315 setFunctionHasBranchProtectedScope(); 8316 return OMPParallelForSimdDirective::Create( 8317 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8318 } 8319 8320 StmtResult 8321 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8322 Stmt *AStmt, SourceLocation StartLoc, 8323 SourceLocation EndLoc) { 8324 if (!AStmt) 8325 return StmtError(); 8326 8327 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8328 auto *CS = cast<CapturedStmt>(AStmt); 8329 // 1.2.2 OpenMP Language Terminology 8330 // Structured block - An executable statement with a single entry at the 8331 // top and a single exit at the bottom. 8332 // The point of exit cannot be a branch out of the structured block. 8333 // longjmp() and throw() must not violate the entry/exit criteria. 8334 CS->getCapturedDecl()->setNothrow(); 8335 8336 setFunctionHasBranchProtectedScope(); 8337 8338 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8339 AStmt); 8340 } 8341 8342 StmtResult 8343 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8344 Stmt *AStmt, SourceLocation StartLoc, 8345 SourceLocation EndLoc) { 8346 if (!AStmt) 8347 return StmtError(); 8348 8349 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8350 auto BaseStmt = AStmt; 8351 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8352 BaseStmt = CS->getCapturedStmt(); 8353 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8354 auto S = C->children(); 8355 if (S.begin() == S.end()) 8356 return StmtError(); 8357 // All associated statements must be '#pragma omp section' except for 8358 // the first one. 8359 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8360 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8361 if (SectionStmt) 8362 Diag(SectionStmt->getBeginLoc(), 8363 diag::err_omp_parallel_sections_substmt_not_section); 8364 return StmtError(); 8365 } 8366 cast<OMPSectionDirective>(SectionStmt) 8367 ->setHasCancel(DSAStack->isCancelRegion()); 8368 } 8369 } else { 8370 Diag(AStmt->getBeginLoc(), 8371 diag::err_omp_parallel_sections_not_compound_stmt); 8372 return StmtError(); 8373 } 8374 8375 setFunctionHasBranchProtectedScope(); 8376 8377 return OMPParallelSectionsDirective::Create( 8378 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8379 } 8380 8381 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8382 Stmt *AStmt, SourceLocation StartLoc, 8383 SourceLocation EndLoc) { 8384 if (!AStmt) 8385 return StmtError(); 8386 8387 auto *CS = cast<CapturedStmt>(AStmt); 8388 // 1.2.2 OpenMP Language Terminology 8389 // Structured block - An executable statement with a single entry at the 8390 // top and a single exit at the bottom. 8391 // The point of exit cannot be a branch out of the structured block. 8392 // longjmp() and throw() must not violate the entry/exit criteria. 8393 CS->getCapturedDecl()->setNothrow(); 8394 8395 setFunctionHasBranchProtectedScope(); 8396 8397 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8398 DSAStack->isCancelRegion()); 8399 } 8400 8401 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8402 SourceLocation EndLoc) { 8403 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8404 } 8405 8406 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8407 SourceLocation EndLoc) { 8408 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8409 } 8410 8411 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8412 SourceLocation EndLoc) { 8413 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8414 } 8415 8416 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8417 Stmt *AStmt, 8418 SourceLocation StartLoc, 8419 SourceLocation EndLoc) { 8420 if (!AStmt) 8421 return StmtError(); 8422 8423 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8424 8425 setFunctionHasBranchProtectedScope(); 8426 8427 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8428 AStmt, 8429 DSAStack->getTaskgroupReductionRef()); 8430 } 8431 8432 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8433 SourceLocation StartLoc, 8434 SourceLocation EndLoc) { 8435 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8436 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8437 } 8438 8439 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8440 Stmt *AStmt, 8441 SourceLocation StartLoc, 8442 SourceLocation EndLoc) { 8443 const OMPClause *DependFound = nullptr; 8444 const OMPClause *DependSourceClause = nullptr; 8445 const OMPClause *DependSinkClause = nullptr; 8446 bool ErrorFound = false; 8447 const OMPThreadsClause *TC = nullptr; 8448 const OMPSIMDClause *SC = nullptr; 8449 for (const OMPClause *C : Clauses) { 8450 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8451 DependFound = C; 8452 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8453 if (DependSourceClause) { 8454 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8455 << getOpenMPDirectiveName(OMPD_ordered) 8456 << getOpenMPClauseName(OMPC_depend) << 2; 8457 ErrorFound = true; 8458 } else { 8459 DependSourceClause = C; 8460 } 8461 if (DependSinkClause) { 8462 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8463 << 0; 8464 ErrorFound = true; 8465 } 8466 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8467 if (DependSourceClause) { 8468 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8469 << 1; 8470 ErrorFound = true; 8471 } 8472 DependSinkClause = C; 8473 } 8474 } else if (C->getClauseKind() == OMPC_threads) { 8475 TC = cast<OMPThreadsClause>(C); 8476 } else if (C->getClauseKind() == OMPC_simd) { 8477 SC = cast<OMPSIMDClause>(C); 8478 } 8479 } 8480 if (!ErrorFound && !SC && 8481 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8482 // OpenMP [2.8.1,simd Construct, Restrictions] 8483 // An ordered construct with the simd clause is the only OpenMP construct 8484 // that can appear in the simd region. 8485 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8486 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8487 ErrorFound = true; 8488 } else if (DependFound && (TC || SC)) { 8489 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8490 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8491 ErrorFound = true; 8492 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8493 Diag(DependFound->getBeginLoc(), 8494 diag::err_omp_ordered_directive_without_param); 8495 ErrorFound = true; 8496 } else if (TC || Clauses.empty()) { 8497 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8498 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8499 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8500 << (TC != nullptr); 8501 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8502 ErrorFound = true; 8503 } 8504 } 8505 if ((!AStmt && !DependFound) || ErrorFound) 8506 return StmtError(); 8507 8508 if (AStmt) { 8509 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8510 8511 setFunctionHasBranchProtectedScope(); 8512 } 8513 8514 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8515 } 8516 8517 namespace { 8518 /// Helper class for checking expression in 'omp atomic [update]' 8519 /// construct. 8520 class OpenMPAtomicUpdateChecker { 8521 /// Error results for atomic update expressions. 8522 enum ExprAnalysisErrorCode { 8523 /// A statement is not an expression statement. 8524 NotAnExpression, 8525 /// Expression is not builtin binary or unary operation. 8526 NotABinaryOrUnaryExpression, 8527 /// Unary operation is not post-/pre- increment/decrement operation. 8528 NotAnUnaryIncDecExpression, 8529 /// An expression is not of scalar type. 8530 NotAScalarType, 8531 /// A binary operation is not an assignment operation. 8532 NotAnAssignmentOp, 8533 /// RHS part of the binary operation is not a binary expression. 8534 NotABinaryExpression, 8535 /// RHS part is not additive/multiplicative/shift/biwise binary 8536 /// expression. 8537 NotABinaryOperator, 8538 /// RHS binary operation does not have reference to the updated LHS 8539 /// part. 8540 NotAnUpdateExpression, 8541 /// No errors is found. 8542 NoError 8543 }; 8544 /// Reference to Sema. 8545 Sema &SemaRef; 8546 /// A location for note diagnostics (when error is found). 8547 SourceLocation NoteLoc; 8548 /// 'x' lvalue part of the source atomic expression. 8549 Expr *X; 8550 /// 'expr' rvalue part of the source atomic expression. 8551 Expr *E; 8552 /// Helper expression of the form 8553 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8554 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8555 Expr *UpdateExpr; 8556 /// Is 'x' a LHS in a RHS part of full update expression. It is 8557 /// important for non-associative operations. 8558 bool IsXLHSInRHSPart; 8559 BinaryOperatorKind Op; 8560 SourceLocation OpLoc; 8561 /// true if the source expression is a postfix unary operation, false 8562 /// if it is a prefix unary operation. 8563 bool IsPostfixUpdate; 8564 8565 public: 8566 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8567 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8568 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8569 /// Check specified statement that it is suitable for 'atomic update' 8570 /// constructs and extract 'x', 'expr' and Operation from the original 8571 /// expression. If DiagId and NoteId == 0, then only check is performed 8572 /// without error notification. 8573 /// \param DiagId Diagnostic which should be emitted if error is found. 8574 /// \param NoteId Diagnostic note for the main error message. 8575 /// \return true if statement is not an update expression, false otherwise. 8576 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8577 /// Return the 'x' lvalue part of the source atomic expression. 8578 Expr *getX() const { return X; } 8579 /// Return the 'expr' rvalue part of the source atomic expression. 8580 Expr *getExpr() const { return E; } 8581 /// Return the update expression used in calculation of the updated 8582 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8583 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8584 Expr *getUpdateExpr() const { return UpdateExpr; } 8585 /// Return true if 'x' is LHS in RHS part of full update expression, 8586 /// false otherwise. 8587 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8588 8589 /// true if the source expression is a postfix unary operation, false 8590 /// if it is a prefix unary operation. 8591 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8592 8593 private: 8594 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8595 unsigned NoteId = 0); 8596 }; 8597 } // namespace 8598 8599 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8600 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8601 ExprAnalysisErrorCode ErrorFound = NoError; 8602 SourceLocation ErrorLoc, NoteLoc; 8603 SourceRange ErrorRange, NoteRange; 8604 // Allowed constructs are: 8605 // x = x binop expr; 8606 // x = expr binop x; 8607 if (AtomicBinOp->getOpcode() == BO_Assign) { 8608 X = AtomicBinOp->getLHS(); 8609 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8610 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8611 if (AtomicInnerBinOp->isMultiplicativeOp() || 8612 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8613 AtomicInnerBinOp->isBitwiseOp()) { 8614 Op = AtomicInnerBinOp->getOpcode(); 8615 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8616 Expr *LHS = AtomicInnerBinOp->getLHS(); 8617 Expr *RHS = AtomicInnerBinOp->getRHS(); 8618 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8619 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8620 /*Canonical=*/true); 8621 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8622 /*Canonical=*/true); 8623 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8624 /*Canonical=*/true); 8625 if (XId == LHSId) { 8626 E = RHS; 8627 IsXLHSInRHSPart = true; 8628 } else if (XId == RHSId) { 8629 E = LHS; 8630 IsXLHSInRHSPart = false; 8631 } else { 8632 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8633 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8634 NoteLoc = X->getExprLoc(); 8635 NoteRange = X->getSourceRange(); 8636 ErrorFound = NotAnUpdateExpression; 8637 } 8638 } else { 8639 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8640 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8641 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8642 NoteRange = SourceRange(NoteLoc, NoteLoc); 8643 ErrorFound = NotABinaryOperator; 8644 } 8645 } else { 8646 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8647 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8648 ErrorFound = NotABinaryExpression; 8649 } 8650 } else { 8651 ErrorLoc = AtomicBinOp->getExprLoc(); 8652 ErrorRange = AtomicBinOp->getSourceRange(); 8653 NoteLoc = AtomicBinOp->getOperatorLoc(); 8654 NoteRange = SourceRange(NoteLoc, NoteLoc); 8655 ErrorFound = NotAnAssignmentOp; 8656 } 8657 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8658 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8659 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8660 return true; 8661 } 8662 if (SemaRef.CurContext->isDependentContext()) 8663 E = X = UpdateExpr = nullptr; 8664 return ErrorFound != NoError; 8665 } 8666 8667 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8668 unsigned NoteId) { 8669 ExprAnalysisErrorCode ErrorFound = NoError; 8670 SourceLocation ErrorLoc, NoteLoc; 8671 SourceRange ErrorRange, NoteRange; 8672 // Allowed constructs are: 8673 // x++; 8674 // x--; 8675 // ++x; 8676 // --x; 8677 // x binop= expr; 8678 // x = x binop expr; 8679 // x = expr binop x; 8680 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8681 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8682 if (AtomicBody->getType()->isScalarType() || 8683 AtomicBody->isInstantiationDependent()) { 8684 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8685 AtomicBody->IgnoreParenImpCasts())) { 8686 // Check for Compound Assignment Operation 8687 Op = BinaryOperator::getOpForCompoundAssignment( 8688 AtomicCompAssignOp->getOpcode()); 8689 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8690 E = AtomicCompAssignOp->getRHS(); 8691 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8692 IsXLHSInRHSPart = true; 8693 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8694 AtomicBody->IgnoreParenImpCasts())) { 8695 // Check for Binary Operation 8696 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8697 return true; 8698 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8699 AtomicBody->IgnoreParenImpCasts())) { 8700 // Check for Unary Operation 8701 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8702 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8703 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8704 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8705 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8706 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8707 IsXLHSInRHSPart = true; 8708 } else { 8709 ErrorFound = NotAnUnaryIncDecExpression; 8710 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8711 ErrorRange = AtomicUnaryOp->getSourceRange(); 8712 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8713 NoteRange = SourceRange(NoteLoc, NoteLoc); 8714 } 8715 } else if (!AtomicBody->isInstantiationDependent()) { 8716 ErrorFound = NotABinaryOrUnaryExpression; 8717 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8718 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8719 } 8720 } else { 8721 ErrorFound = NotAScalarType; 8722 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8723 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8724 } 8725 } else { 8726 ErrorFound = NotAnExpression; 8727 NoteLoc = ErrorLoc = S->getBeginLoc(); 8728 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8729 } 8730 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8731 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8732 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8733 return true; 8734 } 8735 if (SemaRef.CurContext->isDependentContext()) 8736 E = X = UpdateExpr = nullptr; 8737 if (ErrorFound == NoError && E && X) { 8738 // Build an update expression of form 'OpaqueValueExpr(x) binop 8739 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8740 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8741 auto *OVEX = new (SemaRef.getASTContext()) 8742 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8743 auto *OVEExpr = new (SemaRef.getASTContext()) 8744 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8745 ExprResult Update = 8746 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8747 IsXLHSInRHSPart ? OVEExpr : OVEX); 8748 if (Update.isInvalid()) 8749 return true; 8750 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8751 Sema::AA_Casting); 8752 if (Update.isInvalid()) 8753 return true; 8754 UpdateExpr = Update.get(); 8755 } 8756 return ErrorFound != NoError; 8757 } 8758 8759 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8760 Stmt *AStmt, 8761 SourceLocation StartLoc, 8762 SourceLocation EndLoc) { 8763 if (!AStmt) 8764 return StmtError(); 8765 8766 auto *CS = cast<CapturedStmt>(AStmt); 8767 // 1.2.2 OpenMP Language Terminology 8768 // Structured block - An executable statement with a single entry at the 8769 // top and a single exit at the bottom. 8770 // The point of exit cannot be a branch out of the structured block. 8771 // longjmp() and throw() must not violate the entry/exit criteria. 8772 OpenMPClauseKind AtomicKind = OMPC_unknown; 8773 SourceLocation AtomicKindLoc; 8774 for (const OMPClause *C : Clauses) { 8775 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8776 C->getClauseKind() == OMPC_update || 8777 C->getClauseKind() == OMPC_capture) { 8778 if (AtomicKind != OMPC_unknown) { 8779 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8780 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8781 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8782 << getOpenMPClauseName(AtomicKind); 8783 } else { 8784 AtomicKind = C->getClauseKind(); 8785 AtomicKindLoc = C->getBeginLoc(); 8786 } 8787 } 8788 } 8789 8790 Stmt *Body = CS->getCapturedStmt(); 8791 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8792 Body = EWC->getSubExpr(); 8793 8794 Expr *X = nullptr; 8795 Expr *V = nullptr; 8796 Expr *E = nullptr; 8797 Expr *UE = nullptr; 8798 bool IsXLHSInRHSPart = false; 8799 bool IsPostfixUpdate = false; 8800 // OpenMP [2.12.6, atomic Construct] 8801 // In the next expressions: 8802 // * x and v (as applicable) are both l-value expressions with scalar type. 8803 // * During the execution of an atomic region, multiple syntactic 8804 // occurrences of x must designate the same storage location. 8805 // * Neither of v and expr (as applicable) may access the storage location 8806 // designated by x. 8807 // * Neither of x and expr (as applicable) may access the storage location 8808 // designated by v. 8809 // * expr is an expression with scalar type. 8810 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8811 // * binop, binop=, ++, and -- are not overloaded operators. 8812 // * The expression x binop expr must be numerically equivalent to x binop 8813 // (expr). This requirement is satisfied if the operators in expr have 8814 // precedence greater than binop, or by using parentheses around expr or 8815 // subexpressions of expr. 8816 // * The expression expr binop x must be numerically equivalent to (expr) 8817 // binop x. This requirement is satisfied if the operators in expr have 8818 // precedence equal to or greater than binop, or by using parentheses around 8819 // expr or subexpressions of expr. 8820 // * For forms that allow multiple occurrences of x, the number of times 8821 // that x is evaluated is unspecified. 8822 if (AtomicKind == OMPC_read) { 8823 enum { 8824 NotAnExpression, 8825 NotAnAssignmentOp, 8826 NotAScalarType, 8827 NotAnLValue, 8828 NoError 8829 } ErrorFound = NoError; 8830 SourceLocation ErrorLoc, NoteLoc; 8831 SourceRange ErrorRange, NoteRange; 8832 // If clause is read: 8833 // v = x; 8834 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8835 const auto *AtomicBinOp = 8836 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8837 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8838 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8839 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8840 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8841 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8842 if (!X->isLValue() || !V->isLValue()) { 8843 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8844 ErrorFound = NotAnLValue; 8845 ErrorLoc = AtomicBinOp->getExprLoc(); 8846 ErrorRange = AtomicBinOp->getSourceRange(); 8847 NoteLoc = NotLValueExpr->getExprLoc(); 8848 NoteRange = NotLValueExpr->getSourceRange(); 8849 } 8850 } else if (!X->isInstantiationDependent() || 8851 !V->isInstantiationDependent()) { 8852 const Expr *NotScalarExpr = 8853 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8854 ? V 8855 : X; 8856 ErrorFound = NotAScalarType; 8857 ErrorLoc = AtomicBinOp->getExprLoc(); 8858 ErrorRange = AtomicBinOp->getSourceRange(); 8859 NoteLoc = NotScalarExpr->getExprLoc(); 8860 NoteRange = NotScalarExpr->getSourceRange(); 8861 } 8862 } else if (!AtomicBody->isInstantiationDependent()) { 8863 ErrorFound = NotAnAssignmentOp; 8864 ErrorLoc = AtomicBody->getExprLoc(); 8865 ErrorRange = AtomicBody->getSourceRange(); 8866 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8867 : AtomicBody->getExprLoc(); 8868 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8869 : AtomicBody->getSourceRange(); 8870 } 8871 } else { 8872 ErrorFound = NotAnExpression; 8873 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8874 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8875 } 8876 if (ErrorFound != NoError) { 8877 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8878 << ErrorRange; 8879 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8880 << NoteRange; 8881 return StmtError(); 8882 } 8883 if (CurContext->isDependentContext()) 8884 V = X = nullptr; 8885 } else if (AtomicKind == OMPC_write) { 8886 enum { 8887 NotAnExpression, 8888 NotAnAssignmentOp, 8889 NotAScalarType, 8890 NotAnLValue, 8891 NoError 8892 } ErrorFound = NoError; 8893 SourceLocation ErrorLoc, NoteLoc; 8894 SourceRange ErrorRange, NoteRange; 8895 // If clause is write: 8896 // x = expr; 8897 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8898 const auto *AtomicBinOp = 8899 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8900 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8901 X = AtomicBinOp->getLHS(); 8902 E = AtomicBinOp->getRHS(); 8903 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8904 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8905 if (!X->isLValue()) { 8906 ErrorFound = NotAnLValue; 8907 ErrorLoc = AtomicBinOp->getExprLoc(); 8908 ErrorRange = AtomicBinOp->getSourceRange(); 8909 NoteLoc = X->getExprLoc(); 8910 NoteRange = X->getSourceRange(); 8911 } 8912 } else if (!X->isInstantiationDependent() || 8913 !E->isInstantiationDependent()) { 8914 const Expr *NotScalarExpr = 8915 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8916 ? E 8917 : X; 8918 ErrorFound = NotAScalarType; 8919 ErrorLoc = AtomicBinOp->getExprLoc(); 8920 ErrorRange = AtomicBinOp->getSourceRange(); 8921 NoteLoc = NotScalarExpr->getExprLoc(); 8922 NoteRange = NotScalarExpr->getSourceRange(); 8923 } 8924 } else if (!AtomicBody->isInstantiationDependent()) { 8925 ErrorFound = NotAnAssignmentOp; 8926 ErrorLoc = AtomicBody->getExprLoc(); 8927 ErrorRange = AtomicBody->getSourceRange(); 8928 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8929 : AtomicBody->getExprLoc(); 8930 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8931 : AtomicBody->getSourceRange(); 8932 } 8933 } else { 8934 ErrorFound = NotAnExpression; 8935 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8936 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8937 } 8938 if (ErrorFound != NoError) { 8939 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8940 << ErrorRange; 8941 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8942 << NoteRange; 8943 return StmtError(); 8944 } 8945 if (CurContext->isDependentContext()) 8946 E = X = nullptr; 8947 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8948 // If clause is update: 8949 // x++; 8950 // x--; 8951 // ++x; 8952 // --x; 8953 // x binop= expr; 8954 // x = x binop expr; 8955 // x = expr binop x; 8956 OpenMPAtomicUpdateChecker Checker(*this); 8957 if (Checker.checkStatement( 8958 Body, (AtomicKind == OMPC_update) 8959 ? diag::err_omp_atomic_update_not_expression_statement 8960 : diag::err_omp_atomic_not_expression_statement, 8961 diag::note_omp_atomic_update)) 8962 return StmtError(); 8963 if (!CurContext->isDependentContext()) { 8964 E = Checker.getExpr(); 8965 X = Checker.getX(); 8966 UE = Checker.getUpdateExpr(); 8967 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8968 } 8969 } else if (AtomicKind == OMPC_capture) { 8970 enum { 8971 NotAnAssignmentOp, 8972 NotACompoundStatement, 8973 NotTwoSubstatements, 8974 NotASpecificExpression, 8975 NoError 8976 } ErrorFound = NoError; 8977 SourceLocation ErrorLoc, NoteLoc; 8978 SourceRange ErrorRange, NoteRange; 8979 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8980 // If clause is a capture: 8981 // v = x++; 8982 // v = x--; 8983 // v = ++x; 8984 // v = --x; 8985 // v = x binop= expr; 8986 // v = x = x binop expr; 8987 // v = x = expr binop x; 8988 const auto *AtomicBinOp = 8989 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8990 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8991 V = AtomicBinOp->getLHS(); 8992 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8993 OpenMPAtomicUpdateChecker Checker(*this); 8994 if (Checker.checkStatement( 8995 Body, diag::err_omp_atomic_capture_not_expression_statement, 8996 diag::note_omp_atomic_update)) 8997 return StmtError(); 8998 E = Checker.getExpr(); 8999 X = Checker.getX(); 9000 UE = Checker.getUpdateExpr(); 9001 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9002 IsPostfixUpdate = Checker.isPostfixUpdate(); 9003 } else if (!AtomicBody->isInstantiationDependent()) { 9004 ErrorLoc = AtomicBody->getExprLoc(); 9005 ErrorRange = AtomicBody->getSourceRange(); 9006 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9007 : AtomicBody->getExprLoc(); 9008 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9009 : AtomicBody->getSourceRange(); 9010 ErrorFound = NotAnAssignmentOp; 9011 } 9012 if (ErrorFound != NoError) { 9013 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9014 << ErrorRange; 9015 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9016 return StmtError(); 9017 } 9018 if (CurContext->isDependentContext()) 9019 UE = V = E = X = nullptr; 9020 } else { 9021 // If clause is a capture: 9022 // { v = x; x = expr; } 9023 // { v = x; x++; } 9024 // { v = x; x--; } 9025 // { v = x; ++x; } 9026 // { v = x; --x; } 9027 // { v = x; x binop= expr; } 9028 // { v = x; x = x binop expr; } 9029 // { v = x; x = expr binop x; } 9030 // { x++; v = x; } 9031 // { x--; v = x; } 9032 // { ++x; v = x; } 9033 // { --x; v = x; } 9034 // { x binop= expr; v = x; } 9035 // { x = x binop expr; v = x; } 9036 // { x = expr binop x; v = x; } 9037 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9038 // Check that this is { expr1; expr2; } 9039 if (CS->size() == 2) { 9040 Stmt *First = CS->body_front(); 9041 Stmt *Second = CS->body_back(); 9042 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9043 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9044 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9045 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9046 // Need to find what subexpression is 'v' and what is 'x'. 9047 OpenMPAtomicUpdateChecker Checker(*this); 9048 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9049 BinaryOperator *BinOp = nullptr; 9050 if (IsUpdateExprFound) { 9051 BinOp = dyn_cast<BinaryOperator>(First); 9052 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9053 } 9054 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9055 // { v = x; x++; } 9056 // { v = x; x--; } 9057 // { v = x; ++x; } 9058 // { v = x; --x; } 9059 // { v = x; x binop= expr; } 9060 // { v = x; x = x binop expr; } 9061 // { v = x; x = expr binop x; } 9062 // Check that the first expression has form v = x. 9063 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9064 llvm::FoldingSetNodeID XId, PossibleXId; 9065 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9066 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9067 IsUpdateExprFound = XId == PossibleXId; 9068 if (IsUpdateExprFound) { 9069 V = BinOp->getLHS(); 9070 X = Checker.getX(); 9071 E = Checker.getExpr(); 9072 UE = Checker.getUpdateExpr(); 9073 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9074 IsPostfixUpdate = true; 9075 } 9076 } 9077 if (!IsUpdateExprFound) { 9078 IsUpdateExprFound = !Checker.checkStatement(First); 9079 BinOp = nullptr; 9080 if (IsUpdateExprFound) { 9081 BinOp = dyn_cast<BinaryOperator>(Second); 9082 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9083 } 9084 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9085 // { x++; v = x; } 9086 // { x--; v = x; } 9087 // { ++x; v = x; } 9088 // { --x; v = x; } 9089 // { x binop= expr; v = x; } 9090 // { x = x binop expr; v = x; } 9091 // { x = expr binop x; v = x; } 9092 // Check that the second expression has form v = x. 9093 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9094 llvm::FoldingSetNodeID XId, PossibleXId; 9095 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9096 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9097 IsUpdateExprFound = XId == PossibleXId; 9098 if (IsUpdateExprFound) { 9099 V = BinOp->getLHS(); 9100 X = Checker.getX(); 9101 E = Checker.getExpr(); 9102 UE = Checker.getUpdateExpr(); 9103 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9104 IsPostfixUpdate = false; 9105 } 9106 } 9107 } 9108 if (!IsUpdateExprFound) { 9109 // { v = x; x = expr; } 9110 auto *FirstExpr = dyn_cast<Expr>(First); 9111 auto *SecondExpr = dyn_cast<Expr>(Second); 9112 if (!FirstExpr || !SecondExpr || 9113 !(FirstExpr->isInstantiationDependent() || 9114 SecondExpr->isInstantiationDependent())) { 9115 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9116 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9117 ErrorFound = NotAnAssignmentOp; 9118 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9119 : First->getBeginLoc(); 9120 NoteRange = ErrorRange = FirstBinOp 9121 ? FirstBinOp->getSourceRange() 9122 : SourceRange(ErrorLoc, ErrorLoc); 9123 } else { 9124 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9125 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9126 ErrorFound = NotAnAssignmentOp; 9127 NoteLoc = ErrorLoc = SecondBinOp 9128 ? SecondBinOp->getOperatorLoc() 9129 : Second->getBeginLoc(); 9130 NoteRange = ErrorRange = 9131 SecondBinOp ? SecondBinOp->getSourceRange() 9132 : SourceRange(ErrorLoc, ErrorLoc); 9133 } else { 9134 Expr *PossibleXRHSInFirst = 9135 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9136 Expr *PossibleXLHSInSecond = 9137 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9138 llvm::FoldingSetNodeID X1Id, X2Id; 9139 PossibleXRHSInFirst->Profile(X1Id, Context, 9140 /*Canonical=*/true); 9141 PossibleXLHSInSecond->Profile(X2Id, Context, 9142 /*Canonical=*/true); 9143 IsUpdateExprFound = X1Id == X2Id; 9144 if (IsUpdateExprFound) { 9145 V = FirstBinOp->getLHS(); 9146 X = SecondBinOp->getLHS(); 9147 E = SecondBinOp->getRHS(); 9148 UE = nullptr; 9149 IsXLHSInRHSPart = false; 9150 IsPostfixUpdate = true; 9151 } else { 9152 ErrorFound = NotASpecificExpression; 9153 ErrorLoc = FirstBinOp->getExprLoc(); 9154 ErrorRange = FirstBinOp->getSourceRange(); 9155 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9156 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9157 } 9158 } 9159 } 9160 } 9161 } 9162 } else { 9163 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9164 NoteRange = ErrorRange = 9165 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9166 ErrorFound = NotTwoSubstatements; 9167 } 9168 } else { 9169 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9170 NoteRange = ErrorRange = 9171 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9172 ErrorFound = NotACompoundStatement; 9173 } 9174 if (ErrorFound != NoError) { 9175 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9176 << ErrorRange; 9177 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9178 return StmtError(); 9179 } 9180 if (CurContext->isDependentContext()) 9181 UE = V = E = X = nullptr; 9182 } 9183 } 9184 9185 setFunctionHasBranchProtectedScope(); 9186 9187 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9188 X, V, E, UE, IsXLHSInRHSPart, 9189 IsPostfixUpdate); 9190 } 9191 9192 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9193 Stmt *AStmt, 9194 SourceLocation StartLoc, 9195 SourceLocation EndLoc) { 9196 if (!AStmt) 9197 return StmtError(); 9198 9199 auto *CS = cast<CapturedStmt>(AStmt); 9200 // 1.2.2 OpenMP Language Terminology 9201 // Structured block - An executable statement with a single entry at the 9202 // top and a single exit at the bottom. 9203 // The point of exit cannot be a branch out of the structured block. 9204 // longjmp() and throw() must not violate the entry/exit criteria. 9205 CS->getCapturedDecl()->setNothrow(); 9206 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9207 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9208 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9209 // 1.2.2 OpenMP Language Terminology 9210 // Structured block - An executable statement with a single entry at the 9211 // top and a single exit at the bottom. 9212 // The point of exit cannot be a branch out of the structured block. 9213 // longjmp() and throw() must not violate the entry/exit criteria. 9214 CS->getCapturedDecl()->setNothrow(); 9215 } 9216 9217 // OpenMP [2.16, Nesting of Regions] 9218 // If specified, a teams construct must be contained within a target 9219 // construct. That target construct must contain no statements or directives 9220 // outside of the teams construct. 9221 if (DSAStack->hasInnerTeamsRegion()) { 9222 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9223 bool OMPTeamsFound = true; 9224 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9225 auto I = CS->body_begin(); 9226 while (I != CS->body_end()) { 9227 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9228 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9229 OMPTeamsFound) { 9230 9231 OMPTeamsFound = false; 9232 break; 9233 } 9234 ++I; 9235 } 9236 assert(I != CS->body_end() && "Not found statement"); 9237 S = *I; 9238 } else { 9239 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9240 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9241 } 9242 if (!OMPTeamsFound) { 9243 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9244 Diag(DSAStack->getInnerTeamsRegionLoc(), 9245 diag::note_omp_nested_teams_construct_here); 9246 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9247 << isa<OMPExecutableDirective>(S); 9248 return StmtError(); 9249 } 9250 } 9251 9252 setFunctionHasBranchProtectedScope(); 9253 9254 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9255 } 9256 9257 StmtResult 9258 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9259 Stmt *AStmt, SourceLocation StartLoc, 9260 SourceLocation EndLoc) { 9261 if (!AStmt) 9262 return StmtError(); 9263 9264 auto *CS = cast<CapturedStmt>(AStmt); 9265 // 1.2.2 OpenMP Language Terminology 9266 // Structured block - An executable statement with a single entry at the 9267 // top and a single exit at the bottom. 9268 // The point of exit cannot be a branch out of the structured block. 9269 // longjmp() and throw() must not violate the entry/exit criteria. 9270 CS->getCapturedDecl()->setNothrow(); 9271 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9272 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9273 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9274 // 1.2.2 OpenMP Language Terminology 9275 // Structured block - An executable statement with a single entry at the 9276 // top and a single exit at the bottom. 9277 // The point of exit cannot be a branch out of the structured block. 9278 // longjmp() and throw() must not violate the entry/exit criteria. 9279 CS->getCapturedDecl()->setNothrow(); 9280 } 9281 9282 setFunctionHasBranchProtectedScope(); 9283 9284 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9285 AStmt); 9286 } 9287 9288 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9289 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9290 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9291 if (!AStmt) 9292 return StmtError(); 9293 9294 auto *CS = cast<CapturedStmt>(AStmt); 9295 // 1.2.2 OpenMP Language Terminology 9296 // Structured block - An executable statement with a single entry at the 9297 // top and a single exit at the bottom. 9298 // The point of exit cannot be a branch out of the structured block. 9299 // longjmp() and throw() must not violate the entry/exit criteria. 9300 CS->getCapturedDecl()->setNothrow(); 9301 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9302 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9303 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9304 // 1.2.2 OpenMP Language Terminology 9305 // Structured block - An executable statement with a single entry at the 9306 // top and a single exit at the bottom. 9307 // The point of exit cannot be a branch out of the structured block. 9308 // longjmp() and throw() must not violate the entry/exit criteria. 9309 CS->getCapturedDecl()->setNothrow(); 9310 } 9311 9312 OMPLoopDirective::HelperExprs B; 9313 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9314 // define the nested loops number. 9315 unsigned NestedLoopCount = 9316 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9317 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9318 VarsWithImplicitDSA, B); 9319 if (NestedLoopCount == 0) 9320 return StmtError(); 9321 9322 assert((CurContext->isDependentContext() || B.builtAll()) && 9323 "omp target parallel for loop exprs were not built"); 9324 9325 if (!CurContext->isDependentContext()) { 9326 // Finalize the clauses that need pre-built expressions for CodeGen. 9327 for (OMPClause *C : Clauses) { 9328 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9329 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9330 B.NumIterations, *this, CurScope, 9331 DSAStack)) 9332 return StmtError(); 9333 } 9334 } 9335 9336 setFunctionHasBranchProtectedScope(); 9337 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9338 NestedLoopCount, Clauses, AStmt, 9339 B, DSAStack->isCancelRegion()); 9340 } 9341 9342 /// Check for existence of a map clause in the list of clauses. 9343 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9344 const OpenMPClauseKind K) { 9345 return llvm::any_of( 9346 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9347 } 9348 9349 template <typename... Params> 9350 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9351 const Params... ClauseTypes) { 9352 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9353 } 9354 9355 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9356 Stmt *AStmt, 9357 SourceLocation StartLoc, 9358 SourceLocation EndLoc) { 9359 if (!AStmt) 9360 return StmtError(); 9361 9362 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9363 9364 // OpenMP [2.10.1, Restrictions, p. 97] 9365 // At least one map clause must appear on the directive. 9366 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9367 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9368 << "'map' or 'use_device_ptr'" 9369 << getOpenMPDirectiveName(OMPD_target_data); 9370 return StmtError(); 9371 } 9372 9373 setFunctionHasBranchProtectedScope(); 9374 9375 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9376 AStmt); 9377 } 9378 9379 StmtResult 9380 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9381 SourceLocation StartLoc, 9382 SourceLocation EndLoc, Stmt *AStmt) { 9383 if (!AStmt) 9384 return StmtError(); 9385 9386 auto *CS = cast<CapturedStmt>(AStmt); 9387 // 1.2.2 OpenMP Language Terminology 9388 // Structured block - An executable statement with a single entry at the 9389 // top and a single exit at the bottom. 9390 // The point of exit cannot be a branch out of the structured block. 9391 // longjmp() and throw() must not violate the entry/exit criteria. 9392 CS->getCapturedDecl()->setNothrow(); 9393 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9394 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9395 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9396 // 1.2.2 OpenMP Language Terminology 9397 // Structured block - An executable statement with a single entry at the 9398 // top and a single exit at the bottom. 9399 // The point of exit cannot be a branch out of the structured block. 9400 // longjmp() and throw() must not violate the entry/exit criteria. 9401 CS->getCapturedDecl()->setNothrow(); 9402 } 9403 9404 // OpenMP [2.10.2, Restrictions, p. 99] 9405 // At least one map clause must appear on the directive. 9406 if (!hasClauses(Clauses, OMPC_map)) { 9407 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9408 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9409 return StmtError(); 9410 } 9411 9412 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9413 AStmt); 9414 } 9415 9416 StmtResult 9417 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9418 SourceLocation StartLoc, 9419 SourceLocation EndLoc, Stmt *AStmt) { 9420 if (!AStmt) 9421 return StmtError(); 9422 9423 auto *CS = cast<CapturedStmt>(AStmt); 9424 // 1.2.2 OpenMP Language Terminology 9425 // Structured block - An executable statement with a single entry at the 9426 // top and a single exit at the bottom. 9427 // The point of exit cannot be a branch out of the structured block. 9428 // longjmp() and throw() must not violate the entry/exit criteria. 9429 CS->getCapturedDecl()->setNothrow(); 9430 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9431 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9432 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9433 // 1.2.2 OpenMP Language Terminology 9434 // Structured block - An executable statement with a single entry at the 9435 // top and a single exit at the bottom. 9436 // The point of exit cannot be a branch out of the structured block. 9437 // longjmp() and throw() must not violate the entry/exit criteria. 9438 CS->getCapturedDecl()->setNothrow(); 9439 } 9440 9441 // OpenMP [2.10.3, Restrictions, p. 102] 9442 // At least one map clause must appear on the directive. 9443 if (!hasClauses(Clauses, OMPC_map)) { 9444 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9445 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9446 return StmtError(); 9447 } 9448 9449 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9450 AStmt); 9451 } 9452 9453 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9454 SourceLocation StartLoc, 9455 SourceLocation EndLoc, 9456 Stmt *AStmt) { 9457 if (!AStmt) 9458 return StmtError(); 9459 9460 auto *CS = cast<CapturedStmt>(AStmt); 9461 // 1.2.2 OpenMP Language Terminology 9462 // Structured block - An executable statement with a single entry at the 9463 // top and a single exit at the bottom. 9464 // The point of exit cannot be a branch out of the structured block. 9465 // longjmp() and throw() must not violate the entry/exit criteria. 9466 CS->getCapturedDecl()->setNothrow(); 9467 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9468 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9469 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9470 // 1.2.2 OpenMP Language Terminology 9471 // Structured block - An executable statement with a single entry at the 9472 // top and a single exit at the bottom. 9473 // The point of exit cannot be a branch out of the structured block. 9474 // longjmp() and throw() must not violate the entry/exit criteria. 9475 CS->getCapturedDecl()->setNothrow(); 9476 } 9477 9478 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9479 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9480 return StmtError(); 9481 } 9482 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9483 AStmt); 9484 } 9485 9486 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9487 Stmt *AStmt, SourceLocation StartLoc, 9488 SourceLocation EndLoc) { 9489 if (!AStmt) 9490 return StmtError(); 9491 9492 auto *CS = cast<CapturedStmt>(AStmt); 9493 // 1.2.2 OpenMP Language Terminology 9494 // Structured block - An executable statement with a single entry at the 9495 // top and a single exit at the bottom. 9496 // The point of exit cannot be a branch out of the structured block. 9497 // longjmp() and throw() must not violate the entry/exit criteria. 9498 CS->getCapturedDecl()->setNothrow(); 9499 9500 setFunctionHasBranchProtectedScope(); 9501 9502 DSAStack->setParentTeamsRegionLoc(StartLoc); 9503 9504 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9505 } 9506 9507 StmtResult 9508 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9509 SourceLocation EndLoc, 9510 OpenMPDirectiveKind CancelRegion) { 9511 if (DSAStack->isParentNowaitRegion()) { 9512 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9513 return StmtError(); 9514 } 9515 if (DSAStack->isParentOrderedRegion()) { 9516 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9517 return StmtError(); 9518 } 9519 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9520 CancelRegion); 9521 } 9522 9523 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9524 SourceLocation StartLoc, 9525 SourceLocation EndLoc, 9526 OpenMPDirectiveKind CancelRegion) { 9527 if (DSAStack->isParentNowaitRegion()) { 9528 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9529 return StmtError(); 9530 } 9531 if (DSAStack->isParentOrderedRegion()) { 9532 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9533 return StmtError(); 9534 } 9535 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9536 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9537 CancelRegion); 9538 } 9539 9540 static bool checkGrainsizeNumTasksClauses(Sema &S, 9541 ArrayRef<OMPClause *> Clauses) { 9542 const OMPClause *PrevClause = nullptr; 9543 bool ErrorFound = false; 9544 for (const OMPClause *C : Clauses) { 9545 if (C->getClauseKind() == OMPC_grainsize || 9546 C->getClauseKind() == OMPC_num_tasks) { 9547 if (!PrevClause) 9548 PrevClause = C; 9549 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9550 S.Diag(C->getBeginLoc(), 9551 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9552 << getOpenMPClauseName(C->getClauseKind()) 9553 << getOpenMPClauseName(PrevClause->getClauseKind()); 9554 S.Diag(PrevClause->getBeginLoc(), 9555 diag::note_omp_previous_grainsize_num_tasks) 9556 << getOpenMPClauseName(PrevClause->getClauseKind()); 9557 ErrorFound = true; 9558 } 9559 } 9560 } 9561 return ErrorFound; 9562 } 9563 9564 static bool checkReductionClauseWithNogroup(Sema &S, 9565 ArrayRef<OMPClause *> Clauses) { 9566 const OMPClause *ReductionClause = nullptr; 9567 const OMPClause *NogroupClause = nullptr; 9568 for (const OMPClause *C : Clauses) { 9569 if (C->getClauseKind() == OMPC_reduction) { 9570 ReductionClause = C; 9571 if (NogroupClause) 9572 break; 9573 continue; 9574 } 9575 if (C->getClauseKind() == OMPC_nogroup) { 9576 NogroupClause = C; 9577 if (ReductionClause) 9578 break; 9579 continue; 9580 } 9581 } 9582 if (ReductionClause && NogroupClause) { 9583 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9584 << SourceRange(NogroupClause->getBeginLoc(), 9585 NogroupClause->getEndLoc()); 9586 return true; 9587 } 9588 return false; 9589 } 9590 9591 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9592 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9593 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9594 if (!AStmt) 9595 return StmtError(); 9596 9597 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9598 OMPLoopDirective::HelperExprs B; 9599 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9600 // define the nested loops number. 9601 unsigned NestedLoopCount = 9602 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9603 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9604 VarsWithImplicitDSA, B); 9605 if (NestedLoopCount == 0) 9606 return StmtError(); 9607 9608 assert((CurContext->isDependentContext() || B.builtAll()) && 9609 "omp for loop exprs were not built"); 9610 9611 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9612 // The grainsize clause and num_tasks clause are mutually exclusive and may 9613 // not appear on the same taskloop directive. 9614 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9615 return StmtError(); 9616 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9617 // If a reduction clause is present on the taskloop directive, the nogroup 9618 // clause must not be specified. 9619 if (checkReductionClauseWithNogroup(*this, Clauses)) 9620 return StmtError(); 9621 9622 setFunctionHasBranchProtectedScope(); 9623 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9624 NestedLoopCount, Clauses, AStmt, B); 9625 } 9626 9627 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9628 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9629 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9630 if (!AStmt) 9631 return StmtError(); 9632 9633 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9634 OMPLoopDirective::HelperExprs B; 9635 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9636 // define the nested loops number. 9637 unsigned NestedLoopCount = 9638 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9639 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9640 VarsWithImplicitDSA, B); 9641 if (NestedLoopCount == 0) 9642 return StmtError(); 9643 9644 assert((CurContext->isDependentContext() || B.builtAll()) && 9645 "omp for loop exprs were not built"); 9646 9647 if (!CurContext->isDependentContext()) { 9648 // Finalize the clauses that need pre-built expressions for CodeGen. 9649 for (OMPClause *C : Clauses) { 9650 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9651 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9652 B.NumIterations, *this, CurScope, 9653 DSAStack)) 9654 return StmtError(); 9655 } 9656 } 9657 9658 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9659 // The grainsize clause and num_tasks clause are mutually exclusive and may 9660 // not appear on the same taskloop directive. 9661 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9662 return StmtError(); 9663 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9664 // If a reduction clause is present on the taskloop directive, the nogroup 9665 // clause must not be specified. 9666 if (checkReductionClauseWithNogroup(*this, Clauses)) 9667 return StmtError(); 9668 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9669 return StmtError(); 9670 9671 setFunctionHasBranchProtectedScope(); 9672 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9673 NestedLoopCount, Clauses, AStmt, B); 9674 } 9675 9676 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9677 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9678 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9679 if (!AStmt) 9680 return StmtError(); 9681 9682 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9683 OMPLoopDirective::HelperExprs B; 9684 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9685 // define the nested loops number. 9686 unsigned NestedLoopCount = 9687 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9688 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9689 VarsWithImplicitDSA, B); 9690 if (NestedLoopCount == 0) 9691 return StmtError(); 9692 9693 assert((CurContext->isDependentContext() || B.builtAll()) && 9694 "omp for loop exprs were not built"); 9695 9696 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9697 // The grainsize clause and num_tasks clause are mutually exclusive and may 9698 // not appear on the same taskloop directive. 9699 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9700 return StmtError(); 9701 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9702 // If a reduction clause is present on the taskloop directive, the nogroup 9703 // clause must not be specified. 9704 if (checkReductionClauseWithNogroup(*this, Clauses)) 9705 return StmtError(); 9706 9707 setFunctionHasBranchProtectedScope(); 9708 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9709 NestedLoopCount, Clauses, AStmt, B); 9710 } 9711 9712 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9713 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9714 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9715 if (!AStmt) 9716 return StmtError(); 9717 9718 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9719 OMPLoopDirective::HelperExprs B; 9720 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9721 // define the nested loops number. 9722 unsigned NestedLoopCount = 9723 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9724 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9725 VarsWithImplicitDSA, B); 9726 if (NestedLoopCount == 0) 9727 return StmtError(); 9728 9729 assert((CurContext->isDependentContext() || B.builtAll()) && 9730 "omp for loop exprs were not built"); 9731 9732 if (!CurContext->isDependentContext()) { 9733 // Finalize the clauses that need pre-built expressions for CodeGen. 9734 for (OMPClause *C : Clauses) { 9735 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9736 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9737 B.NumIterations, *this, CurScope, 9738 DSAStack)) 9739 return StmtError(); 9740 } 9741 } 9742 9743 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9744 // The grainsize clause and num_tasks clause are mutually exclusive and may 9745 // not appear on the same taskloop directive. 9746 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9747 return StmtError(); 9748 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9749 // If a reduction clause is present on the taskloop directive, the nogroup 9750 // clause must not be specified. 9751 if (checkReductionClauseWithNogroup(*this, Clauses)) 9752 return StmtError(); 9753 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9754 return StmtError(); 9755 9756 setFunctionHasBranchProtectedScope(); 9757 return OMPMasterTaskLoopSimdDirective::Create( 9758 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9759 } 9760 9761 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9762 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9763 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9764 if (!AStmt) 9765 return StmtError(); 9766 9767 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9768 auto *CS = cast<CapturedStmt>(AStmt); 9769 // 1.2.2 OpenMP Language Terminology 9770 // Structured block - An executable statement with a single entry at the 9771 // top and a single exit at the bottom. 9772 // The point of exit cannot be a branch out of the structured block. 9773 // longjmp() and throw() must not violate the entry/exit criteria. 9774 CS->getCapturedDecl()->setNothrow(); 9775 for (int ThisCaptureLevel = 9776 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9777 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9778 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9779 // 1.2.2 OpenMP Language Terminology 9780 // Structured block - An executable statement with a single entry at the 9781 // top and a single exit at the bottom. 9782 // The point of exit cannot be a branch out of the structured block. 9783 // longjmp() and throw() must not violate the entry/exit criteria. 9784 CS->getCapturedDecl()->setNothrow(); 9785 } 9786 9787 OMPLoopDirective::HelperExprs B; 9788 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9789 // define the nested loops number. 9790 unsigned NestedLoopCount = checkOpenMPLoop( 9791 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9792 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9793 VarsWithImplicitDSA, B); 9794 if (NestedLoopCount == 0) 9795 return StmtError(); 9796 9797 assert((CurContext->isDependentContext() || B.builtAll()) && 9798 "omp for loop exprs were not built"); 9799 9800 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9801 // The grainsize clause and num_tasks clause are mutually exclusive and may 9802 // not appear on the same taskloop directive. 9803 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9804 return StmtError(); 9805 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9806 // If a reduction clause is present on the taskloop directive, the nogroup 9807 // clause must not be specified. 9808 if (checkReductionClauseWithNogroup(*this, Clauses)) 9809 return StmtError(); 9810 9811 setFunctionHasBranchProtectedScope(); 9812 return OMPParallelMasterTaskLoopDirective::Create( 9813 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9814 } 9815 9816 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 9817 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9818 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9819 if (!AStmt) 9820 return StmtError(); 9821 9822 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9823 auto *CS = cast<CapturedStmt>(AStmt); 9824 // 1.2.2 OpenMP Language Terminology 9825 // Structured block - An executable statement with a single entry at the 9826 // top and a single exit at the bottom. 9827 // The point of exit cannot be a branch out of the structured block. 9828 // longjmp() and throw() must not violate the entry/exit criteria. 9829 CS->getCapturedDecl()->setNothrow(); 9830 for (int ThisCaptureLevel = 9831 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 9832 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9833 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9834 // 1.2.2 OpenMP Language Terminology 9835 // Structured block - An executable statement with a single entry at the 9836 // top and a single exit at the bottom. 9837 // The point of exit cannot be a branch out of the structured block. 9838 // longjmp() and throw() must not violate the entry/exit criteria. 9839 CS->getCapturedDecl()->setNothrow(); 9840 } 9841 9842 OMPLoopDirective::HelperExprs B; 9843 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9844 // define the nested loops number. 9845 unsigned NestedLoopCount = checkOpenMPLoop( 9846 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9847 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9848 VarsWithImplicitDSA, B); 9849 if (NestedLoopCount == 0) 9850 return StmtError(); 9851 9852 assert((CurContext->isDependentContext() || B.builtAll()) && 9853 "omp for loop exprs were not built"); 9854 9855 if (!CurContext->isDependentContext()) { 9856 // Finalize the clauses that need pre-built expressions for CodeGen. 9857 for (OMPClause *C : Clauses) { 9858 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9859 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9860 B.NumIterations, *this, CurScope, 9861 DSAStack)) 9862 return StmtError(); 9863 } 9864 } 9865 9866 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9867 // The grainsize clause and num_tasks clause are mutually exclusive and may 9868 // not appear on the same taskloop directive. 9869 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9870 return StmtError(); 9871 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9872 // If a reduction clause is present on the taskloop directive, the nogroup 9873 // clause must not be specified. 9874 if (checkReductionClauseWithNogroup(*this, Clauses)) 9875 return StmtError(); 9876 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9877 return StmtError(); 9878 9879 setFunctionHasBranchProtectedScope(); 9880 return OMPParallelMasterTaskLoopSimdDirective::Create( 9881 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9882 } 9883 9884 StmtResult Sema::ActOnOpenMPDistributeDirective( 9885 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9886 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9887 if (!AStmt) 9888 return StmtError(); 9889 9890 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9891 OMPLoopDirective::HelperExprs B; 9892 // In presence of clause 'collapse' with number of loops, it will 9893 // define the nested loops number. 9894 unsigned NestedLoopCount = 9895 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9896 nullptr /*ordered not a clause on distribute*/, AStmt, 9897 *this, *DSAStack, VarsWithImplicitDSA, B); 9898 if (NestedLoopCount == 0) 9899 return StmtError(); 9900 9901 assert((CurContext->isDependentContext() || B.builtAll()) && 9902 "omp for loop exprs were not built"); 9903 9904 setFunctionHasBranchProtectedScope(); 9905 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9906 NestedLoopCount, Clauses, AStmt, B); 9907 } 9908 9909 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9910 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9911 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9912 if (!AStmt) 9913 return StmtError(); 9914 9915 auto *CS = cast<CapturedStmt>(AStmt); 9916 // 1.2.2 OpenMP Language Terminology 9917 // Structured block - An executable statement with a single entry at the 9918 // top and a single exit at the bottom. 9919 // The point of exit cannot be a branch out of the structured block. 9920 // longjmp() and throw() must not violate the entry/exit criteria. 9921 CS->getCapturedDecl()->setNothrow(); 9922 for (int ThisCaptureLevel = 9923 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 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 = checkOpenMPLoop( 9938 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9939 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9940 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 setFunctionHasBranchProtectedScope(); 9948 return OMPDistributeParallelForDirective::Create( 9949 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9950 DSAStack->isCancelRegion()); 9951 } 9952 9953 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9954 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9955 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9956 if (!AStmt) 9957 return StmtError(); 9958 9959 auto *CS = cast<CapturedStmt>(AStmt); 9960 // 1.2.2 OpenMP Language Terminology 9961 // Structured block - An executable statement with a single entry at the 9962 // top and a single exit at the bottom. 9963 // The point of exit cannot be a branch out of the structured block. 9964 // longjmp() and throw() must not violate the entry/exit criteria. 9965 CS->getCapturedDecl()->setNothrow(); 9966 for (int ThisCaptureLevel = 9967 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9968 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9969 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9970 // 1.2.2 OpenMP Language Terminology 9971 // Structured block - An executable statement with a single entry at the 9972 // top and a single exit at the bottom. 9973 // The point of exit cannot be a branch out of the structured block. 9974 // longjmp() and throw() must not violate the entry/exit criteria. 9975 CS->getCapturedDecl()->setNothrow(); 9976 } 9977 9978 OMPLoopDirective::HelperExprs B; 9979 // In presence of clause 'collapse' with number of loops, it will 9980 // define the nested loops number. 9981 unsigned NestedLoopCount = checkOpenMPLoop( 9982 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9983 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9984 VarsWithImplicitDSA, B); 9985 if (NestedLoopCount == 0) 9986 return StmtError(); 9987 9988 assert((CurContext->isDependentContext() || B.builtAll()) && 9989 "omp for loop exprs were not built"); 9990 9991 if (!CurContext->isDependentContext()) { 9992 // Finalize the clauses that need pre-built expressions for CodeGen. 9993 for (OMPClause *C : Clauses) { 9994 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9995 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9996 B.NumIterations, *this, CurScope, 9997 DSAStack)) 9998 return StmtError(); 9999 } 10000 } 10001 10002 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10003 return StmtError(); 10004 10005 setFunctionHasBranchProtectedScope(); 10006 return OMPDistributeParallelForSimdDirective::Create( 10007 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10008 } 10009 10010 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10011 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10012 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10013 if (!AStmt) 10014 return StmtError(); 10015 10016 auto *CS = cast<CapturedStmt>(AStmt); 10017 // 1.2.2 OpenMP Language Terminology 10018 // Structured block - An executable statement with a single entry at the 10019 // top and a single exit at the bottom. 10020 // The point of exit cannot be a branch out of the structured block. 10021 // longjmp() and throw() must not violate the entry/exit criteria. 10022 CS->getCapturedDecl()->setNothrow(); 10023 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10024 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10025 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10026 // 1.2.2 OpenMP Language Terminology 10027 // Structured block - An executable statement with a single entry at the 10028 // top and a single exit at the bottom. 10029 // The point of exit cannot be a branch out of the structured block. 10030 // longjmp() and throw() must not violate the entry/exit criteria. 10031 CS->getCapturedDecl()->setNothrow(); 10032 } 10033 10034 OMPLoopDirective::HelperExprs B; 10035 // In presence of clause 'collapse' with number of loops, it will 10036 // define the nested loops number. 10037 unsigned NestedLoopCount = 10038 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10039 nullptr /*ordered not a clause on distribute*/, CS, *this, 10040 *DSAStack, VarsWithImplicitDSA, B); 10041 if (NestedLoopCount == 0) 10042 return StmtError(); 10043 10044 assert((CurContext->isDependentContext() || B.builtAll()) && 10045 "omp for loop exprs were not built"); 10046 10047 if (!CurContext->isDependentContext()) { 10048 // Finalize the clauses that need pre-built expressions for CodeGen. 10049 for (OMPClause *C : Clauses) { 10050 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10051 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10052 B.NumIterations, *this, CurScope, 10053 DSAStack)) 10054 return StmtError(); 10055 } 10056 } 10057 10058 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10059 return StmtError(); 10060 10061 setFunctionHasBranchProtectedScope(); 10062 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10063 NestedLoopCount, Clauses, AStmt, B); 10064 } 10065 10066 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10067 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10068 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10069 if (!AStmt) 10070 return StmtError(); 10071 10072 auto *CS = cast<CapturedStmt>(AStmt); 10073 // 1.2.2 OpenMP Language Terminology 10074 // Structured block - An executable statement with a single entry at the 10075 // top and a single exit at the bottom. 10076 // The point of exit cannot be a branch out of the structured block. 10077 // longjmp() and throw() must not violate the entry/exit criteria. 10078 CS->getCapturedDecl()->setNothrow(); 10079 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10080 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10081 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10082 // 1.2.2 OpenMP Language Terminology 10083 // Structured block - An executable statement with a single entry at the 10084 // top and a single exit at the bottom. 10085 // The point of exit cannot be a branch out of the structured block. 10086 // longjmp() and throw() must not violate the entry/exit criteria. 10087 CS->getCapturedDecl()->setNothrow(); 10088 } 10089 10090 OMPLoopDirective::HelperExprs B; 10091 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10092 // define the nested loops number. 10093 unsigned NestedLoopCount = checkOpenMPLoop( 10094 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10095 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10096 VarsWithImplicitDSA, B); 10097 if (NestedLoopCount == 0) 10098 return StmtError(); 10099 10100 assert((CurContext->isDependentContext() || B.builtAll()) && 10101 "omp target parallel for simd loop exprs were not built"); 10102 10103 if (!CurContext->isDependentContext()) { 10104 // Finalize the clauses that need pre-built expressions for CodeGen. 10105 for (OMPClause *C : Clauses) { 10106 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10107 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10108 B.NumIterations, *this, CurScope, 10109 DSAStack)) 10110 return StmtError(); 10111 } 10112 } 10113 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10114 return StmtError(); 10115 10116 setFunctionHasBranchProtectedScope(); 10117 return OMPTargetParallelForSimdDirective::Create( 10118 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10119 } 10120 10121 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10122 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10123 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10124 if (!AStmt) 10125 return StmtError(); 10126 10127 auto *CS = cast<CapturedStmt>(AStmt); 10128 // 1.2.2 OpenMP Language Terminology 10129 // Structured block - An executable statement with a single entry at the 10130 // top and a single exit at the bottom. 10131 // The point of exit cannot be a branch out of the structured block. 10132 // longjmp() and throw() must not violate the entry/exit criteria. 10133 CS->getCapturedDecl()->setNothrow(); 10134 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10135 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10136 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10137 // 1.2.2 OpenMP Language Terminology 10138 // Structured block - An executable statement with a single entry at the 10139 // top and a single exit at the bottom. 10140 // The point of exit cannot be a branch out of the structured block. 10141 // longjmp() and throw() must not violate the entry/exit criteria. 10142 CS->getCapturedDecl()->setNothrow(); 10143 } 10144 10145 OMPLoopDirective::HelperExprs B; 10146 // In presence of clause 'collapse' with number of loops, it will define the 10147 // nested loops number. 10148 unsigned NestedLoopCount = 10149 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10150 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10151 VarsWithImplicitDSA, B); 10152 if (NestedLoopCount == 0) 10153 return StmtError(); 10154 10155 assert((CurContext->isDependentContext() || B.builtAll()) && 10156 "omp target simd loop exprs were not built"); 10157 10158 if (!CurContext->isDependentContext()) { 10159 // Finalize the clauses that need pre-built expressions for CodeGen. 10160 for (OMPClause *C : Clauses) { 10161 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10162 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10163 B.NumIterations, *this, CurScope, 10164 DSAStack)) 10165 return StmtError(); 10166 } 10167 } 10168 10169 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10170 return StmtError(); 10171 10172 setFunctionHasBranchProtectedScope(); 10173 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10174 NestedLoopCount, Clauses, AStmt, B); 10175 } 10176 10177 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10178 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10179 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10180 if (!AStmt) 10181 return StmtError(); 10182 10183 auto *CS = cast<CapturedStmt>(AStmt); 10184 // 1.2.2 OpenMP Language Terminology 10185 // Structured block - An executable statement with a single entry at the 10186 // top and a single exit at the bottom. 10187 // The point of exit cannot be a branch out of the structured block. 10188 // longjmp() and throw() must not violate the entry/exit criteria. 10189 CS->getCapturedDecl()->setNothrow(); 10190 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10191 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10192 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10193 // 1.2.2 OpenMP Language Terminology 10194 // Structured block - An executable statement with a single entry at the 10195 // top and a single exit at the bottom. 10196 // The point of exit cannot be a branch out of the structured block. 10197 // longjmp() and throw() must not violate the entry/exit criteria. 10198 CS->getCapturedDecl()->setNothrow(); 10199 } 10200 10201 OMPLoopDirective::HelperExprs B; 10202 // In presence of clause 'collapse' with number of loops, it will 10203 // define the nested loops number. 10204 unsigned NestedLoopCount = 10205 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10206 nullptr /*ordered not a clause on distribute*/, CS, *this, 10207 *DSAStack, VarsWithImplicitDSA, B); 10208 if (NestedLoopCount == 0) 10209 return StmtError(); 10210 10211 assert((CurContext->isDependentContext() || B.builtAll()) && 10212 "omp teams distribute loop exprs were not built"); 10213 10214 setFunctionHasBranchProtectedScope(); 10215 10216 DSAStack->setParentTeamsRegionLoc(StartLoc); 10217 10218 return OMPTeamsDistributeDirective::Create( 10219 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10220 } 10221 10222 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10223 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10224 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10225 if (!AStmt) 10226 return StmtError(); 10227 10228 auto *CS = cast<CapturedStmt>(AStmt); 10229 // 1.2.2 OpenMP Language Terminology 10230 // Structured block - An executable statement with a single entry at the 10231 // top and a single exit at the bottom. 10232 // The point of exit cannot be a branch out of the structured block. 10233 // longjmp() and throw() must not violate the entry/exit criteria. 10234 CS->getCapturedDecl()->setNothrow(); 10235 for (int ThisCaptureLevel = 10236 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10237 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10238 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10239 // 1.2.2 OpenMP Language Terminology 10240 // Structured block - An executable statement with a single entry at the 10241 // top and a single exit at the bottom. 10242 // The point of exit cannot be a branch out of the structured block. 10243 // longjmp() and throw() must not violate the entry/exit criteria. 10244 CS->getCapturedDecl()->setNothrow(); 10245 } 10246 10247 10248 OMPLoopDirective::HelperExprs B; 10249 // In presence of clause 'collapse' with number of loops, it will 10250 // define the nested loops number. 10251 unsigned NestedLoopCount = checkOpenMPLoop( 10252 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10253 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10254 VarsWithImplicitDSA, B); 10255 10256 if (NestedLoopCount == 0) 10257 return StmtError(); 10258 10259 assert((CurContext->isDependentContext() || B.builtAll()) && 10260 "omp teams distribute simd loop exprs were not built"); 10261 10262 if (!CurContext->isDependentContext()) { 10263 // Finalize the clauses that need pre-built expressions for CodeGen. 10264 for (OMPClause *C : Clauses) { 10265 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10266 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10267 B.NumIterations, *this, CurScope, 10268 DSAStack)) 10269 return StmtError(); 10270 } 10271 } 10272 10273 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10274 return StmtError(); 10275 10276 setFunctionHasBranchProtectedScope(); 10277 10278 DSAStack->setParentTeamsRegionLoc(StartLoc); 10279 10280 return OMPTeamsDistributeSimdDirective::Create( 10281 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10282 } 10283 10284 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10285 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10286 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10287 if (!AStmt) 10288 return StmtError(); 10289 10290 auto *CS = cast<CapturedStmt>(AStmt); 10291 // 1.2.2 OpenMP Language Terminology 10292 // Structured block - An executable statement with a single entry at the 10293 // top and a single exit at the bottom. 10294 // The point of exit cannot be a branch out of the structured block. 10295 // longjmp() and throw() must not violate the entry/exit criteria. 10296 CS->getCapturedDecl()->setNothrow(); 10297 10298 for (int ThisCaptureLevel = 10299 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10300 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10301 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10302 // 1.2.2 OpenMP Language Terminology 10303 // Structured block - An executable statement with a single entry at the 10304 // top and a single exit at the bottom. 10305 // The point of exit cannot be a branch out of the structured block. 10306 // longjmp() and throw() must not violate the entry/exit criteria. 10307 CS->getCapturedDecl()->setNothrow(); 10308 } 10309 10310 OMPLoopDirective::HelperExprs B; 10311 // In presence of clause 'collapse' with number of loops, it will 10312 // define the nested loops number. 10313 unsigned NestedLoopCount = checkOpenMPLoop( 10314 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10315 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10316 VarsWithImplicitDSA, B); 10317 10318 if (NestedLoopCount == 0) 10319 return StmtError(); 10320 10321 assert((CurContext->isDependentContext() || B.builtAll()) && 10322 "omp for loop exprs were not built"); 10323 10324 if (!CurContext->isDependentContext()) { 10325 // Finalize the clauses that need pre-built expressions for CodeGen. 10326 for (OMPClause *C : Clauses) { 10327 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10328 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10329 B.NumIterations, *this, CurScope, 10330 DSAStack)) 10331 return StmtError(); 10332 } 10333 } 10334 10335 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10336 return StmtError(); 10337 10338 setFunctionHasBranchProtectedScope(); 10339 10340 DSAStack->setParentTeamsRegionLoc(StartLoc); 10341 10342 return OMPTeamsDistributeParallelForSimdDirective::Create( 10343 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10344 } 10345 10346 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10347 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10348 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10349 if (!AStmt) 10350 return StmtError(); 10351 10352 auto *CS = cast<CapturedStmt>(AStmt); 10353 // 1.2.2 OpenMP Language Terminology 10354 // Structured block - An executable statement with a single entry at the 10355 // top and a single exit at the bottom. 10356 // The point of exit cannot be a branch out of the structured block. 10357 // longjmp() and throw() must not violate the entry/exit criteria. 10358 CS->getCapturedDecl()->setNothrow(); 10359 10360 for (int ThisCaptureLevel = 10361 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10362 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10363 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10364 // 1.2.2 OpenMP Language Terminology 10365 // Structured block - An executable statement with a single entry at the 10366 // top and a single exit at the bottom. 10367 // The point of exit cannot be a branch out of the structured block. 10368 // longjmp() and throw() must not violate the entry/exit criteria. 10369 CS->getCapturedDecl()->setNothrow(); 10370 } 10371 10372 OMPLoopDirective::HelperExprs B; 10373 // In presence of clause 'collapse' with number of loops, it will 10374 // define the nested loops number. 10375 unsigned NestedLoopCount = checkOpenMPLoop( 10376 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10377 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10378 VarsWithImplicitDSA, B); 10379 10380 if (NestedLoopCount == 0) 10381 return StmtError(); 10382 10383 assert((CurContext->isDependentContext() || B.builtAll()) && 10384 "omp for loop exprs were not built"); 10385 10386 setFunctionHasBranchProtectedScope(); 10387 10388 DSAStack->setParentTeamsRegionLoc(StartLoc); 10389 10390 return OMPTeamsDistributeParallelForDirective::Create( 10391 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10392 DSAStack->isCancelRegion()); 10393 } 10394 10395 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10396 Stmt *AStmt, 10397 SourceLocation StartLoc, 10398 SourceLocation EndLoc) { 10399 if (!AStmt) 10400 return StmtError(); 10401 10402 auto *CS = cast<CapturedStmt>(AStmt); 10403 // 1.2.2 OpenMP Language Terminology 10404 // Structured block - An executable statement with a single entry at the 10405 // top and a single exit at the bottom. 10406 // The point of exit cannot be a branch out of the structured block. 10407 // longjmp() and throw() must not violate the entry/exit criteria. 10408 CS->getCapturedDecl()->setNothrow(); 10409 10410 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10411 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10412 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10413 // 1.2.2 OpenMP Language Terminology 10414 // Structured block - An executable statement with a single entry at the 10415 // top and a single exit at the bottom. 10416 // The point of exit cannot be a branch out of the structured block. 10417 // longjmp() and throw() must not violate the entry/exit criteria. 10418 CS->getCapturedDecl()->setNothrow(); 10419 } 10420 setFunctionHasBranchProtectedScope(); 10421 10422 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10423 AStmt); 10424 } 10425 10426 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10427 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10428 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10429 if (!AStmt) 10430 return StmtError(); 10431 10432 auto *CS = cast<CapturedStmt>(AStmt); 10433 // 1.2.2 OpenMP Language Terminology 10434 // Structured block - An executable statement with a single entry at the 10435 // top and a single exit at the bottom. 10436 // The point of exit cannot be a branch out of the structured block. 10437 // longjmp() and throw() must not violate the entry/exit criteria. 10438 CS->getCapturedDecl()->setNothrow(); 10439 for (int ThisCaptureLevel = 10440 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10441 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10442 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10443 // 1.2.2 OpenMP Language Terminology 10444 // Structured block - An executable statement with a single entry at the 10445 // top and a single exit at the bottom. 10446 // The point of exit cannot be a branch out of the structured block. 10447 // longjmp() and throw() must not violate the entry/exit criteria. 10448 CS->getCapturedDecl()->setNothrow(); 10449 } 10450 10451 OMPLoopDirective::HelperExprs B; 10452 // In presence of clause 'collapse' with number of loops, it will 10453 // define the nested loops number. 10454 unsigned NestedLoopCount = checkOpenMPLoop( 10455 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10456 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10457 VarsWithImplicitDSA, B); 10458 if (NestedLoopCount == 0) 10459 return StmtError(); 10460 10461 assert((CurContext->isDependentContext() || B.builtAll()) && 10462 "omp target teams distribute loop exprs were not built"); 10463 10464 setFunctionHasBranchProtectedScope(); 10465 return OMPTargetTeamsDistributeDirective::Create( 10466 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10467 } 10468 10469 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10470 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10471 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10472 if (!AStmt) 10473 return StmtError(); 10474 10475 auto *CS = cast<CapturedStmt>(AStmt); 10476 // 1.2.2 OpenMP Language Terminology 10477 // Structured block - An executable statement with a single entry at the 10478 // top and a single exit at the bottom. 10479 // The point of exit cannot be a branch out of the structured block. 10480 // longjmp() and throw() must not violate the entry/exit criteria. 10481 CS->getCapturedDecl()->setNothrow(); 10482 for (int ThisCaptureLevel = 10483 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10484 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10485 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10486 // 1.2.2 OpenMP Language Terminology 10487 // Structured block - An executable statement with a single entry at the 10488 // top and a single exit at the bottom. 10489 // The point of exit cannot be a branch out of the structured block. 10490 // longjmp() and throw() must not violate the entry/exit criteria. 10491 CS->getCapturedDecl()->setNothrow(); 10492 } 10493 10494 OMPLoopDirective::HelperExprs B; 10495 // In presence of clause 'collapse' with number of loops, it will 10496 // define the nested loops number. 10497 unsigned NestedLoopCount = checkOpenMPLoop( 10498 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10499 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10500 VarsWithImplicitDSA, B); 10501 if (NestedLoopCount == 0) 10502 return StmtError(); 10503 10504 assert((CurContext->isDependentContext() || B.builtAll()) && 10505 "omp target teams distribute parallel for loop exprs were not built"); 10506 10507 if (!CurContext->isDependentContext()) { 10508 // Finalize the clauses that need pre-built expressions for CodeGen. 10509 for (OMPClause *C : Clauses) { 10510 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10511 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10512 B.NumIterations, *this, CurScope, 10513 DSAStack)) 10514 return StmtError(); 10515 } 10516 } 10517 10518 setFunctionHasBranchProtectedScope(); 10519 return OMPTargetTeamsDistributeParallelForDirective::Create( 10520 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10521 DSAStack->isCancelRegion()); 10522 } 10523 10524 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10525 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10526 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10527 if (!AStmt) 10528 return StmtError(); 10529 10530 auto *CS = cast<CapturedStmt>(AStmt); 10531 // 1.2.2 OpenMP Language Terminology 10532 // Structured block - An executable statement with a single entry at the 10533 // top and a single exit at the bottom. 10534 // The point of exit cannot be a branch out of the structured block. 10535 // longjmp() and throw() must not violate the entry/exit criteria. 10536 CS->getCapturedDecl()->setNothrow(); 10537 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10538 OMPD_target_teams_distribute_parallel_for_simd); 10539 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10540 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10541 // 1.2.2 OpenMP Language Terminology 10542 // Structured block - An executable statement with a single entry at the 10543 // top and a single exit at the bottom. 10544 // The point of exit cannot be a branch out of the structured block. 10545 // longjmp() and throw() must not violate the entry/exit criteria. 10546 CS->getCapturedDecl()->setNothrow(); 10547 } 10548 10549 OMPLoopDirective::HelperExprs B; 10550 // In presence of clause 'collapse' with number of loops, it will 10551 // define the nested loops number. 10552 unsigned NestedLoopCount = 10553 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10554 getCollapseNumberExpr(Clauses), 10555 nullptr /*ordered not a clause on distribute*/, CS, *this, 10556 *DSAStack, VarsWithImplicitDSA, B); 10557 if (NestedLoopCount == 0) 10558 return StmtError(); 10559 10560 assert((CurContext->isDependentContext() || B.builtAll()) && 10561 "omp target teams distribute parallel for simd loop exprs were not " 10562 "built"); 10563 10564 if (!CurContext->isDependentContext()) { 10565 // Finalize the clauses that need pre-built expressions for CodeGen. 10566 for (OMPClause *C : Clauses) { 10567 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10568 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10569 B.NumIterations, *this, CurScope, 10570 DSAStack)) 10571 return StmtError(); 10572 } 10573 } 10574 10575 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10576 return StmtError(); 10577 10578 setFunctionHasBranchProtectedScope(); 10579 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10580 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10581 } 10582 10583 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10584 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10585 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10586 if (!AStmt) 10587 return StmtError(); 10588 10589 auto *CS = cast<CapturedStmt>(AStmt); 10590 // 1.2.2 OpenMP Language Terminology 10591 // Structured block - An executable statement with a single entry at the 10592 // top and a single exit at the bottom. 10593 // The point of exit cannot be a branch out of the structured block. 10594 // longjmp() and throw() must not violate the entry/exit criteria. 10595 CS->getCapturedDecl()->setNothrow(); 10596 for (int ThisCaptureLevel = 10597 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10598 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10599 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10600 // 1.2.2 OpenMP Language Terminology 10601 // Structured block - An executable statement with a single entry at the 10602 // top and a single exit at the bottom. 10603 // The point of exit cannot be a branch out of the structured block. 10604 // longjmp() and throw() must not violate the entry/exit criteria. 10605 CS->getCapturedDecl()->setNothrow(); 10606 } 10607 10608 OMPLoopDirective::HelperExprs B; 10609 // In presence of clause 'collapse' with number of loops, it will 10610 // define the nested loops number. 10611 unsigned NestedLoopCount = checkOpenMPLoop( 10612 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10613 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10614 VarsWithImplicitDSA, B); 10615 if (NestedLoopCount == 0) 10616 return StmtError(); 10617 10618 assert((CurContext->isDependentContext() || B.builtAll()) && 10619 "omp target teams distribute simd loop exprs were not built"); 10620 10621 if (!CurContext->isDependentContext()) { 10622 // Finalize the clauses that need pre-built expressions for CodeGen. 10623 for (OMPClause *C : Clauses) { 10624 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10625 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10626 B.NumIterations, *this, CurScope, 10627 DSAStack)) 10628 return StmtError(); 10629 } 10630 } 10631 10632 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10633 return StmtError(); 10634 10635 setFunctionHasBranchProtectedScope(); 10636 return OMPTargetTeamsDistributeSimdDirective::Create( 10637 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10638 } 10639 10640 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10641 SourceLocation StartLoc, 10642 SourceLocation LParenLoc, 10643 SourceLocation EndLoc) { 10644 OMPClause *Res = nullptr; 10645 switch (Kind) { 10646 case OMPC_final: 10647 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10648 break; 10649 case OMPC_num_threads: 10650 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10651 break; 10652 case OMPC_safelen: 10653 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10654 break; 10655 case OMPC_simdlen: 10656 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10657 break; 10658 case OMPC_allocator: 10659 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10660 break; 10661 case OMPC_collapse: 10662 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10663 break; 10664 case OMPC_ordered: 10665 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10666 break; 10667 case OMPC_device: 10668 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10669 break; 10670 case OMPC_num_teams: 10671 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10672 break; 10673 case OMPC_thread_limit: 10674 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10675 break; 10676 case OMPC_priority: 10677 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10678 break; 10679 case OMPC_grainsize: 10680 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10681 break; 10682 case OMPC_num_tasks: 10683 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10684 break; 10685 case OMPC_hint: 10686 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10687 break; 10688 case OMPC_if: 10689 case OMPC_default: 10690 case OMPC_proc_bind: 10691 case OMPC_schedule: 10692 case OMPC_private: 10693 case OMPC_firstprivate: 10694 case OMPC_lastprivate: 10695 case OMPC_shared: 10696 case OMPC_reduction: 10697 case OMPC_task_reduction: 10698 case OMPC_in_reduction: 10699 case OMPC_linear: 10700 case OMPC_aligned: 10701 case OMPC_copyin: 10702 case OMPC_copyprivate: 10703 case OMPC_nowait: 10704 case OMPC_untied: 10705 case OMPC_mergeable: 10706 case OMPC_threadprivate: 10707 case OMPC_allocate: 10708 case OMPC_flush: 10709 case OMPC_read: 10710 case OMPC_write: 10711 case OMPC_update: 10712 case OMPC_capture: 10713 case OMPC_seq_cst: 10714 case OMPC_depend: 10715 case OMPC_threads: 10716 case OMPC_simd: 10717 case OMPC_map: 10718 case OMPC_nogroup: 10719 case OMPC_dist_schedule: 10720 case OMPC_defaultmap: 10721 case OMPC_unknown: 10722 case OMPC_uniform: 10723 case OMPC_to: 10724 case OMPC_from: 10725 case OMPC_use_device_ptr: 10726 case OMPC_is_device_ptr: 10727 case OMPC_unified_address: 10728 case OMPC_unified_shared_memory: 10729 case OMPC_reverse_offload: 10730 case OMPC_dynamic_allocators: 10731 case OMPC_atomic_default_mem_order: 10732 case OMPC_device_type: 10733 case OMPC_match: 10734 llvm_unreachable("Clause is not allowed."); 10735 } 10736 return Res; 10737 } 10738 10739 // An OpenMP directive such as 'target parallel' has two captured regions: 10740 // for the 'target' and 'parallel' respectively. This function returns 10741 // the region in which to capture expressions associated with a clause. 10742 // A return value of OMPD_unknown signifies that the expression should not 10743 // be captured. 10744 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10745 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 10746 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10747 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10748 switch (CKind) { 10749 case OMPC_if: 10750 switch (DKind) { 10751 case OMPD_target_parallel_for_simd: 10752 if (OpenMPVersion >= 50 && 10753 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10754 CaptureRegion = OMPD_parallel; 10755 break; 10756 } 10757 LLVM_FALLTHROUGH; 10758 case OMPD_target_parallel: 10759 case OMPD_target_parallel_for: 10760 // If this clause applies to the nested 'parallel' region, capture within 10761 // the 'target' region, otherwise do not capture. 10762 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10763 CaptureRegion = OMPD_target; 10764 break; 10765 case OMPD_target_teams_distribute_parallel_for: 10766 case OMPD_target_teams_distribute_parallel_for_simd: 10767 // If this clause applies to the nested 'parallel' region, capture within 10768 // the 'teams' region, otherwise do not capture. 10769 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10770 CaptureRegion = OMPD_teams; 10771 break; 10772 case OMPD_teams_distribute_parallel_for_simd: 10773 if (OpenMPVersion >= 50 && 10774 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10775 CaptureRegion = OMPD_parallel; 10776 break; 10777 } 10778 LLVM_FALLTHROUGH; 10779 case OMPD_teams_distribute_parallel_for: 10780 CaptureRegion = OMPD_teams; 10781 break; 10782 case OMPD_target_update: 10783 case OMPD_target_enter_data: 10784 case OMPD_target_exit_data: 10785 CaptureRegion = OMPD_task; 10786 break; 10787 case OMPD_parallel_master_taskloop: 10788 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10789 CaptureRegion = OMPD_parallel; 10790 break; 10791 case OMPD_parallel_master_taskloop_simd: 10792 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 10793 NameModifier == OMPD_taskloop) { 10794 CaptureRegion = OMPD_parallel; 10795 break; 10796 } 10797 if (OpenMPVersion <= 45) 10798 break; 10799 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10800 CaptureRegion = OMPD_taskloop; 10801 break; 10802 case OMPD_parallel_for_simd: 10803 if (OpenMPVersion <= 45) 10804 break; 10805 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10806 CaptureRegion = OMPD_parallel; 10807 break; 10808 case OMPD_taskloop_simd: 10809 case OMPD_master_taskloop_simd: 10810 if (OpenMPVersion <= 45) 10811 break; 10812 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10813 CaptureRegion = OMPD_taskloop; 10814 break; 10815 case OMPD_distribute_parallel_for_simd: 10816 if (OpenMPVersion <= 45) 10817 break; 10818 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 10819 CaptureRegion = OMPD_parallel; 10820 break; 10821 case OMPD_target_simd: 10822 if (OpenMPVersion >= 50 && 10823 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10824 CaptureRegion = OMPD_target; 10825 break; 10826 case OMPD_teams_distribute_simd: 10827 if (OpenMPVersion >= 50 && 10828 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 10829 CaptureRegion = OMPD_teams; 10830 break; 10831 case OMPD_cancel: 10832 case OMPD_parallel: 10833 case OMPD_parallel_master: 10834 case OMPD_parallel_sections: 10835 case OMPD_parallel_for: 10836 case OMPD_target: 10837 case OMPD_target_teams: 10838 case OMPD_target_teams_distribute: 10839 case OMPD_target_teams_distribute_simd: 10840 case OMPD_distribute_parallel_for: 10841 case OMPD_task: 10842 case OMPD_taskloop: 10843 case OMPD_master_taskloop: 10844 case OMPD_target_data: 10845 case OMPD_simd: 10846 case OMPD_for_simd: 10847 case OMPD_distribute_simd: 10848 // Do not capture if-clause expressions. 10849 break; 10850 case OMPD_threadprivate: 10851 case OMPD_allocate: 10852 case OMPD_taskyield: 10853 case OMPD_barrier: 10854 case OMPD_taskwait: 10855 case OMPD_cancellation_point: 10856 case OMPD_flush: 10857 case OMPD_declare_reduction: 10858 case OMPD_declare_mapper: 10859 case OMPD_declare_simd: 10860 case OMPD_declare_variant: 10861 case OMPD_declare_target: 10862 case OMPD_end_declare_target: 10863 case OMPD_teams: 10864 case OMPD_for: 10865 case OMPD_sections: 10866 case OMPD_section: 10867 case OMPD_single: 10868 case OMPD_master: 10869 case OMPD_critical: 10870 case OMPD_taskgroup: 10871 case OMPD_distribute: 10872 case OMPD_ordered: 10873 case OMPD_atomic: 10874 case OMPD_teams_distribute: 10875 case OMPD_requires: 10876 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10877 case OMPD_unknown: 10878 llvm_unreachable("Unknown OpenMP directive"); 10879 } 10880 break; 10881 case OMPC_num_threads: 10882 switch (DKind) { 10883 case OMPD_target_parallel: 10884 case OMPD_target_parallel_for: 10885 case OMPD_target_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_target_teams_distribute_parallel_for: 10891 case OMPD_target_teams_distribute_parallel_for_simd: 10892 CaptureRegion = OMPD_teams; 10893 break; 10894 case OMPD_parallel: 10895 case OMPD_parallel_master: 10896 case OMPD_parallel_sections: 10897 case OMPD_parallel_for: 10898 case OMPD_parallel_for_simd: 10899 case OMPD_distribute_parallel_for: 10900 case OMPD_distribute_parallel_for_simd: 10901 case OMPD_parallel_master_taskloop: 10902 case OMPD_parallel_master_taskloop_simd: 10903 // Do not capture num_threads-clause expressions. 10904 break; 10905 case OMPD_target_data: 10906 case OMPD_target_enter_data: 10907 case OMPD_target_exit_data: 10908 case OMPD_target_update: 10909 case OMPD_target: 10910 case OMPD_target_simd: 10911 case OMPD_target_teams: 10912 case OMPD_target_teams_distribute: 10913 case OMPD_target_teams_distribute_simd: 10914 case OMPD_cancel: 10915 case OMPD_task: 10916 case OMPD_taskloop: 10917 case OMPD_taskloop_simd: 10918 case OMPD_master_taskloop: 10919 case OMPD_master_taskloop_simd: 10920 case OMPD_threadprivate: 10921 case OMPD_allocate: 10922 case OMPD_taskyield: 10923 case OMPD_barrier: 10924 case OMPD_taskwait: 10925 case OMPD_cancellation_point: 10926 case OMPD_flush: 10927 case OMPD_declare_reduction: 10928 case OMPD_declare_mapper: 10929 case OMPD_declare_simd: 10930 case OMPD_declare_variant: 10931 case OMPD_declare_target: 10932 case OMPD_end_declare_target: 10933 case OMPD_teams: 10934 case OMPD_simd: 10935 case OMPD_for: 10936 case OMPD_for_simd: 10937 case OMPD_sections: 10938 case OMPD_section: 10939 case OMPD_single: 10940 case OMPD_master: 10941 case OMPD_critical: 10942 case OMPD_taskgroup: 10943 case OMPD_distribute: 10944 case OMPD_ordered: 10945 case OMPD_atomic: 10946 case OMPD_distribute_simd: 10947 case OMPD_teams_distribute: 10948 case OMPD_teams_distribute_simd: 10949 case OMPD_requires: 10950 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10951 case OMPD_unknown: 10952 llvm_unreachable("Unknown OpenMP directive"); 10953 } 10954 break; 10955 case OMPC_num_teams: 10956 switch (DKind) { 10957 case OMPD_target_teams: 10958 case OMPD_target_teams_distribute: 10959 case OMPD_target_teams_distribute_simd: 10960 case OMPD_target_teams_distribute_parallel_for: 10961 case OMPD_target_teams_distribute_parallel_for_simd: 10962 CaptureRegion = OMPD_target; 10963 break; 10964 case OMPD_teams_distribute_parallel_for: 10965 case OMPD_teams_distribute_parallel_for_simd: 10966 case OMPD_teams: 10967 case OMPD_teams_distribute: 10968 case OMPD_teams_distribute_simd: 10969 // Do not capture num_teams-clause expressions. 10970 break; 10971 case OMPD_distribute_parallel_for: 10972 case OMPD_distribute_parallel_for_simd: 10973 case OMPD_task: 10974 case OMPD_taskloop: 10975 case OMPD_taskloop_simd: 10976 case OMPD_master_taskloop: 10977 case OMPD_master_taskloop_simd: 10978 case OMPD_parallel_master_taskloop: 10979 case OMPD_parallel_master_taskloop_simd: 10980 case OMPD_target_data: 10981 case OMPD_target_enter_data: 10982 case OMPD_target_exit_data: 10983 case OMPD_target_update: 10984 case OMPD_cancel: 10985 case OMPD_parallel: 10986 case OMPD_parallel_master: 10987 case OMPD_parallel_sections: 10988 case OMPD_parallel_for: 10989 case OMPD_parallel_for_simd: 10990 case OMPD_target: 10991 case OMPD_target_simd: 10992 case OMPD_target_parallel: 10993 case OMPD_target_parallel_for: 10994 case OMPD_target_parallel_for_simd: 10995 case OMPD_threadprivate: 10996 case OMPD_allocate: 10997 case OMPD_taskyield: 10998 case OMPD_barrier: 10999 case OMPD_taskwait: 11000 case OMPD_cancellation_point: 11001 case OMPD_flush: 11002 case OMPD_declare_reduction: 11003 case OMPD_declare_mapper: 11004 case OMPD_declare_simd: 11005 case OMPD_declare_variant: 11006 case OMPD_declare_target: 11007 case OMPD_end_declare_target: 11008 case OMPD_simd: 11009 case OMPD_for: 11010 case OMPD_for_simd: 11011 case OMPD_sections: 11012 case OMPD_section: 11013 case OMPD_single: 11014 case OMPD_master: 11015 case OMPD_critical: 11016 case OMPD_taskgroup: 11017 case OMPD_distribute: 11018 case OMPD_ordered: 11019 case OMPD_atomic: 11020 case OMPD_distribute_simd: 11021 case OMPD_requires: 11022 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11023 case OMPD_unknown: 11024 llvm_unreachable("Unknown OpenMP directive"); 11025 } 11026 break; 11027 case OMPC_thread_limit: 11028 switch (DKind) { 11029 case OMPD_target_teams: 11030 case OMPD_target_teams_distribute: 11031 case OMPD_target_teams_distribute_simd: 11032 case OMPD_target_teams_distribute_parallel_for: 11033 case OMPD_target_teams_distribute_parallel_for_simd: 11034 CaptureRegion = OMPD_target; 11035 break; 11036 case OMPD_teams_distribute_parallel_for: 11037 case OMPD_teams_distribute_parallel_for_simd: 11038 case OMPD_teams: 11039 case OMPD_teams_distribute: 11040 case OMPD_teams_distribute_simd: 11041 // Do not capture thread_limit-clause expressions. 11042 break; 11043 case OMPD_distribute_parallel_for: 11044 case OMPD_distribute_parallel_for_simd: 11045 case OMPD_task: 11046 case OMPD_taskloop: 11047 case OMPD_taskloop_simd: 11048 case OMPD_master_taskloop: 11049 case OMPD_master_taskloop_simd: 11050 case OMPD_parallel_master_taskloop: 11051 case OMPD_parallel_master_taskloop_simd: 11052 case OMPD_target_data: 11053 case OMPD_target_enter_data: 11054 case OMPD_target_exit_data: 11055 case OMPD_target_update: 11056 case OMPD_cancel: 11057 case OMPD_parallel: 11058 case OMPD_parallel_master: 11059 case OMPD_parallel_sections: 11060 case OMPD_parallel_for: 11061 case OMPD_parallel_for_simd: 11062 case OMPD_target: 11063 case OMPD_target_simd: 11064 case OMPD_target_parallel: 11065 case OMPD_target_parallel_for: 11066 case OMPD_target_parallel_for_simd: 11067 case OMPD_threadprivate: 11068 case OMPD_allocate: 11069 case OMPD_taskyield: 11070 case OMPD_barrier: 11071 case OMPD_taskwait: 11072 case OMPD_cancellation_point: 11073 case OMPD_flush: 11074 case OMPD_declare_reduction: 11075 case OMPD_declare_mapper: 11076 case OMPD_declare_simd: 11077 case OMPD_declare_variant: 11078 case OMPD_declare_target: 11079 case OMPD_end_declare_target: 11080 case OMPD_simd: 11081 case OMPD_for: 11082 case OMPD_for_simd: 11083 case OMPD_sections: 11084 case OMPD_section: 11085 case OMPD_single: 11086 case OMPD_master: 11087 case OMPD_critical: 11088 case OMPD_taskgroup: 11089 case OMPD_distribute: 11090 case OMPD_ordered: 11091 case OMPD_atomic: 11092 case OMPD_distribute_simd: 11093 case OMPD_requires: 11094 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11095 case OMPD_unknown: 11096 llvm_unreachable("Unknown OpenMP directive"); 11097 } 11098 break; 11099 case OMPC_schedule: 11100 switch (DKind) { 11101 case OMPD_parallel_for: 11102 case OMPD_parallel_for_simd: 11103 case OMPD_distribute_parallel_for: 11104 case OMPD_distribute_parallel_for_simd: 11105 case OMPD_teams_distribute_parallel_for: 11106 case OMPD_teams_distribute_parallel_for_simd: 11107 case OMPD_target_parallel_for: 11108 case OMPD_target_parallel_for_simd: 11109 case OMPD_target_teams_distribute_parallel_for: 11110 case OMPD_target_teams_distribute_parallel_for_simd: 11111 CaptureRegion = OMPD_parallel; 11112 break; 11113 case OMPD_for: 11114 case OMPD_for_simd: 11115 // Do not capture schedule-clause expressions. 11116 break; 11117 case OMPD_task: 11118 case OMPD_taskloop: 11119 case OMPD_taskloop_simd: 11120 case OMPD_master_taskloop: 11121 case OMPD_master_taskloop_simd: 11122 case OMPD_parallel_master_taskloop: 11123 case OMPD_parallel_master_taskloop_simd: 11124 case OMPD_target_data: 11125 case OMPD_target_enter_data: 11126 case OMPD_target_exit_data: 11127 case OMPD_target_update: 11128 case OMPD_teams: 11129 case OMPD_teams_distribute: 11130 case OMPD_teams_distribute_simd: 11131 case OMPD_target_teams_distribute: 11132 case OMPD_target_teams_distribute_simd: 11133 case OMPD_target: 11134 case OMPD_target_simd: 11135 case OMPD_target_parallel: 11136 case OMPD_cancel: 11137 case OMPD_parallel: 11138 case OMPD_parallel_master: 11139 case OMPD_parallel_sections: 11140 case OMPD_threadprivate: 11141 case OMPD_allocate: 11142 case OMPD_taskyield: 11143 case OMPD_barrier: 11144 case OMPD_taskwait: 11145 case OMPD_cancellation_point: 11146 case OMPD_flush: 11147 case OMPD_declare_reduction: 11148 case OMPD_declare_mapper: 11149 case OMPD_declare_simd: 11150 case OMPD_declare_variant: 11151 case OMPD_declare_target: 11152 case OMPD_end_declare_target: 11153 case OMPD_simd: 11154 case OMPD_sections: 11155 case OMPD_section: 11156 case OMPD_single: 11157 case OMPD_master: 11158 case OMPD_critical: 11159 case OMPD_taskgroup: 11160 case OMPD_distribute: 11161 case OMPD_ordered: 11162 case OMPD_atomic: 11163 case OMPD_distribute_simd: 11164 case OMPD_target_teams: 11165 case OMPD_requires: 11166 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11167 case OMPD_unknown: 11168 llvm_unreachable("Unknown OpenMP directive"); 11169 } 11170 break; 11171 case OMPC_dist_schedule: 11172 switch (DKind) { 11173 case OMPD_teams_distribute_parallel_for: 11174 case OMPD_teams_distribute_parallel_for_simd: 11175 case OMPD_teams_distribute: 11176 case OMPD_teams_distribute_simd: 11177 case OMPD_target_teams_distribute_parallel_for: 11178 case OMPD_target_teams_distribute_parallel_for_simd: 11179 case OMPD_target_teams_distribute: 11180 case OMPD_target_teams_distribute_simd: 11181 CaptureRegion = OMPD_teams; 11182 break; 11183 case OMPD_distribute_parallel_for: 11184 case OMPD_distribute_parallel_for_simd: 11185 case OMPD_distribute: 11186 case OMPD_distribute_simd: 11187 // Do not capture thread_limit-clause expressions. 11188 break; 11189 case OMPD_parallel_for: 11190 case OMPD_parallel_for_simd: 11191 case OMPD_target_parallel_for_simd: 11192 case OMPD_target_parallel_for: 11193 case OMPD_task: 11194 case OMPD_taskloop: 11195 case OMPD_taskloop_simd: 11196 case OMPD_master_taskloop: 11197 case OMPD_master_taskloop_simd: 11198 case OMPD_parallel_master_taskloop: 11199 case OMPD_parallel_master_taskloop_simd: 11200 case OMPD_target_data: 11201 case OMPD_target_enter_data: 11202 case OMPD_target_exit_data: 11203 case OMPD_target_update: 11204 case OMPD_teams: 11205 case OMPD_target: 11206 case OMPD_target_simd: 11207 case OMPD_target_parallel: 11208 case OMPD_cancel: 11209 case OMPD_parallel: 11210 case OMPD_parallel_master: 11211 case OMPD_parallel_sections: 11212 case OMPD_threadprivate: 11213 case OMPD_allocate: 11214 case OMPD_taskyield: 11215 case OMPD_barrier: 11216 case OMPD_taskwait: 11217 case OMPD_cancellation_point: 11218 case OMPD_flush: 11219 case OMPD_declare_reduction: 11220 case OMPD_declare_mapper: 11221 case OMPD_declare_simd: 11222 case OMPD_declare_variant: 11223 case OMPD_declare_target: 11224 case OMPD_end_declare_target: 11225 case OMPD_simd: 11226 case OMPD_for: 11227 case OMPD_for_simd: 11228 case OMPD_sections: 11229 case OMPD_section: 11230 case OMPD_single: 11231 case OMPD_master: 11232 case OMPD_critical: 11233 case OMPD_taskgroup: 11234 case OMPD_ordered: 11235 case OMPD_atomic: 11236 case OMPD_target_teams: 11237 case OMPD_requires: 11238 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11239 case OMPD_unknown: 11240 llvm_unreachable("Unknown OpenMP directive"); 11241 } 11242 break; 11243 case OMPC_device: 11244 switch (DKind) { 11245 case OMPD_target_update: 11246 case OMPD_target_enter_data: 11247 case OMPD_target_exit_data: 11248 case OMPD_target: 11249 case OMPD_target_simd: 11250 case OMPD_target_teams: 11251 case OMPD_target_parallel: 11252 case OMPD_target_teams_distribute: 11253 case OMPD_target_teams_distribute_simd: 11254 case OMPD_target_parallel_for: 11255 case OMPD_target_parallel_for_simd: 11256 case OMPD_target_teams_distribute_parallel_for: 11257 case OMPD_target_teams_distribute_parallel_for_simd: 11258 CaptureRegion = OMPD_task; 11259 break; 11260 case OMPD_target_data: 11261 // Do not capture device-clause expressions. 11262 break; 11263 case OMPD_teams_distribute_parallel_for: 11264 case OMPD_teams_distribute_parallel_for_simd: 11265 case OMPD_teams: 11266 case OMPD_teams_distribute: 11267 case OMPD_teams_distribute_simd: 11268 case OMPD_distribute_parallel_for: 11269 case OMPD_distribute_parallel_for_simd: 11270 case OMPD_task: 11271 case OMPD_taskloop: 11272 case OMPD_taskloop_simd: 11273 case OMPD_master_taskloop: 11274 case OMPD_master_taskloop_simd: 11275 case OMPD_parallel_master_taskloop: 11276 case OMPD_parallel_master_taskloop_simd: 11277 case OMPD_cancel: 11278 case OMPD_parallel: 11279 case OMPD_parallel_master: 11280 case OMPD_parallel_sections: 11281 case OMPD_parallel_for: 11282 case OMPD_parallel_for_simd: 11283 case OMPD_threadprivate: 11284 case OMPD_allocate: 11285 case OMPD_taskyield: 11286 case OMPD_barrier: 11287 case OMPD_taskwait: 11288 case OMPD_cancellation_point: 11289 case OMPD_flush: 11290 case OMPD_declare_reduction: 11291 case OMPD_declare_mapper: 11292 case OMPD_declare_simd: 11293 case OMPD_declare_variant: 11294 case OMPD_declare_target: 11295 case OMPD_end_declare_target: 11296 case OMPD_simd: 11297 case OMPD_for: 11298 case OMPD_for_simd: 11299 case OMPD_sections: 11300 case OMPD_section: 11301 case OMPD_single: 11302 case OMPD_master: 11303 case OMPD_critical: 11304 case OMPD_taskgroup: 11305 case OMPD_distribute: 11306 case OMPD_ordered: 11307 case OMPD_atomic: 11308 case OMPD_distribute_simd: 11309 case OMPD_requires: 11310 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11311 case OMPD_unknown: 11312 llvm_unreachable("Unknown OpenMP directive"); 11313 } 11314 break; 11315 case OMPC_grainsize: 11316 case OMPC_num_tasks: 11317 case OMPC_final: 11318 case OMPC_priority: 11319 switch (DKind) { 11320 case OMPD_task: 11321 case OMPD_taskloop: 11322 case OMPD_taskloop_simd: 11323 case OMPD_master_taskloop: 11324 case OMPD_master_taskloop_simd: 11325 break; 11326 case OMPD_parallel_master_taskloop: 11327 case OMPD_parallel_master_taskloop_simd: 11328 CaptureRegion = OMPD_parallel; 11329 break; 11330 case OMPD_target_update: 11331 case OMPD_target_enter_data: 11332 case OMPD_target_exit_data: 11333 case OMPD_target: 11334 case OMPD_target_simd: 11335 case OMPD_target_teams: 11336 case OMPD_target_parallel: 11337 case OMPD_target_teams_distribute: 11338 case OMPD_target_teams_distribute_simd: 11339 case OMPD_target_parallel_for: 11340 case OMPD_target_parallel_for_simd: 11341 case OMPD_target_teams_distribute_parallel_for: 11342 case OMPD_target_teams_distribute_parallel_for_simd: 11343 case OMPD_target_data: 11344 case OMPD_teams_distribute_parallel_for: 11345 case OMPD_teams_distribute_parallel_for_simd: 11346 case OMPD_teams: 11347 case OMPD_teams_distribute: 11348 case OMPD_teams_distribute_simd: 11349 case OMPD_distribute_parallel_for: 11350 case OMPD_distribute_parallel_for_simd: 11351 case OMPD_cancel: 11352 case OMPD_parallel: 11353 case OMPD_parallel_master: 11354 case OMPD_parallel_sections: 11355 case OMPD_parallel_for: 11356 case OMPD_parallel_for_simd: 11357 case OMPD_threadprivate: 11358 case OMPD_allocate: 11359 case OMPD_taskyield: 11360 case OMPD_barrier: 11361 case OMPD_taskwait: 11362 case OMPD_cancellation_point: 11363 case OMPD_flush: 11364 case OMPD_declare_reduction: 11365 case OMPD_declare_mapper: 11366 case OMPD_declare_simd: 11367 case OMPD_declare_variant: 11368 case OMPD_declare_target: 11369 case OMPD_end_declare_target: 11370 case OMPD_simd: 11371 case OMPD_for: 11372 case OMPD_for_simd: 11373 case OMPD_sections: 11374 case OMPD_section: 11375 case OMPD_single: 11376 case OMPD_master: 11377 case OMPD_critical: 11378 case OMPD_taskgroup: 11379 case OMPD_distribute: 11380 case OMPD_ordered: 11381 case OMPD_atomic: 11382 case OMPD_distribute_simd: 11383 case OMPD_requires: 11384 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11385 case OMPD_unknown: 11386 llvm_unreachable("Unknown OpenMP directive"); 11387 } 11388 break; 11389 case OMPC_firstprivate: 11390 case OMPC_lastprivate: 11391 case OMPC_reduction: 11392 case OMPC_task_reduction: 11393 case OMPC_in_reduction: 11394 case OMPC_linear: 11395 case OMPC_default: 11396 case OMPC_proc_bind: 11397 case OMPC_safelen: 11398 case OMPC_simdlen: 11399 case OMPC_allocator: 11400 case OMPC_collapse: 11401 case OMPC_private: 11402 case OMPC_shared: 11403 case OMPC_aligned: 11404 case OMPC_copyin: 11405 case OMPC_copyprivate: 11406 case OMPC_ordered: 11407 case OMPC_nowait: 11408 case OMPC_untied: 11409 case OMPC_mergeable: 11410 case OMPC_threadprivate: 11411 case OMPC_allocate: 11412 case OMPC_flush: 11413 case OMPC_read: 11414 case OMPC_write: 11415 case OMPC_update: 11416 case OMPC_capture: 11417 case OMPC_seq_cst: 11418 case OMPC_depend: 11419 case OMPC_threads: 11420 case OMPC_simd: 11421 case OMPC_map: 11422 case OMPC_nogroup: 11423 case OMPC_hint: 11424 case OMPC_defaultmap: 11425 case OMPC_unknown: 11426 case OMPC_uniform: 11427 case OMPC_to: 11428 case OMPC_from: 11429 case OMPC_use_device_ptr: 11430 case OMPC_is_device_ptr: 11431 case OMPC_unified_address: 11432 case OMPC_unified_shared_memory: 11433 case OMPC_reverse_offload: 11434 case OMPC_dynamic_allocators: 11435 case OMPC_atomic_default_mem_order: 11436 case OMPC_device_type: 11437 case OMPC_match: 11438 llvm_unreachable("Unexpected OpenMP clause."); 11439 } 11440 return CaptureRegion; 11441 } 11442 11443 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11444 Expr *Condition, SourceLocation StartLoc, 11445 SourceLocation LParenLoc, 11446 SourceLocation NameModifierLoc, 11447 SourceLocation ColonLoc, 11448 SourceLocation EndLoc) { 11449 Expr *ValExpr = Condition; 11450 Stmt *HelperValStmt = nullptr; 11451 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11452 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11453 !Condition->isInstantiationDependent() && 11454 !Condition->containsUnexpandedParameterPack()) { 11455 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11456 if (Val.isInvalid()) 11457 return nullptr; 11458 11459 ValExpr = Val.get(); 11460 11461 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11462 CaptureRegion = getOpenMPCaptureRegionForClause( 11463 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 11464 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11465 ValExpr = MakeFullExpr(ValExpr).get(); 11466 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11467 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11468 HelperValStmt = buildPreInits(Context, Captures); 11469 } 11470 } 11471 11472 return new (Context) 11473 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11474 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11475 } 11476 11477 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11478 SourceLocation StartLoc, 11479 SourceLocation LParenLoc, 11480 SourceLocation EndLoc) { 11481 Expr *ValExpr = Condition; 11482 Stmt *HelperValStmt = nullptr; 11483 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11484 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11485 !Condition->isInstantiationDependent() && 11486 !Condition->containsUnexpandedParameterPack()) { 11487 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11488 if (Val.isInvalid()) 11489 return nullptr; 11490 11491 ValExpr = MakeFullExpr(Val.get()).get(); 11492 11493 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11494 CaptureRegion = 11495 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 11496 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11497 ValExpr = MakeFullExpr(ValExpr).get(); 11498 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11499 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11500 HelperValStmt = buildPreInits(Context, Captures); 11501 } 11502 } 11503 11504 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11505 StartLoc, LParenLoc, EndLoc); 11506 } 11507 11508 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11509 Expr *Op) { 11510 if (!Op) 11511 return ExprError(); 11512 11513 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11514 public: 11515 IntConvertDiagnoser() 11516 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11517 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11518 QualType T) override { 11519 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11520 } 11521 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11522 QualType T) override { 11523 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11524 } 11525 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11526 QualType T, 11527 QualType ConvTy) override { 11528 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11529 } 11530 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11531 QualType ConvTy) override { 11532 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11533 << ConvTy->isEnumeralType() << ConvTy; 11534 } 11535 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11536 QualType T) override { 11537 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11538 } 11539 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11540 QualType ConvTy) override { 11541 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11542 << ConvTy->isEnumeralType() << ConvTy; 11543 } 11544 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11545 QualType) override { 11546 llvm_unreachable("conversion functions are permitted"); 11547 } 11548 } ConvertDiagnoser; 11549 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11550 } 11551 11552 static bool 11553 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11554 bool StrictlyPositive, bool BuildCapture = false, 11555 OpenMPDirectiveKind DKind = OMPD_unknown, 11556 OpenMPDirectiveKind *CaptureRegion = nullptr, 11557 Stmt **HelperValStmt = nullptr) { 11558 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11559 !ValExpr->isInstantiationDependent()) { 11560 SourceLocation Loc = ValExpr->getExprLoc(); 11561 ExprResult Value = 11562 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11563 if (Value.isInvalid()) 11564 return false; 11565 11566 ValExpr = Value.get(); 11567 // The expression must evaluate to a non-negative integer value. 11568 llvm::APSInt Result; 11569 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11570 Result.isSigned() && 11571 !((!StrictlyPositive && Result.isNonNegative()) || 11572 (StrictlyPositive && Result.isStrictlyPositive()))) { 11573 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11574 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11575 << ValExpr->getSourceRange(); 11576 return false; 11577 } 11578 if (!BuildCapture) 11579 return true; 11580 *CaptureRegion = 11581 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 11582 if (*CaptureRegion != OMPD_unknown && 11583 !SemaRef.CurContext->isDependentContext()) { 11584 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11585 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11586 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11587 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11588 } 11589 } 11590 return true; 11591 } 11592 11593 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11594 SourceLocation StartLoc, 11595 SourceLocation LParenLoc, 11596 SourceLocation EndLoc) { 11597 Expr *ValExpr = NumThreads; 11598 Stmt *HelperValStmt = nullptr; 11599 11600 // OpenMP [2.5, Restrictions] 11601 // The num_threads expression must evaluate to a positive integer value. 11602 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11603 /*StrictlyPositive=*/true)) 11604 return nullptr; 11605 11606 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11607 OpenMPDirectiveKind CaptureRegion = 11608 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 11609 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11610 ValExpr = MakeFullExpr(ValExpr).get(); 11611 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11612 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11613 HelperValStmt = buildPreInits(Context, Captures); 11614 } 11615 11616 return new (Context) OMPNumThreadsClause( 11617 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11618 } 11619 11620 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11621 OpenMPClauseKind CKind, 11622 bool StrictlyPositive) { 11623 if (!E) 11624 return ExprError(); 11625 if (E->isValueDependent() || E->isTypeDependent() || 11626 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11627 return E; 11628 llvm::APSInt Result; 11629 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11630 if (ICE.isInvalid()) 11631 return ExprError(); 11632 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11633 (!StrictlyPositive && !Result.isNonNegative())) { 11634 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11635 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11636 << E->getSourceRange(); 11637 return ExprError(); 11638 } 11639 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11640 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11641 << E->getSourceRange(); 11642 return ExprError(); 11643 } 11644 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11645 DSAStack->setAssociatedLoops(Result.getExtValue()); 11646 else if (CKind == OMPC_ordered) 11647 DSAStack->setAssociatedLoops(Result.getExtValue()); 11648 return ICE; 11649 } 11650 11651 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11652 SourceLocation LParenLoc, 11653 SourceLocation EndLoc) { 11654 // OpenMP [2.8.1, simd construct, Description] 11655 // The parameter of the safelen clause must be a constant 11656 // positive integer expression. 11657 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11658 if (Safelen.isInvalid()) 11659 return nullptr; 11660 return new (Context) 11661 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11662 } 11663 11664 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11665 SourceLocation LParenLoc, 11666 SourceLocation EndLoc) { 11667 // OpenMP [2.8.1, simd construct, Description] 11668 // The parameter of the simdlen clause must be a constant 11669 // positive integer expression. 11670 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11671 if (Simdlen.isInvalid()) 11672 return nullptr; 11673 return new (Context) 11674 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11675 } 11676 11677 /// Tries to find omp_allocator_handle_t type. 11678 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11679 DSAStackTy *Stack) { 11680 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11681 if (!OMPAllocatorHandleT.isNull()) 11682 return true; 11683 // Build the predefined allocator expressions. 11684 bool ErrorFound = false; 11685 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11686 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11687 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11688 StringRef Allocator = 11689 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11690 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11691 auto *VD = dyn_cast_or_null<ValueDecl>( 11692 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11693 if (!VD) { 11694 ErrorFound = true; 11695 break; 11696 } 11697 QualType AllocatorType = 11698 VD->getType().getNonLValueExprType(S.getASTContext()); 11699 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11700 if (!Res.isUsable()) { 11701 ErrorFound = true; 11702 break; 11703 } 11704 if (OMPAllocatorHandleT.isNull()) 11705 OMPAllocatorHandleT = AllocatorType; 11706 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11707 ErrorFound = true; 11708 break; 11709 } 11710 Stack->setAllocator(AllocatorKind, Res.get()); 11711 } 11712 if (ErrorFound) { 11713 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11714 return false; 11715 } 11716 OMPAllocatorHandleT.addConst(); 11717 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11718 return true; 11719 } 11720 11721 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11722 SourceLocation LParenLoc, 11723 SourceLocation EndLoc) { 11724 // OpenMP [2.11.3, allocate Directive, Description] 11725 // allocator is an expression of omp_allocator_handle_t type. 11726 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11727 return nullptr; 11728 11729 ExprResult Allocator = DefaultLvalueConversion(A); 11730 if (Allocator.isInvalid()) 11731 return nullptr; 11732 Allocator = PerformImplicitConversion(Allocator.get(), 11733 DSAStack->getOMPAllocatorHandleT(), 11734 Sema::AA_Initializing, 11735 /*AllowExplicit=*/true); 11736 if (Allocator.isInvalid()) 11737 return nullptr; 11738 return new (Context) 11739 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11740 } 11741 11742 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11743 SourceLocation StartLoc, 11744 SourceLocation LParenLoc, 11745 SourceLocation EndLoc) { 11746 // OpenMP [2.7.1, loop construct, Description] 11747 // OpenMP [2.8.1, simd construct, Description] 11748 // OpenMP [2.9.6, distribute construct, Description] 11749 // The parameter of the collapse clause must be a constant 11750 // positive integer expression. 11751 ExprResult NumForLoopsResult = 11752 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11753 if (NumForLoopsResult.isInvalid()) 11754 return nullptr; 11755 return new (Context) 11756 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11757 } 11758 11759 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11760 SourceLocation EndLoc, 11761 SourceLocation LParenLoc, 11762 Expr *NumForLoops) { 11763 // OpenMP [2.7.1, loop construct, Description] 11764 // OpenMP [2.8.1, simd construct, Description] 11765 // OpenMP [2.9.6, distribute construct, Description] 11766 // The parameter of the ordered clause must be a constant 11767 // positive integer expression if any. 11768 if (NumForLoops && LParenLoc.isValid()) { 11769 ExprResult NumForLoopsResult = 11770 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11771 if (NumForLoopsResult.isInvalid()) 11772 return nullptr; 11773 NumForLoops = NumForLoopsResult.get(); 11774 } else { 11775 NumForLoops = nullptr; 11776 } 11777 auto *Clause = OMPOrderedClause::Create( 11778 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11779 StartLoc, LParenLoc, EndLoc); 11780 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11781 return Clause; 11782 } 11783 11784 OMPClause *Sema::ActOnOpenMPSimpleClause( 11785 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11786 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11787 OMPClause *Res = nullptr; 11788 switch (Kind) { 11789 case OMPC_default: 11790 Res = 11791 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11792 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11793 break; 11794 case OMPC_proc_bind: 11795 Res = ActOnOpenMPProcBindClause( 11796 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11797 LParenLoc, EndLoc); 11798 break; 11799 case OMPC_atomic_default_mem_order: 11800 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11801 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11802 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11803 break; 11804 case OMPC_if: 11805 case OMPC_final: 11806 case OMPC_num_threads: 11807 case OMPC_safelen: 11808 case OMPC_simdlen: 11809 case OMPC_allocator: 11810 case OMPC_collapse: 11811 case OMPC_schedule: 11812 case OMPC_private: 11813 case OMPC_firstprivate: 11814 case OMPC_lastprivate: 11815 case OMPC_shared: 11816 case OMPC_reduction: 11817 case OMPC_task_reduction: 11818 case OMPC_in_reduction: 11819 case OMPC_linear: 11820 case OMPC_aligned: 11821 case OMPC_copyin: 11822 case OMPC_copyprivate: 11823 case OMPC_ordered: 11824 case OMPC_nowait: 11825 case OMPC_untied: 11826 case OMPC_mergeable: 11827 case OMPC_threadprivate: 11828 case OMPC_allocate: 11829 case OMPC_flush: 11830 case OMPC_read: 11831 case OMPC_write: 11832 case OMPC_update: 11833 case OMPC_capture: 11834 case OMPC_seq_cst: 11835 case OMPC_depend: 11836 case OMPC_device: 11837 case OMPC_threads: 11838 case OMPC_simd: 11839 case OMPC_map: 11840 case OMPC_num_teams: 11841 case OMPC_thread_limit: 11842 case OMPC_priority: 11843 case OMPC_grainsize: 11844 case OMPC_nogroup: 11845 case OMPC_num_tasks: 11846 case OMPC_hint: 11847 case OMPC_dist_schedule: 11848 case OMPC_defaultmap: 11849 case OMPC_unknown: 11850 case OMPC_uniform: 11851 case OMPC_to: 11852 case OMPC_from: 11853 case OMPC_use_device_ptr: 11854 case OMPC_is_device_ptr: 11855 case OMPC_unified_address: 11856 case OMPC_unified_shared_memory: 11857 case OMPC_reverse_offload: 11858 case OMPC_dynamic_allocators: 11859 case OMPC_device_type: 11860 case OMPC_match: 11861 llvm_unreachable("Clause is not allowed."); 11862 } 11863 return Res; 11864 } 11865 11866 static std::string 11867 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11868 ArrayRef<unsigned> Exclude = llvm::None) { 11869 SmallString<256> Buffer; 11870 llvm::raw_svector_ostream Out(Buffer); 11871 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11872 unsigned Skipped = Exclude.size(); 11873 auto S = Exclude.begin(), E = Exclude.end(); 11874 for (unsigned I = First; I < Last; ++I) { 11875 if (std::find(S, E, I) != E) { 11876 --Skipped; 11877 continue; 11878 } 11879 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11880 if (I == Bound - Skipped) 11881 Out << " or "; 11882 else if (I != Bound + 1 - Skipped) 11883 Out << ", "; 11884 } 11885 return Out.str(); 11886 } 11887 11888 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11889 SourceLocation KindKwLoc, 11890 SourceLocation StartLoc, 11891 SourceLocation LParenLoc, 11892 SourceLocation EndLoc) { 11893 if (Kind == OMPC_DEFAULT_unknown) { 11894 static_assert(OMPC_DEFAULT_unknown > 0, 11895 "OMPC_DEFAULT_unknown not greater than 0"); 11896 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11897 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11898 /*Last=*/OMPC_DEFAULT_unknown) 11899 << getOpenMPClauseName(OMPC_default); 11900 return nullptr; 11901 } 11902 switch (Kind) { 11903 case OMPC_DEFAULT_none: 11904 DSAStack->setDefaultDSANone(KindKwLoc); 11905 break; 11906 case OMPC_DEFAULT_shared: 11907 DSAStack->setDefaultDSAShared(KindKwLoc); 11908 break; 11909 case OMPC_DEFAULT_unknown: 11910 llvm_unreachable("Clause kind is not allowed."); 11911 break; 11912 } 11913 return new (Context) 11914 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11915 } 11916 11917 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11918 SourceLocation KindKwLoc, 11919 SourceLocation StartLoc, 11920 SourceLocation LParenLoc, 11921 SourceLocation EndLoc) { 11922 if (Kind == OMPC_PROC_BIND_unknown) { 11923 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11924 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11925 /*Last=*/OMPC_PROC_BIND_unknown) 11926 << getOpenMPClauseName(OMPC_proc_bind); 11927 return nullptr; 11928 } 11929 return new (Context) 11930 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11931 } 11932 11933 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11934 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11935 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11936 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11937 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11938 << getListOfPossibleValues( 11939 OMPC_atomic_default_mem_order, /*First=*/0, 11940 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11941 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11942 return nullptr; 11943 } 11944 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11945 LParenLoc, EndLoc); 11946 } 11947 11948 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11949 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11950 SourceLocation StartLoc, SourceLocation LParenLoc, 11951 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11952 SourceLocation EndLoc) { 11953 OMPClause *Res = nullptr; 11954 switch (Kind) { 11955 case OMPC_schedule: 11956 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11957 assert(Argument.size() == NumberOfElements && 11958 ArgumentLoc.size() == NumberOfElements); 11959 Res = ActOnOpenMPScheduleClause( 11960 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11961 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11962 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11963 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11964 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11965 break; 11966 case OMPC_if: 11967 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11968 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11969 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11970 DelimLoc, EndLoc); 11971 break; 11972 case OMPC_dist_schedule: 11973 Res = ActOnOpenMPDistScheduleClause( 11974 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11975 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11976 break; 11977 case OMPC_defaultmap: 11978 enum { Modifier, DefaultmapKind }; 11979 Res = ActOnOpenMPDefaultmapClause( 11980 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11981 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11982 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11983 EndLoc); 11984 break; 11985 case OMPC_final: 11986 case OMPC_num_threads: 11987 case OMPC_safelen: 11988 case OMPC_simdlen: 11989 case OMPC_allocator: 11990 case OMPC_collapse: 11991 case OMPC_default: 11992 case OMPC_proc_bind: 11993 case OMPC_private: 11994 case OMPC_firstprivate: 11995 case OMPC_lastprivate: 11996 case OMPC_shared: 11997 case OMPC_reduction: 11998 case OMPC_task_reduction: 11999 case OMPC_in_reduction: 12000 case OMPC_linear: 12001 case OMPC_aligned: 12002 case OMPC_copyin: 12003 case OMPC_copyprivate: 12004 case OMPC_ordered: 12005 case OMPC_nowait: 12006 case OMPC_untied: 12007 case OMPC_mergeable: 12008 case OMPC_threadprivate: 12009 case OMPC_allocate: 12010 case OMPC_flush: 12011 case OMPC_read: 12012 case OMPC_write: 12013 case OMPC_update: 12014 case OMPC_capture: 12015 case OMPC_seq_cst: 12016 case OMPC_depend: 12017 case OMPC_device: 12018 case OMPC_threads: 12019 case OMPC_simd: 12020 case OMPC_map: 12021 case OMPC_num_teams: 12022 case OMPC_thread_limit: 12023 case OMPC_priority: 12024 case OMPC_grainsize: 12025 case OMPC_nogroup: 12026 case OMPC_num_tasks: 12027 case OMPC_hint: 12028 case OMPC_unknown: 12029 case OMPC_uniform: 12030 case OMPC_to: 12031 case OMPC_from: 12032 case OMPC_use_device_ptr: 12033 case OMPC_is_device_ptr: 12034 case OMPC_unified_address: 12035 case OMPC_unified_shared_memory: 12036 case OMPC_reverse_offload: 12037 case OMPC_dynamic_allocators: 12038 case OMPC_atomic_default_mem_order: 12039 case OMPC_device_type: 12040 case OMPC_match: 12041 llvm_unreachable("Clause is not allowed."); 12042 } 12043 return Res; 12044 } 12045 12046 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12047 OpenMPScheduleClauseModifier M2, 12048 SourceLocation M1Loc, SourceLocation M2Loc) { 12049 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12050 SmallVector<unsigned, 2> Excluded; 12051 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12052 Excluded.push_back(M2); 12053 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12054 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12055 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12056 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12057 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12058 << getListOfPossibleValues(OMPC_schedule, 12059 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12060 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12061 Excluded) 12062 << getOpenMPClauseName(OMPC_schedule); 12063 return true; 12064 } 12065 return false; 12066 } 12067 12068 OMPClause *Sema::ActOnOpenMPScheduleClause( 12069 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12070 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12071 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12072 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12073 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12074 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12075 return nullptr; 12076 // OpenMP, 2.7.1, Loop Construct, Restrictions 12077 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12078 // but not both. 12079 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12080 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12081 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12082 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12083 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12084 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12085 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12086 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12087 return nullptr; 12088 } 12089 if (Kind == OMPC_SCHEDULE_unknown) { 12090 std::string Values; 12091 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12092 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12093 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12094 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12095 Exclude); 12096 } else { 12097 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12098 /*Last=*/OMPC_SCHEDULE_unknown); 12099 } 12100 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12101 << Values << getOpenMPClauseName(OMPC_schedule); 12102 return nullptr; 12103 } 12104 // OpenMP, 2.7.1, Loop Construct, Restrictions 12105 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12106 // schedule(guided). 12107 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12108 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12109 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12110 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12111 diag::err_omp_schedule_nonmonotonic_static); 12112 return nullptr; 12113 } 12114 Expr *ValExpr = ChunkSize; 12115 Stmt *HelperValStmt = nullptr; 12116 if (ChunkSize) { 12117 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12118 !ChunkSize->isInstantiationDependent() && 12119 !ChunkSize->containsUnexpandedParameterPack()) { 12120 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12121 ExprResult Val = 12122 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12123 if (Val.isInvalid()) 12124 return nullptr; 12125 12126 ValExpr = Val.get(); 12127 12128 // OpenMP [2.7.1, Restrictions] 12129 // chunk_size must be a loop invariant integer expression with a positive 12130 // value. 12131 llvm::APSInt Result; 12132 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12133 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12134 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12135 << "schedule" << 1 << ChunkSize->getSourceRange(); 12136 return nullptr; 12137 } 12138 } else if (getOpenMPCaptureRegionForClause( 12139 DSAStack->getCurrentDirective(), OMPC_schedule, 12140 LangOpts.OpenMP) != OMPD_unknown && 12141 !CurContext->isDependentContext()) { 12142 ValExpr = MakeFullExpr(ValExpr).get(); 12143 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12144 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12145 HelperValStmt = buildPreInits(Context, Captures); 12146 } 12147 } 12148 } 12149 12150 return new (Context) 12151 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12152 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12153 } 12154 12155 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12156 SourceLocation StartLoc, 12157 SourceLocation EndLoc) { 12158 OMPClause *Res = nullptr; 12159 switch (Kind) { 12160 case OMPC_ordered: 12161 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12162 break; 12163 case OMPC_nowait: 12164 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12165 break; 12166 case OMPC_untied: 12167 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12168 break; 12169 case OMPC_mergeable: 12170 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12171 break; 12172 case OMPC_read: 12173 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12174 break; 12175 case OMPC_write: 12176 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12177 break; 12178 case OMPC_update: 12179 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12180 break; 12181 case OMPC_capture: 12182 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12183 break; 12184 case OMPC_seq_cst: 12185 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12186 break; 12187 case OMPC_threads: 12188 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12189 break; 12190 case OMPC_simd: 12191 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12192 break; 12193 case OMPC_nogroup: 12194 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12195 break; 12196 case OMPC_unified_address: 12197 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12198 break; 12199 case OMPC_unified_shared_memory: 12200 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12201 break; 12202 case OMPC_reverse_offload: 12203 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12204 break; 12205 case OMPC_dynamic_allocators: 12206 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12207 break; 12208 case OMPC_if: 12209 case OMPC_final: 12210 case OMPC_num_threads: 12211 case OMPC_safelen: 12212 case OMPC_simdlen: 12213 case OMPC_allocator: 12214 case OMPC_collapse: 12215 case OMPC_schedule: 12216 case OMPC_private: 12217 case OMPC_firstprivate: 12218 case OMPC_lastprivate: 12219 case OMPC_shared: 12220 case OMPC_reduction: 12221 case OMPC_task_reduction: 12222 case OMPC_in_reduction: 12223 case OMPC_linear: 12224 case OMPC_aligned: 12225 case OMPC_copyin: 12226 case OMPC_copyprivate: 12227 case OMPC_default: 12228 case OMPC_proc_bind: 12229 case OMPC_threadprivate: 12230 case OMPC_allocate: 12231 case OMPC_flush: 12232 case OMPC_depend: 12233 case OMPC_device: 12234 case OMPC_map: 12235 case OMPC_num_teams: 12236 case OMPC_thread_limit: 12237 case OMPC_priority: 12238 case OMPC_grainsize: 12239 case OMPC_num_tasks: 12240 case OMPC_hint: 12241 case OMPC_dist_schedule: 12242 case OMPC_defaultmap: 12243 case OMPC_unknown: 12244 case OMPC_uniform: 12245 case OMPC_to: 12246 case OMPC_from: 12247 case OMPC_use_device_ptr: 12248 case OMPC_is_device_ptr: 12249 case OMPC_atomic_default_mem_order: 12250 case OMPC_device_type: 12251 case OMPC_match: 12252 llvm_unreachable("Clause is not allowed."); 12253 } 12254 return Res; 12255 } 12256 12257 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12258 SourceLocation EndLoc) { 12259 DSAStack->setNowaitRegion(); 12260 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12261 } 12262 12263 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12264 SourceLocation EndLoc) { 12265 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12266 } 12267 12268 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12269 SourceLocation EndLoc) { 12270 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12271 } 12272 12273 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12274 SourceLocation EndLoc) { 12275 return new (Context) OMPReadClause(StartLoc, EndLoc); 12276 } 12277 12278 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12279 SourceLocation EndLoc) { 12280 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12281 } 12282 12283 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12284 SourceLocation EndLoc) { 12285 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 12286 } 12287 12288 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12289 SourceLocation EndLoc) { 12290 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12291 } 12292 12293 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12294 SourceLocation EndLoc) { 12295 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12296 } 12297 12298 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12299 SourceLocation EndLoc) { 12300 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12301 } 12302 12303 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12304 SourceLocation EndLoc) { 12305 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12306 } 12307 12308 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12309 SourceLocation EndLoc) { 12310 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12311 } 12312 12313 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12314 SourceLocation EndLoc) { 12315 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12316 } 12317 12318 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12319 SourceLocation EndLoc) { 12320 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12321 } 12322 12323 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12324 SourceLocation EndLoc) { 12325 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12326 } 12327 12328 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12329 SourceLocation EndLoc) { 12330 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12331 } 12332 12333 OMPClause *Sema::ActOnOpenMPVarListClause( 12334 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12335 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12336 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12337 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 12338 OpenMPLinearClauseKind LinKind, 12339 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12340 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 12341 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 12342 SourceLocation StartLoc = Locs.StartLoc; 12343 SourceLocation LParenLoc = Locs.LParenLoc; 12344 SourceLocation EndLoc = Locs.EndLoc; 12345 OMPClause *Res = nullptr; 12346 switch (Kind) { 12347 case OMPC_private: 12348 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12349 break; 12350 case OMPC_firstprivate: 12351 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12352 break; 12353 case OMPC_lastprivate: 12354 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12355 break; 12356 case OMPC_shared: 12357 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12358 break; 12359 case OMPC_reduction: 12360 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12361 EndLoc, ReductionOrMapperIdScopeSpec, 12362 ReductionOrMapperId); 12363 break; 12364 case OMPC_task_reduction: 12365 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12366 EndLoc, ReductionOrMapperIdScopeSpec, 12367 ReductionOrMapperId); 12368 break; 12369 case OMPC_in_reduction: 12370 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12371 EndLoc, ReductionOrMapperIdScopeSpec, 12372 ReductionOrMapperId); 12373 break; 12374 case OMPC_linear: 12375 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 12376 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 12377 break; 12378 case OMPC_aligned: 12379 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12380 ColonLoc, EndLoc); 12381 break; 12382 case OMPC_copyin: 12383 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12384 break; 12385 case OMPC_copyprivate: 12386 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12387 break; 12388 case OMPC_flush: 12389 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12390 break; 12391 case OMPC_depend: 12392 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 12393 StartLoc, LParenLoc, EndLoc); 12394 break; 12395 case OMPC_map: 12396 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 12397 ReductionOrMapperIdScopeSpec, 12398 ReductionOrMapperId, MapType, IsMapTypeImplicit, 12399 DepLinMapLoc, ColonLoc, VarList, Locs); 12400 break; 12401 case OMPC_to: 12402 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12403 ReductionOrMapperId, Locs); 12404 break; 12405 case OMPC_from: 12406 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12407 ReductionOrMapperId, Locs); 12408 break; 12409 case OMPC_use_device_ptr: 12410 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12411 break; 12412 case OMPC_is_device_ptr: 12413 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12414 break; 12415 case OMPC_allocate: 12416 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12417 ColonLoc, EndLoc); 12418 break; 12419 case OMPC_if: 12420 case OMPC_final: 12421 case OMPC_num_threads: 12422 case OMPC_safelen: 12423 case OMPC_simdlen: 12424 case OMPC_allocator: 12425 case OMPC_collapse: 12426 case OMPC_default: 12427 case OMPC_proc_bind: 12428 case OMPC_schedule: 12429 case OMPC_ordered: 12430 case OMPC_nowait: 12431 case OMPC_untied: 12432 case OMPC_mergeable: 12433 case OMPC_threadprivate: 12434 case OMPC_read: 12435 case OMPC_write: 12436 case OMPC_update: 12437 case OMPC_capture: 12438 case OMPC_seq_cst: 12439 case OMPC_device: 12440 case OMPC_threads: 12441 case OMPC_simd: 12442 case OMPC_num_teams: 12443 case OMPC_thread_limit: 12444 case OMPC_priority: 12445 case OMPC_grainsize: 12446 case OMPC_nogroup: 12447 case OMPC_num_tasks: 12448 case OMPC_hint: 12449 case OMPC_dist_schedule: 12450 case OMPC_defaultmap: 12451 case OMPC_unknown: 12452 case OMPC_uniform: 12453 case OMPC_unified_address: 12454 case OMPC_unified_shared_memory: 12455 case OMPC_reverse_offload: 12456 case OMPC_dynamic_allocators: 12457 case OMPC_atomic_default_mem_order: 12458 case OMPC_device_type: 12459 case OMPC_match: 12460 llvm_unreachable("Clause is not allowed."); 12461 } 12462 return Res; 12463 } 12464 12465 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12466 ExprObjectKind OK, SourceLocation Loc) { 12467 ExprResult Res = BuildDeclRefExpr( 12468 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12469 if (!Res.isUsable()) 12470 return ExprError(); 12471 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12472 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12473 if (!Res.isUsable()) 12474 return ExprError(); 12475 } 12476 if (VK != VK_LValue && Res.get()->isGLValue()) { 12477 Res = DefaultLvalueConversion(Res.get()); 12478 if (!Res.isUsable()) 12479 return ExprError(); 12480 } 12481 return Res; 12482 } 12483 12484 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12485 SourceLocation StartLoc, 12486 SourceLocation LParenLoc, 12487 SourceLocation EndLoc) { 12488 SmallVector<Expr *, 8> Vars; 12489 SmallVector<Expr *, 8> PrivateCopies; 12490 for (Expr *RefExpr : VarList) { 12491 assert(RefExpr && "NULL expr in OpenMP private clause."); 12492 SourceLocation ELoc; 12493 SourceRange ERange; 12494 Expr *SimpleRefExpr = RefExpr; 12495 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12496 if (Res.second) { 12497 // It will be analyzed later. 12498 Vars.push_back(RefExpr); 12499 PrivateCopies.push_back(nullptr); 12500 } 12501 ValueDecl *D = Res.first; 12502 if (!D) 12503 continue; 12504 12505 QualType Type = D->getType(); 12506 auto *VD = dyn_cast<VarDecl>(D); 12507 12508 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12509 // A variable that appears in a private clause must not have an incomplete 12510 // type or a reference type. 12511 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12512 continue; 12513 Type = Type.getNonReferenceType(); 12514 12515 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12516 // A variable that is privatized must not have a const-qualified type 12517 // unless it is of class type with a mutable member. This restriction does 12518 // not apply to the firstprivate clause. 12519 // 12520 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12521 // A variable that appears in a private clause must not have a 12522 // const-qualified type unless it is of class type with a mutable member. 12523 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12524 continue; 12525 12526 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12527 // in a Construct] 12528 // Variables with the predetermined data-sharing attributes may not be 12529 // listed in data-sharing attributes clauses, except for the cases 12530 // listed below. For these exceptions only, listing a predetermined 12531 // variable in a data-sharing attribute clause is allowed and overrides 12532 // the variable's predetermined data-sharing attributes. 12533 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12534 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12535 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12536 << getOpenMPClauseName(OMPC_private); 12537 reportOriginalDsa(*this, DSAStack, D, DVar); 12538 continue; 12539 } 12540 12541 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12542 // Variably modified types are not supported for tasks. 12543 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12544 isOpenMPTaskingDirective(CurrDir)) { 12545 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12546 << getOpenMPClauseName(OMPC_private) << Type 12547 << getOpenMPDirectiveName(CurrDir); 12548 bool IsDecl = 12549 !VD || 12550 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12551 Diag(D->getLocation(), 12552 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12553 << D; 12554 continue; 12555 } 12556 12557 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12558 // A list item cannot appear in both a map clause and a data-sharing 12559 // attribute clause on the same construct 12560 // 12561 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12562 // A list item cannot appear in both a map clause and a data-sharing 12563 // attribute clause on the same construct unless the construct is a 12564 // combined construct. 12565 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12566 CurrDir == OMPD_target) { 12567 OpenMPClauseKind ConflictKind; 12568 if (DSAStack->checkMappableExprComponentListsForDecl( 12569 VD, /*CurrentRegionOnly=*/true, 12570 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12571 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12572 ConflictKind = WhereFoundClauseKind; 12573 return true; 12574 })) { 12575 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12576 << getOpenMPClauseName(OMPC_private) 12577 << getOpenMPClauseName(ConflictKind) 12578 << getOpenMPDirectiveName(CurrDir); 12579 reportOriginalDsa(*this, DSAStack, D, DVar); 12580 continue; 12581 } 12582 } 12583 12584 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12585 // A variable of class type (or array thereof) that appears in a private 12586 // clause requires an accessible, unambiguous default constructor for the 12587 // class type. 12588 // Generate helper private variable and initialize it with the default 12589 // value. The address of the original variable is replaced by the address of 12590 // the new private variable in CodeGen. This new variable is not added to 12591 // IdResolver, so the code in the OpenMP region uses original variable for 12592 // proper diagnostics. 12593 Type = Type.getUnqualifiedType(); 12594 VarDecl *VDPrivate = 12595 buildVarDecl(*this, ELoc, Type, D->getName(), 12596 D->hasAttrs() ? &D->getAttrs() : nullptr, 12597 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12598 ActOnUninitializedDecl(VDPrivate); 12599 if (VDPrivate->isInvalidDecl()) 12600 continue; 12601 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12602 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12603 12604 DeclRefExpr *Ref = nullptr; 12605 if (!VD && !CurContext->isDependentContext()) 12606 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12607 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12608 Vars.push_back((VD || CurContext->isDependentContext()) 12609 ? RefExpr->IgnoreParens() 12610 : Ref); 12611 PrivateCopies.push_back(VDPrivateRefExpr); 12612 } 12613 12614 if (Vars.empty()) 12615 return nullptr; 12616 12617 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12618 PrivateCopies); 12619 } 12620 12621 namespace { 12622 class DiagsUninitializedSeveretyRAII { 12623 private: 12624 DiagnosticsEngine &Diags; 12625 SourceLocation SavedLoc; 12626 bool IsIgnored = false; 12627 12628 public: 12629 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12630 bool IsIgnored) 12631 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12632 if (!IsIgnored) { 12633 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12634 /*Map*/ diag::Severity::Ignored, Loc); 12635 } 12636 } 12637 ~DiagsUninitializedSeveretyRAII() { 12638 if (!IsIgnored) 12639 Diags.popMappings(SavedLoc); 12640 } 12641 }; 12642 } 12643 12644 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12645 SourceLocation StartLoc, 12646 SourceLocation LParenLoc, 12647 SourceLocation EndLoc) { 12648 SmallVector<Expr *, 8> Vars; 12649 SmallVector<Expr *, 8> PrivateCopies; 12650 SmallVector<Expr *, 8> Inits; 12651 SmallVector<Decl *, 4> ExprCaptures; 12652 bool IsImplicitClause = 12653 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12654 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12655 12656 for (Expr *RefExpr : VarList) { 12657 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12658 SourceLocation ELoc; 12659 SourceRange ERange; 12660 Expr *SimpleRefExpr = RefExpr; 12661 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12662 if (Res.second) { 12663 // It will be analyzed later. 12664 Vars.push_back(RefExpr); 12665 PrivateCopies.push_back(nullptr); 12666 Inits.push_back(nullptr); 12667 } 12668 ValueDecl *D = Res.first; 12669 if (!D) 12670 continue; 12671 12672 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12673 QualType Type = D->getType(); 12674 auto *VD = dyn_cast<VarDecl>(D); 12675 12676 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12677 // A variable that appears in a private clause must not have an incomplete 12678 // type or a reference type. 12679 if (RequireCompleteType(ELoc, Type, 12680 diag::err_omp_firstprivate_incomplete_type)) 12681 continue; 12682 Type = Type.getNonReferenceType(); 12683 12684 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12685 // A variable of class type (or array thereof) that appears in a private 12686 // clause requires an accessible, unambiguous copy constructor for the 12687 // class type. 12688 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12689 12690 // If an implicit firstprivate variable found it was checked already. 12691 DSAStackTy::DSAVarData TopDVar; 12692 if (!IsImplicitClause) { 12693 DSAStackTy::DSAVarData DVar = 12694 DSAStack->getTopDSA(D, /*FromParent=*/false); 12695 TopDVar = DVar; 12696 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12697 bool IsConstant = ElemType.isConstant(Context); 12698 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12699 // A list item that specifies a given variable may not appear in more 12700 // than one clause on the same directive, except that a variable may be 12701 // specified in both firstprivate and lastprivate clauses. 12702 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12703 // A list item may appear in a firstprivate or lastprivate clause but not 12704 // both. 12705 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12706 (isOpenMPDistributeDirective(CurrDir) || 12707 DVar.CKind != OMPC_lastprivate) && 12708 DVar.RefExpr) { 12709 Diag(ELoc, diag::err_omp_wrong_dsa) 12710 << getOpenMPClauseName(DVar.CKind) 12711 << getOpenMPClauseName(OMPC_firstprivate); 12712 reportOriginalDsa(*this, DSAStack, D, DVar); 12713 continue; 12714 } 12715 12716 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12717 // in a Construct] 12718 // Variables with the predetermined data-sharing attributes may not be 12719 // listed in data-sharing attributes clauses, except for the cases 12720 // listed below. For these exceptions only, listing a predetermined 12721 // variable in a data-sharing attribute clause is allowed and overrides 12722 // the variable's predetermined data-sharing attributes. 12723 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12724 // in a Construct, C/C++, p.2] 12725 // Variables with const-qualified type having no mutable member may be 12726 // listed in a firstprivate clause, even if they are static data members. 12727 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12728 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12729 Diag(ELoc, diag::err_omp_wrong_dsa) 12730 << getOpenMPClauseName(DVar.CKind) 12731 << getOpenMPClauseName(OMPC_firstprivate); 12732 reportOriginalDsa(*this, DSAStack, D, DVar); 12733 continue; 12734 } 12735 12736 // OpenMP [2.9.3.4, Restrictions, p.2] 12737 // A list item that is private within a parallel region must not appear 12738 // in a firstprivate clause on a worksharing construct if any of the 12739 // worksharing regions arising from the worksharing construct ever bind 12740 // to any of the parallel regions arising from the parallel construct. 12741 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12742 // A list item that is private within a teams region must not appear in a 12743 // firstprivate clause on a distribute construct if any of the distribute 12744 // regions arising from the distribute construct ever bind to any of the 12745 // teams regions arising from the teams construct. 12746 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12747 // A list item that appears in a reduction clause of a teams construct 12748 // must not appear in a firstprivate clause on a distribute construct if 12749 // any of the distribute regions arising from the distribute construct 12750 // ever bind to any of the teams regions arising from the teams construct. 12751 if ((isOpenMPWorksharingDirective(CurrDir) || 12752 isOpenMPDistributeDirective(CurrDir)) && 12753 !isOpenMPParallelDirective(CurrDir) && 12754 !isOpenMPTeamsDirective(CurrDir)) { 12755 DVar = DSAStack->getImplicitDSA(D, true); 12756 if (DVar.CKind != OMPC_shared && 12757 (isOpenMPParallelDirective(DVar.DKind) || 12758 isOpenMPTeamsDirective(DVar.DKind) || 12759 DVar.DKind == OMPD_unknown)) { 12760 Diag(ELoc, diag::err_omp_required_access) 12761 << getOpenMPClauseName(OMPC_firstprivate) 12762 << getOpenMPClauseName(OMPC_shared); 12763 reportOriginalDsa(*this, DSAStack, D, DVar); 12764 continue; 12765 } 12766 } 12767 // OpenMP [2.9.3.4, Restrictions, p.3] 12768 // A list item that appears in a reduction clause of a parallel construct 12769 // must not appear in a firstprivate clause on a worksharing or task 12770 // construct if any of the worksharing or task regions arising from the 12771 // worksharing or task construct ever bind to any of the parallel regions 12772 // arising from the parallel construct. 12773 // OpenMP [2.9.3.4, Restrictions, p.4] 12774 // A list item that appears in a reduction clause in worksharing 12775 // construct must not appear in a firstprivate clause in a task construct 12776 // encountered during execution of any of the worksharing regions arising 12777 // from the worksharing construct. 12778 if (isOpenMPTaskingDirective(CurrDir)) { 12779 DVar = DSAStack->hasInnermostDSA( 12780 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12781 [](OpenMPDirectiveKind K) { 12782 return isOpenMPParallelDirective(K) || 12783 isOpenMPWorksharingDirective(K) || 12784 isOpenMPTeamsDirective(K); 12785 }, 12786 /*FromParent=*/true); 12787 if (DVar.CKind == OMPC_reduction && 12788 (isOpenMPParallelDirective(DVar.DKind) || 12789 isOpenMPWorksharingDirective(DVar.DKind) || 12790 isOpenMPTeamsDirective(DVar.DKind))) { 12791 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12792 << getOpenMPDirectiveName(DVar.DKind); 12793 reportOriginalDsa(*this, DSAStack, D, DVar); 12794 continue; 12795 } 12796 } 12797 12798 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12799 // A list item cannot appear in both a map clause and a data-sharing 12800 // attribute clause on the same construct 12801 // 12802 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12803 // A list item cannot appear in both a map clause and a data-sharing 12804 // attribute clause on the same construct unless the construct is a 12805 // combined construct. 12806 if ((LangOpts.OpenMP <= 45 && 12807 isOpenMPTargetExecutionDirective(CurrDir)) || 12808 CurrDir == OMPD_target) { 12809 OpenMPClauseKind ConflictKind; 12810 if (DSAStack->checkMappableExprComponentListsForDecl( 12811 VD, /*CurrentRegionOnly=*/true, 12812 [&ConflictKind]( 12813 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12814 OpenMPClauseKind WhereFoundClauseKind) { 12815 ConflictKind = WhereFoundClauseKind; 12816 return true; 12817 })) { 12818 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12819 << getOpenMPClauseName(OMPC_firstprivate) 12820 << getOpenMPClauseName(ConflictKind) 12821 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12822 reportOriginalDsa(*this, DSAStack, D, DVar); 12823 continue; 12824 } 12825 } 12826 } 12827 12828 // Variably modified types are not supported for tasks. 12829 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12830 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12831 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12832 << getOpenMPClauseName(OMPC_firstprivate) << Type 12833 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12834 bool IsDecl = 12835 !VD || 12836 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12837 Diag(D->getLocation(), 12838 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12839 << D; 12840 continue; 12841 } 12842 12843 Type = Type.getUnqualifiedType(); 12844 VarDecl *VDPrivate = 12845 buildVarDecl(*this, ELoc, Type, D->getName(), 12846 D->hasAttrs() ? &D->getAttrs() : nullptr, 12847 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12848 // Generate helper private variable and initialize it with the value of the 12849 // original variable. The address of the original variable is replaced by 12850 // the address of the new private variable in the CodeGen. This new variable 12851 // is not added to IdResolver, so the code in the OpenMP region uses 12852 // original variable for proper diagnostics and variable capturing. 12853 Expr *VDInitRefExpr = nullptr; 12854 // For arrays generate initializer for single element and replace it by the 12855 // original array element in CodeGen. 12856 if (Type->isArrayType()) { 12857 VarDecl *VDInit = 12858 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12859 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12860 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12861 ElemType = ElemType.getUnqualifiedType(); 12862 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12863 ".firstprivate.temp"); 12864 InitializedEntity Entity = 12865 InitializedEntity::InitializeVariable(VDInitTemp); 12866 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12867 12868 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12869 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12870 if (Result.isInvalid()) 12871 VDPrivate->setInvalidDecl(); 12872 else 12873 VDPrivate->setInit(Result.getAs<Expr>()); 12874 // Remove temp variable declaration. 12875 Context.Deallocate(VDInitTemp); 12876 } else { 12877 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12878 ".firstprivate.temp"); 12879 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12880 RefExpr->getExprLoc()); 12881 AddInitializerToDecl(VDPrivate, 12882 DefaultLvalueConversion(VDInitRefExpr).get(), 12883 /*DirectInit=*/false); 12884 } 12885 if (VDPrivate->isInvalidDecl()) { 12886 if (IsImplicitClause) { 12887 Diag(RefExpr->getExprLoc(), 12888 diag::note_omp_task_predetermined_firstprivate_here); 12889 } 12890 continue; 12891 } 12892 CurContext->addDecl(VDPrivate); 12893 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12894 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12895 RefExpr->getExprLoc()); 12896 DeclRefExpr *Ref = nullptr; 12897 if (!VD && !CurContext->isDependentContext()) { 12898 if (TopDVar.CKind == OMPC_lastprivate) { 12899 Ref = TopDVar.PrivateCopy; 12900 } else { 12901 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12902 if (!isOpenMPCapturedDecl(D)) 12903 ExprCaptures.push_back(Ref->getDecl()); 12904 } 12905 } 12906 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12907 Vars.push_back((VD || CurContext->isDependentContext()) 12908 ? RefExpr->IgnoreParens() 12909 : Ref); 12910 PrivateCopies.push_back(VDPrivateRefExpr); 12911 Inits.push_back(VDInitRefExpr); 12912 } 12913 12914 if (Vars.empty()) 12915 return nullptr; 12916 12917 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12918 Vars, PrivateCopies, Inits, 12919 buildPreInits(Context, ExprCaptures)); 12920 } 12921 12922 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12923 SourceLocation StartLoc, 12924 SourceLocation LParenLoc, 12925 SourceLocation EndLoc) { 12926 SmallVector<Expr *, 8> Vars; 12927 SmallVector<Expr *, 8> SrcExprs; 12928 SmallVector<Expr *, 8> DstExprs; 12929 SmallVector<Expr *, 8> AssignmentOps; 12930 SmallVector<Decl *, 4> ExprCaptures; 12931 SmallVector<Expr *, 4> ExprPostUpdates; 12932 for (Expr *RefExpr : VarList) { 12933 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12934 SourceLocation ELoc; 12935 SourceRange ERange; 12936 Expr *SimpleRefExpr = RefExpr; 12937 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12938 if (Res.second) { 12939 // It will be analyzed later. 12940 Vars.push_back(RefExpr); 12941 SrcExprs.push_back(nullptr); 12942 DstExprs.push_back(nullptr); 12943 AssignmentOps.push_back(nullptr); 12944 } 12945 ValueDecl *D = Res.first; 12946 if (!D) 12947 continue; 12948 12949 QualType Type = D->getType(); 12950 auto *VD = dyn_cast<VarDecl>(D); 12951 12952 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12953 // A variable that appears in a lastprivate clause must not have an 12954 // incomplete type or a reference type. 12955 if (RequireCompleteType(ELoc, Type, 12956 diag::err_omp_lastprivate_incomplete_type)) 12957 continue; 12958 Type = Type.getNonReferenceType(); 12959 12960 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12961 // A variable that is privatized must not have a const-qualified type 12962 // unless it is of class type with a mutable member. This restriction does 12963 // not apply to the firstprivate clause. 12964 // 12965 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12966 // A variable that appears in a lastprivate clause must not have a 12967 // const-qualified type unless it is of class type with a mutable member. 12968 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12969 continue; 12970 12971 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12972 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12973 // in a Construct] 12974 // Variables with the predetermined data-sharing attributes may not be 12975 // listed in data-sharing attributes clauses, except for the cases 12976 // listed below. 12977 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12978 // A list item may appear in a firstprivate or lastprivate clause but not 12979 // both. 12980 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12981 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12982 (isOpenMPDistributeDirective(CurrDir) || 12983 DVar.CKind != OMPC_firstprivate) && 12984 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12985 Diag(ELoc, diag::err_omp_wrong_dsa) 12986 << getOpenMPClauseName(DVar.CKind) 12987 << getOpenMPClauseName(OMPC_lastprivate); 12988 reportOriginalDsa(*this, DSAStack, D, DVar); 12989 continue; 12990 } 12991 12992 // OpenMP [2.14.3.5, Restrictions, p.2] 12993 // A list item that is private within a parallel region, or that appears in 12994 // the reduction clause of a parallel construct, must not appear in a 12995 // lastprivate clause on a worksharing construct if any of the corresponding 12996 // worksharing regions ever binds to any of the corresponding parallel 12997 // regions. 12998 DSAStackTy::DSAVarData TopDVar = DVar; 12999 if (isOpenMPWorksharingDirective(CurrDir) && 13000 !isOpenMPParallelDirective(CurrDir) && 13001 !isOpenMPTeamsDirective(CurrDir)) { 13002 DVar = DSAStack->getImplicitDSA(D, true); 13003 if (DVar.CKind != OMPC_shared) { 13004 Diag(ELoc, diag::err_omp_required_access) 13005 << getOpenMPClauseName(OMPC_lastprivate) 13006 << getOpenMPClauseName(OMPC_shared); 13007 reportOriginalDsa(*this, DSAStack, D, DVar); 13008 continue; 13009 } 13010 } 13011 13012 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13013 // A variable of class type (or array thereof) that appears in a 13014 // lastprivate clause requires an accessible, unambiguous default 13015 // constructor for the class type, unless the list item is also specified 13016 // in a firstprivate clause. 13017 // A variable of class type (or array thereof) that appears in a 13018 // lastprivate clause requires an accessible, unambiguous copy assignment 13019 // operator for the class type. 13020 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13021 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13022 Type.getUnqualifiedType(), ".lastprivate.src", 13023 D->hasAttrs() ? &D->getAttrs() : nullptr); 13024 DeclRefExpr *PseudoSrcExpr = 13025 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13026 VarDecl *DstVD = 13027 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13028 D->hasAttrs() ? &D->getAttrs() : nullptr); 13029 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13030 // For arrays generate assignment operation for single element and replace 13031 // it by the original array element in CodeGen. 13032 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13033 PseudoDstExpr, PseudoSrcExpr); 13034 if (AssignmentOp.isInvalid()) 13035 continue; 13036 AssignmentOp = 13037 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13038 if (AssignmentOp.isInvalid()) 13039 continue; 13040 13041 DeclRefExpr *Ref = nullptr; 13042 if (!VD && !CurContext->isDependentContext()) { 13043 if (TopDVar.CKind == OMPC_firstprivate) { 13044 Ref = TopDVar.PrivateCopy; 13045 } else { 13046 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13047 if (!isOpenMPCapturedDecl(D)) 13048 ExprCaptures.push_back(Ref->getDecl()); 13049 } 13050 if (TopDVar.CKind == OMPC_firstprivate || 13051 (!isOpenMPCapturedDecl(D) && 13052 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13053 ExprResult RefRes = DefaultLvalueConversion(Ref); 13054 if (!RefRes.isUsable()) 13055 continue; 13056 ExprResult PostUpdateRes = 13057 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13058 RefRes.get()); 13059 if (!PostUpdateRes.isUsable()) 13060 continue; 13061 ExprPostUpdates.push_back( 13062 IgnoredValueConversions(PostUpdateRes.get()).get()); 13063 } 13064 } 13065 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13066 Vars.push_back((VD || CurContext->isDependentContext()) 13067 ? RefExpr->IgnoreParens() 13068 : Ref); 13069 SrcExprs.push_back(PseudoSrcExpr); 13070 DstExprs.push_back(PseudoDstExpr); 13071 AssignmentOps.push_back(AssignmentOp.get()); 13072 } 13073 13074 if (Vars.empty()) 13075 return nullptr; 13076 13077 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13078 Vars, SrcExprs, DstExprs, AssignmentOps, 13079 buildPreInits(Context, ExprCaptures), 13080 buildPostUpdate(*this, ExprPostUpdates)); 13081 } 13082 13083 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13084 SourceLocation StartLoc, 13085 SourceLocation LParenLoc, 13086 SourceLocation EndLoc) { 13087 SmallVector<Expr *, 8> Vars; 13088 for (Expr *RefExpr : VarList) { 13089 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13090 SourceLocation ELoc; 13091 SourceRange ERange; 13092 Expr *SimpleRefExpr = RefExpr; 13093 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13094 if (Res.second) { 13095 // It will be analyzed later. 13096 Vars.push_back(RefExpr); 13097 } 13098 ValueDecl *D = Res.first; 13099 if (!D) 13100 continue; 13101 13102 auto *VD = dyn_cast<VarDecl>(D); 13103 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13104 // in a Construct] 13105 // Variables with the predetermined data-sharing attributes may not be 13106 // listed in data-sharing attributes clauses, except for the cases 13107 // listed below. For these exceptions only, listing a predetermined 13108 // variable in a data-sharing attribute clause is allowed and overrides 13109 // the variable's predetermined data-sharing attributes. 13110 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13111 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13112 DVar.RefExpr) { 13113 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13114 << getOpenMPClauseName(OMPC_shared); 13115 reportOriginalDsa(*this, DSAStack, D, DVar); 13116 continue; 13117 } 13118 13119 DeclRefExpr *Ref = nullptr; 13120 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13121 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13122 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13123 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13124 ? RefExpr->IgnoreParens() 13125 : Ref); 13126 } 13127 13128 if (Vars.empty()) 13129 return nullptr; 13130 13131 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13132 } 13133 13134 namespace { 13135 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13136 DSAStackTy *Stack; 13137 13138 public: 13139 bool VisitDeclRefExpr(DeclRefExpr *E) { 13140 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13141 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13142 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13143 return false; 13144 if (DVar.CKind != OMPC_unknown) 13145 return true; 13146 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13147 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13148 /*FromParent=*/true); 13149 return DVarPrivate.CKind != OMPC_unknown; 13150 } 13151 return false; 13152 } 13153 bool VisitStmt(Stmt *S) { 13154 for (Stmt *Child : S->children()) { 13155 if (Child && Visit(Child)) 13156 return true; 13157 } 13158 return false; 13159 } 13160 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13161 }; 13162 } // namespace 13163 13164 namespace { 13165 // Transform MemberExpression for specified FieldDecl of current class to 13166 // DeclRefExpr to specified OMPCapturedExprDecl. 13167 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13168 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13169 ValueDecl *Field = nullptr; 13170 DeclRefExpr *CapturedExpr = nullptr; 13171 13172 public: 13173 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13174 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13175 13176 ExprResult TransformMemberExpr(MemberExpr *E) { 13177 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13178 E->getMemberDecl() == Field) { 13179 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13180 return CapturedExpr; 13181 } 13182 return BaseTransform::TransformMemberExpr(E); 13183 } 13184 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13185 }; 13186 } // namespace 13187 13188 template <typename T, typename U> 13189 static T filterLookupForUDReductionAndMapper( 13190 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13191 for (U &Set : Lookups) { 13192 for (auto *D : Set) { 13193 if (T Res = Gen(cast<ValueDecl>(D))) 13194 return Res; 13195 } 13196 } 13197 return T(); 13198 } 13199 13200 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13201 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13202 13203 for (auto RD : D->redecls()) { 13204 // Don't bother with extra checks if we already know this one isn't visible. 13205 if (RD == D) 13206 continue; 13207 13208 auto ND = cast<NamedDecl>(RD); 13209 if (LookupResult::isVisible(SemaRef, ND)) 13210 return ND; 13211 } 13212 13213 return nullptr; 13214 } 13215 13216 static void 13217 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13218 SourceLocation Loc, QualType Ty, 13219 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13220 // Find all of the associated namespaces and classes based on the 13221 // arguments we have. 13222 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13223 Sema::AssociatedClassSet AssociatedClasses; 13224 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13225 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13226 AssociatedClasses); 13227 13228 // C++ [basic.lookup.argdep]p3: 13229 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13230 // and let Y be the lookup set produced by argument dependent 13231 // lookup (defined as follows). If X contains [...] then Y is 13232 // empty. Otherwise Y is the set of declarations found in the 13233 // namespaces associated with the argument types as described 13234 // below. The set of declarations found by the lookup of the name 13235 // is the union of X and Y. 13236 // 13237 // Here, we compute Y and add its members to the overloaded 13238 // candidate set. 13239 for (auto *NS : AssociatedNamespaces) { 13240 // When considering an associated namespace, the lookup is the 13241 // same as the lookup performed when the associated namespace is 13242 // used as a qualifier (3.4.3.2) except that: 13243 // 13244 // -- Any using-directives in the associated namespace are 13245 // ignored. 13246 // 13247 // -- Any namespace-scope friend functions declared in 13248 // associated classes are visible within their respective 13249 // namespaces even if they are not visible during an ordinary 13250 // lookup (11.4). 13251 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13252 for (auto *D : R) { 13253 auto *Underlying = D; 13254 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13255 Underlying = USD->getTargetDecl(); 13256 13257 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13258 !isa<OMPDeclareMapperDecl>(Underlying)) 13259 continue; 13260 13261 if (!SemaRef.isVisible(D)) { 13262 D = findAcceptableDecl(SemaRef, D); 13263 if (!D) 13264 continue; 13265 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13266 Underlying = USD->getTargetDecl(); 13267 } 13268 Lookups.emplace_back(); 13269 Lookups.back().addDecl(Underlying); 13270 } 13271 } 13272 } 13273 13274 static ExprResult 13275 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13276 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13277 const DeclarationNameInfo &ReductionId, QualType Ty, 13278 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13279 if (ReductionIdScopeSpec.isInvalid()) 13280 return ExprError(); 13281 SmallVector<UnresolvedSet<8>, 4> Lookups; 13282 if (S) { 13283 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13284 Lookup.suppressDiagnostics(); 13285 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13286 NamedDecl *D = Lookup.getRepresentativeDecl(); 13287 do { 13288 S = S->getParent(); 13289 } while (S && !S->isDeclScope(D)); 13290 if (S) 13291 S = S->getParent(); 13292 Lookups.emplace_back(); 13293 Lookups.back().append(Lookup.begin(), Lookup.end()); 13294 Lookup.clear(); 13295 } 13296 } else if (auto *ULE = 13297 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13298 Lookups.push_back(UnresolvedSet<8>()); 13299 Decl *PrevD = nullptr; 13300 for (NamedDecl *D : ULE->decls()) { 13301 if (D == PrevD) 13302 Lookups.push_back(UnresolvedSet<8>()); 13303 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13304 Lookups.back().addDecl(DRD); 13305 PrevD = D; 13306 } 13307 } 13308 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13309 Ty->isInstantiationDependentType() || 13310 Ty->containsUnexpandedParameterPack() || 13311 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13312 return !D->isInvalidDecl() && 13313 (D->getType()->isDependentType() || 13314 D->getType()->isInstantiationDependentType() || 13315 D->getType()->containsUnexpandedParameterPack()); 13316 })) { 13317 UnresolvedSet<8> ResSet; 13318 for (const UnresolvedSet<8> &Set : Lookups) { 13319 if (Set.empty()) 13320 continue; 13321 ResSet.append(Set.begin(), Set.end()); 13322 // The last item marks the end of all declarations at the specified scope. 13323 ResSet.addDecl(Set[Set.size() - 1]); 13324 } 13325 return UnresolvedLookupExpr::Create( 13326 SemaRef.Context, /*NamingClass=*/nullptr, 13327 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13328 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13329 } 13330 // Lookup inside the classes. 13331 // C++ [over.match.oper]p3: 13332 // For a unary operator @ with an operand of a type whose 13333 // cv-unqualified version is T1, and for a binary operator @ with 13334 // a left operand of a type whose cv-unqualified version is T1 and 13335 // a right operand of a type whose cv-unqualified version is T2, 13336 // three sets of candidate functions, designated member 13337 // candidates, non-member candidates and built-in candidates, are 13338 // constructed as follows: 13339 // -- If T1 is a complete class type or a class currently being 13340 // defined, the set of member candidates is the result of the 13341 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13342 // the set of member candidates is empty. 13343 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13344 Lookup.suppressDiagnostics(); 13345 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13346 // Complete the type if it can be completed. 13347 // If the type is neither complete nor being defined, bail out now. 13348 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13349 TyRec->getDecl()->getDefinition()) { 13350 Lookup.clear(); 13351 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13352 if (Lookup.empty()) { 13353 Lookups.emplace_back(); 13354 Lookups.back().append(Lookup.begin(), Lookup.end()); 13355 } 13356 } 13357 } 13358 // Perform ADL. 13359 if (SemaRef.getLangOpts().CPlusPlus) 13360 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13361 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13362 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13363 if (!D->isInvalidDecl() && 13364 SemaRef.Context.hasSameType(D->getType(), Ty)) 13365 return D; 13366 return nullptr; 13367 })) 13368 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13369 VK_LValue, Loc); 13370 if (SemaRef.getLangOpts().CPlusPlus) { 13371 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13372 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13373 if (!D->isInvalidDecl() && 13374 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13375 !Ty.isMoreQualifiedThan(D->getType())) 13376 return D; 13377 return nullptr; 13378 })) { 13379 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13380 /*DetectVirtual=*/false); 13381 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13382 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13383 VD->getType().getUnqualifiedType()))) { 13384 if (SemaRef.CheckBaseClassAccess( 13385 Loc, VD->getType(), Ty, Paths.front(), 13386 /*DiagID=*/0) != Sema::AR_inaccessible) { 13387 SemaRef.BuildBasePathArray(Paths, BasePath); 13388 return SemaRef.BuildDeclRefExpr( 13389 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13390 } 13391 } 13392 } 13393 } 13394 } 13395 if (ReductionIdScopeSpec.isSet()) { 13396 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 13397 return ExprError(); 13398 } 13399 return ExprEmpty(); 13400 } 13401 13402 namespace { 13403 /// Data for the reduction-based clauses. 13404 struct ReductionData { 13405 /// List of original reduction items. 13406 SmallVector<Expr *, 8> Vars; 13407 /// List of private copies of the reduction items. 13408 SmallVector<Expr *, 8> Privates; 13409 /// LHS expressions for the reduction_op expressions. 13410 SmallVector<Expr *, 8> LHSs; 13411 /// RHS expressions for the reduction_op expressions. 13412 SmallVector<Expr *, 8> RHSs; 13413 /// Reduction operation expression. 13414 SmallVector<Expr *, 8> ReductionOps; 13415 /// Taskgroup descriptors for the corresponding reduction items in 13416 /// in_reduction clauses. 13417 SmallVector<Expr *, 8> TaskgroupDescriptors; 13418 /// List of captures for clause. 13419 SmallVector<Decl *, 4> ExprCaptures; 13420 /// List of postupdate expressions. 13421 SmallVector<Expr *, 4> ExprPostUpdates; 13422 ReductionData() = delete; 13423 /// Reserves required memory for the reduction data. 13424 ReductionData(unsigned Size) { 13425 Vars.reserve(Size); 13426 Privates.reserve(Size); 13427 LHSs.reserve(Size); 13428 RHSs.reserve(Size); 13429 ReductionOps.reserve(Size); 13430 TaskgroupDescriptors.reserve(Size); 13431 ExprCaptures.reserve(Size); 13432 ExprPostUpdates.reserve(Size); 13433 } 13434 /// Stores reduction item and reduction operation only (required for dependent 13435 /// reduction item). 13436 void push(Expr *Item, Expr *ReductionOp) { 13437 Vars.emplace_back(Item); 13438 Privates.emplace_back(nullptr); 13439 LHSs.emplace_back(nullptr); 13440 RHSs.emplace_back(nullptr); 13441 ReductionOps.emplace_back(ReductionOp); 13442 TaskgroupDescriptors.emplace_back(nullptr); 13443 } 13444 /// Stores reduction data. 13445 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13446 Expr *TaskgroupDescriptor) { 13447 Vars.emplace_back(Item); 13448 Privates.emplace_back(Private); 13449 LHSs.emplace_back(LHS); 13450 RHSs.emplace_back(RHS); 13451 ReductionOps.emplace_back(ReductionOp); 13452 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13453 } 13454 }; 13455 } // namespace 13456 13457 static bool checkOMPArraySectionConstantForReduction( 13458 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13459 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13460 const Expr *Length = OASE->getLength(); 13461 if (Length == nullptr) { 13462 // For array sections of the form [1:] or [:], we would need to analyze 13463 // the lower bound... 13464 if (OASE->getColonLoc().isValid()) 13465 return false; 13466 13467 // This is an array subscript which has implicit length 1! 13468 SingleElement = true; 13469 ArraySizes.push_back(llvm::APSInt::get(1)); 13470 } else { 13471 Expr::EvalResult Result; 13472 if (!Length->EvaluateAsInt(Result, Context)) 13473 return false; 13474 13475 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13476 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13477 ArraySizes.push_back(ConstantLengthValue); 13478 } 13479 13480 // Get the base of this array section and walk up from there. 13481 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13482 13483 // We require length = 1 for all array sections except the right-most to 13484 // guarantee that the memory region is contiguous and has no holes in it. 13485 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13486 Length = TempOASE->getLength(); 13487 if (Length == nullptr) { 13488 // For array sections of the form [1:] or [:], we would need to analyze 13489 // the lower bound... 13490 if (OASE->getColonLoc().isValid()) 13491 return false; 13492 13493 // This is an array subscript which has implicit length 1! 13494 ArraySizes.push_back(llvm::APSInt::get(1)); 13495 } else { 13496 Expr::EvalResult Result; 13497 if (!Length->EvaluateAsInt(Result, Context)) 13498 return false; 13499 13500 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13501 if (ConstantLengthValue.getSExtValue() != 1) 13502 return false; 13503 13504 ArraySizes.push_back(ConstantLengthValue); 13505 } 13506 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13507 } 13508 13509 // If we have a single element, we don't need to add the implicit lengths. 13510 if (!SingleElement) { 13511 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13512 // Has implicit length 1! 13513 ArraySizes.push_back(llvm::APSInt::get(1)); 13514 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13515 } 13516 } 13517 13518 // This array section can be privatized as a single value or as a constant 13519 // sized array. 13520 return true; 13521 } 13522 13523 static bool actOnOMPReductionKindClause( 13524 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13525 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13526 SourceLocation ColonLoc, SourceLocation EndLoc, 13527 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13528 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13529 DeclarationName DN = ReductionId.getName(); 13530 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13531 BinaryOperatorKind BOK = BO_Comma; 13532 13533 ASTContext &Context = S.Context; 13534 // OpenMP [2.14.3.6, reduction clause] 13535 // C 13536 // reduction-identifier is either an identifier or one of the following 13537 // operators: +, -, *, &, |, ^, && and || 13538 // C++ 13539 // reduction-identifier is either an id-expression or one of the following 13540 // operators: +, -, *, &, |, ^, && and || 13541 switch (OOK) { 13542 case OO_Plus: 13543 case OO_Minus: 13544 BOK = BO_Add; 13545 break; 13546 case OO_Star: 13547 BOK = BO_Mul; 13548 break; 13549 case OO_Amp: 13550 BOK = BO_And; 13551 break; 13552 case OO_Pipe: 13553 BOK = BO_Or; 13554 break; 13555 case OO_Caret: 13556 BOK = BO_Xor; 13557 break; 13558 case OO_AmpAmp: 13559 BOK = BO_LAnd; 13560 break; 13561 case OO_PipePipe: 13562 BOK = BO_LOr; 13563 break; 13564 case OO_New: 13565 case OO_Delete: 13566 case OO_Array_New: 13567 case OO_Array_Delete: 13568 case OO_Slash: 13569 case OO_Percent: 13570 case OO_Tilde: 13571 case OO_Exclaim: 13572 case OO_Equal: 13573 case OO_Less: 13574 case OO_Greater: 13575 case OO_LessEqual: 13576 case OO_GreaterEqual: 13577 case OO_PlusEqual: 13578 case OO_MinusEqual: 13579 case OO_StarEqual: 13580 case OO_SlashEqual: 13581 case OO_PercentEqual: 13582 case OO_CaretEqual: 13583 case OO_AmpEqual: 13584 case OO_PipeEqual: 13585 case OO_LessLess: 13586 case OO_GreaterGreater: 13587 case OO_LessLessEqual: 13588 case OO_GreaterGreaterEqual: 13589 case OO_EqualEqual: 13590 case OO_ExclaimEqual: 13591 case OO_Spaceship: 13592 case OO_PlusPlus: 13593 case OO_MinusMinus: 13594 case OO_Comma: 13595 case OO_ArrowStar: 13596 case OO_Arrow: 13597 case OO_Call: 13598 case OO_Subscript: 13599 case OO_Conditional: 13600 case OO_Coawait: 13601 case NUM_OVERLOADED_OPERATORS: 13602 llvm_unreachable("Unexpected reduction identifier"); 13603 case OO_None: 13604 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13605 if (II->isStr("max")) 13606 BOK = BO_GT; 13607 else if (II->isStr("min")) 13608 BOK = BO_LT; 13609 } 13610 break; 13611 } 13612 SourceRange ReductionIdRange; 13613 if (ReductionIdScopeSpec.isValid()) 13614 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13615 else 13616 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13617 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13618 13619 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13620 bool FirstIter = true; 13621 for (Expr *RefExpr : VarList) { 13622 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13623 // OpenMP [2.1, C/C++] 13624 // A list item is a variable or array section, subject to the restrictions 13625 // specified in Section 2.4 on page 42 and in each of the sections 13626 // describing clauses and directives for which a list appears. 13627 // OpenMP [2.14.3.3, Restrictions, p.1] 13628 // A variable that is part of another variable (as an array or 13629 // structure element) cannot appear in a private clause. 13630 if (!FirstIter && IR != ER) 13631 ++IR; 13632 FirstIter = false; 13633 SourceLocation ELoc; 13634 SourceRange ERange; 13635 Expr *SimpleRefExpr = RefExpr; 13636 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13637 /*AllowArraySection=*/true); 13638 if (Res.second) { 13639 // Try to find 'declare reduction' corresponding construct before using 13640 // builtin/overloaded operators. 13641 QualType Type = Context.DependentTy; 13642 CXXCastPath BasePath; 13643 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13644 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13645 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13646 Expr *ReductionOp = nullptr; 13647 if (S.CurContext->isDependentContext() && 13648 (DeclareReductionRef.isUnset() || 13649 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13650 ReductionOp = DeclareReductionRef.get(); 13651 // It will be analyzed later. 13652 RD.push(RefExpr, ReductionOp); 13653 } 13654 ValueDecl *D = Res.first; 13655 if (!D) 13656 continue; 13657 13658 Expr *TaskgroupDescriptor = nullptr; 13659 QualType Type; 13660 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13661 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13662 if (ASE) { 13663 Type = ASE->getType().getNonReferenceType(); 13664 } else if (OASE) { 13665 QualType BaseType = 13666 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13667 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13668 Type = ATy->getElementType(); 13669 else 13670 Type = BaseType->getPointeeType(); 13671 Type = Type.getNonReferenceType(); 13672 } else { 13673 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13674 } 13675 auto *VD = dyn_cast<VarDecl>(D); 13676 13677 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13678 // A variable that appears in a private clause must not have an incomplete 13679 // type or a reference type. 13680 if (S.RequireCompleteType(ELoc, D->getType(), 13681 diag::err_omp_reduction_incomplete_type)) 13682 continue; 13683 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13684 // A list item that appears in a reduction clause must not be 13685 // const-qualified. 13686 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13687 /*AcceptIfMutable*/ false, ASE || OASE)) 13688 continue; 13689 13690 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13691 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13692 // If a list-item is a reference type then it must bind to the same object 13693 // for all threads of the team. 13694 if (!ASE && !OASE) { 13695 if (VD) { 13696 VarDecl *VDDef = VD->getDefinition(); 13697 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13698 DSARefChecker Check(Stack); 13699 if (Check.Visit(VDDef->getInit())) { 13700 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13701 << getOpenMPClauseName(ClauseKind) << ERange; 13702 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13703 continue; 13704 } 13705 } 13706 } 13707 13708 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13709 // in a Construct] 13710 // Variables with the predetermined data-sharing attributes may not be 13711 // listed in data-sharing attributes clauses, except for the cases 13712 // listed below. For these exceptions only, listing a predetermined 13713 // variable in a data-sharing attribute clause is allowed and overrides 13714 // the variable's predetermined data-sharing attributes. 13715 // OpenMP [2.14.3.6, Restrictions, p.3] 13716 // Any number of reduction clauses can be specified on the directive, 13717 // but a list item can appear only once in the reduction clauses for that 13718 // directive. 13719 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13720 if (DVar.CKind == OMPC_reduction) { 13721 S.Diag(ELoc, diag::err_omp_once_referenced) 13722 << getOpenMPClauseName(ClauseKind); 13723 if (DVar.RefExpr) 13724 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13725 continue; 13726 } 13727 if (DVar.CKind != OMPC_unknown) { 13728 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13729 << getOpenMPClauseName(DVar.CKind) 13730 << getOpenMPClauseName(OMPC_reduction); 13731 reportOriginalDsa(S, Stack, D, DVar); 13732 continue; 13733 } 13734 13735 // OpenMP [2.14.3.6, Restrictions, p.1] 13736 // A list item that appears in a reduction clause of a worksharing 13737 // construct must be shared in the parallel regions to which any of the 13738 // worksharing regions arising from the worksharing construct bind. 13739 if (isOpenMPWorksharingDirective(CurrDir) && 13740 !isOpenMPParallelDirective(CurrDir) && 13741 !isOpenMPTeamsDirective(CurrDir)) { 13742 DVar = Stack->getImplicitDSA(D, true); 13743 if (DVar.CKind != OMPC_shared) { 13744 S.Diag(ELoc, diag::err_omp_required_access) 13745 << getOpenMPClauseName(OMPC_reduction) 13746 << getOpenMPClauseName(OMPC_shared); 13747 reportOriginalDsa(S, Stack, D, DVar); 13748 continue; 13749 } 13750 } 13751 } 13752 13753 // Try to find 'declare reduction' corresponding construct before using 13754 // builtin/overloaded operators. 13755 CXXCastPath BasePath; 13756 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13757 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13758 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13759 if (DeclareReductionRef.isInvalid()) 13760 continue; 13761 if (S.CurContext->isDependentContext() && 13762 (DeclareReductionRef.isUnset() || 13763 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13764 RD.push(RefExpr, DeclareReductionRef.get()); 13765 continue; 13766 } 13767 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13768 // Not allowed reduction identifier is found. 13769 S.Diag(ReductionId.getBeginLoc(), 13770 diag::err_omp_unknown_reduction_identifier) 13771 << Type << ReductionIdRange; 13772 continue; 13773 } 13774 13775 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13776 // The type of a list item that appears in a reduction clause must be valid 13777 // for the reduction-identifier. For a max or min reduction in C, the type 13778 // of the list item must be an allowed arithmetic data type: char, int, 13779 // float, double, or _Bool, possibly modified with long, short, signed, or 13780 // unsigned. For a max or min reduction in C++, the type of the list item 13781 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13782 // double, or bool, possibly modified with long, short, signed, or unsigned. 13783 if (DeclareReductionRef.isUnset()) { 13784 if ((BOK == BO_GT || BOK == BO_LT) && 13785 !(Type->isScalarType() || 13786 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13787 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13788 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13789 if (!ASE && !OASE) { 13790 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13791 VarDecl::DeclarationOnly; 13792 S.Diag(D->getLocation(), 13793 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13794 << D; 13795 } 13796 continue; 13797 } 13798 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13799 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13800 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13801 << getOpenMPClauseName(ClauseKind); 13802 if (!ASE && !OASE) { 13803 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13804 VarDecl::DeclarationOnly; 13805 S.Diag(D->getLocation(), 13806 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13807 << D; 13808 } 13809 continue; 13810 } 13811 } 13812 13813 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13814 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13815 D->hasAttrs() ? &D->getAttrs() : nullptr); 13816 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13817 D->hasAttrs() ? &D->getAttrs() : nullptr); 13818 QualType PrivateTy = Type; 13819 13820 // Try if we can determine constant lengths for all array sections and avoid 13821 // the VLA. 13822 bool ConstantLengthOASE = false; 13823 if (OASE) { 13824 bool SingleElement; 13825 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13826 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13827 Context, OASE, SingleElement, ArraySizes); 13828 13829 // If we don't have a single element, we must emit a constant array type. 13830 if (ConstantLengthOASE && !SingleElement) { 13831 for (llvm::APSInt &Size : ArraySizes) 13832 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13833 ArrayType::Normal, 13834 /*IndexTypeQuals=*/0); 13835 } 13836 } 13837 13838 if ((OASE && !ConstantLengthOASE) || 13839 (!OASE && !ASE && 13840 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13841 if (!Context.getTargetInfo().isVLASupported()) { 13842 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13843 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13844 S.Diag(ELoc, diag::note_vla_unsupported); 13845 } else { 13846 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13847 S.targetDiag(ELoc, diag::note_vla_unsupported); 13848 } 13849 continue; 13850 } 13851 // For arrays/array sections only: 13852 // Create pseudo array type for private copy. The size for this array will 13853 // be generated during codegen. 13854 // For array subscripts or single variables Private Ty is the same as Type 13855 // (type of the variable or single array element). 13856 PrivateTy = Context.getVariableArrayType( 13857 Type, 13858 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13859 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13860 } else if (!ASE && !OASE && 13861 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13862 PrivateTy = D->getType().getNonReferenceType(); 13863 } 13864 // Private copy. 13865 VarDecl *PrivateVD = 13866 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13867 D->hasAttrs() ? &D->getAttrs() : nullptr, 13868 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13869 // Add initializer for private variable. 13870 Expr *Init = nullptr; 13871 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13872 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13873 if (DeclareReductionRef.isUsable()) { 13874 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13875 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13876 if (DRD->getInitializer()) { 13877 Init = DRDRef; 13878 RHSVD->setInit(DRDRef); 13879 RHSVD->setInitStyle(VarDecl::CallInit); 13880 } 13881 } else { 13882 switch (BOK) { 13883 case BO_Add: 13884 case BO_Xor: 13885 case BO_Or: 13886 case BO_LOr: 13887 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13888 if (Type->isScalarType() || Type->isAnyComplexType()) 13889 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13890 break; 13891 case BO_Mul: 13892 case BO_LAnd: 13893 if (Type->isScalarType() || Type->isAnyComplexType()) { 13894 // '*' and '&&' reduction ops - initializer is '1'. 13895 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13896 } 13897 break; 13898 case BO_And: { 13899 // '&' reduction op - initializer is '~0'. 13900 QualType OrigType = Type; 13901 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13902 Type = ComplexTy->getElementType(); 13903 if (Type->isRealFloatingType()) { 13904 llvm::APFloat InitValue = 13905 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13906 /*isIEEE=*/true); 13907 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13908 Type, ELoc); 13909 } else if (Type->isScalarType()) { 13910 uint64_t Size = Context.getTypeSize(Type); 13911 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13912 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13913 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13914 } 13915 if (Init && OrigType->isAnyComplexType()) { 13916 // Init = 0xFFFF + 0xFFFFi; 13917 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13918 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13919 } 13920 Type = OrigType; 13921 break; 13922 } 13923 case BO_LT: 13924 case BO_GT: { 13925 // 'min' reduction op - initializer is 'Largest representable number in 13926 // the reduction list item type'. 13927 // 'max' reduction op - initializer is 'Least representable number in 13928 // the reduction list item type'. 13929 if (Type->isIntegerType() || Type->isPointerType()) { 13930 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13931 uint64_t Size = Context.getTypeSize(Type); 13932 QualType IntTy = 13933 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13934 llvm::APInt InitValue = 13935 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13936 : llvm::APInt::getMinValue(Size) 13937 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13938 : llvm::APInt::getMaxValue(Size); 13939 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13940 if (Type->isPointerType()) { 13941 // Cast to pointer type. 13942 ExprResult CastExpr = S.BuildCStyleCastExpr( 13943 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13944 if (CastExpr.isInvalid()) 13945 continue; 13946 Init = CastExpr.get(); 13947 } 13948 } else if (Type->isRealFloatingType()) { 13949 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13950 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13951 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13952 Type, ELoc); 13953 } 13954 break; 13955 } 13956 case BO_PtrMemD: 13957 case BO_PtrMemI: 13958 case BO_MulAssign: 13959 case BO_Div: 13960 case BO_Rem: 13961 case BO_Sub: 13962 case BO_Shl: 13963 case BO_Shr: 13964 case BO_LE: 13965 case BO_GE: 13966 case BO_EQ: 13967 case BO_NE: 13968 case BO_Cmp: 13969 case BO_AndAssign: 13970 case BO_XorAssign: 13971 case BO_OrAssign: 13972 case BO_Assign: 13973 case BO_AddAssign: 13974 case BO_SubAssign: 13975 case BO_DivAssign: 13976 case BO_RemAssign: 13977 case BO_ShlAssign: 13978 case BO_ShrAssign: 13979 case BO_Comma: 13980 llvm_unreachable("Unexpected reduction operation"); 13981 } 13982 } 13983 if (Init && DeclareReductionRef.isUnset()) 13984 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13985 else if (!Init) 13986 S.ActOnUninitializedDecl(RHSVD); 13987 if (RHSVD->isInvalidDecl()) 13988 continue; 13989 if (!RHSVD->hasInit() && 13990 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13991 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13992 << Type << ReductionIdRange; 13993 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13994 VarDecl::DeclarationOnly; 13995 S.Diag(D->getLocation(), 13996 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13997 << D; 13998 continue; 13999 } 14000 // Store initializer for single element in private copy. Will be used during 14001 // codegen. 14002 PrivateVD->setInit(RHSVD->getInit()); 14003 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14004 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14005 ExprResult ReductionOp; 14006 if (DeclareReductionRef.isUsable()) { 14007 QualType RedTy = DeclareReductionRef.get()->getType(); 14008 QualType PtrRedTy = Context.getPointerType(RedTy); 14009 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14010 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14011 if (!BasePath.empty()) { 14012 LHS = S.DefaultLvalueConversion(LHS.get()); 14013 RHS = S.DefaultLvalueConversion(RHS.get()); 14014 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14015 CK_UncheckedDerivedToBase, LHS.get(), 14016 &BasePath, LHS.get()->getValueKind()); 14017 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14018 CK_UncheckedDerivedToBase, RHS.get(), 14019 &BasePath, RHS.get()->getValueKind()); 14020 } 14021 FunctionProtoType::ExtProtoInfo EPI; 14022 QualType Params[] = {PtrRedTy, PtrRedTy}; 14023 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14024 auto *OVE = new (Context) OpaqueValueExpr( 14025 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14026 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14027 Expr *Args[] = {LHS.get(), RHS.get()}; 14028 ReductionOp = 14029 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14030 } else { 14031 ReductionOp = S.BuildBinOp( 14032 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14033 if (ReductionOp.isUsable()) { 14034 if (BOK != BO_LT && BOK != BO_GT) { 14035 ReductionOp = 14036 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14037 BO_Assign, LHSDRE, ReductionOp.get()); 14038 } else { 14039 auto *ConditionalOp = new (Context) 14040 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14041 Type, VK_LValue, OK_Ordinary); 14042 ReductionOp = 14043 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14044 BO_Assign, LHSDRE, ConditionalOp); 14045 } 14046 if (ReductionOp.isUsable()) 14047 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14048 /*DiscardedValue*/ false); 14049 } 14050 if (!ReductionOp.isUsable()) 14051 continue; 14052 } 14053 14054 // OpenMP [2.15.4.6, Restrictions, p.2] 14055 // A list item that appears in an in_reduction clause of a task construct 14056 // must appear in a task_reduction clause of a construct associated with a 14057 // taskgroup region that includes the participating task in its taskgroup 14058 // set. The construct associated with the innermost region that meets this 14059 // condition must specify the same reduction-identifier as the in_reduction 14060 // clause. 14061 if (ClauseKind == OMPC_in_reduction) { 14062 SourceRange ParentSR; 14063 BinaryOperatorKind ParentBOK; 14064 const Expr *ParentReductionOp; 14065 Expr *ParentBOKTD, *ParentReductionOpTD; 14066 DSAStackTy::DSAVarData ParentBOKDSA = 14067 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14068 ParentBOKTD); 14069 DSAStackTy::DSAVarData ParentReductionOpDSA = 14070 Stack->getTopMostTaskgroupReductionData( 14071 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14072 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14073 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14074 if (!IsParentBOK && !IsParentReductionOp) { 14075 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 14076 continue; 14077 } 14078 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14079 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 14080 IsParentReductionOp) { 14081 bool EmitError = true; 14082 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14083 llvm::FoldingSetNodeID RedId, ParentRedId; 14084 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14085 DeclareReductionRef.get()->Profile(RedId, Context, 14086 /*Canonical=*/true); 14087 EmitError = RedId != ParentRedId; 14088 } 14089 if (EmitError) { 14090 S.Diag(ReductionId.getBeginLoc(), 14091 diag::err_omp_reduction_identifier_mismatch) 14092 << ReductionIdRange << RefExpr->getSourceRange(); 14093 S.Diag(ParentSR.getBegin(), 14094 diag::note_omp_previous_reduction_identifier) 14095 << ParentSR 14096 << (IsParentBOK ? ParentBOKDSA.RefExpr 14097 : ParentReductionOpDSA.RefExpr) 14098 ->getSourceRange(); 14099 continue; 14100 } 14101 } 14102 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14103 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 14104 } 14105 14106 DeclRefExpr *Ref = nullptr; 14107 Expr *VarsExpr = RefExpr->IgnoreParens(); 14108 if (!VD && !S.CurContext->isDependentContext()) { 14109 if (ASE || OASE) { 14110 TransformExprToCaptures RebuildToCapture(S, D); 14111 VarsExpr = 14112 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14113 Ref = RebuildToCapture.getCapturedExpr(); 14114 } else { 14115 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14116 } 14117 if (!S.isOpenMPCapturedDecl(D)) { 14118 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14119 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14120 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14121 if (!RefRes.isUsable()) 14122 continue; 14123 ExprResult PostUpdateRes = 14124 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14125 RefRes.get()); 14126 if (!PostUpdateRes.isUsable()) 14127 continue; 14128 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14129 Stack->getCurrentDirective() == OMPD_taskgroup) { 14130 S.Diag(RefExpr->getExprLoc(), 14131 diag::err_omp_reduction_non_addressable_expression) 14132 << RefExpr->getSourceRange(); 14133 continue; 14134 } 14135 RD.ExprPostUpdates.emplace_back( 14136 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14137 } 14138 } 14139 } 14140 // All reduction items are still marked as reduction (to do not increase 14141 // code base size). 14142 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 14143 if (CurrDir == OMPD_taskgroup) { 14144 if (DeclareReductionRef.isUsable()) 14145 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14146 DeclareReductionRef.get()); 14147 else 14148 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14149 } 14150 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14151 TaskgroupDescriptor); 14152 } 14153 return RD.Vars.empty(); 14154 } 14155 14156 OMPClause *Sema::ActOnOpenMPReductionClause( 14157 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14158 SourceLocation ColonLoc, SourceLocation EndLoc, 14159 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14160 ArrayRef<Expr *> UnresolvedReductions) { 14161 ReductionData RD(VarList.size()); 14162 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14163 StartLoc, LParenLoc, ColonLoc, EndLoc, 14164 ReductionIdScopeSpec, ReductionId, 14165 UnresolvedReductions, RD)) 14166 return nullptr; 14167 14168 return OMPReductionClause::Create( 14169 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14170 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14171 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14172 buildPreInits(Context, RD.ExprCaptures), 14173 buildPostUpdate(*this, RD.ExprPostUpdates)); 14174 } 14175 14176 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14177 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14178 SourceLocation ColonLoc, SourceLocation EndLoc, 14179 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14180 ArrayRef<Expr *> UnresolvedReductions) { 14181 ReductionData RD(VarList.size()); 14182 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14183 StartLoc, LParenLoc, ColonLoc, EndLoc, 14184 ReductionIdScopeSpec, ReductionId, 14185 UnresolvedReductions, RD)) 14186 return nullptr; 14187 14188 return OMPTaskReductionClause::Create( 14189 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14190 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14191 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14192 buildPreInits(Context, RD.ExprCaptures), 14193 buildPostUpdate(*this, RD.ExprPostUpdates)); 14194 } 14195 14196 OMPClause *Sema::ActOnOpenMPInReductionClause( 14197 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14198 SourceLocation ColonLoc, SourceLocation EndLoc, 14199 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14200 ArrayRef<Expr *> UnresolvedReductions) { 14201 ReductionData RD(VarList.size()); 14202 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14203 StartLoc, LParenLoc, ColonLoc, EndLoc, 14204 ReductionIdScopeSpec, ReductionId, 14205 UnresolvedReductions, RD)) 14206 return nullptr; 14207 14208 return OMPInReductionClause::Create( 14209 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14210 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14211 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14212 buildPreInits(Context, RD.ExprCaptures), 14213 buildPostUpdate(*this, RD.ExprPostUpdates)); 14214 } 14215 14216 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14217 SourceLocation LinLoc) { 14218 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14219 LinKind == OMPC_LINEAR_unknown) { 14220 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14221 return true; 14222 } 14223 return false; 14224 } 14225 14226 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14227 OpenMPLinearClauseKind LinKind, 14228 QualType Type) { 14229 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14230 // A variable must not have an incomplete type or a reference type. 14231 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14232 return true; 14233 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14234 !Type->isReferenceType()) { 14235 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14236 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14237 return true; 14238 } 14239 Type = Type.getNonReferenceType(); 14240 14241 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14242 // A variable that is privatized must not have a const-qualified type 14243 // unless it is of class type with a mutable member. This restriction does 14244 // not apply to the firstprivate clause. 14245 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14246 return true; 14247 14248 // A list item must be of integral or pointer type. 14249 Type = Type.getUnqualifiedType().getCanonicalType(); 14250 const auto *Ty = Type.getTypePtrOrNull(); 14251 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 14252 !Ty->isPointerType())) { 14253 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14254 if (D) { 14255 bool IsDecl = 14256 !VD || 14257 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14258 Diag(D->getLocation(), 14259 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14260 << D; 14261 } 14262 return true; 14263 } 14264 return false; 14265 } 14266 14267 OMPClause *Sema::ActOnOpenMPLinearClause( 14268 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14269 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14270 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14271 SmallVector<Expr *, 8> Vars; 14272 SmallVector<Expr *, 8> Privates; 14273 SmallVector<Expr *, 8> Inits; 14274 SmallVector<Decl *, 4> ExprCaptures; 14275 SmallVector<Expr *, 4> ExprPostUpdates; 14276 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14277 LinKind = OMPC_LINEAR_val; 14278 for (Expr *RefExpr : VarList) { 14279 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14280 SourceLocation ELoc; 14281 SourceRange ERange; 14282 Expr *SimpleRefExpr = RefExpr; 14283 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14284 if (Res.second) { 14285 // It will be analyzed later. 14286 Vars.push_back(RefExpr); 14287 Privates.push_back(nullptr); 14288 Inits.push_back(nullptr); 14289 } 14290 ValueDecl *D = Res.first; 14291 if (!D) 14292 continue; 14293 14294 QualType Type = D->getType(); 14295 auto *VD = dyn_cast<VarDecl>(D); 14296 14297 // OpenMP [2.14.3.7, linear clause] 14298 // A list-item cannot appear in more than one linear clause. 14299 // A list-item that appears in a linear clause cannot appear in any 14300 // other data-sharing attribute clause. 14301 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14302 if (DVar.RefExpr) { 14303 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14304 << getOpenMPClauseName(OMPC_linear); 14305 reportOriginalDsa(*this, DSAStack, D, DVar); 14306 continue; 14307 } 14308 14309 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14310 continue; 14311 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14312 14313 // Build private copy of original var. 14314 VarDecl *Private = 14315 buildVarDecl(*this, ELoc, Type, D->getName(), 14316 D->hasAttrs() ? &D->getAttrs() : nullptr, 14317 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14318 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14319 // Build var to save initial value. 14320 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14321 Expr *InitExpr; 14322 DeclRefExpr *Ref = nullptr; 14323 if (!VD && !CurContext->isDependentContext()) { 14324 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14325 if (!isOpenMPCapturedDecl(D)) { 14326 ExprCaptures.push_back(Ref->getDecl()); 14327 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14328 ExprResult RefRes = DefaultLvalueConversion(Ref); 14329 if (!RefRes.isUsable()) 14330 continue; 14331 ExprResult PostUpdateRes = 14332 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14333 SimpleRefExpr, RefRes.get()); 14334 if (!PostUpdateRes.isUsable()) 14335 continue; 14336 ExprPostUpdates.push_back( 14337 IgnoredValueConversions(PostUpdateRes.get()).get()); 14338 } 14339 } 14340 } 14341 if (LinKind == OMPC_LINEAR_uval) 14342 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14343 else 14344 InitExpr = VD ? SimpleRefExpr : Ref; 14345 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14346 /*DirectInit=*/false); 14347 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14348 14349 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14350 Vars.push_back((VD || CurContext->isDependentContext()) 14351 ? RefExpr->IgnoreParens() 14352 : Ref); 14353 Privates.push_back(PrivateRef); 14354 Inits.push_back(InitRef); 14355 } 14356 14357 if (Vars.empty()) 14358 return nullptr; 14359 14360 Expr *StepExpr = Step; 14361 Expr *CalcStepExpr = nullptr; 14362 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14363 !Step->isInstantiationDependent() && 14364 !Step->containsUnexpandedParameterPack()) { 14365 SourceLocation StepLoc = Step->getBeginLoc(); 14366 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14367 if (Val.isInvalid()) 14368 return nullptr; 14369 StepExpr = Val.get(); 14370 14371 // Build var to save the step value. 14372 VarDecl *SaveVar = 14373 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14374 ExprResult SaveRef = 14375 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14376 ExprResult CalcStep = 14377 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14378 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14379 14380 // Warn about zero linear step (it would be probably better specified as 14381 // making corresponding variables 'const'). 14382 llvm::APSInt Result; 14383 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14384 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14385 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14386 << (Vars.size() > 1); 14387 if (!IsConstant && CalcStep.isUsable()) { 14388 // Calculate the step beforehand instead of doing this on each iteration. 14389 // (This is not used if the number of iterations may be kfold-ed). 14390 CalcStepExpr = CalcStep.get(); 14391 } 14392 } 14393 14394 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14395 ColonLoc, EndLoc, Vars, Privates, Inits, 14396 StepExpr, CalcStepExpr, 14397 buildPreInits(Context, ExprCaptures), 14398 buildPostUpdate(*this, ExprPostUpdates)); 14399 } 14400 14401 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14402 Expr *NumIterations, Sema &SemaRef, 14403 Scope *S, DSAStackTy *Stack) { 14404 // Walk the vars and build update/final expressions for the CodeGen. 14405 SmallVector<Expr *, 8> Updates; 14406 SmallVector<Expr *, 8> Finals; 14407 SmallVector<Expr *, 8> UsedExprs; 14408 Expr *Step = Clause.getStep(); 14409 Expr *CalcStep = Clause.getCalcStep(); 14410 // OpenMP [2.14.3.7, linear clause] 14411 // If linear-step is not specified it is assumed to be 1. 14412 if (!Step) 14413 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14414 else if (CalcStep) 14415 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14416 bool HasErrors = false; 14417 auto CurInit = Clause.inits().begin(); 14418 auto CurPrivate = Clause.privates().begin(); 14419 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14420 for (Expr *RefExpr : Clause.varlists()) { 14421 SourceLocation ELoc; 14422 SourceRange ERange; 14423 Expr *SimpleRefExpr = RefExpr; 14424 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14425 ValueDecl *D = Res.first; 14426 if (Res.second || !D) { 14427 Updates.push_back(nullptr); 14428 Finals.push_back(nullptr); 14429 HasErrors = true; 14430 continue; 14431 } 14432 auto &&Info = Stack->isLoopControlVariable(D); 14433 // OpenMP [2.15.11, distribute simd Construct] 14434 // A list item may not appear in a linear clause, unless it is the loop 14435 // iteration variable. 14436 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14437 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14438 SemaRef.Diag(ELoc, 14439 diag::err_omp_linear_distribute_var_non_loop_iteration); 14440 Updates.push_back(nullptr); 14441 Finals.push_back(nullptr); 14442 HasErrors = true; 14443 continue; 14444 } 14445 Expr *InitExpr = *CurInit; 14446 14447 // Build privatized reference to the current linear var. 14448 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14449 Expr *CapturedRef; 14450 if (LinKind == OMPC_LINEAR_uval) 14451 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14452 else 14453 CapturedRef = 14454 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14455 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14456 /*RefersToCapture=*/true); 14457 14458 // Build update: Var = InitExpr + IV * Step 14459 ExprResult Update; 14460 if (!Info.first) 14461 Update = buildCounterUpdate( 14462 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14463 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14464 else 14465 Update = *CurPrivate; 14466 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14467 /*DiscardedValue*/ false); 14468 14469 // Build final: Var = InitExpr + NumIterations * Step 14470 ExprResult Final; 14471 if (!Info.first) 14472 Final = 14473 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14474 InitExpr, NumIterations, Step, /*Subtract=*/false, 14475 /*IsNonRectangularLB=*/false); 14476 else 14477 Final = *CurPrivate; 14478 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14479 /*DiscardedValue*/ false); 14480 14481 if (!Update.isUsable() || !Final.isUsable()) { 14482 Updates.push_back(nullptr); 14483 Finals.push_back(nullptr); 14484 UsedExprs.push_back(nullptr); 14485 HasErrors = true; 14486 } else { 14487 Updates.push_back(Update.get()); 14488 Finals.push_back(Final.get()); 14489 if (!Info.first) 14490 UsedExprs.push_back(SimpleRefExpr); 14491 } 14492 ++CurInit; 14493 ++CurPrivate; 14494 } 14495 if (Expr *S = Clause.getStep()) 14496 UsedExprs.push_back(S); 14497 // Fill the remaining part with the nullptr. 14498 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14499 Clause.setUpdates(Updates); 14500 Clause.setFinals(Finals); 14501 Clause.setUsedExprs(UsedExprs); 14502 return HasErrors; 14503 } 14504 14505 OMPClause *Sema::ActOnOpenMPAlignedClause( 14506 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14507 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14508 SmallVector<Expr *, 8> Vars; 14509 for (Expr *RefExpr : VarList) { 14510 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14511 SourceLocation ELoc; 14512 SourceRange ERange; 14513 Expr *SimpleRefExpr = RefExpr; 14514 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14515 if (Res.second) { 14516 // It will be analyzed later. 14517 Vars.push_back(RefExpr); 14518 } 14519 ValueDecl *D = Res.first; 14520 if (!D) 14521 continue; 14522 14523 QualType QType = D->getType(); 14524 auto *VD = dyn_cast<VarDecl>(D); 14525 14526 // OpenMP [2.8.1, simd construct, Restrictions] 14527 // The type of list items appearing in the aligned clause must be 14528 // array, pointer, reference to array, or reference to pointer. 14529 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14530 const Type *Ty = QType.getTypePtrOrNull(); 14531 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14532 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14533 << QType << getLangOpts().CPlusPlus << ERange; 14534 bool IsDecl = 14535 !VD || 14536 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14537 Diag(D->getLocation(), 14538 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14539 << D; 14540 continue; 14541 } 14542 14543 // OpenMP [2.8.1, simd construct, Restrictions] 14544 // A list-item cannot appear in more than one aligned clause. 14545 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14546 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 14547 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14548 << getOpenMPClauseName(OMPC_aligned); 14549 continue; 14550 } 14551 14552 DeclRefExpr *Ref = nullptr; 14553 if (!VD && isOpenMPCapturedDecl(D)) 14554 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14555 Vars.push_back(DefaultFunctionArrayConversion( 14556 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14557 .get()); 14558 } 14559 14560 // OpenMP [2.8.1, simd construct, Description] 14561 // The parameter of the aligned clause, alignment, must be a constant 14562 // positive integer expression. 14563 // If no optional parameter is specified, implementation-defined default 14564 // alignments for SIMD instructions on the target platforms are assumed. 14565 if (Alignment != nullptr) { 14566 ExprResult AlignResult = 14567 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14568 if (AlignResult.isInvalid()) 14569 return nullptr; 14570 Alignment = AlignResult.get(); 14571 } 14572 if (Vars.empty()) 14573 return nullptr; 14574 14575 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14576 EndLoc, Vars, Alignment); 14577 } 14578 14579 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14580 SourceLocation StartLoc, 14581 SourceLocation LParenLoc, 14582 SourceLocation EndLoc) { 14583 SmallVector<Expr *, 8> Vars; 14584 SmallVector<Expr *, 8> SrcExprs; 14585 SmallVector<Expr *, 8> DstExprs; 14586 SmallVector<Expr *, 8> AssignmentOps; 14587 for (Expr *RefExpr : VarList) { 14588 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14589 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14590 // It will be analyzed later. 14591 Vars.push_back(RefExpr); 14592 SrcExprs.push_back(nullptr); 14593 DstExprs.push_back(nullptr); 14594 AssignmentOps.push_back(nullptr); 14595 continue; 14596 } 14597 14598 SourceLocation ELoc = RefExpr->getExprLoc(); 14599 // OpenMP [2.1, C/C++] 14600 // A list item is a variable name. 14601 // OpenMP [2.14.4.1, Restrictions, p.1] 14602 // A list item that appears in a copyin clause must be threadprivate. 14603 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14604 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14605 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14606 << 0 << RefExpr->getSourceRange(); 14607 continue; 14608 } 14609 14610 Decl *D = DE->getDecl(); 14611 auto *VD = cast<VarDecl>(D); 14612 14613 QualType Type = VD->getType(); 14614 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14615 // It will be analyzed later. 14616 Vars.push_back(DE); 14617 SrcExprs.push_back(nullptr); 14618 DstExprs.push_back(nullptr); 14619 AssignmentOps.push_back(nullptr); 14620 continue; 14621 } 14622 14623 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14624 // A list item that appears in a copyin clause must be threadprivate. 14625 if (!DSAStack->isThreadPrivate(VD)) { 14626 Diag(ELoc, diag::err_omp_required_access) 14627 << getOpenMPClauseName(OMPC_copyin) 14628 << getOpenMPDirectiveName(OMPD_threadprivate); 14629 continue; 14630 } 14631 14632 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14633 // A variable of class type (or array thereof) that appears in a 14634 // copyin clause requires an accessible, unambiguous copy assignment 14635 // operator for the class type. 14636 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14637 VarDecl *SrcVD = 14638 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14639 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14640 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14641 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14642 VarDecl *DstVD = 14643 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14644 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14645 DeclRefExpr *PseudoDstExpr = 14646 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14647 // For arrays generate assignment operation for single element and replace 14648 // it by the original array element in CodeGen. 14649 ExprResult AssignmentOp = 14650 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14651 PseudoSrcExpr); 14652 if (AssignmentOp.isInvalid()) 14653 continue; 14654 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14655 /*DiscardedValue*/ false); 14656 if (AssignmentOp.isInvalid()) 14657 continue; 14658 14659 DSAStack->addDSA(VD, DE, OMPC_copyin); 14660 Vars.push_back(DE); 14661 SrcExprs.push_back(PseudoSrcExpr); 14662 DstExprs.push_back(PseudoDstExpr); 14663 AssignmentOps.push_back(AssignmentOp.get()); 14664 } 14665 14666 if (Vars.empty()) 14667 return nullptr; 14668 14669 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14670 SrcExprs, DstExprs, AssignmentOps); 14671 } 14672 14673 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14674 SourceLocation StartLoc, 14675 SourceLocation LParenLoc, 14676 SourceLocation EndLoc) { 14677 SmallVector<Expr *, 8> Vars; 14678 SmallVector<Expr *, 8> SrcExprs; 14679 SmallVector<Expr *, 8> DstExprs; 14680 SmallVector<Expr *, 8> AssignmentOps; 14681 for (Expr *RefExpr : VarList) { 14682 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14683 SourceLocation ELoc; 14684 SourceRange ERange; 14685 Expr *SimpleRefExpr = RefExpr; 14686 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14687 if (Res.second) { 14688 // It will be analyzed later. 14689 Vars.push_back(RefExpr); 14690 SrcExprs.push_back(nullptr); 14691 DstExprs.push_back(nullptr); 14692 AssignmentOps.push_back(nullptr); 14693 } 14694 ValueDecl *D = Res.first; 14695 if (!D) 14696 continue; 14697 14698 QualType Type = D->getType(); 14699 auto *VD = dyn_cast<VarDecl>(D); 14700 14701 // OpenMP [2.14.4.2, Restrictions, p.2] 14702 // A list item that appears in a copyprivate clause may not appear in a 14703 // private or firstprivate clause on the single construct. 14704 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14705 DSAStackTy::DSAVarData DVar = 14706 DSAStack->getTopDSA(D, /*FromParent=*/false); 14707 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14708 DVar.RefExpr) { 14709 Diag(ELoc, diag::err_omp_wrong_dsa) 14710 << getOpenMPClauseName(DVar.CKind) 14711 << getOpenMPClauseName(OMPC_copyprivate); 14712 reportOriginalDsa(*this, DSAStack, D, DVar); 14713 continue; 14714 } 14715 14716 // OpenMP [2.11.4.2, Restrictions, p.1] 14717 // All list items that appear in a copyprivate clause must be either 14718 // threadprivate or private in the enclosing context. 14719 if (DVar.CKind == OMPC_unknown) { 14720 DVar = DSAStack->getImplicitDSA(D, false); 14721 if (DVar.CKind == OMPC_shared) { 14722 Diag(ELoc, diag::err_omp_required_access) 14723 << getOpenMPClauseName(OMPC_copyprivate) 14724 << "threadprivate or private in the enclosing context"; 14725 reportOriginalDsa(*this, DSAStack, D, DVar); 14726 continue; 14727 } 14728 } 14729 } 14730 14731 // Variably modified types are not supported. 14732 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14733 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14734 << getOpenMPClauseName(OMPC_copyprivate) << Type 14735 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14736 bool IsDecl = 14737 !VD || 14738 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14739 Diag(D->getLocation(), 14740 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14741 << D; 14742 continue; 14743 } 14744 14745 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14746 // A variable of class type (or array thereof) that appears in a 14747 // copyin clause requires an accessible, unambiguous copy assignment 14748 // operator for the class type. 14749 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14750 .getUnqualifiedType(); 14751 VarDecl *SrcVD = 14752 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14753 D->hasAttrs() ? &D->getAttrs() : nullptr); 14754 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14755 VarDecl *DstVD = 14756 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14757 D->hasAttrs() ? &D->getAttrs() : nullptr); 14758 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14759 ExprResult AssignmentOp = BuildBinOp( 14760 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14761 if (AssignmentOp.isInvalid()) 14762 continue; 14763 AssignmentOp = 14764 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14765 if (AssignmentOp.isInvalid()) 14766 continue; 14767 14768 // No need to mark vars as copyprivate, they are already threadprivate or 14769 // implicitly private. 14770 assert(VD || isOpenMPCapturedDecl(D)); 14771 Vars.push_back( 14772 VD ? RefExpr->IgnoreParens() 14773 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14774 SrcExprs.push_back(PseudoSrcExpr); 14775 DstExprs.push_back(PseudoDstExpr); 14776 AssignmentOps.push_back(AssignmentOp.get()); 14777 } 14778 14779 if (Vars.empty()) 14780 return nullptr; 14781 14782 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14783 Vars, SrcExprs, DstExprs, AssignmentOps); 14784 } 14785 14786 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14787 SourceLocation StartLoc, 14788 SourceLocation LParenLoc, 14789 SourceLocation EndLoc) { 14790 if (VarList.empty()) 14791 return nullptr; 14792 14793 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14794 } 14795 14796 OMPClause * 14797 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14798 SourceLocation DepLoc, SourceLocation ColonLoc, 14799 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14800 SourceLocation LParenLoc, SourceLocation EndLoc) { 14801 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14802 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14803 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14804 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14805 return nullptr; 14806 } 14807 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14808 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14809 DepKind == OMPC_DEPEND_sink)) { 14810 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14811 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14812 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14813 /*Last=*/OMPC_DEPEND_unknown, Except) 14814 << getOpenMPClauseName(OMPC_depend); 14815 return nullptr; 14816 } 14817 SmallVector<Expr *, 8> Vars; 14818 DSAStackTy::OperatorOffsetTy OpsOffs; 14819 llvm::APSInt DepCounter(/*BitWidth=*/32); 14820 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14821 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14822 if (const Expr *OrderedCountExpr = 14823 DSAStack->getParentOrderedRegionParam().first) { 14824 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14825 TotalDepCount.setIsUnsigned(/*Val=*/true); 14826 } 14827 } 14828 for (Expr *RefExpr : VarList) { 14829 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14830 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14831 // It will be analyzed later. 14832 Vars.push_back(RefExpr); 14833 continue; 14834 } 14835 14836 SourceLocation ELoc = RefExpr->getExprLoc(); 14837 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14838 if (DepKind == OMPC_DEPEND_sink) { 14839 if (DSAStack->getParentOrderedRegionParam().first && 14840 DepCounter >= TotalDepCount) { 14841 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14842 continue; 14843 } 14844 ++DepCounter; 14845 // OpenMP [2.13.9, Summary] 14846 // depend(dependence-type : vec), where dependence-type is: 14847 // 'sink' and where vec is the iteration vector, which has the form: 14848 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14849 // where n is the value specified by the ordered clause in the loop 14850 // directive, xi denotes the loop iteration variable of the i-th nested 14851 // loop associated with the loop directive, and di is a constant 14852 // non-negative integer. 14853 if (CurContext->isDependentContext()) { 14854 // It will be analyzed later. 14855 Vars.push_back(RefExpr); 14856 continue; 14857 } 14858 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14859 OverloadedOperatorKind OOK = OO_None; 14860 SourceLocation OOLoc; 14861 Expr *LHS = SimpleExpr; 14862 Expr *RHS = nullptr; 14863 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14864 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14865 OOLoc = BO->getOperatorLoc(); 14866 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14867 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14868 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14869 OOK = OCE->getOperator(); 14870 OOLoc = OCE->getOperatorLoc(); 14871 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14872 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14873 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14874 OOK = MCE->getMethodDecl() 14875 ->getNameInfo() 14876 .getName() 14877 .getCXXOverloadedOperator(); 14878 OOLoc = MCE->getCallee()->getExprLoc(); 14879 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14880 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14881 } 14882 SourceLocation ELoc; 14883 SourceRange ERange; 14884 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14885 if (Res.second) { 14886 // It will be analyzed later. 14887 Vars.push_back(RefExpr); 14888 } 14889 ValueDecl *D = Res.first; 14890 if (!D) 14891 continue; 14892 14893 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14894 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14895 continue; 14896 } 14897 if (RHS) { 14898 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14899 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14900 if (RHSRes.isInvalid()) 14901 continue; 14902 } 14903 if (!CurContext->isDependentContext() && 14904 DSAStack->getParentOrderedRegionParam().first && 14905 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14906 const ValueDecl *VD = 14907 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14908 if (VD) 14909 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14910 << 1 << VD; 14911 else 14912 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14913 continue; 14914 } 14915 OpsOffs.emplace_back(RHS, OOK); 14916 } else { 14917 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14918 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14919 (ASE && 14920 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14921 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14922 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14923 << RefExpr->getSourceRange(); 14924 continue; 14925 } 14926 14927 ExprResult Res; 14928 { 14929 Sema::TentativeAnalysisScope Trap(*this); 14930 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14931 RefExpr->IgnoreParenImpCasts()); 14932 } 14933 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14934 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14935 << RefExpr->getSourceRange(); 14936 continue; 14937 } 14938 } 14939 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14940 } 14941 14942 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14943 TotalDepCount > VarList.size() && 14944 DSAStack->getParentOrderedRegionParam().first && 14945 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14946 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14947 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14948 } 14949 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14950 Vars.empty()) 14951 return nullptr; 14952 14953 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14954 DepKind, DepLoc, ColonLoc, Vars, 14955 TotalDepCount.getZExtValue()); 14956 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14957 DSAStack->isParentOrderedRegion()) 14958 DSAStack->addDoacrossDependClause(C, OpsOffs); 14959 return C; 14960 } 14961 14962 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14963 SourceLocation LParenLoc, 14964 SourceLocation EndLoc) { 14965 Expr *ValExpr = Device; 14966 Stmt *HelperValStmt = nullptr; 14967 14968 // OpenMP [2.9.1, Restrictions] 14969 // The device expression must evaluate to a non-negative integer value. 14970 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14971 /*StrictlyPositive=*/false)) 14972 return nullptr; 14973 14974 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14975 OpenMPDirectiveKind CaptureRegion = 14976 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 14977 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14978 ValExpr = MakeFullExpr(ValExpr).get(); 14979 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14980 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14981 HelperValStmt = buildPreInits(Context, Captures); 14982 } 14983 14984 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14985 StartLoc, LParenLoc, EndLoc); 14986 } 14987 14988 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14989 DSAStackTy *Stack, QualType QTy, 14990 bool FullCheck = true) { 14991 NamedDecl *ND; 14992 if (QTy->isIncompleteType(&ND)) { 14993 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14994 return false; 14995 } 14996 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14997 !QTy.isTriviallyCopyableType(SemaRef.Context)) 14998 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14999 return true; 15000 } 15001 15002 /// Return true if it can be proven that the provided array expression 15003 /// (array section or array subscript) does NOT specify the whole size of the 15004 /// array whose base type is \a BaseQTy. 15005 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15006 const Expr *E, 15007 QualType BaseQTy) { 15008 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15009 15010 // If this is an array subscript, it refers to the whole size if the size of 15011 // the dimension is constant and equals 1. Also, an array section assumes the 15012 // format of an array subscript if no colon is used. 15013 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15014 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15015 return ATy->getSize().getSExtValue() != 1; 15016 // Size can't be evaluated statically. 15017 return false; 15018 } 15019 15020 assert(OASE && "Expecting array section if not an array subscript."); 15021 const Expr *LowerBound = OASE->getLowerBound(); 15022 const Expr *Length = OASE->getLength(); 15023 15024 // If there is a lower bound that does not evaluates to zero, we are not 15025 // covering the whole dimension. 15026 if (LowerBound) { 15027 Expr::EvalResult Result; 15028 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15029 return false; // Can't get the integer value as a constant. 15030 15031 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15032 if (ConstLowerBound.getSExtValue()) 15033 return true; 15034 } 15035 15036 // If we don't have a length we covering the whole dimension. 15037 if (!Length) 15038 return false; 15039 15040 // If the base is a pointer, we don't have a way to get the size of the 15041 // pointee. 15042 if (BaseQTy->isPointerType()) 15043 return false; 15044 15045 // We can only check if the length is the same as the size of the dimension 15046 // if we have a constant array. 15047 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15048 if (!CATy) 15049 return false; 15050 15051 Expr::EvalResult Result; 15052 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15053 return false; // Can't get the integer value as a constant. 15054 15055 llvm::APSInt ConstLength = Result.Val.getInt(); 15056 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15057 } 15058 15059 // Return true if it can be proven that the provided array expression (array 15060 // section or array subscript) does NOT specify a single element of the array 15061 // whose base type is \a BaseQTy. 15062 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15063 const Expr *E, 15064 QualType BaseQTy) { 15065 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15066 15067 // An array subscript always refer to a single element. Also, an array section 15068 // assumes the format of an array subscript if no colon is used. 15069 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 15070 return false; 15071 15072 assert(OASE && "Expecting array section if not an array subscript."); 15073 const Expr *Length = OASE->getLength(); 15074 15075 // If we don't have a length we have to check if the array has unitary size 15076 // for this dimension. Also, we should always expect a length if the base type 15077 // is pointer. 15078 if (!Length) { 15079 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15080 return ATy->getSize().getSExtValue() != 1; 15081 // We cannot assume anything. 15082 return false; 15083 } 15084 15085 // Check if the length evaluates to 1. 15086 Expr::EvalResult Result; 15087 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15088 return false; // Can't get the integer value as a constant. 15089 15090 llvm::APSInt ConstLength = Result.Val.getInt(); 15091 return ConstLength.getSExtValue() != 1; 15092 } 15093 15094 // Return the expression of the base of the mappable expression or null if it 15095 // cannot be determined and do all the necessary checks to see if the expression 15096 // is valid as a standalone mappable expression. In the process, record all the 15097 // components of the expression. 15098 static const Expr *checkMapClauseExpressionBase( 15099 Sema &SemaRef, Expr *E, 15100 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 15101 OpenMPClauseKind CKind, bool NoDiagnose) { 15102 SourceLocation ELoc = E->getExprLoc(); 15103 SourceRange ERange = E->getSourceRange(); 15104 15105 // The base of elements of list in a map clause have to be either: 15106 // - a reference to variable or field. 15107 // - a member expression. 15108 // - an array expression. 15109 // 15110 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 15111 // reference to 'r'. 15112 // 15113 // If we have: 15114 // 15115 // struct SS { 15116 // Bla S; 15117 // foo() { 15118 // #pragma omp target map (S.Arr[:12]); 15119 // } 15120 // } 15121 // 15122 // We want to retrieve the member expression 'this->S'; 15123 15124 const Expr *RelevantExpr = nullptr; 15125 15126 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 15127 // If a list item is an array section, it must specify contiguous storage. 15128 // 15129 // For this restriction it is sufficient that we make sure only references 15130 // to variables or fields and array expressions, and that no array sections 15131 // exist except in the rightmost expression (unless they cover the whole 15132 // dimension of the array). E.g. these would be invalid: 15133 // 15134 // r.ArrS[3:5].Arr[6:7] 15135 // 15136 // r.ArrS[3:5].x 15137 // 15138 // but these would be valid: 15139 // r.ArrS[3].Arr[6:7] 15140 // 15141 // r.ArrS[3].x 15142 15143 bool AllowUnitySizeArraySection = true; 15144 bool AllowWholeSizeArraySection = true; 15145 15146 while (!RelevantExpr) { 15147 E = E->IgnoreParenImpCasts(); 15148 15149 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 15150 if (!isa<VarDecl>(CurE->getDecl())) 15151 return nullptr; 15152 15153 RelevantExpr = CurE; 15154 15155 // If we got a reference to a declaration, we should not expect any array 15156 // section before that. 15157 AllowUnitySizeArraySection = false; 15158 AllowWholeSizeArraySection = false; 15159 15160 // Record the component. 15161 CurComponents.emplace_back(CurE, CurE->getDecl()); 15162 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 15163 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 15164 15165 if (isa<CXXThisExpr>(BaseE)) 15166 // We found a base expression: this->Val. 15167 RelevantExpr = CurE; 15168 else 15169 E = BaseE; 15170 15171 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 15172 if (!NoDiagnose) { 15173 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15174 << CurE->getSourceRange(); 15175 return nullptr; 15176 } 15177 if (RelevantExpr) 15178 return nullptr; 15179 continue; 15180 } 15181 15182 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 15183 15184 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15185 // A bit-field cannot appear in a map clause. 15186 // 15187 if (FD->isBitField()) { 15188 if (!NoDiagnose) { 15189 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15190 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 15191 return nullptr; 15192 } 15193 if (RelevantExpr) 15194 return nullptr; 15195 continue; 15196 } 15197 15198 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15199 // If the type of a list item is a reference to a type T then the type 15200 // will be considered to be T for all purposes of this clause. 15201 QualType CurType = BaseE->getType().getNonReferenceType(); 15202 15203 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15204 // A list item cannot be a variable that is a member of a structure with 15205 // a union type. 15206 // 15207 if (CurType->isUnionType()) { 15208 if (!NoDiagnose) { 15209 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15210 << CurE->getSourceRange(); 15211 return nullptr; 15212 } 15213 continue; 15214 } 15215 15216 // If we got a member expression, we should not expect any array section 15217 // before that: 15218 // 15219 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15220 // If a list item is an element of a structure, only the rightmost symbol 15221 // of the variable reference can be an array section. 15222 // 15223 AllowUnitySizeArraySection = false; 15224 AllowWholeSizeArraySection = false; 15225 15226 // Record the component. 15227 CurComponents.emplace_back(CurE, FD); 15228 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 15229 E = CurE->getBase()->IgnoreParenImpCasts(); 15230 15231 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15232 if (!NoDiagnose) { 15233 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15234 << 0 << CurE->getSourceRange(); 15235 return nullptr; 15236 } 15237 continue; 15238 } 15239 15240 // If we got an array subscript that express the whole dimension we 15241 // can have any array expressions before. If it only expressing part of 15242 // the dimension, we can only have unitary-size array expressions. 15243 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 15244 E->getType())) 15245 AllowWholeSizeArraySection = false; 15246 15247 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15248 Expr::EvalResult Result; 15249 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 15250 if (!Result.Val.getInt().isNullValue()) { 15251 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15252 diag::err_omp_invalid_map_this_expr); 15253 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15254 diag::note_omp_invalid_subscript_on_this_ptr_map); 15255 } 15256 } 15257 RelevantExpr = TE; 15258 } 15259 15260 // Record the component - we don't have any declaration associated. 15261 CurComponents.emplace_back(CurE, nullptr); 15262 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 15263 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15264 E = CurE->getBase()->IgnoreParenImpCasts(); 15265 15266 QualType CurType = 15267 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15268 15269 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15270 // If the type of a list item is a reference to a type T then the type 15271 // will be considered to be T for all purposes of this clause. 15272 if (CurType->isReferenceType()) 15273 CurType = CurType->getPointeeType(); 15274 15275 bool IsPointer = CurType->isAnyPointerType(); 15276 15277 if (!IsPointer && !CurType->isArrayType()) { 15278 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15279 << 0 << CurE->getSourceRange(); 15280 return nullptr; 15281 } 15282 15283 bool NotWhole = 15284 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 15285 bool NotUnity = 15286 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 15287 15288 if (AllowWholeSizeArraySection) { 15289 // Any array section is currently allowed. Allowing a whole size array 15290 // section implies allowing a unity array section as well. 15291 // 15292 // If this array section refers to the whole dimension we can still 15293 // accept other array sections before this one, except if the base is a 15294 // pointer. Otherwise, only unitary sections are accepted. 15295 if (NotWhole || IsPointer) 15296 AllowWholeSizeArraySection = false; 15297 } else if (AllowUnitySizeArraySection && NotUnity) { 15298 // A unity or whole array section is not allowed and that is not 15299 // compatible with the properties of the current array section. 15300 SemaRef.Diag( 15301 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15302 << CurE->getSourceRange(); 15303 return nullptr; 15304 } 15305 15306 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15307 Expr::EvalResult ResultR; 15308 Expr::EvalResult ResultL; 15309 if (CurE->getLength()->EvaluateAsInt(ResultR, 15310 SemaRef.getASTContext())) { 15311 if (!ResultR.Val.getInt().isOneValue()) { 15312 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15313 diag::err_omp_invalid_map_this_expr); 15314 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15315 diag::note_omp_invalid_length_on_this_ptr_mapping); 15316 } 15317 } 15318 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 15319 ResultL, SemaRef.getASTContext())) { 15320 if (!ResultL.Val.getInt().isNullValue()) { 15321 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15322 diag::err_omp_invalid_map_this_expr); 15323 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15324 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15325 } 15326 } 15327 RelevantExpr = TE; 15328 } 15329 15330 // Record the component - we don't have any declaration associated. 15331 CurComponents.emplace_back(CurE, nullptr); 15332 } else { 15333 if (!NoDiagnose) { 15334 // If nothing else worked, this is not a valid map clause expression. 15335 SemaRef.Diag( 15336 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15337 << ERange; 15338 } 15339 return nullptr; 15340 } 15341 } 15342 15343 return RelevantExpr; 15344 } 15345 15346 // Return true if expression E associated with value VD has conflicts with other 15347 // map information. 15348 static bool checkMapConflicts( 15349 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15350 bool CurrentRegionOnly, 15351 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15352 OpenMPClauseKind CKind) { 15353 assert(VD && E); 15354 SourceLocation ELoc = E->getExprLoc(); 15355 SourceRange ERange = E->getSourceRange(); 15356 15357 // In order to easily check the conflicts we need to match each component of 15358 // the expression under test with the components of the expressions that are 15359 // already in the stack. 15360 15361 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15362 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15363 "Map clause expression with unexpected base!"); 15364 15365 // Variables to help detecting enclosing problems in data environment nests. 15366 bool IsEnclosedByDataEnvironmentExpr = false; 15367 const Expr *EnclosingExpr = nullptr; 15368 15369 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15370 VD, CurrentRegionOnly, 15371 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15372 ERange, CKind, &EnclosingExpr, 15373 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15374 StackComponents, 15375 OpenMPClauseKind) { 15376 assert(!StackComponents.empty() && 15377 "Map clause expression with no components!"); 15378 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15379 "Map clause expression with unexpected base!"); 15380 (void)VD; 15381 15382 // The whole expression in the stack. 15383 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15384 15385 // Expressions must start from the same base. Here we detect at which 15386 // point both expressions diverge from each other and see if we can 15387 // detect if the memory referred to both expressions is contiguous and 15388 // do not overlap. 15389 auto CI = CurComponents.rbegin(); 15390 auto CE = CurComponents.rend(); 15391 auto SI = StackComponents.rbegin(); 15392 auto SE = StackComponents.rend(); 15393 for (; CI != CE && SI != SE; ++CI, ++SI) { 15394 15395 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15396 // At most one list item can be an array item derived from a given 15397 // variable in map clauses of the same construct. 15398 if (CurrentRegionOnly && 15399 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15400 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15401 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15402 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15403 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15404 diag::err_omp_multiple_array_items_in_map_clause) 15405 << CI->getAssociatedExpression()->getSourceRange(); 15406 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15407 diag::note_used_here) 15408 << SI->getAssociatedExpression()->getSourceRange(); 15409 return true; 15410 } 15411 15412 // Do both expressions have the same kind? 15413 if (CI->getAssociatedExpression()->getStmtClass() != 15414 SI->getAssociatedExpression()->getStmtClass()) 15415 break; 15416 15417 // Are we dealing with different variables/fields? 15418 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15419 break; 15420 } 15421 // Check if the extra components of the expressions in the enclosing 15422 // data environment are redundant for the current base declaration. 15423 // If they are, the maps completely overlap, which is legal. 15424 for (; SI != SE; ++SI) { 15425 QualType Type; 15426 if (const auto *ASE = 15427 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15428 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15429 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15430 SI->getAssociatedExpression())) { 15431 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15432 Type = 15433 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15434 } 15435 if (Type.isNull() || Type->isAnyPointerType() || 15436 checkArrayExpressionDoesNotReferToWholeSize( 15437 SemaRef, SI->getAssociatedExpression(), Type)) 15438 break; 15439 } 15440 15441 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15442 // List items of map clauses in the same construct must not share 15443 // original storage. 15444 // 15445 // If the expressions are exactly the same or one is a subset of the 15446 // other, it means they are sharing storage. 15447 if (CI == CE && SI == SE) { 15448 if (CurrentRegionOnly) { 15449 if (CKind == OMPC_map) { 15450 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15451 } else { 15452 assert(CKind == OMPC_to || CKind == OMPC_from); 15453 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15454 << ERange; 15455 } 15456 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15457 << RE->getSourceRange(); 15458 return true; 15459 } 15460 // If we find the same expression in the enclosing data environment, 15461 // that is legal. 15462 IsEnclosedByDataEnvironmentExpr = true; 15463 return false; 15464 } 15465 15466 QualType DerivedType = 15467 std::prev(CI)->getAssociatedDeclaration()->getType(); 15468 SourceLocation DerivedLoc = 15469 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15470 15471 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15472 // If the type of a list item is a reference to a type T then the type 15473 // will be considered to be T for all purposes of this clause. 15474 DerivedType = DerivedType.getNonReferenceType(); 15475 15476 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15477 // A variable for which the type is pointer and an array section 15478 // derived from that variable must not appear as list items of map 15479 // clauses of the same construct. 15480 // 15481 // Also, cover one of the cases in: 15482 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15483 // If any part of the original storage of a list item has corresponding 15484 // storage in the device data environment, all of the original storage 15485 // must have corresponding storage in the device data environment. 15486 // 15487 if (DerivedType->isAnyPointerType()) { 15488 if (CI == CE || SI == SE) { 15489 SemaRef.Diag( 15490 DerivedLoc, 15491 diag::err_omp_pointer_mapped_along_with_derived_section) 15492 << DerivedLoc; 15493 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15494 << RE->getSourceRange(); 15495 return true; 15496 } 15497 if (CI->getAssociatedExpression()->getStmtClass() != 15498 SI->getAssociatedExpression()->getStmtClass() || 15499 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15500 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15501 assert(CI != CE && SI != SE); 15502 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15503 << DerivedLoc; 15504 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15505 << RE->getSourceRange(); 15506 return true; 15507 } 15508 } 15509 15510 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15511 // List items of map clauses in the same construct must not share 15512 // original storage. 15513 // 15514 // An expression is a subset of the other. 15515 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15516 if (CKind == OMPC_map) { 15517 if (CI != CE || SI != SE) { 15518 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15519 // a pointer. 15520 auto Begin = 15521 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15522 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15523 auto It = Begin; 15524 while (It != End && !It->getAssociatedDeclaration()) 15525 std::advance(It, 1); 15526 assert(It != End && 15527 "Expected at least one component with the declaration."); 15528 if (It != Begin && It->getAssociatedDeclaration() 15529 ->getType() 15530 .getCanonicalType() 15531 ->isAnyPointerType()) { 15532 IsEnclosedByDataEnvironmentExpr = false; 15533 EnclosingExpr = nullptr; 15534 return false; 15535 } 15536 } 15537 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15538 } else { 15539 assert(CKind == OMPC_to || CKind == OMPC_from); 15540 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15541 << ERange; 15542 } 15543 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15544 << RE->getSourceRange(); 15545 return true; 15546 } 15547 15548 // The current expression uses the same base as other expression in the 15549 // data environment but does not contain it completely. 15550 if (!CurrentRegionOnly && SI != SE) 15551 EnclosingExpr = RE; 15552 15553 // The current expression is a subset of the expression in the data 15554 // environment. 15555 IsEnclosedByDataEnvironmentExpr |= 15556 (!CurrentRegionOnly && CI != CE && SI == SE); 15557 15558 return false; 15559 }); 15560 15561 if (CurrentRegionOnly) 15562 return FoundError; 15563 15564 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15565 // If any part of the original storage of a list item has corresponding 15566 // storage in the device data environment, all of the original storage must 15567 // have corresponding storage in the device data environment. 15568 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15569 // If a list item is an element of a structure, and a different element of 15570 // the structure has a corresponding list item in the device data environment 15571 // prior to a task encountering the construct associated with the map clause, 15572 // then the list item must also have a corresponding list item in the device 15573 // data environment prior to the task encountering the construct. 15574 // 15575 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15576 SemaRef.Diag(ELoc, 15577 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15578 << ERange; 15579 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15580 << EnclosingExpr->getSourceRange(); 15581 return true; 15582 } 15583 15584 return FoundError; 15585 } 15586 15587 // Look up the user-defined mapper given the mapper name and mapped type, and 15588 // build a reference to it. 15589 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15590 CXXScopeSpec &MapperIdScopeSpec, 15591 const DeclarationNameInfo &MapperId, 15592 QualType Type, 15593 Expr *UnresolvedMapper) { 15594 if (MapperIdScopeSpec.isInvalid()) 15595 return ExprError(); 15596 // Get the actual type for the array type. 15597 if (Type->isArrayType()) { 15598 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15599 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15600 } 15601 // Find all user-defined mappers with the given MapperId. 15602 SmallVector<UnresolvedSet<8>, 4> Lookups; 15603 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15604 Lookup.suppressDiagnostics(); 15605 if (S) { 15606 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15607 NamedDecl *D = Lookup.getRepresentativeDecl(); 15608 while (S && !S->isDeclScope(D)) 15609 S = S->getParent(); 15610 if (S) 15611 S = S->getParent(); 15612 Lookups.emplace_back(); 15613 Lookups.back().append(Lookup.begin(), Lookup.end()); 15614 Lookup.clear(); 15615 } 15616 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15617 // Extract the user-defined mappers with the given MapperId. 15618 Lookups.push_back(UnresolvedSet<8>()); 15619 for (NamedDecl *D : ULE->decls()) { 15620 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15621 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15622 Lookups.back().addDecl(DMD); 15623 } 15624 } 15625 // Defer the lookup for dependent types. The results will be passed through 15626 // UnresolvedMapper on instantiation. 15627 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15628 Type->isInstantiationDependentType() || 15629 Type->containsUnexpandedParameterPack() || 15630 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15631 return !D->isInvalidDecl() && 15632 (D->getType()->isDependentType() || 15633 D->getType()->isInstantiationDependentType() || 15634 D->getType()->containsUnexpandedParameterPack()); 15635 })) { 15636 UnresolvedSet<8> URS; 15637 for (const UnresolvedSet<8> &Set : Lookups) { 15638 if (Set.empty()) 15639 continue; 15640 URS.append(Set.begin(), Set.end()); 15641 } 15642 return UnresolvedLookupExpr::Create( 15643 SemaRef.Context, /*NamingClass=*/nullptr, 15644 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15645 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15646 } 15647 SourceLocation Loc = MapperId.getLoc(); 15648 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15649 // The type must be of struct, union or class type in C and C++ 15650 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15651 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15652 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15653 return ExprError(); 15654 } 15655 // Perform argument dependent lookup. 15656 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15657 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15658 // Return the first user-defined mapper with the desired type. 15659 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15660 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15661 if (!D->isInvalidDecl() && 15662 SemaRef.Context.hasSameType(D->getType(), Type)) 15663 return D; 15664 return nullptr; 15665 })) 15666 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15667 // Find the first user-defined mapper with a type derived from the desired 15668 // type. 15669 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15670 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15671 if (!D->isInvalidDecl() && 15672 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15673 !Type.isMoreQualifiedThan(D->getType())) 15674 return D; 15675 return nullptr; 15676 })) { 15677 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15678 /*DetectVirtual=*/false); 15679 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15680 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15681 VD->getType().getUnqualifiedType()))) { 15682 if (SemaRef.CheckBaseClassAccess( 15683 Loc, VD->getType(), Type, Paths.front(), 15684 /*DiagID=*/0) != Sema::AR_inaccessible) { 15685 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15686 } 15687 } 15688 } 15689 } 15690 // Report error if a mapper is specified, but cannot be found. 15691 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15692 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15693 << Type << MapperId.getName(); 15694 return ExprError(); 15695 } 15696 return ExprEmpty(); 15697 } 15698 15699 namespace { 15700 // Utility struct that gathers all the related lists associated with a mappable 15701 // expression. 15702 struct MappableVarListInfo { 15703 // The list of expressions. 15704 ArrayRef<Expr *> VarList; 15705 // The list of processed expressions. 15706 SmallVector<Expr *, 16> ProcessedVarList; 15707 // The mappble components for each expression. 15708 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15709 // The base declaration of the variable. 15710 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15711 // The reference to the user-defined mapper associated with every expression. 15712 SmallVector<Expr *, 16> UDMapperList; 15713 15714 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15715 // We have a list of components and base declarations for each entry in the 15716 // variable list. 15717 VarComponents.reserve(VarList.size()); 15718 VarBaseDeclarations.reserve(VarList.size()); 15719 } 15720 }; 15721 } 15722 15723 // Check the validity of the provided variable list for the provided clause kind 15724 // \a CKind. In the check process the valid expressions, mappable expression 15725 // components, variables, and user-defined mappers are extracted and used to 15726 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15727 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15728 // and \a MapperId are expected to be valid if the clause kind is 'map'. 15729 static void checkMappableExpressionList( 15730 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15731 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15732 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15733 ArrayRef<Expr *> UnresolvedMappers, 15734 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15735 bool IsMapTypeImplicit = false) { 15736 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15737 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15738 "Unexpected clause kind with mappable expressions!"); 15739 15740 // If the identifier of user-defined mapper is not specified, it is "default". 15741 // We do not change the actual name in this clause to distinguish whether a 15742 // mapper is specified explicitly, i.e., it is not explicitly specified when 15743 // MapperId.getName() is empty. 15744 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15745 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15746 MapperId.setName(DeclNames.getIdentifier( 15747 &SemaRef.getASTContext().Idents.get("default"))); 15748 } 15749 15750 // Iterators to find the current unresolved mapper expression. 15751 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15752 bool UpdateUMIt = false; 15753 Expr *UnresolvedMapper = nullptr; 15754 15755 // Keep track of the mappable components and base declarations in this clause. 15756 // Each entry in the list is going to have a list of components associated. We 15757 // record each set of the components so that we can build the clause later on. 15758 // In the end we should have the same amount of declarations and component 15759 // lists. 15760 15761 for (Expr *RE : MVLI.VarList) { 15762 assert(RE && "Null expr in omp to/from/map clause"); 15763 SourceLocation ELoc = RE->getExprLoc(); 15764 15765 // Find the current unresolved mapper expression. 15766 if (UpdateUMIt && UMIt != UMEnd) { 15767 UMIt++; 15768 assert( 15769 UMIt != UMEnd && 15770 "Expect the size of UnresolvedMappers to match with that of VarList"); 15771 } 15772 UpdateUMIt = true; 15773 if (UMIt != UMEnd) 15774 UnresolvedMapper = *UMIt; 15775 15776 const Expr *VE = RE->IgnoreParenLValueCasts(); 15777 15778 if (VE->isValueDependent() || VE->isTypeDependent() || 15779 VE->isInstantiationDependent() || 15780 VE->containsUnexpandedParameterPack()) { 15781 // Try to find the associated user-defined mapper. 15782 ExprResult ER = buildUserDefinedMapperRef( 15783 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15784 VE->getType().getCanonicalType(), UnresolvedMapper); 15785 if (ER.isInvalid()) 15786 continue; 15787 MVLI.UDMapperList.push_back(ER.get()); 15788 // We can only analyze this information once the missing information is 15789 // resolved. 15790 MVLI.ProcessedVarList.push_back(RE); 15791 continue; 15792 } 15793 15794 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15795 15796 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15797 SemaRef.Diag(ELoc, 15798 diag::err_omp_expected_named_var_member_or_array_expression) 15799 << RE->getSourceRange(); 15800 continue; 15801 } 15802 15803 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15804 ValueDecl *CurDeclaration = nullptr; 15805 15806 // Obtain the array or member expression bases if required. Also, fill the 15807 // components array with all the components identified in the process. 15808 const Expr *BE = checkMapClauseExpressionBase( 15809 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15810 if (!BE) 15811 continue; 15812 15813 assert(!CurComponents.empty() && 15814 "Invalid mappable expression information."); 15815 15816 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15817 // Add store "this" pointer to class in DSAStackTy for future checking 15818 DSAS->addMappedClassesQualTypes(TE->getType()); 15819 // Try to find the associated user-defined mapper. 15820 ExprResult ER = buildUserDefinedMapperRef( 15821 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15822 VE->getType().getCanonicalType(), UnresolvedMapper); 15823 if (ER.isInvalid()) 15824 continue; 15825 MVLI.UDMapperList.push_back(ER.get()); 15826 // Skip restriction checking for variable or field declarations 15827 MVLI.ProcessedVarList.push_back(RE); 15828 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15829 MVLI.VarComponents.back().append(CurComponents.begin(), 15830 CurComponents.end()); 15831 MVLI.VarBaseDeclarations.push_back(nullptr); 15832 continue; 15833 } 15834 15835 // For the following checks, we rely on the base declaration which is 15836 // expected to be associated with the last component. The declaration is 15837 // expected to be a variable or a field (if 'this' is being mapped). 15838 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15839 assert(CurDeclaration && "Null decl on map clause."); 15840 assert( 15841 CurDeclaration->isCanonicalDecl() && 15842 "Expecting components to have associated only canonical declarations."); 15843 15844 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15845 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15846 15847 assert((VD || FD) && "Only variables or fields are expected here!"); 15848 (void)FD; 15849 15850 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15851 // threadprivate variables cannot appear in a map clause. 15852 // OpenMP 4.5 [2.10.5, target update Construct] 15853 // threadprivate variables cannot appear in a from clause. 15854 if (VD && DSAS->isThreadPrivate(VD)) { 15855 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15856 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15857 << getOpenMPClauseName(CKind); 15858 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15859 continue; 15860 } 15861 15862 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15863 // A list item cannot appear in both a map clause and a data-sharing 15864 // attribute clause on the same construct. 15865 15866 // Check conflicts with other map clause expressions. We check the conflicts 15867 // with the current construct separately from the enclosing data 15868 // environment, because the restrictions are different. We only have to 15869 // check conflicts across regions for the map clauses. 15870 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15871 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15872 break; 15873 if (CKind == OMPC_map && 15874 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15875 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15876 break; 15877 15878 // OpenMP 4.5 [2.10.5, target update Construct] 15879 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15880 // If the type of a list item is a reference to a type T then the type will 15881 // be considered to be T for all purposes of this clause. 15882 auto I = llvm::find_if( 15883 CurComponents, 15884 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15885 return MC.getAssociatedDeclaration(); 15886 }); 15887 assert(I != CurComponents.end() && "Null decl on map clause."); 15888 QualType Type = 15889 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15890 15891 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15892 // A list item in a to or from clause must have a mappable type. 15893 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15894 // A list item must have a mappable type. 15895 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15896 DSAS, Type)) 15897 continue; 15898 15899 if (CKind == OMPC_map) { 15900 // target enter data 15901 // OpenMP [2.10.2, Restrictions, p. 99] 15902 // A map-type must be specified in all map clauses and must be either 15903 // to or alloc. 15904 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15905 if (DKind == OMPD_target_enter_data && 15906 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15907 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15908 << (IsMapTypeImplicit ? 1 : 0) 15909 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15910 << getOpenMPDirectiveName(DKind); 15911 continue; 15912 } 15913 15914 // target exit_data 15915 // OpenMP [2.10.3, Restrictions, p. 102] 15916 // A map-type must be specified in all map clauses and must be either 15917 // from, release, or delete. 15918 if (DKind == OMPD_target_exit_data && 15919 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15920 MapType == OMPC_MAP_delete)) { 15921 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15922 << (IsMapTypeImplicit ? 1 : 0) 15923 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15924 << getOpenMPDirectiveName(DKind); 15925 continue; 15926 } 15927 15928 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15929 // A list item cannot appear in both a map clause and a data-sharing 15930 // attribute clause on the same construct 15931 // 15932 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15933 // A list item cannot appear in both a map clause and a data-sharing 15934 // attribute clause on the same construct unless the construct is a 15935 // combined construct. 15936 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15937 isOpenMPTargetExecutionDirective(DKind)) || 15938 DKind == OMPD_target)) { 15939 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15940 if (isOpenMPPrivate(DVar.CKind)) { 15941 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15942 << getOpenMPClauseName(DVar.CKind) 15943 << getOpenMPClauseName(OMPC_map) 15944 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15945 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15946 continue; 15947 } 15948 } 15949 } 15950 15951 // Try to find the associated user-defined mapper. 15952 ExprResult ER = buildUserDefinedMapperRef( 15953 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15954 Type.getCanonicalType(), UnresolvedMapper); 15955 if (ER.isInvalid()) 15956 continue; 15957 MVLI.UDMapperList.push_back(ER.get()); 15958 15959 // Save the current expression. 15960 MVLI.ProcessedVarList.push_back(RE); 15961 15962 // Store the components in the stack so that they can be used to check 15963 // against other clauses later on. 15964 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15965 /*WhereFoundClauseKind=*/OMPC_map); 15966 15967 // Save the components and declaration to create the clause. For purposes of 15968 // the clause creation, any component list that has has base 'this' uses 15969 // null as base declaration. 15970 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15971 MVLI.VarComponents.back().append(CurComponents.begin(), 15972 CurComponents.end()); 15973 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15974 : CurDeclaration); 15975 } 15976 } 15977 15978 OMPClause *Sema::ActOnOpenMPMapClause( 15979 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15980 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15981 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15982 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15983 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15984 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15985 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15986 OMPC_MAP_MODIFIER_unknown, 15987 OMPC_MAP_MODIFIER_unknown}; 15988 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15989 15990 // Process map-type-modifiers, flag errors for duplicate modifiers. 15991 unsigned Count = 0; 15992 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15993 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15994 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15995 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15996 continue; 15997 } 15998 assert(Count < OMPMapClause::NumberOfModifiers && 15999 "Modifiers exceed the allowed number of map type modifiers"); 16000 Modifiers[Count] = MapTypeModifiers[I]; 16001 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 16002 ++Count; 16003 } 16004 16005 MappableVarListInfo MVLI(VarList); 16006 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 16007 MapperIdScopeSpec, MapperId, UnresolvedMappers, 16008 MapType, IsMapTypeImplicit); 16009 16010 // We need to produce a map clause even if we don't have variables so that 16011 // other diagnostics related with non-existing map clauses are accurate. 16012 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 16013 MVLI.VarBaseDeclarations, MVLI.VarComponents, 16014 MVLI.UDMapperList, Modifiers, ModifiersLoc, 16015 MapperIdScopeSpec.getWithLocInContext(Context), 16016 MapperId, MapType, IsMapTypeImplicit, MapLoc); 16017 } 16018 16019 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 16020 TypeResult ParsedType) { 16021 assert(ParsedType.isUsable()); 16022 16023 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 16024 if (ReductionType.isNull()) 16025 return QualType(); 16026 16027 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 16028 // A type name in a declare reduction directive cannot be a function type, an 16029 // array type, a reference type, or a type qualified with const, volatile or 16030 // restrict. 16031 if (ReductionType.hasQualifiers()) { 16032 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 16033 return QualType(); 16034 } 16035 16036 if (ReductionType->isFunctionType()) { 16037 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 16038 return QualType(); 16039 } 16040 if (ReductionType->isReferenceType()) { 16041 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 16042 return QualType(); 16043 } 16044 if (ReductionType->isArrayType()) { 16045 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 16046 return QualType(); 16047 } 16048 return ReductionType; 16049 } 16050 16051 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 16052 Scope *S, DeclContext *DC, DeclarationName Name, 16053 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 16054 AccessSpecifier AS, Decl *PrevDeclInScope) { 16055 SmallVector<Decl *, 8> Decls; 16056 Decls.reserve(ReductionTypes.size()); 16057 16058 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 16059 forRedeclarationInCurContext()); 16060 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 16061 // A reduction-identifier may not be re-declared in the current scope for the 16062 // same type or for a type that is compatible according to the base language 16063 // rules. 16064 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16065 OMPDeclareReductionDecl *PrevDRD = nullptr; 16066 bool InCompoundScope = true; 16067 if (S != nullptr) { 16068 // Find previous declaration with the same name not referenced in other 16069 // declarations. 16070 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16071 InCompoundScope = 16072 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16073 LookupName(Lookup, S); 16074 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16075 /*AllowInlineNamespace=*/false); 16076 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 16077 LookupResult::Filter Filter = Lookup.makeFilter(); 16078 while (Filter.hasNext()) { 16079 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 16080 if (InCompoundScope) { 16081 auto I = UsedAsPrevious.find(PrevDecl); 16082 if (I == UsedAsPrevious.end()) 16083 UsedAsPrevious[PrevDecl] = false; 16084 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 16085 UsedAsPrevious[D] = true; 16086 } 16087 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16088 PrevDecl->getLocation(); 16089 } 16090 Filter.done(); 16091 if (InCompoundScope) { 16092 for (const auto &PrevData : UsedAsPrevious) { 16093 if (!PrevData.second) { 16094 PrevDRD = PrevData.first; 16095 break; 16096 } 16097 } 16098 } 16099 } else if (PrevDeclInScope != nullptr) { 16100 auto *PrevDRDInScope = PrevDRD = 16101 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 16102 do { 16103 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 16104 PrevDRDInScope->getLocation(); 16105 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 16106 } while (PrevDRDInScope != nullptr); 16107 } 16108 for (const auto &TyData : ReductionTypes) { 16109 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 16110 bool Invalid = false; 16111 if (I != PreviousRedeclTypes.end()) { 16112 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 16113 << TyData.first; 16114 Diag(I->second, diag::note_previous_definition); 16115 Invalid = true; 16116 } 16117 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 16118 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 16119 Name, TyData.first, PrevDRD); 16120 DC->addDecl(DRD); 16121 DRD->setAccess(AS); 16122 Decls.push_back(DRD); 16123 if (Invalid) 16124 DRD->setInvalidDecl(); 16125 else 16126 PrevDRD = DRD; 16127 } 16128 16129 return DeclGroupPtrTy::make( 16130 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 16131 } 16132 16133 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 16134 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16135 16136 // Enter new function scope. 16137 PushFunctionScope(); 16138 setFunctionHasBranchProtectedScope(); 16139 getCurFunction()->setHasOMPDeclareReductionCombiner(); 16140 16141 if (S != nullptr) 16142 PushDeclContext(S, DRD); 16143 else 16144 CurContext = DRD; 16145 16146 PushExpressionEvaluationContext( 16147 ExpressionEvaluationContext::PotentiallyEvaluated); 16148 16149 QualType ReductionType = DRD->getType(); 16150 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 16151 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 16152 // uses semantics of argument handles by value, but it should be passed by 16153 // reference. C lang does not support references, so pass all parameters as 16154 // pointers. 16155 // Create 'T omp_in;' variable. 16156 VarDecl *OmpInParm = 16157 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16158 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16159 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16160 // uses semantics of argument handles by value, but it should be passed by 16161 // reference. C lang does not support references, so pass all parameters as 16162 // pointers. 16163 // Create 'T omp_out;' variable. 16164 VarDecl *OmpOutParm = 16165 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16166 if (S != nullptr) { 16167 PushOnScopeChains(OmpInParm, S); 16168 PushOnScopeChains(OmpOutParm, S); 16169 } else { 16170 DRD->addDecl(OmpInParm); 16171 DRD->addDecl(OmpOutParm); 16172 } 16173 Expr *InE = 16174 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16175 Expr *OutE = 16176 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16177 DRD->setCombinerData(InE, OutE); 16178 } 16179 16180 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16181 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16182 DiscardCleanupsInEvaluationContext(); 16183 PopExpressionEvaluationContext(); 16184 16185 PopDeclContext(); 16186 PopFunctionScopeInfo(); 16187 16188 if (Combiner != nullptr) 16189 DRD->setCombiner(Combiner); 16190 else 16191 DRD->setInvalidDecl(); 16192 } 16193 16194 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16195 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16196 16197 // Enter new function scope. 16198 PushFunctionScope(); 16199 setFunctionHasBranchProtectedScope(); 16200 16201 if (S != nullptr) 16202 PushDeclContext(S, DRD); 16203 else 16204 CurContext = DRD; 16205 16206 PushExpressionEvaluationContext( 16207 ExpressionEvaluationContext::PotentiallyEvaluated); 16208 16209 QualType ReductionType = DRD->getType(); 16210 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16211 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16212 // uses semantics of argument handles by value, but it should be passed by 16213 // reference. C lang does not support references, so pass all parameters as 16214 // pointers. 16215 // Create 'T omp_priv;' variable. 16216 VarDecl *OmpPrivParm = 16217 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16218 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16219 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16220 // uses semantics of argument handles by value, but it should be passed by 16221 // reference. C lang does not support references, so pass all parameters as 16222 // pointers. 16223 // Create 'T omp_orig;' variable. 16224 VarDecl *OmpOrigParm = 16225 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16226 if (S != nullptr) { 16227 PushOnScopeChains(OmpPrivParm, S); 16228 PushOnScopeChains(OmpOrigParm, S); 16229 } else { 16230 DRD->addDecl(OmpPrivParm); 16231 DRD->addDecl(OmpOrigParm); 16232 } 16233 Expr *OrigE = 16234 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16235 Expr *PrivE = 16236 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16237 DRD->setInitializerData(OrigE, PrivE); 16238 return OmpPrivParm; 16239 } 16240 16241 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16242 VarDecl *OmpPrivParm) { 16243 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16244 DiscardCleanupsInEvaluationContext(); 16245 PopExpressionEvaluationContext(); 16246 16247 PopDeclContext(); 16248 PopFunctionScopeInfo(); 16249 16250 if (Initializer != nullptr) { 16251 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16252 } else if (OmpPrivParm->hasInit()) { 16253 DRD->setInitializer(OmpPrivParm->getInit(), 16254 OmpPrivParm->isDirectInit() 16255 ? OMPDeclareReductionDecl::DirectInit 16256 : OMPDeclareReductionDecl::CopyInit); 16257 } else { 16258 DRD->setInvalidDecl(); 16259 } 16260 } 16261 16262 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16263 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16264 for (Decl *D : DeclReductions.get()) { 16265 if (IsValid) { 16266 if (S) 16267 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16268 /*AddToContext=*/false); 16269 } else { 16270 D->setInvalidDecl(); 16271 } 16272 } 16273 return DeclReductions; 16274 } 16275 16276 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16277 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16278 QualType T = TInfo->getType(); 16279 if (D.isInvalidType()) 16280 return true; 16281 16282 if (getLangOpts().CPlusPlus) { 16283 // Check that there are no default arguments (C++ only). 16284 CheckExtraCXXDefaultArguments(D); 16285 } 16286 16287 return CreateParsedType(T, TInfo); 16288 } 16289 16290 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16291 TypeResult ParsedType) { 16292 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16293 16294 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16295 assert(!MapperType.isNull() && "Expect valid mapper type"); 16296 16297 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16298 // The type must be of struct, union or class type in C and C++ 16299 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16300 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16301 return QualType(); 16302 } 16303 return MapperType; 16304 } 16305 16306 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16307 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16308 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16309 Decl *PrevDeclInScope) { 16310 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16311 forRedeclarationInCurContext()); 16312 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16313 // A mapper-identifier may not be redeclared in the current scope for the 16314 // same type or for a type that is compatible according to the base language 16315 // rules. 16316 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16317 OMPDeclareMapperDecl *PrevDMD = nullptr; 16318 bool InCompoundScope = true; 16319 if (S != nullptr) { 16320 // Find previous declaration with the same name not referenced in other 16321 // declarations. 16322 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16323 InCompoundScope = 16324 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16325 LookupName(Lookup, S); 16326 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16327 /*AllowInlineNamespace=*/false); 16328 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16329 LookupResult::Filter Filter = Lookup.makeFilter(); 16330 while (Filter.hasNext()) { 16331 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16332 if (InCompoundScope) { 16333 auto I = UsedAsPrevious.find(PrevDecl); 16334 if (I == UsedAsPrevious.end()) 16335 UsedAsPrevious[PrevDecl] = false; 16336 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16337 UsedAsPrevious[D] = true; 16338 } 16339 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16340 PrevDecl->getLocation(); 16341 } 16342 Filter.done(); 16343 if (InCompoundScope) { 16344 for (const auto &PrevData : UsedAsPrevious) { 16345 if (!PrevData.second) { 16346 PrevDMD = PrevData.first; 16347 break; 16348 } 16349 } 16350 } 16351 } else if (PrevDeclInScope) { 16352 auto *PrevDMDInScope = PrevDMD = 16353 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16354 do { 16355 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16356 PrevDMDInScope->getLocation(); 16357 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16358 } while (PrevDMDInScope != nullptr); 16359 } 16360 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16361 bool Invalid = false; 16362 if (I != PreviousRedeclTypes.end()) { 16363 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16364 << MapperType << Name; 16365 Diag(I->second, diag::note_previous_definition); 16366 Invalid = true; 16367 } 16368 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16369 MapperType, VN, PrevDMD); 16370 DC->addDecl(DMD); 16371 DMD->setAccess(AS); 16372 if (Invalid) 16373 DMD->setInvalidDecl(); 16374 16375 // Enter new function scope. 16376 PushFunctionScope(); 16377 setFunctionHasBranchProtectedScope(); 16378 16379 CurContext = DMD; 16380 16381 return DMD; 16382 } 16383 16384 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16385 Scope *S, 16386 QualType MapperType, 16387 SourceLocation StartLoc, 16388 DeclarationName VN) { 16389 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16390 if (S) 16391 PushOnScopeChains(VD, S); 16392 else 16393 DMD->addDecl(VD); 16394 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16395 DMD->setMapperVarRef(MapperVarRefExpr); 16396 } 16397 16398 Sema::DeclGroupPtrTy 16399 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16400 ArrayRef<OMPClause *> ClauseList) { 16401 PopDeclContext(); 16402 PopFunctionScopeInfo(); 16403 16404 if (D) { 16405 if (S) 16406 PushOnScopeChains(D, S, /*AddToContext=*/false); 16407 D->CreateClauses(Context, ClauseList); 16408 } 16409 16410 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16411 } 16412 16413 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16414 SourceLocation StartLoc, 16415 SourceLocation LParenLoc, 16416 SourceLocation EndLoc) { 16417 Expr *ValExpr = NumTeams; 16418 Stmt *HelperValStmt = nullptr; 16419 16420 // OpenMP [teams Constrcut, Restrictions] 16421 // The num_teams expression must evaluate to a positive integer value. 16422 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16423 /*StrictlyPositive=*/true)) 16424 return nullptr; 16425 16426 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16427 OpenMPDirectiveKind CaptureRegion = 16428 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 16429 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16430 ValExpr = MakeFullExpr(ValExpr).get(); 16431 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16432 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16433 HelperValStmt = buildPreInits(Context, Captures); 16434 } 16435 16436 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16437 StartLoc, LParenLoc, EndLoc); 16438 } 16439 16440 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16441 SourceLocation StartLoc, 16442 SourceLocation LParenLoc, 16443 SourceLocation EndLoc) { 16444 Expr *ValExpr = ThreadLimit; 16445 Stmt *HelperValStmt = nullptr; 16446 16447 // OpenMP [teams Constrcut, Restrictions] 16448 // The thread_limit expression must evaluate to a positive integer value. 16449 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16450 /*StrictlyPositive=*/true)) 16451 return nullptr; 16452 16453 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16454 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 16455 DKind, OMPC_thread_limit, LangOpts.OpenMP); 16456 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16457 ValExpr = MakeFullExpr(ValExpr).get(); 16458 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16459 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16460 HelperValStmt = buildPreInits(Context, Captures); 16461 } 16462 16463 return new (Context) OMPThreadLimitClause( 16464 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16465 } 16466 16467 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16468 SourceLocation StartLoc, 16469 SourceLocation LParenLoc, 16470 SourceLocation EndLoc) { 16471 Expr *ValExpr = Priority; 16472 Stmt *HelperValStmt = nullptr; 16473 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16474 16475 // OpenMP [2.9.1, task Constrcut] 16476 // The priority-value is a non-negative numerical scalar expression. 16477 if (!isNonNegativeIntegerValue( 16478 ValExpr, *this, OMPC_priority, 16479 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16480 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16481 return nullptr; 16482 16483 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16484 StartLoc, LParenLoc, EndLoc); 16485 } 16486 16487 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16488 SourceLocation StartLoc, 16489 SourceLocation LParenLoc, 16490 SourceLocation EndLoc) { 16491 Expr *ValExpr = Grainsize; 16492 Stmt *HelperValStmt = nullptr; 16493 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16494 16495 // OpenMP [2.9.2, taskloop Constrcut] 16496 // The parameter of the grainsize clause must be a positive integer 16497 // expression. 16498 if (!isNonNegativeIntegerValue( 16499 ValExpr, *this, OMPC_grainsize, 16500 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16501 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16502 return nullptr; 16503 16504 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16505 StartLoc, LParenLoc, EndLoc); 16506 } 16507 16508 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16509 SourceLocation StartLoc, 16510 SourceLocation LParenLoc, 16511 SourceLocation EndLoc) { 16512 Expr *ValExpr = NumTasks; 16513 Stmt *HelperValStmt = nullptr; 16514 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16515 16516 // OpenMP [2.9.2, taskloop Constrcut] 16517 // The parameter of the num_tasks clause must be a positive integer 16518 // expression. 16519 if (!isNonNegativeIntegerValue( 16520 ValExpr, *this, OMPC_num_tasks, 16521 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16522 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16523 return nullptr; 16524 16525 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16526 StartLoc, LParenLoc, EndLoc); 16527 } 16528 16529 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16530 SourceLocation LParenLoc, 16531 SourceLocation EndLoc) { 16532 // OpenMP [2.13.2, critical construct, Description] 16533 // ... where hint-expression is an integer constant expression that evaluates 16534 // to a valid lock hint. 16535 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16536 if (HintExpr.isInvalid()) 16537 return nullptr; 16538 return new (Context) 16539 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16540 } 16541 16542 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16543 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16544 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16545 SourceLocation EndLoc) { 16546 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16547 std::string Values; 16548 Values += "'"; 16549 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16550 Values += "'"; 16551 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16552 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16553 return nullptr; 16554 } 16555 Expr *ValExpr = ChunkSize; 16556 Stmt *HelperValStmt = nullptr; 16557 if (ChunkSize) { 16558 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16559 !ChunkSize->isInstantiationDependent() && 16560 !ChunkSize->containsUnexpandedParameterPack()) { 16561 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16562 ExprResult Val = 16563 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16564 if (Val.isInvalid()) 16565 return nullptr; 16566 16567 ValExpr = Val.get(); 16568 16569 // OpenMP [2.7.1, Restrictions] 16570 // chunk_size must be a loop invariant integer expression with a positive 16571 // value. 16572 llvm::APSInt Result; 16573 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16574 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16575 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16576 << "dist_schedule" << ChunkSize->getSourceRange(); 16577 return nullptr; 16578 } 16579 } else if (getOpenMPCaptureRegionForClause( 16580 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 16581 LangOpts.OpenMP) != OMPD_unknown && 16582 !CurContext->isDependentContext()) { 16583 ValExpr = MakeFullExpr(ValExpr).get(); 16584 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16585 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16586 HelperValStmt = buildPreInits(Context, Captures); 16587 } 16588 } 16589 } 16590 16591 return new (Context) 16592 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16593 Kind, ValExpr, HelperValStmt); 16594 } 16595 16596 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16597 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16598 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16599 SourceLocation KindLoc, SourceLocation EndLoc) { 16600 if (getLangOpts().OpenMP < 50) { 16601 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 16602 Kind != OMPC_DEFAULTMAP_scalar) { 16603 std::string Value; 16604 SourceLocation Loc; 16605 Value += "'"; 16606 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16607 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16608 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16609 Loc = MLoc; 16610 } else { 16611 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16612 OMPC_DEFAULTMAP_scalar); 16613 Loc = KindLoc; 16614 } 16615 Value += "'"; 16616 Diag(Loc, diag::err_omp_unexpected_clause_value) 16617 << Value << getOpenMPClauseName(OMPC_defaultmap); 16618 return nullptr; 16619 } 16620 } else { 16621 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 16622 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 16623 if (!isDefaultmapKind || !isDefaultmapModifier) { 16624 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 16625 "'firstprivate', 'none', 'default'"; 16626 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 16627 if (!isDefaultmapKind && isDefaultmapModifier) { 16628 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16629 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16630 } else if (isDefaultmapKind && !isDefaultmapModifier) { 16631 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16632 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16633 } else { 16634 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16635 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 16636 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16637 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 16638 } 16639 return nullptr; 16640 } 16641 16642 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 16643 // At most one defaultmap clause for each category can appear on the 16644 // directive. 16645 if (DSAStack->checkDefaultmapCategory(Kind)) { 16646 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 16647 return nullptr; 16648 } 16649 } 16650 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 16651 16652 return new (Context) 16653 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16654 } 16655 16656 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16657 DeclContext *CurLexicalContext = getCurLexicalContext(); 16658 if (!CurLexicalContext->isFileContext() && 16659 !CurLexicalContext->isExternCContext() && 16660 !CurLexicalContext->isExternCXXContext() && 16661 !isa<CXXRecordDecl>(CurLexicalContext) && 16662 !isa<ClassTemplateDecl>(CurLexicalContext) && 16663 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16664 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16665 Diag(Loc, diag::err_omp_region_not_file_context); 16666 return false; 16667 } 16668 ++DeclareTargetNestingLevel; 16669 return true; 16670 } 16671 16672 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16673 assert(DeclareTargetNestingLevel > 0 && 16674 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16675 --DeclareTargetNestingLevel; 16676 } 16677 16678 NamedDecl * 16679 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16680 const DeclarationNameInfo &Id, 16681 NamedDeclSetType &SameDirectiveDecls) { 16682 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16683 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16684 16685 if (Lookup.isAmbiguous()) 16686 return nullptr; 16687 Lookup.suppressDiagnostics(); 16688 16689 if (!Lookup.isSingleResult()) { 16690 VarOrFuncDeclFilterCCC CCC(*this); 16691 if (TypoCorrection Corrected = 16692 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16693 CTK_ErrorRecovery)) { 16694 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16695 << Id.getName()); 16696 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16697 return nullptr; 16698 } 16699 16700 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16701 return nullptr; 16702 } 16703 16704 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16705 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16706 !isa<FunctionTemplateDecl>(ND)) { 16707 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16708 return nullptr; 16709 } 16710 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16711 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16712 return ND; 16713 } 16714 16715 void Sema::ActOnOpenMPDeclareTargetName( 16716 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16717 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16718 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16719 isa<FunctionTemplateDecl>(ND)) && 16720 "Expected variable, function or function template."); 16721 16722 // Diagnose marking after use as it may lead to incorrect diagnosis and 16723 // codegen. 16724 if (LangOpts.OpenMP >= 50 && 16725 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16726 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16727 16728 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16729 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16730 if (DevTy.hasValue() && *DevTy != DT) { 16731 Diag(Loc, diag::err_omp_device_type_mismatch) 16732 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16733 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16734 return; 16735 } 16736 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16737 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16738 if (!Res) { 16739 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16740 SourceRange(Loc, Loc)); 16741 ND->addAttr(A); 16742 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16743 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16744 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16745 } else if (*Res != MT) { 16746 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16747 } 16748 } 16749 16750 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16751 Sema &SemaRef, Decl *D) { 16752 if (!D || !isa<VarDecl>(D)) 16753 return; 16754 auto *VD = cast<VarDecl>(D); 16755 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16756 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16757 if (SemaRef.LangOpts.OpenMP >= 50 && 16758 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16759 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16760 VD->hasGlobalStorage()) { 16761 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16762 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16763 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16764 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16765 // If a lambda declaration and definition appears between a 16766 // declare target directive and the matching end declare target 16767 // directive, all variables that are captured by the lambda 16768 // expression must also appear in a to clause. 16769 SemaRef.Diag(VD->getLocation(), 16770 diag::err_omp_lambda_capture_in_declare_target_not_to); 16771 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16772 << VD << 0 << SR; 16773 return; 16774 } 16775 } 16776 if (MapTy.hasValue()) 16777 return; 16778 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16779 SemaRef.Diag(SL, diag::note_used_here) << SR; 16780 } 16781 16782 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16783 Sema &SemaRef, DSAStackTy *Stack, 16784 ValueDecl *VD) { 16785 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16786 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16787 /*FullCheck=*/false); 16788 } 16789 16790 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16791 SourceLocation IdLoc) { 16792 if (!D || D->isInvalidDecl()) 16793 return; 16794 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16795 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16796 if (auto *VD = dyn_cast<VarDecl>(D)) { 16797 // Only global variables can be marked as declare target. 16798 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16799 !VD->isStaticDataMember()) 16800 return; 16801 // 2.10.6: threadprivate variable cannot appear in a declare target 16802 // directive. 16803 if (DSAStack->isThreadPrivate(VD)) { 16804 Diag(SL, diag::err_omp_threadprivate_in_target); 16805 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16806 return; 16807 } 16808 } 16809 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16810 D = FTD->getTemplatedDecl(); 16811 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16812 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16813 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16814 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16815 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16816 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16817 return; 16818 } 16819 // Mark the function as must be emitted for the device. 16820 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16821 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16822 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16823 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16824 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16825 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16826 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16827 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16828 } 16829 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16830 // Problem if any with var declared with incomplete type will be reported 16831 // as normal, so no need to check it here. 16832 if ((E || !VD->getType()->isIncompleteType()) && 16833 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16834 return; 16835 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16836 // Checking declaration inside declare target region. 16837 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16838 isa<FunctionTemplateDecl>(D)) { 16839 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16840 Context, OMPDeclareTargetDeclAttr::MT_To, 16841 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16842 D->addAttr(A); 16843 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16844 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16845 } 16846 return; 16847 } 16848 } 16849 if (!E) 16850 return; 16851 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16852 } 16853 16854 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16855 CXXScopeSpec &MapperIdScopeSpec, 16856 DeclarationNameInfo &MapperId, 16857 const OMPVarListLocTy &Locs, 16858 ArrayRef<Expr *> UnresolvedMappers) { 16859 MappableVarListInfo MVLI(VarList); 16860 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16861 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16862 if (MVLI.ProcessedVarList.empty()) 16863 return nullptr; 16864 16865 return OMPToClause::Create( 16866 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16867 MVLI.VarComponents, MVLI.UDMapperList, 16868 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16869 } 16870 16871 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16872 CXXScopeSpec &MapperIdScopeSpec, 16873 DeclarationNameInfo &MapperId, 16874 const OMPVarListLocTy &Locs, 16875 ArrayRef<Expr *> UnresolvedMappers) { 16876 MappableVarListInfo MVLI(VarList); 16877 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16878 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16879 if (MVLI.ProcessedVarList.empty()) 16880 return nullptr; 16881 16882 return OMPFromClause::Create( 16883 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16884 MVLI.VarComponents, MVLI.UDMapperList, 16885 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16886 } 16887 16888 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16889 const OMPVarListLocTy &Locs) { 16890 MappableVarListInfo MVLI(VarList); 16891 SmallVector<Expr *, 8> PrivateCopies; 16892 SmallVector<Expr *, 8> Inits; 16893 16894 for (Expr *RefExpr : VarList) { 16895 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16896 SourceLocation ELoc; 16897 SourceRange ERange; 16898 Expr *SimpleRefExpr = RefExpr; 16899 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16900 if (Res.second) { 16901 // It will be analyzed later. 16902 MVLI.ProcessedVarList.push_back(RefExpr); 16903 PrivateCopies.push_back(nullptr); 16904 Inits.push_back(nullptr); 16905 } 16906 ValueDecl *D = Res.first; 16907 if (!D) 16908 continue; 16909 16910 QualType Type = D->getType(); 16911 Type = Type.getNonReferenceType().getUnqualifiedType(); 16912 16913 auto *VD = dyn_cast<VarDecl>(D); 16914 16915 // Item should be a pointer or reference to pointer. 16916 if (!Type->isPointerType()) { 16917 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16918 << 0 << RefExpr->getSourceRange(); 16919 continue; 16920 } 16921 16922 // Build the private variable and the expression that refers to it. 16923 auto VDPrivate = 16924 buildVarDecl(*this, ELoc, Type, D->getName(), 16925 D->hasAttrs() ? &D->getAttrs() : nullptr, 16926 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16927 if (VDPrivate->isInvalidDecl()) 16928 continue; 16929 16930 CurContext->addDecl(VDPrivate); 16931 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16932 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16933 16934 // Add temporary variable to initialize the private copy of the pointer. 16935 VarDecl *VDInit = 16936 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16937 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16938 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16939 AddInitializerToDecl(VDPrivate, 16940 DefaultLvalueConversion(VDInitRefExpr).get(), 16941 /*DirectInit=*/false); 16942 16943 // If required, build a capture to implement the privatization initialized 16944 // with the current list item value. 16945 DeclRefExpr *Ref = nullptr; 16946 if (!VD) 16947 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16948 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16949 PrivateCopies.push_back(VDPrivateRefExpr); 16950 Inits.push_back(VDInitRefExpr); 16951 16952 // We need to add a data sharing attribute for this variable to make sure it 16953 // is correctly captured. A variable that shows up in a use_device_ptr has 16954 // similar properties of a first private variable. 16955 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16956 16957 // Create a mappable component for the list item. List items in this clause 16958 // only need a component. 16959 MVLI.VarBaseDeclarations.push_back(D); 16960 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16961 MVLI.VarComponents.back().push_back( 16962 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16963 } 16964 16965 if (MVLI.ProcessedVarList.empty()) 16966 return nullptr; 16967 16968 return OMPUseDevicePtrClause::Create( 16969 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16970 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16971 } 16972 16973 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16974 const OMPVarListLocTy &Locs) { 16975 MappableVarListInfo MVLI(VarList); 16976 for (Expr *RefExpr : VarList) { 16977 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16978 SourceLocation ELoc; 16979 SourceRange ERange; 16980 Expr *SimpleRefExpr = RefExpr; 16981 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16982 if (Res.second) { 16983 // It will be analyzed later. 16984 MVLI.ProcessedVarList.push_back(RefExpr); 16985 } 16986 ValueDecl *D = Res.first; 16987 if (!D) 16988 continue; 16989 16990 QualType Type = D->getType(); 16991 // item should be a pointer or array or reference to pointer or array 16992 if (!Type.getNonReferenceType()->isPointerType() && 16993 !Type.getNonReferenceType()->isArrayType()) { 16994 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16995 << 0 << RefExpr->getSourceRange(); 16996 continue; 16997 } 16998 16999 // Check if the declaration in the clause does not show up in any data 17000 // sharing attribute. 17001 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17002 if (isOpenMPPrivate(DVar.CKind)) { 17003 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17004 << getOpenMPClauseName(DVar.CKind) 17005 << getOpenMPClauseName(OMPC_is_device_ptr) 17006 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17007 reportOriginalDsa(*this, DSAStack, D, DVar); 17008 continue; 17009 } 17010 17011 const Expr *ConflictExpr; 17012 if (DSAStack->checkMappableExprComponentListsForDecl( 17013 D, /*CurrentRegionOnly=*/true, 17014 [&ConflictExpr]( 17015 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 17016 OpenMPClauseKind) -> bool { 17017 ConflictExpr = R.front().getAssociatedExpression(); 17018 return true; 17019 })) { 17020 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 17021 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 17022 << ConflictExpr->getSourceRange(); 17023 continue; 17024 } 17025 17026 // Store the components in the stack so that they can be used to check 17027 // against other clauses later on. 17028 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 17029 DSAStack->addMappableExpressionComponents( 17030 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 17031 17032 // Record the expression we've just processed. 17033 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 17034 17035 // Create a mappable component for the list item. List items in this clause 17036 // only need a component. We use a null declaration to signal fields in 17037 // 'this'. 17038 assert((isa<DeclRefExpr>(SimpleRefExpr) || 17039 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 17040 "Unexpected device pointer expression!"); 17041 MVLI.VarBaseDeclarations.push_back( 17042 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 17043 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17044 MVLI.VarComponents.back().push_back(MC); 17045 } 17046 17047 if (MVLI.ProcessedVarList.empty()) 17048 return nullptr; 17049 17050 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 17051 MVLI.VarBaseDeclarations, 17052 MVLI.VarComponents); 17053 } 17054 17055 OMPClause *Sema::ActOnOpenMPAllocateClause( 17056 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17057 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17058 if (Allocator) { 17059 // OpenMP [2.11.4 allocate Clause, Description] 17060 // allocator is an expression of omp_allocator_handle_t type. 17061 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 17062 return nullptr; 17063 17064 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 17065 if (AllocatorRes.isInvalid()) 17066 return nullptr; 17067 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 17068 DSAStack->getOMPAllocatorHandleT(), 17069 Sema::AA_Initializing, 17070 /*AllowExplicit=*/true); 17071 if (AllocatorRes.isInvalid()) 17072 return nullptr; 17073 Allocator = AllocatorRes.get(); 17074 } else { 17075 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 17076 // allocate clauses that appear on a target construct or on constructs in a 17077 // target region must specify an allocator expression unless a requires 17078 // directive with the dynamic_allocators clause is present in the same 17079 // compilation unit. 17080 if (LangOpts.OpenMPIsDevice && 17081 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 17082 targetDiag(StartLoc, diag::err_expected_allocator_expression); 17083 } 17084 // Analyze and build list of variables. 17085 SmallVector<Expr *, 8> Vars; 17086 for (Expr *RefExpr : VarList) { 17087 assert(RefExpr && "NULL expr in OpenMP private clause."); 17088 SourceLocation ELoc; 17089 SourceRange ERange; 17090 Expr *SimpleRefExpr = RefExpr; 17091 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17092 if (Res.second) { 17093 // It will be analyzed later. 17094 Vars.push_back(RefExpr); 17095 } 17096 ValueDecl *D = Res.first; 17097 if (!D) 17098 continue; 17099 17100 auto *VD = dyn_cast<VarDecl>(D); 17101 DeclRefExpr *Ref = nullptr; 17102 if (!VD && !CurContext->isDependentContext()) 17103 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17104 Vars.push_back((VD || CurContext->isDependentContext()) 17105 ? RefExpr->IgnoreParens() 17106 : Ref); 17107 } 17108 17109 if (Vars.empty()) 17110 return nullptr; 17111 17112 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 17113 ColonLoc, EndLoc, Vars); 17114 } 17115