1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 bool HasMutipleLoops = false; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 bool BodyComplete = false; 148 SourceLocation InnerTeamsRegionLoc; 149 /// Reference to the taskgroup task_reduction reference expression. 150 Expr *TaskgroupReductionRef = nullptr; 151 llvm::DenseSet<QualType> MappedClassesQualTypes; 152 /// List of globals marked as declare target link in this target region 153 /// (isOpenMPTargetExecutionDirective(Directive) == true). 154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 156 Scope *CurScope, SourceLocation Loc) 157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 158 ConstructLoc(Loc) {} 159 SharingMapTy() = default; 160 }; 161 162 using StackTy = SmallVector<SharingMapTy, 4>; 163 164 /// Stack of used declaration and their data-sharing attributes. 165 DeclSAMapTy Threadprivates; 166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 168 /// true, if check for DSA must be from parent directive, false, if 169 /// from current directive. 170 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 171 Sema &SemaRef; 172 bool ForceCapturing = false; 173 /// true if all the variables in the target executable directives must be 174 /// captured by reference. 175 bool ForceCaptureByReferenceInTargetExecutable = false; 176 CriticalsWithHintsTy Criticals; 177 unsigned IgnoredStackElements = 0; 178 179 /// Iterators over the stack iterate in order from innermost to outermost 180 /// directive. 181 using const_iterator = StackTy::const_reverse_iterator; 182 const_iterator begin() const { 183 return Stack.empty() ? const_iterator() 184 : Stack.back().first.rbegin() + IgnoredStackElements; 185 } 186 const_iterator end() const { 187 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 188 } 189 using iterator = StackTy::reverse_iterator; 190 iterator begin() { 191 return Stack.empty() ? iterator() 192 : Stack.back().first.rbegin() + IgnoredStackElements; 193 } 194 iterator end() { 195 return Stack.empty() ? iterator() : Stack.back().first.rend(); 196 } 197 198 // Convenience operations to get at the elements of the stack. 199 200 bool isStackEmpty() const { 201 return Stack.empty() || 202 Stack.back().second != CurrentNonCapturingFunctionScope || 203 Stack.back().first.size() <= IgnoredStackElements; 204 } 205 size_t getStackSize() const { 206 return isStackEmpty() ? 0 207 : Stack.back().first.size() - IgnoredStackElements; 208 } 209 210 SharingMapTy *getTopOfStackOrNull() { 211 size_t Size = getStackSize(); 212 if (Size == 0) 213 return nullptr; 214 return &Stack.back().first[Size - 1]; 215 } 216 const SharingMapTy *getTopOfStackOrNull() const { 217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 218 } 219 SharingMapTy &getTopOfStack() { 220 assert(!isStackEmpty() && "no current directive"); 221 return *getTopOfStackOrNull(); 222 } 223 const SharingMapTy &getTopOfStack() const { 224 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 225 } 226 227 SharingMapTy *getSecondOnStackOrNull() { 228 size_t Size = getStackSize(); 229 if (Size <= 1) 230 return nullptr; 231 return &Stack.back().first[Size - 2]; 232 } 233 const SharingMapTy *getSecondOnStackOrNull() const { 234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 235 } 236 237 /// Get the stack element at a certain level (previously returned by 238 /// \c getNestingLevel). 239 /// 240 /// Note that nesting levels count from outermost to innermost, and this is 241 /// the reverse of our iteration order where new inner levels are pushed at 242 /// the front of the stack. 243 SharingMapTy &getStackElemAtLevel(unsigned Level) { 244 assert(Level < getStackSize() && "no such stack element"); 245 return Stack.back().first[Level]; 246 } 247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 249 } 250 251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 252 253 /// Checks if the variable is a local for OpenMP region. 254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 255 256 /// Vector of previously declared requires directives 257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 258 /// omp_allocator_handle_t type. 259 QualType OMPAllocatorHandleT; 260 /// Expression for the predefined allocators. 261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 262 nullptr}; 263 /// Vector of previously encountered target directives 264 SmallVector<SourceLocation, 2> TargetLocations; 265 266 public: 267 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 268 269 /// Sets omp_allocator_handle_t type. 270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 271 /// Gets omp_allocator_handle_t type. 272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 273 /// Sets the given default allocator. 274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 275 Expr *Allocator) { 276 OMPPredefinedAllocators[AllocatorKind] = Allocator; 277 } 278 /// Returns the specified default allocator. 279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 280 return OMPPredefinedAllocators[AllocatorKind]; 281 } 282 283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 284 OpenMPClauseKind getClauseParsingMode() const { 285 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 286 return ClauseKindMode; 287 } 288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 289 290 bool isBodyComplete() const { 291 const SharingMapTy *Top = getTopOfStackOrNull(); 292 return Top && Top->BodyComplete; 293 } 294 void setBodyComplete() { 295 getTopOfStack().BodyComplete = true; 296 } 297 298 bool isForceVarCapturing() const { return ForceCapturing; } 299 void setForceVarCapturing(bool V) { ForceCapturing = V; } 300 301 void setForceCaptureByReferenceInTargetExecutable(bool V) { 302 ForceCaptureByReferenceInTargetExecutable = V; 303 } 304 bool isForceCaptureByReferenceInTargetExecutable() const { 305 return ForceCaptureByReferenceInTargetExecutable; 306 } 307 308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 309 Scope *CurScope, SourceLocation Loc) { 310 assert(!IgnoredStackElements && 311 "cannot change stack while ignoring elements"); 312 if (Stack.empty() || 313 Stack.back().second != CurrentNonCapturingFunctionScope) 314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 316 Stack.back().first.back().DefaultAttrLoc = Loc; 317 } 318 319 void pop() { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 assert(!Stack.back().first.empty() && 323 "Data-sharing attributes stack is empty!"); 324 Stack.back().first.pop_back(); 325 } 326 327 /// RAII object to temporarily leave the scope of a directive when we want to 328 /// logically operate in its parent. 329 class ParentDirectiveScope { 330 DSAStackTy &Self; 331 bool Active; 332 public: 333 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 334 : Self(Self), Active(false) { 335 if (Activate) 336 enable(); 337 } 338 ~ParentDirectiveScope() { disable(); } 339 void disable() { 340 if (Active) { 341 --Self.IgnoredStackElements; 342 Active = false; 343 } 344 } 345 void enable() { 346 if (!Active) { 347 ++Self.IgnoredStackElements; 348 Active = true; 349 } 350 } 351 }; 352 353 /// Marks that we're started loop parsing. 354 void loopInit() { 355 assert(isOpenMPLoopDirective(getCurrentDirective()) && 356 "Expected loop-based directive."); 357 getTopOfStack().LoopStart = true; 358 } 359 /// Start capturing of the variables in the loop context. 360 void loopStart() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = false; 364 } 365 /// true, if variables are captured, false otherwise. 366 bool isLoopStarted() const { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 return !getTopOfStack().LoopStart; 370 } 371 /// Marks (or clears) declaration as possibly loop counter. 372 void resetPossibleLoopCounter(const Decl *D = nullptr) { 373 getTopOfStack().PossiblyLoopCounter = 374 D ? D->getCanonicalDecl() : D; 375 } 376 /// Gets the possible loop counter decl. 377 const Decl *getPossiblyLoopCunter() const { 378 return getTopOfStack().PossiblyLoopCounter; 379 } 380 /// Start new OpenMP region stack in new non-capturing function. 381 void pushFunction() { 382 assert(!IgnoredStackElements && 383 "cannot change stack while ignoring elements"); 384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 385 assert(!isa<CapturingScopeInfo>(CurFnScope)); 386 CurrentNonCapturingFunctionScope = CurFnScope; 387 } 388 /// Pop region stack for non-capturing function. 389 void popFunction(const FunctionScopeInfo *OldFSI) { 390 assert(!IgnoredStackElements && 391 "cannot change stack while ignoring elements"); 392 if (!Stack.empty() && Stack.back().second == OldFSI) { 393 assert(Stack.back().first.empty()); 394 Stack.pop_back(); 395 } 396 CurrentNonCapturingFunctionScope = nullptr; 397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 398 if (!isa<CapturingScopeInfo>(FSI)) { 399 CurrentNonCapturingFunctionScope = FSI; 400 break; 401 } 402 } 403 } 404 405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 407 } 408 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 409 getCriticalWithHint(const DeclarationNameInfo &Name) const { 410 auto I = Criticals.find(Name.getAsString()); 411 if (I != Criticals.end()) 412 return I->second; 413 return std::make_pair(nullptr, llvm::APSInt()); 414 } 415 /// If 'aligned' declaration for given variable \a D was not seen yet, 416 /// add it and return NULL; otherwise return previous occurrence's expression 417 /// for diagnostics. 418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 419 420 /// Register specified variable as loop control variable. 421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 422 /// Check if the specified variable is a loop control variable for 423 /// current region. 424 /// \return The index of the loop control variable in the list of associated 425 /// for-loops (from outer to inner). 426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 427 /// Check if the specified variable is a loop control variable for 428 /// parent region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 432 /// Get the loop control variable for the I-th loop (or nullptr) in 433 /// parent directive. 434 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 435 436 /// Adds explicit data sharing attribute to the specified declaration. 437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 438 DeclRefExpr *PrivateCopy = nullptr); 439 440 /// Adds additional information for the reduction items with the reduction id 441 /// represented as an operator. 442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 443 BinaryOperatorKind BOK); 444 /// Adds additional information for the reduction items with the reduction id 445 /// represented as reduction identifier. 446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 447 const Expr *ReductionRef); 448 /// Returns the location and reduction operation from the innermost parent 449 /// region for the given \p D. 450 const DSAVarData 451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 452 BinaryOperatorKind &BOK, 453 Expr *&TaskgroupDescriptor) const; 454 /// Returns the location and reduction operation from the innermost parent 455 /// region for the given \p D. 456 const DSAVarData 457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 458 const Expr *&ReductionRef, 459 Expr *&TaskgroupDescriptor) const; 460 /// Return reduction reference expression for the current taskgroup. 461 Expr *getTaskgroupReductionRef() const { 462 assert(getTopOfStack().Directive == OMPD_taskgroup && 463 "taskgroup reference expression requested for non taskgroup " 464 "directive."); 465 return getTopOfStack().TaskgroupReductionRef; 466 } 467 /// Checks if the given \p VD declaration is actually a taskgroup reduction 468 /// descriptor variable at the \p Level of OpenMP regions. 469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 470 return getStackElemAtLevel(Level).TaskgroupReductionRef && 471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 472 ->getDecl() == VD; 473 } 474 475 /// Returns data sharing attributes from top of the stack for the 476 /// specified declaration. 477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 478 /// Returns data-sharing attributes for the specified declaration. 479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 480 /// Checks if the specified variables has data-sharing attributes which 481 /// match specified \a CPred predicate in any directive which matches \a DPred 482 /// predicate. 483 const DSAVarData 484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 486 bool FromParent) const; 487 /// Checks if the specified variables has data-sharing attributes which 488 /// match specified \a CPred predicate in any innermost directive which 489 /// matches \a DPred predicate. 490 const DSAVarData 491 hasInnermostDSA(ValueDecl *D, 492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 494 bool FromParent) const; 495 /// Checks if the specified variables has explicit data-sharing 496 /// attributes which match specified \a CPred predicate at the specified 497 /// OpenMP region. 498 bool hasExplicitDSA(const ValueDecl *D, 499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 500 unsigned Level, bool NotLastprivate = false) const; 501 502 /// Returns true if the directive at level \Level matches in the 503 /// specified \a DPred predicate. 504 bool hasExplicitDirective( 505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 506 unsigned Level) const; 507 508 /// Finds a directive which matches specified \a DPred predicate. 509 bool hasDirective( 510 const llvm::function_ref<bool( 511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 512 DPred, 513 bool FromParent) const; 514 515 /// Returns currently analyzed directive. 516 OpenMPDirectiveKind getCurrentDirective() const { 517 const SharingMapTy *Top = getTopOfStackOrNull(); 518 return Top ? Top->Directive : OMPD_unknown; 519 } 520 /// Returns directive kind at specified level. 521 OpenMPDirectiveKind getDirective(unsigned Level) const { 522 assert(!isStackEmpty() && "No directive at specified level."); 523 return getStackElemAtLevel(Level).Directive; 524 } 525 /// Returns the capture region at the specified level. 526 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 527 unsigned OpenMPCaptureLevel) const { 528 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 529 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 530 return CaptureRegions[OpenMPCaptureLevel]; 531 } 532 /// Returns parent directive. 533 OpenMPDirectiveKind getParentDirective() const { 534 const SharingMapTy *Parent = getSecondOnStackOrNull(); 535 return Parent ? Parent->Directive : OMPD_unknown; 536 } 537 538 /// Add requires decl to internal vector 539 void addRequiresDecl(OMPRequiresDecl *RD) { 540 RequiresDecls.push_back(RD); 541 } 542 543 /// Checks if the defined 'requires' directive has specified type of clause. 544 template <typename ClauseType> 545 bool hasRequiresDeclWithClause() { 546 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 547 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 548 return isa<ClauseType>(C); 549 }); 550 }); 551 } 552 553 /// Checks for a duplicate clause amongst previously declared requires 554 /// directives 555 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 556 bool IsDuplicate = false; 557 for (OMPClause *CNew : ClauseList) { 558 for (const OMPRequiresDecl *D : RequiresDecls) { 559 for (const OMPClause *CPrev : D->clauselists()) { 560 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 561 SemaRef.Diag(CNew->getBeginLoc(), 562 diag::err_omp_requires_clause_redeclaration) 563 << getOpenMPClauseName(CNew->getClauseKind()); 564 SemaRef.Diag(CPrev->getBeginLoc(), 565 diag::note_omp_requires_previous_clause) 566 << getOpenMPClauseName(CPrev->getClauseKind()); 567 IsDuplicate = true; 568 } 569 } 570 } 571 } 572 return IsDuplicate; 573 } 574 575 /// Add location of previously encountered target to internal vector 576 void addTargetDirLocation(SourceLocation LocStart) { 577 TargetLocations.push_back(LocStart); 578 } 579 580 // Return previously encountered target region locations. 581 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 582 return TargetLocations; 583 } 584 585 /// Set default data sharing attribute to none. 586 void setDefaultDSANone(SourceLocation Loc) { 587 getTopOfStack().DefaultAttr = DSA_none; 588 getTopOfStack().DefaultAttrLoc = Loc; 589 } 590 /// Set default data sharing attribute to shared. 591 void setDefaultDSAShared(SourceLocation Loc) { 592 getTopOfStack().DefaultAttr = DSA_shared; 593 getTopOfStack().DefaultAttrLoc = Loc; 594 } 595 /// Set default data mapping attribute to 'tofrom:scalar'. 596 void setDefaultDMAToFromScalar(SourceLocation Loc) { 597 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 598 getTopOfStack().DefaultMapAttrLoc = Loc; 599 } 600 601 DefaultDataSharingAttributes getDefaultDSA() const { 602 return isStackEmpty() ? DSA_unspecified 603 : getTopOfStack().DefaultAttr; 604 } 605 SourceLocation getDefaultDSALocation() const { 606 return isStackEmpty() ? SourceLocation() 607 : getTopOfStack().DefaultAttrLoc; 608 } 609 DefaultMapAttributes getDefaultDMA() const { 610 return isStackEmpty() ? DMA_unspecified 611 : getTopOfStack().DefaultMapAttr; 612 } 613 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 614 return getStackElemAtLevel(Level).DefaultMapAttr; 615 } 616 SourceLocation getDefaultDMALocation() const { 617 return isStackEmpty() ? SourceLocation() 618 : getTopOfStack().DefaultMapAttrLoc; 619 } 620 621 /// Checks if the specified variable is a threadprivate. 622 bool isThreadPrivate(VarDecl *D) { 623 const DSAVarData DVar = getTopDSA(D, false); 624 return isOpenMPThreadPrivate(DVar.CKind); 625 } 626 627 /// Marks current region as ordered (it has an 'ordered' clause). 628 void setOrderedRegion(bool IsOrdered, const Expr *Param, 629 OMPOrderedClause *Clause) { 630 if (IsOrdered) 631 getTopOfStack().OrderedRegion.emplace(Param, Clause); 632 else 633 getTopOfStack().OrderedRegion.reset(); 634 } 635 /// Returns true, if region is ordered (has associated 'ordered' clause), 636 /// false - otherwise. 637 bool isOrderedRegion() const { 638 if (const SharingMapTy *Top = getTopOfStackOrNull()) 639 return Top->OrderedRegion.hasValue(); 640 return false; 641 } 642 /// Returns optional parameter for the ordered region. 643 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 644 if (const SharingMapTy *Top = getTopOfStackOrNull()) 645 if (Top->OrderedRegion.hasValue()) 646 return Top->OrderedRegion.getValue(); 647 return std::make_pair(nullptr, nullptr); 648 } 649 /// Returns true, if parent region is ordered (has associated 650 /// 'ordered' clause), false - otherwise. 651 bool isParentOrderedRegion() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 return Parent->OrderedRegion.hasValue(); 654 return false; 655 } 656 /// Returns optional parameter for the ordered region. 657 std::pair<const Expr *, OMPOrderedClause *> 658 getParentOrderedRegionParam() const { 659 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 660 if (Parent->OrderedRegion.hasValue()) 661 return Parent->OrderedRegion.getValue(); 662 return std::make_pair(nullptr, nullptr); 663 } 664 /// Marks current region as nowait (it has a 'nowait' clause). 665 void setNowaitRegion(bool IsNowait = true) { 666 getTopOfStack().NowaitRegion = IsNowait; 667 } 668 /// Returns true, if parent region is nowait (has associated 669 /// 'nowait' clause), false - otherwise. 670 bool isParentNowaitRegion() const { 671 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 672 return Parent->NowaitRegion; 673 return false; 674 } 675 /// Marks parent region as cancel region. 676 void setParentCancelRegion(bool Cancel = true) { 677 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 678 Parent->CancelRegion |= Cancel; 679 } 680 /// Return true if current region has inner cancel construct. 681 bool isCancelRegion() const { 682 const SharingMapTy *Top = getTopOfStackOrNull(); 683 return Top ? Top->CancelRegion : false; 684 } 685 686 /// Set collapse value for the region. 687 void setAssociatedLoops(unsigned Val) { 688 getTopOfStack().AssociatedLoops = Val; 689 if (Val > 1) 690 getTopOfStack().HasMutipleLoops = true; 691 } 692 /// Return collapse value for region. 693 unsigned getAssociatedLoops() const { 694 const SharingMapTy *Top = getTopOfStackOrNull(); 695 return Top ? Top->AssociatedLoops : 0; 696 } 697 /// Returns true if the construct is associated with multiple loops. 698 bool hasMutipleLoops() const { 699 const SharingMapTy *Top = getTopOfStackOrNull(); 700 return Top ? Top->HasMutipleLoops : false; 701 } 702 703 /// Marks current target region as one with closely nested teams 704 /// region. 705 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 706 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 707 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 708 } 709 /// Returns true, if current region has closely nested teams region. 710 bool hasInnerTeamsRegion() const { 711 return getInnerTeamsRegionLoc().isValid(); 712 } 713 /// Returns location of the nested teams region (if any). 714 SourceLocation getInnerTeamsRegionLoc() const { 715 const SharingMapTy *Top = getTopOfStackOrNull(); 716 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 717 } 718 719 Scope *getCurScope() const { 720 const SharingMapTy *Top = getTopOfStackOrNull(); 721 return Top ? Top->CurScope : nullptr; 722 } 723 SourceLocation getConstructLoc() const { 724 const SharingMapTy *Top = getTopOfStackOrNull(); 725 return Top ? Top->ConstructLoc : SourceLocation(); 726 } 727 728 /// Do the check specified in \a Check to all component lists and return true 729 /// if any issue is found. 730 bool checkMappableExprComponentListsForDecl( 731 const ValueDecl *VD, bool CurrentRegionOnly, 732 const llvm::function_ref< 733 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 734 OpenMPClauseKind)> 735 Check) const { 736 if (isStackEmpty()) 737 return false; 738 auto SI = begin(); 739 auto SE = end(); 740 741 if (SI == SE) 742 return false; 743 744 if (CurrentRegionOnly) 745 SE = std::next(SI); 746 else 747 std::advance(SI, 1); 748 749 for (; SI != SE; ++SI) { 750 auto MI = SI->MappedExprComponents.find(VD); 751 if (MI != SI->MappedExprComponents.end()) 752 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 753 MI->second.Components) 754 if (Check(L, MI->second.Kind)) 755 return true; 756 } 757 return false; 758 } 759 760 /// Do the check specified in \a Check to all component lists at a given level 761 /// and return true if any issue is found. 762 bool checkMappableExprComponentListsForDeclAtLevel( 763 const ValueDecl *VD, unsigned Level, 764 const llvm::function_ref< 765 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 766 OpenMPClauseKind)> 767 Check) const { 768 if (getStackSize() <= Level) 769 return false; 770 771 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 772 auto MI = StackElem.MappedExprComponents.find(VD); 773 if (MI != StackElem.MappedExprComponents.end()) 774 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 775 MI->second.Components) 776 if (Check(L, MI->second.Kind)) 777 return true; 778 return false; 779 } 780 781 /// Create a new mappable expression component list associated with a given 782 /// declaration and initialize it with the provided list of components. 783 void addMappableExpressionComponents( 784 const ValueDecl *VD, 785 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 786 OpenMPClauseKind WhereFoundClauseKind) { 787 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 788 // Create new entry and append the new components there. 789 MEC.Components.resize(MEC.Components.size() + 1); 790 MEC.Components.back().append(Components.begin(), Components.end()); 791 MEC.Kind = WhereFoundClauseKind; 792 } 793 794 unsigned getNestingLevel() const { 795 assert(!isStackEmpty()); 796 return getStackSize() - 1; 797 } 798 void addDoacrossDependClause(OMPDependClause *C, 799 const OperatorOffsetTy &OpsOffs) { 800 SharingMapTy *Parent = getSecondOnStackOrNull(); 801 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 802 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 803 } 804 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 805 getDoacrossDependClauses() const { 806 const SharingMapTy &StackElem = getTopOfStack(); 807 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 808 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 809 return llvm::make_range(Ref.begin(), Ref.end()); 810 } 811 return llvm::make_range(StackElem.DoacrossDepends.end(), 812 StackElem.DoacrossDepends.end()); 813 } 814 815 // Store types of classes which have been explicitly mapped 816 void addMappedClassesQualTypes(QualType QT) { 817 SharingMapTy &StackElem = getTopOfStack(); 818 StackElem.MappedClassesQualTypes.insert(QT); 819 } 820 821 // Return set of mapped classes types 822 bool isClassPreviouslyMapped(QualType QT) const { 823 const SharingMapTy &StackElem = getTopOfStack(); 824 return StackElem.MappedClassesQualTypes.count(QT) != 0; 825 } 826 827 /// Adds global declare target to the parent target region. 828 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 829 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 830 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 831 "Expected declare target link global."); 832 for (auto &Elem : *this) { 833 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 834 Elem.DeclareTargetLinkVarDecls.push_back(E); 835 return; 836 } 837 } 838 } 839 840 /// Returns the list of globals with declare target link if current directive 841 /// is target. 842 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 843 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 844 "Expected target executable directive."); 845 return getTopOfStack().DeclareTargetLinkVarDecls; 846 } 847 }; 848 849 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 850 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 851 } 852 853 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 854 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 855 DKind == OMPD_unknown; 856 } 857 858 } // namespace 859 860 static const Expr *getExprAsWritten(const Expr *E) { 861 if (const auto *FE = dyn_cast<FullExpr>(E)) 862 E = FE->getSubExpr(); 863 864 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 865 E = MTE->GetTemporaryExpr(); 866 867 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 868 E = Binder->getSubExpr(); 869 870 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 871 E = ICE->getSubExprAsWritten(); 872 return E->IgnoreParens(); 873 } 874 875 static Expr *getExprAsWritten(Expr *E) { 876 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 877 } 878 879 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 880 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 881 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 882 D = ME->getMemberDecl(); 883 const auto *VD = dyn_cast<VarDecl>(D); 884 const auto *FD = dyn_cast<FieldDecl>(D); 885 if (VD != nullptr) { 886 VD = VD->getCanonicalDecl(); 887 D = VD; 888 } else { 889 assert(FD); 890 FD = FD->getCanonicalDecl(); 891 D = FD; 892 } 893 return D; 894 } 895 896 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 897 return const_cast<ValueDecl *>( 898 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 899 } 900 901 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 902 ValueDecl *D) const { 903 D = getCanonicalDecl(D); 904 auto *VD = dyn_cast<VarDecl>(D); 905 const auto *FD = dyn_cast<FieldDecl>(D); 906 DSAVarData DVar; 907 if (Iter == end()) { 908 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 909 // in a region but not in construct] 910 // File-scope or namespace-scope variables referenced in called routines 911 // in the region are shared unless they appear in a threadprivate 912 // directive. 913 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 914 DVar.CKind = OMPC_shared; 915 916 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 917 // in a region but not in construct] 918 // Variables with static storage duration that are declared in called 919 // routines in the region are shared. 920 if (VD && VD->hasGlobalStorage()) 921 DVar.CKind = OMPC_shared; 922 923 // Non-static data members are shared by default. 924 if (FD) 925 DVar.CKind = OMPC_shared; 926 927 return DVar; 928 } 929 930 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 931 // in a Construct, C/C++, predetermined, p.1] 932 // Variables with automatic storage duration that are declared in a scope 933 // inside the construct are private. 934 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 935 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 936 DVar.CKind = OMPC_private; 937 return DVar; 938 } 939 940 DVar.DKind = Iter->Directive; 941 // Explicitly specified attributes and local variables with predetermined 942 // attributes. 943 if (Iter->SharingMap.count(D)) { 944 const DSAInfo &Data = Iter->SharingMap.lookup(D); 945 DVar.RefExpr = Data.RefExpr.getPointer(); 946 DVar.PrivateCopy = Data.PrivateCopy; 947 DVar.CKind = Data.Attributes; 948 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 949 return DVar; 950 } 951 952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 953 // in a Construct, C/C++, implicitly determined, p.1] 954 // In a parallel or task construct, the data-sharing attributes of these 955 // variables are determined by the default clause, if present. 956 switch (Iter->DefaultAttr) { 957 case DSA_shared: 958 DVar.CKind = OMPC_shared; 959 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 960 return DVar; 961 case DSA_none: 962 return DVar; 963 case DSA_unspecified: 964 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 965 // in a Construct, implicitly determined, p.2] 966 // In a parallel construct, if no default clause is present, these 967 // variables are shared. 968 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 969 if (isOpenMPParallelDirective(DVar.DKind) || 970 isOpenMPTeamsDirective(DVar.DKind)) { 971 DVar.CKind = OMPC_shared; 972 return DVar; 973 } 974 975 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 976 // in a Construct, implicitly determined, p.4] 977 // In a task construct, if no default clause is present, a variable that in 978 // the enclosing context is determined to be shared by all implicit tasks 979 // bound to the current team is shared. 980 if (isOpenMPTaskingDirective(DVar.DKind)) { 981 DSAVarData DVarTemp; 982 const_iterator I = Iter, E = end(); 983 do { 984 ++I; 985 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 986 // Referenced in a Construct, implicitly determined, p.6] 987 // In a task construct, if no default clause is present, a variable 988 // whose data-sharing attribute is not determined by the rules above is 989 // firstprivate. 990 DVarTemp = getDSA(I, D); 991 if (DVarTemp.CKind != OMPC_shared) { 992 DVar.RefExpr = nullptr; 993 DVar.CKind = OMPC_firstprivate; 994 return DVar; 995 } 996 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 997 DVar.CKind = 998 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 999 return DVar; 1000 } 1001 } 1002 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1003 // in a Construct, implicitly determined, p.3] 1004 // For constructs other than task, if no default clause is present, these 1005 // variables inherit their data-sharing attributes from the enclosing 1006 // context. 1007 return getDSA(++Iter, D); 1008 } 1009 1010 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1011 const Expr *NewDE) { 1012 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1013 D = getCanonicalDecl(D); 1014 SharingMapTy &StackElem = getTopOfStack(); 1015 auto It = StackElem.AlignedMap.find(D); 1016 if (It == StackElem.AlignedMap.end()) { 1017 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1018 StackElem.AlignedMap[D] = NewDE; 1019 return nullptr; 1020 } 1021 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1022 return It->second; 1023 } 1024 1025 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1026 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1027 D = getCanonicalDecl(D); 1028 SharingMapTy &StackElem = getTopOfStack(); 1029 StackElem.LCVMap.try_emplace( 1030 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1031 } 1032 1033 const DSAStackTy::LCDeclInfo 1034 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1035 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1036 D = getCanonicalDecl(D); 1037 const SharingMapTy &StackElem = getTopOfStack(); 1038 auto It = StackElem.LCVMap.find(D); 1039 if (It != StackElem.LCVMap.end()) 1040 return It->second; 1041 return {0, nullptr}; 1042 } 1043 1044 const DSAStackTy::LCDeclInfo 1045 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1046 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1047 assert(Parent && "Data-sharing attributes stack is empty"); 1048 D = getCanonicalDecl(D); 1049 auto It = Parent->LCVMap.find(D); 1050 if (It != Parent->LCVMap.end()) 1051 return It->second; 1052 return {0, nullptr}; 1053 } 1054 1055 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1056 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1057 assert(Parent && "Data-sharing attributes stack is empty"); 1058 if (Parent->LCVMap.size() < I) 1059 return nullptr; 1060 for (const auto &Pair : Parent->LCVMap) 1061 if (Pair.second.first == I) 1062 return Pair.first; 1063 return nullptr; 1064 } 1065 1066 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1067 DeclRefExpr *PrivateCopy) { 1068 D = getCanonicalDecl(D); 1069 if (A == OMPC_threadprivate) { 1070 DSAInfo &Data = Threadprivates[D]; 1071 Data.Attributes = A; 1072 Data.RefExpr.setPointer(E); 1073 Data.PrivateCopy = nullptr; 1074 } else { 1075 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1076 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1077 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1078 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1079 (isLoopControlVariable(D).first && A == OMPC_private)); 1080 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1081 Data.RefExpr.setInt(/*IntVal=*/true); 1082 return; 1083 } 1084 const bool IsLastprivate = 1085 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1086 Data.Attributes = A; 1087 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1088 Data.PrivateCopy = PrivateCopy; 1089 if (PrivateCopy) { 1090 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1091 Data.Attributes = A; 1092 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1093 Data.PrivateCopy = nullptr; 1094 } 1095 } 1096 } 1097 1098 /// Build a variable declaration for OpenMP loop iteration variable. 1099 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1100 StringRef Name, const AttrVec *Attrs = nullptr, 1101 DeclRefExpr *OrigRef = nullptr) { 1102 DeclContext *DC = SemaRef.CurContext; 1103 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1104 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1105 auto *Decl = 1106 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1107 if (Attrs) { 1108 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1109 I != E; ++I) 1110 Decl->addAttr(*I); 1111 } 1112 Decl->setImplicit(); 1113 if (OrigRef) { 1114 Decl->addAttr( 1115 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1116 } 1117 return Decl; 1118 } 1119 1120 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1121 SourceLocation Loc, 1122 bool RefersToCapture = false) { 1123 D->setReferenced(); 1124 D->markUsed(S.Context); 1125 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1126 SourceLocation(), D, RefersToCapture, Loc, Ty, 1127 VK_LValue); 1128 } 1129 1130 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1131 BinaryOperatorKind BOK) { 1132 D = getCanonicalDecl(D); 1133 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1134 assert( 1135 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1136 "Additional reduction info may be specified only for reduction items."); 1137 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1138 assert(ReductionData.ReductionRange.isInvalid() && 1139 getTopOfStack().Directive == OMPD_taskgroup && 1140 "Additional reduction info may be specified only once for reduction " 1141 "items."); 1142 ReductionData.set(BOK, SR); 1143 Expr *&TaskgroupReductionRef = 1144 getTopOfStack().TaskgroupReductionRef; 1145 if (!TaskgroupReductionRef) { 1146 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1147 SemaRef.Context.VoidPtrTy, ".task_red."); 1148 TaskgroupReductionRef = 1149 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1150 } 1151 } 1152 1153 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1154 const Expr *ReductionRef) { 1155 D = getCanonicalDecl(D); 1156 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1157 assert( 1158 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1159 "Additional reduction info may be specified only for reduction items."); 1160 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1161 assert(ReductionData.ReductionRange.isInvalid() && 1162 getTopOfStack().Directive == OMPD_taskgroup && 1163 "Additional reduction info may be specified only once for reduction " 1164 "items."); 1165 ReductionData.set(ReductionRef, SR); 1166 Expr *&TaskgroupReductionRef = 1167 getTopOfStack().TaskgroupReductionRef; 1168 if (!TaskgroupReductionRef) { 1169 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1170 SemaRef.Context.VoidPtrTy, ".task_red."); 1171 TaskgroupReductionRef = 1172 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1173 } 1174 } 1175 1176 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1177 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1178 Expr *&TaskgroupDescriptor) const { 1179 D = getCanonicalDecl(D); 1180 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1181 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1182 const DSAInfo &Data = I->SharingMap.lookup(D); 1183 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1184 continue; 1185 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1186 if (!ReductionData.ReductionOp || 1187 ReductionData.ReductionOp.is<const Expr *>()) 1188 return DSAVarData(); 1189 SR = ReductionData.ReductionRange; 1190 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1191 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1192 "expression for the descriptor is not " 1193 "set."); 1194 TaskgroupDescriptor = I->TaskgroupReductionRef; 1195 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1196 Data.PrivateCopy, I->DefaultAttrLoc); 1197 } 1198 return DSAVarData(); 1199 } 1200 1201 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1202 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1203 Expr *&TaskgroupDescriptor) const { 1204 D = getCanonicalDecl(D); 1205 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1206 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1207 const DSAInfo &Data = I->SharingMap.lookup(D); 1208 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1209 continue; 1210 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1211 if (!ReductionData.ReductionOp || 1212 !ReductionData.ReductionOp.is<const Expr *>()) 1213 return DSAVarData(); 1214 SR = ReductionData.ReductionRange; 1215 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1216 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1217 "expression for the descriptor is not " 1218 "set."); 1219 TaskgroupDescriptor = I->TaskgroupReductionRef; 1220 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1221 Data.PrivateCopy, I->DefaultAttrLoc); 1222 } 1223 return DSAVarData(); 1224 } 1225 1226 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1227 D = D->getCanonicalDecl(); 1228 for (const_iterator E = end(); I != E; ++I) { 1229 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1230 isOpenMPTargetExecutionDirective(I->Directive)) { 1231 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1232 Scope *CurScope = getCurScope(); 1233 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1234 CurScope = CurScope->getParent(); 1235 return CurScope != TopScope; 1236 } 1237 } 1238 return false; 1239 } 1240 1241 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1242 bool AcceptIfMutable = true, 1243 bool *IsClassType = nullptr) { 1244 ASTContext &Context = SemaRef.getASTContext(); 1245 Type = Type.getNonReferenceType().getCanonicalType(); 1246 bool IsConstant = Type.isConstant(Context); 1247 Type = Context.getBaseElementType(Type); 1248 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1249 ? Type->getAsCXXRecordDecl() 1250 : nullptr; 1251 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1252 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1253 RD = CTD->getTemplatedDecl(); 1254 if (IsClassType) 1255 *IsClassType = RD; 1256 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1257 RD->hasDefinition() && RD->hasMutableFields()); 1258 } 1259 1260 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1261 QualType Type, OpenMPClauseKind CKind, 1262 SourceLocation ELoc, 1263 bool AcceptIfMutable = true, 1264 bool ListItemNotVar = false) { 1265 ASTContext &Context = SemaRef.getASTContext(); 1266 bool IsClassType; 1267 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1268 unsigned Diag = ListItemNotVar 1269 ? diag::err_omp_const_list_item 1270 : IsClassType ? diag::err_omp_const_not_mutable_variable 1271 : diag::err_omp_const_variable; 1272 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1273 if (!ListItemNotVar && D) { 1274 const VarDecl *VD = dyn_cast<VarDecl>(D); 1275 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1276 VarDecl::DeclarationOnly; 1277 SemaRef.Diag(D->getLocation(), 1278 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1279 << D; 1280 } 1281 return true; 1282 } 1283 return false; 1284 } 1285 1286 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1287 bool FromParent) { 1288 D = getCanonicalDecl(D); 1289 DSAVarData DVar; 1290 1291 auto *VD = dyn_cast<VarDecl>(D); 1292 auto TI = Threadprivates.find(D); 1293 if (TI != Threadprivates.end()) { 1294 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1295 DVar.CKind = OMPC_threadprivate; 1296 return DVar; 1297 } 1298 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1299 DVar.RefExpr = buildDeclRefExpr( 1300 SemaRef, VD, D->getType().getNonReferenceType(), 1301 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1302 DVar.CKind = OMPC_threadprivate; 1303 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1304 return DVar; 1305 } 1306 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1307 // in a Construct, C/C++, predetermined, p.1] 1308 // Variables appearing in threadprivate directives are threadprivate. 1309 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1310 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1311 SemaRef.getLangOpts().OpenMPUseTLS && 1312 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1313 (VD && VD->getStorageClass() == SC_Register && 1314 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1315 DVar.RefExpr = buildDeclRefExpr( 1316 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1317 DVar.CKind = OMPC_threadprivate; 1318 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1319 return DVar; 1320 } 1321 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1322 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1323 !isLoopControlVariable(D).first) { 1324 const_iterator IterTarget = 1325 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1326 return isOpenMPTargetExecutionDirective(Data.Directive); 1327 }); 1328 if (IterTarget != end()) { 1329 const_iterator ParentIterTarget = IterTarget + 1; 1330 for (const_iterator Iter = begin(); 1331 Iter != ParentIterTarget; ++Iter) { 1332 if (isOpenMPLocal(VD, Iter)) { 1333 DVar.RefExpr = 1334 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1335 D->getLocation()); 1336 DVar.CKind = OMPC_threadprivate; 1337 return DVar; 1338 } 1339 } 1340 if (!isClauseParsingMode() || IterTarget != begin()) { 1341 auto DSAIter = IterTarget->SharingMap.find(D); 1342 if (DSAIter != IterTarget->SharingMap.end() && 1343 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1344 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1345 DVar.CKind = OMPC_threadprivate; 1346 return DVar; 1347 } 1348 const_iterator End = end(); 1349 if (!SemaRef.isOpenMPCapturedByRef( 1350 D, std::distance(ParentIterTarget, End), 1351 /*OpenMPCaptureLevel=*/0)) { 1352 DVar.RefExpr = 1353 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1354 IterTarget->ConstructLoc); 1355 DVar.CKind = OMPC_threadprivate; 1356 return DVar; 1357 } 1358 } 1359 } 1360 } 1361 1362 if (isStackEmpty()) 1363 // Not in OpenMP execution region and top scope was already checked. 1364 return DVar; 1365 1366 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1367 // in a Construct, C/C++, predetermined, p.4] 1368 // Static data members are shared. 1369 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1370 // in a Construct, C/C++, predetermined, p.7] 1371 // Variables with static storage duration that are declared in a scope 1372 // inside the construct are shared. 1373 if (VD && VD->isStaticDataMember()) { 1374 // Check for explicitly specified attributes. 1375 const_iterator I = begin(); 1376 const_iterator EndI = end(); 1377 if (FromParent && I != EndI) 1378 ++I; 1379 auto It = I->SharingMap.find(D); 1380 if (It != I->SharingMap.end()) { 1381 const DSAInfo &Data = It->getSecond(); 1382 DVar.RefExpr = Data.RefExpr.getPointer(); 1383 DVar.PrivateCopy = Data.PrivateCopy; 1384 DVar.CKind = Data.Attributes; 1385 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1386 DVar.DKind = I->Directive; 1387 return DVar; 1388 } 1389 1390 DVar.CKind = OMPC_shared; 1391 return DVar; 1392 } 1393 1394 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1395 // The predetermined shared attribute for const-qualified types having no 1396 // mutable members was removed after OpenMP 3.1. 1397 if (SemaRef.LangOpts.OpenMP <= 31) { 1398 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1399 // in a Construct, C/C++, predetermined, p.6] 1400 // Variables with const qualified type having no mutable member are 1401 // shared. 1402 if (isConstNotMutableType(SemaRef, D->getType())) { 1403 // Variables with const-qualified type having no mutable member may be 1404 // listed in a firstprivate clause, even if they are static data members. 1405 DSAVarData DVarTemp = hasInnermostDSA( 1406 D, 1407 [](OpenMPClauseKind C) { 1408 return C == OMPC_firstprivate || C == OMPC_shared; 1409 }, 1410 MatchesAlways, FromParent); 1411 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1412 return DVarTemp; 1413 1414 DVar.CKind = OMPC_shared; 1415 return DVar; 1416 } 1417 } 1418 1419 // Explicitly specified attributes and local variables with predetermined 1420 // attributes. 1421 const_iterator I = begin(); 1422 const_iterator EndI = end(); 1423 if (FromParent && I != EndI) 1424 ++I; 1425 auto It = I->SharingMap.find(D); 1426 if (It != I->SharingMap.end()) { 1427 const DSAInfo &Data = It->getSecond(); 1428 DVar.RefExpr = Data.RefExpr.getPointer(); 1429 DVar.PrivateCopy = Data.PrivateCopy; 1430 DVar.CKind = Data.Attributes; 1431 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1432 DVar.DKind = I->Directive; 1433 } 1434 1435 return DVar; 1436 } 1437 1438 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1439 bool FromParent) const { 1440 if (isStackEmpty()) { 1441 const_iterator I; 1442 return getDSA(I, D); 1443 } 1444 D = getCanonicalDecl(D); 1445 const_iterator StartI = begin(); 1446 const_iterator EndI = end(); 1447 if (FromParent && StartI != EndI) 1448 ++StartI; 1449 return getDSA(StartI, D); 1450 } 1451 1452 const DSAStackTy::DSAVarData 1453 DSAStackTy::hasDSA(ValueDecl *D, 1454 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1455 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1456 bool FromParent) const { 1457 if (isStackEmpty()) 1458 return {}; 1459 D = getCanonicalDecl(D); 1460 const_iterator I = begin(); 1461 const_iterator EndI = end(); 1462 if (FromParent && I != EndI) 1463 ++I; 1464 for (; I != EndI; ++I) { 1465 if (!DPred(I->Directive) && 1466 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1467 continue; 1468 const_iterator NewI = I; 1469 DSAVarData DVar = getDSA(NewI, D); 1470 if (I == NewI && CPred(DVar.CKind)) 1471 return DVar; 1472 } 1473 return {}; 1474 } 1475 1476 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1477 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1478 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1479 bool FromParent) const { 1480 if (isStackEmpty()) 1481 return {}; 1482 D = getCanonicalDecl(D); 1483 const_iterator StartI = begin(); 1484 const_iterator EndI = end(); 1485 if (FromParent && StartI != EndI) 1486 ++StartI; 1487 if (StartI == EndI || !DPred(StartI->Directive)) 1488 return {}; 1489 const_iterator NewI = StartI; 1490 DSAVarData DVar = getDSA(NewI, D); 1491 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1492 } 1493 1494 bool DSAStackTy::hasExplicitDSA( 1495 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1496 unsigned Level, bool NotLastprivate) const { 1497 if (getStackSize() <= Level) 1498 return false; 1499 D = getCanonicalDecl(D); 1500 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1501 auto I = StackElem.SharingMap.find(D); 1502 if (I != StackElem.SharingMap.end() && 1503 I->getSecond().RefExpr.getPointer() && 1504 CPred(I->getSecond().Attributes) && 1505 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1506 return true; 1507 // Check predetermined rules for the loop control variables. 1508 auto LI = StackElem.LCVMap.find(D); 1509 if (LI != StackElem.LCVMap.end()) 1510 return CPred(OMPC_private); 1511 return false; 1512 } 1513 1514 bool DSAStackTy::hasExplicitDirective( 1515 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1516 unsigned Level) const { 1517 if (getStackSize() <= Level) 1518 return false; 1519 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1520 return DPred(StackElem.Directive); 1521 } 1522 1523 bool DSAStackTy::hasDirective( 1524 const llvm::function_ref<bool(OpenMPDirectiveKind, 1525 const DeclarationNameInfo &, SourceLocation)> 1526 DPred, 1527 bool FromParent) const { 1528 // We look only in the enclosing region. 1529 size_t Skip = FromParent ? 2 : 1; 1530 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1531 I != E; ++I) { 1532 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1533 return true; 1534 } 1535 return false; 1536 } 1537 1538 void Sema::InitDataSharingAttributesStack() { 1539 VarDataSharingAttributesStack = new DSAStackTy(*this); 1540 } 1541 1542 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1543 1544 void Sema::pushOpenMPFunctionRegion() { 1545 DSAStack->pushFunction(); 1546 } 1547 1548 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1549 DSAStack->popFunction(OldFSI); 1550 } 1551 1552 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1553 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1554 "Expected OpenMP device compilation."); 1555 return !S.isInOpenMPTargetExecutionDirective() && 1556 !S.isInOpenMPDeclareTargetContext(); 1557 } 1558 1559 namespace { 1560 /// Status of the function emission on the host/device. 1561 enum class FunctionEmissionStatus { 1562 Emitted, 1563 Discarded, 1564 Unknown, 1565 }; 1566 } // anonymous namespace 1567 1568 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1569 unsigned DiagID) { 1570 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1571 "Expected OpenMP device compilation."); 1572 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1573 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1574 switch (FES) { 1575 case FunctionEmissionStatus::Emitted: 1576 Kind = DeviceDiagBuilder::K_Immediate; 1577 break; 1578 case FunctionEmissionStatus::Unknown: 1579 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1580 : DeviceDiagBuilder::K_Immediate; 1581 break; 1582 case FunctionEmissionStatus::TemplateDiscarded: 1583 case FunctionEmissionStatus::OMPDiscarded: 1584 Kind = DeviceDiagBuilder::K_Nop; 1585 break; 1586 case FunctionEmissionStatus::CUDADiscarded: 1587 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1588 break; 1589 } 1590 1591 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1592 } 1593 1594 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1595 unsigned DiagID) { 1596 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1597 "Expected OpenMP host compilation."); 1598 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1599 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1600 switch (FES) { 1601 case FunctionEmissionStatus::Emitted: 1602 Kind = DeviceDiagBuilder::K_Immediate; 1603 break; 1604 case FunctionEmissionStatus::Unknown: 1605 Kind = DeviceDiagBuilder::K_Deferred; 1606 break; 1607 case FunctionEmissionStatus::TemplateDiscarded: 1608 case FunctionEmissionStatus::OMPDiscarded: 1609 case FunctionEmissionStatus::CUDADiscarded: 1610 Kind = DeviceDiagBuilder::K_Nop; 1611 break; 1612 } 1613 1614 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1615 } 1616 1617 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1618 bool CheckForDelayedContext) { 1619 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1620 "Expected OpenMP device compilation."); 1621 assert(Callee && "Callee may not be null."); 1622 Callee = Callee->getMostRecentDecl(); 1623 FunctionDecl *Caller = getCurFunctionDecl(); 1624 1625 // host only function are not available on the device. 1626 if (Caller) { 1627 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1628 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1629 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1630 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1631 "CUDADiscarded unexpected in OpenMP device function check"); 1632 if ((CallerS == FunctionEmissionStatus::Emitted || 1633 (!isOpenMPDeviceDelayedContext(*this) && 1634 CallerS == FunctionEmissionStatus::Unknown)) && 1635 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1636 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1637 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1638 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1639 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1640 diag::note_omp_marked_device_type_here) 1641 << HostDevTy; 1642 return; 1643 } 1644 } 1645 // If the caller is known-emitted, mark the callee as known-emitted. 1646 // Otherwise, mark the call in our call graph so we can traverse it later. 1647 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1648 (!Caller && !CheckForDelayedContext) || 1649 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1650 markKnownEmitted(*this, Caller, Callee, Loc, 1651 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1652 return CheckForDelayedContext && 1653 S.getEmissionStatus(FD) == 1654 FunctionEmissionStatus::Emitted; 1655 }); 1656 else if (Caller) 1657 DeviceCallGraph[Caller].insert({Callee, Loc}); 1658 } 1659 1660 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1661 bool CheckCaller) { 1662 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1663 "Expected OpenMP host compilation."); 1664 assert(Callee && "Callee may not be null."); 1665 Callee = Callee->getMostRecentDecl(); 1666 FunctionDecl *Caller = getCurFunctionDecl(); 1667 1668 // device only function are not available on the host. 1669 if (Caller) { 1670 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1671 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1672 assert( 1673 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1674 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1675 "CUDADiscarded unexpected in OpenMP host function check"); 1676 if (CallerS == FunctionEmissionStatus::Emitted && 1677 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1678 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1679 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1680 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1681 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1682 diag::note_omp_marked_device_type_here) 1683 << NoHostDevTy; 1684 return; 1685 } 1686 } 1687 // If the caller is known-emitted, mark the callee as known-emitted. 1688 // Otherwise, mark the call in our call graph so we can traverse it later. 1689 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1690 if ((!CheckCaller && !Caller) || 1691 (Caller && 1692 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1693 markKnownEmitted( 1694 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1695 return CheckCaller && 1696 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1697 }); 1698 else if (Caller) 1699 DeviceCallGraph[Caller].insert({Callee, Loc}); 1700 } 1701 } 1702 1703 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1704 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1705 "OpenMP device compilation mode is expected."); 1706 QualType Ty = E->getType(); 1707 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1708 ((Ty->isFloat128Type() || 1709 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1710 !Context.getTargetInfo().hasFloat128Type()) || 1711 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1712 !Context.getTargetInfo().hasInt128Type())) 1713 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1714 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1715 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1716 } 1717 1718 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1719 unsigned OpenMPCaptureLevel) const { 1720 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1721 1722 ASTContext &Ctx = getASTContext(); 1723 bool IsByRef = true; 1724 1725 // Find the directive that is associated with the provided scope. 1726 D = cast<ValueDecl>(D->getCanonicalDecl()); 1727 QualType Ty = D->getType(); 1728 1729 bool IsVariableUsedInMapClause = false; 1730 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1731 // This table summarizes how a given variable should be passed to the device 1732 // given its type and the clauses where it appears. This table is based on 1733 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1734 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1735 // 1736 // ========================================================================= 1737 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1738 // | |(tofrom:scalar)| | pvt | | | | 1739 // ========================================================================= 1740 // | scl | | | | - | | bycopy| 1741 // | scl | | - | x | - | - | bycopy| 1742 // | scl | | x | - | - | - | null | 1743 // | scl | x | | | - | | byref | 1744 // | scl | x | - | x | - | - | bycopy| 1745 // | scl | x | x | - | - | - | null | 1746 // | scl | | - | - | - | x | byref | 1747 // | scl | x | - | - | - | x | byref | 1748 // 1749 // | agg | n.a. | | | - | | byref | 1750 // | agg | n.a. | - | x | - | - | byref | 1751 // | agg | n.a. | x | - | - | - | null | 1752 // | agg | n.a. | - | - | - | x | byref | 1753 // | agg | n.a. | - | - | - | x[] | byref | 1754 // 1755 // | ptr | n.a. | | | - | | bycopy| 1756 // | ptr | n.a. | - | x | - | - | bycopy| 1757 // | ptr | n.a. | x | - | - | - | null | 1758 // | ptr | n.a. | - | - | - | x | byref | 1759 // | ptr | n.a. | - | - | - | x[] | bycopy| 1760 // | ptr | n.a. | - | - | x | | bycopy| 1761 // | ptr | n.a. | - | - | x | x | bycopy| 1762 // | ptr | n.a. | - | - | x | x[] | bycopy| 1763 // ========================================================================= 1764 // Legend: 1765 // scl - scalar 1766 // ptr - pointer 1767 // agg - aggregate 1768 // x - applies 1769 // - - invalid in this combination 1770 // [] - mapped with an array section 1771 // byref - should be mapped by reference 1772 // byval - should be mapped by value 1773 // null - initialize a local variable to null on the device 1774 // 1775 // Observations: 1776 // - All scalar declarations that show up in a map clause have to be passed 1777 // by reference, because they may have been mapped in the enclosing data 1778 // environment. 1779 // - If the scalar value does not fit the size of uintptr, it has to be 1780 // passed by reference, regardless the result in the table above. 1781 // - For pointers mapped by value that have either an implicit map or an 1782 // array section, the runtime library may pass the NULL value to the 1783 // device instead of the value passed to it by the compiler. 1784 1785 if (Ty->isReferenceType()) 1786 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1787 1788 // Locate map clauses and see if the variable being captured is referred to 1789 // in any of those clauses. Here we only care about variables, not fields, 1790 // because fields are part of aggregates. 1791 bool IsVariableAssociatedWithSection = false; 1792 1793 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1794 D, Level, 1795 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1796 OMPClauseMappableExprCommon::MappableExprComponentListRef 1797 MapExprComponents, 1798 OpenMPClauseKind WhereFoundClauseKind) { 1799 // Only the map clause information influences how a variable is 1800 // captured. E.g. is_device_ptr does not require changing the default 1801 // behavior. 1802 if (WhereFoundClauseKind != OMPC_map) 1803 return false; 1804 1805 auto EI = MapExprComponents.rbegin(); 1806 auto EE = MapExprComponents.rend(); 1807 1808 assert(EI != EE && "Invalid map expression!"); 1809 1810 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1811 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1812 1813 ++EI; 1814 if (EI == EE) 1815 return false; 1816 1817 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1818 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1819 isa<MemberExpr>(EI->getAssociatedExpression())) { 1820 IsVariableAssociatedWithSection = true; 1821 // There is nothing more we need to know about this variable. 1822 return true; 1823 } 1824 1825 // Keep looking for more map info. 1826 return false; 1827 }); 1828 1829 if (IsVariableUsedInMapClause) { 1830 // If variable is identified in a map clause it is always captured by 1831 // reference except if it is a pointer that is dereferenced somehow. 1832 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1833 } else { 1834 // By default, all the data that has a scalar type is mapped by copy 1835 // (except for reduction variables). 1836 IsByRef = 1837 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1838 !Ty->isAnyPointerType()) || 1839 !Ty->isScalarType() || 1840 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1841 DSAStack->hasExplicitDSA( 1842 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1843 } 1844 } 1845 1846 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1847 IsByRef = 1848 ((IsVariableUsedInMapClause && 1849 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1850 OMPD_target) || 1851 !DSAStack->hasExplicitDSA( 1852 D, 1853 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1854 Level, /*NotLastprivate=*/true)) && 1855 // If the variable is artificial and must be captured by value - try to 1856 // capture by value. 1857 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1858 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1859 } 1860 1861 // When passing data by copy, we need to make sure it fits the uintptr size 1862 // and alignment, because the runtime library only deals with uintptr types. 1863 // If it does not fit the uintptr size, we need to pass the data by reference 1864 // instead. 1865 if (!IsByRef && 1866 (Ctx.getTypeSizeInChars(Ty) > 1867 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1868 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1869 IsByRef = true; 1870 } 1871 1872 return IsByRef; 1873 } 1874 1875 unsigned Sema::getOpenMPNestingLevel() const { 1876 assert(getLangOpts().OpenMP); 1877 return DSAStack->getNestingLevel(); 1878 } 1879 1880 bool Sema::isInOpenMPTargetExecutionDirective() const { 1881 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1882 !DSAStack->isClauseParsingMode()) || 1883 DSAStack->hasDirective( 1884 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1885 SourceLocation) -> bool { 1886 return isOpenMPTargetExecutionDirective(K); 1887 }, 1888 false); 1889 } 1890 1891 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1892 unsigned StopAt) { 1893 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1894 D = getCanonicalDecl(D); 1895 1896 // If we want to determine whether the variable should be captured from the 1897 // perspective of the current capturing scope, and we've already left all the 1898 // capturing scopes of the top directive on the stack, check from the 1899 // perspective of its parent directive (if any) instead. 1900 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1901 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1902 1903 // If we are attempting to capture a global variable in a directive with 1904 // 'target' we return true so that this global is also mapped to the device. 1905 // 1906 auto *VD = dyn_cast<VarDecl>(D); 1907 if (VD && !VD->hasLocalStorage() && 1908 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1909 if (isInOpenMPDeclareTargetContext()) { 1910 // Try to mark variable as declare target if it is used in capturing 1911 // regions. 1912 if (LangOpts.OpenMP <= 45 && 1913 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1914 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1915 return nullptr; 1916 } else if (isInOpenMPTargetExecutionDirective()) { 1917 // If the declaration is enclosed in a 'declare target' directive, 1918 // then it should not be captured. 1919 // 1920 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1921 return nullptr; 1922 return VD; 1923 } 1924 } 1925 1926 if (CheckScopeInfo) { 1927 bool OpenMPFound = false; 1928 for (unsigned I = StopAt + 1; I > 0; --I) { 1929 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1930 if(!isa<CapturingScopeInfo>(FSI)) 1931 return nullptr; 1932 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1933 if (RSI->CapRegionKind == CR_OpenMP) { 1934 OpenMPFound = true; 1935 break; 1936 } 1937 } 1938 if (!OpenMPFound) 1939 return nullptr; 1940 } 1941 1942 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1943 (!DSAStack->isClauseParsingMode() || 1944 DSAStack->getParentDirective() != OMPD_unknown)) { 1945 auto &&Info = DSAStack->isLoopControlVariable(D); 1946 if (Info.first || 1947 (VD && VD->hasLocalStorage() && 1948 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1949 (VD && DSAStack->isForceVarCapturing())) 1950 return VD ? VD : Info.second; 1951 DSAStackTy::DSAVarData DVarPrivate = 1952 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1953 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1954 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1955 // Threadprivate variables must not be captured. 1956 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1957 return nullptr; 1958 // The variable is not private or it is the variable in the directive with 1959 // default(none) clause and not used in any clause. 1960 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1961 [](OpenMPDirectiveKind) { return true; }, 1962 DSAStack->isClauseParsingMode()); 1963 if (DVarPrivate.CKind != OMPC_unknown || 1964 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1965 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1966 } 1967 return nullptr; 1968 } 1969 1970 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1971 unsigned Level) const { 1972 SmallVector<OpenMPDirectiveKind, 4> Regions; 1973 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1974 FunctionScopesIndex -= Regions.size(); 1975 } 1976 1977 void Sema::startOpenMPLoop() { 1978 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1979 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1980 DSAStack->loopInit(); 1981 } 1982 1983 void Sema::startOpenMPCXXRangeFor() { 1984 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1985 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1986 DSAStack->resetPossibleLoopCounter(); 1987 DSAStack->loopStart(); 1988 } 1989 } 1990 1991 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1992 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1993 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1994 if (DSAStack->getAssociatedLoops() > 0 && 1995 !DSAStack->isLoopStarted()) { 1996 DSAStack->resetPossibleLoopCounter(D); 1997 DSAStack->loopStart(); 1998 return true; 1999 } 2000 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2001 DSAStack->isLoopControlVariable(D).first) && 2002 !DSAStack->hasExplicitDSA( 2003 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2004 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2005 return true; 2006 } 2007 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2008 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2009 DSAStack->isForceVarCapturing() && 2010 !DSAStack->hasExplicitDSA( 2011 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2012 return true; 2013 } 2014 return DSAStack->hasExplicitDSA( 2015 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2016 (DSAStack->isClauseParsingMode() && 2017 DSAStack->getClauseParsingMode() == OMPC_private) || 2018 // Consider taskgroup reduction descriptor variable a private to avoid 2019 // possible capture in the region. 2020 (DSAStack->hasExplicitDirective( 2021 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2022 Level) && 2023 DSAStack->isTaskgroupReductionRef(D, Level)); 2024 } 2025 2026 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2027 unsigned Level) { 2028 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2029 D = getCanonicalDecl(D); 2030 OpenMPClauseKind OMPC = OMPC_unknown; 2031 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2032 const unsigned NewLevel = I - 1; 2033 if (DSAStack->hasExplicitDSA(D, 2034 [&OMPC](const OpenMPClauseKind K) { 2035 if (isOpenMPPrivate(K)) { 2036 OMPC = K; 2037 return true; 2038 } 2039 return false; 2040 }, 2041 NewLevel)) 2042 break; 2043 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2044 D, NewLevel, 2045 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2046 OpenMPClauseKind) { return true; })) { 2047 OMPC = OMPC_map; 2048 break; 2049 } 2050 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2051 NewLevel)) { 2052 OMPC = OMPC_map; 2053 if (D->getType()->isScalarType() && 2054 DSAStack->getDefaultDMAAtLevel(NewLevel) != 2055 DefaultMapAttributes::DMA_tofrom_scalar) 2056 OMPC = OMPC_firstprivate; 2057 break; 2058 } 2059 } 2060 if (OMPC != OMPC_unknown) 2061 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2062 } 2063 2064 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2065 unsigned Level) const { 2066 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2067 // Return true if the current level is no longer enclosed in a target region. 2068 2069 const auto *VD = dyn_cast<VarDecl>(D); 2070 return VD && !VD->hasLocalStorage() && 2071 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2072 Level); 2073 } 2074 2075 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2076 2077 void Sema::finalizeOpenMPDelayedAnalysis() { 2078 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2079 // Diagnose implicit declare target functions and their callees. 2080 for (const auto &CallerCallees : DeviceCallGraph) { 2081 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2082 OMPDeclareTargetDeclAttr::getDeviceType( 2083 CallerCallees.getFirst()->getMostRecentDecl()); 2084 // Ignore host functions during device analyzis. 2085 if (LangOpts.OpenMPIsDevice && DevTy && 2086 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2087 continue; 2088 // Ignore nohost functions during host analyzis. 2089 if (!LangOpts.OpenMPIsDevice && DevTy && 2090 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2091 continue; 2092 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2093 &Callee : CallerCallees.getSecond()) { 2094 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2095 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2096 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2097 if (LangOpts.OpenMPIsDevice && DevTy && 2098 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2099 // Diagnose host function called during device codegen. 2100 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2101 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2102 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2103 << HostDevTy << 0; 2104 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2105 diag::note_omp_marked_device_type_here) 2106 << HostDevTy; 2107 continue; 2108 } 2109 if (!LangOpts.OpenMPIsDevice && DevTy && 2110 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2111 // Diagnose nohost function called during host codegen. 2112 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2113 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2114 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2115 << NoHostDevTy << 1; 2116 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2117 diag::note_omp_marked_device_type_here) 2118 << NoHostDevTy; 2119 continue; 2120 } 2121 } 2122 } 2123 } 2124 2125 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2126 const DeclarationNameInfo &DirName, 2127 Scope *CurScope, SourceLocation Loc) { 2128 DSAStack->push(DKind, DirName, CurScope, Loc); 2129 PushExpressionEvaluationContext( 2130 ExpressionEvaluationContext::PotentiallyEvaluated); 2131 } 2132 2133 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2134 DSAStack->setClauseParsingMode(K); 2135 } 2136 2137 void Sema::EndOpenMPClause() { 2138 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2139 } 2140 2141 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2142 ArrayRef<OMPClause *> Clauses); 2143 2144 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2145 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2146 // A variable of class type (or array thereof) that appears in a lastprivate 2147 // clause requires an accessible, unambiguous default constructor for the 2148 // class type, unless the list item is also specified in a firstprivate 2149 // clause. 2150 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2151 for (OMPClause *C : D->clauses()) { 2152 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2153 SmallVector<Expr *, 8> PrivateCopies; 2154 for (Expr *DE : Clause->varlists()) { 2155 if (DE->isValueDependent() || DE->isTypeDependent()) { 2156 PrivateCopies.push_back(nullptr); 2157 continue; 2158 } 2159 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2160 auto *VD = cast<VarDecl>(DRE->getDecl()); 2161 QualType Type = VD->getType().getNonReferenceType(); 2162 const DSAStackTy::DSAVarData DVar = 2163 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2164 if (DVar.CKind == OMPC_lastprivate) { 2165 // Generate helper private variable and initialize it with the 2166 // default value. The address of the original variable is replaced 2167 // by the address of the new private variable in CodeGen. This new 2168 // variable is not added to IdResolver, so the code in the OpenMP 2169 // region uses original variable for proper diagnostics. 2170 VarDecl *VDPrivate = buildVarDecl( 2171 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2172 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2173 ActOnUninitializedDecl(VDPrivate); 2174 if (VDPrivate->isInvalidDecl()) { 2175 PrivateCopies.push_back(nullptr); 2176 continue; 2177 } 2178 PrivateCopies.push_back(buildDeclRefExpr( 2179 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2180 } else { 2181 // The variable is also a firstprivate, so initialization sequence 2182 // for private copy is generated already. 2183 PrivateCopies.push_back(nullptr); 2184 } 2185 } 2186 Clause->setPrivateCopies(PrivateCopies); 2187 } 2188 } 2189 // Check allocate clauses. 2190 if (!CurContext->isDependentContext()) 2191 checkAllocateClauses(*this, DSAStack, D->clauses()); 2192 } 2193 2194 DSAStack->pop(); 2195 DiscardCleanupsInEvaluationContext(); 2196 PopExpressionEvaluationContext(); 2197 } 2198 2199 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2200 Expr *NumIterations, Sema &SemaRef, 2201 Scope *S, DSAStackTy *Stack); 2202 2203 namespace { 2204 2205 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2206 private: 2207 Sema &SemaRef; 2208 2209 public: 2210 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2211 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2212 NamedDecl *ND = Candidate.getCorrectionDecl(); 2213 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2214 return VD->hasGlobalStorage() && 2215 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2216 SemaRef.getCurScope()); 2217 } 2218 return false; 2219 } 2220 2221 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2222 return std::make_unique<VarDeclFilterCCC>(*this); 2223 } 2224 2225 }; 2226 2227 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2228 private: 2229 Sema &SemaRef; 2230 2231 public: 2232 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2233 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2234 NamedDecl *ND = Candidate.getCorrectionDecl(); 2235 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2236 isa<FunctionDecl>(ND))) { 2237 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2238 SemaRef.getCurScope()); 2239 } 2240 return false; 2241 } 2242 2243 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2244 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2245 } 2246 }; 2247 2248 } // namespace 2249 2250 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2251 CXXScopeSpec &ScopeSpec, 2252 const DeclarationNameInfo &Id, 2253 OpenMPDirectiveKind Kind) { 2254 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2255 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2256 2257 if (Lookup.isAmbiguous()) 2258 return ExprError(); 2259 2260 VarDecl *VD; 2261 if (!Lookup.isSingleResult()) { 2262 VarDeclFilterCCC CCC(*this); 2263 if (TypoCorrection Corrected = 2264 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2265 CTK_ErrorRecovery)) { 2266 diagnoseTypo(Corrected, 2267 PDiag(Lookup.empty() 2268 ? diag::err_undeclared_var_use_suggest 2269 : diag::err_omp_expected_var_arg_suggest) 2270 << Id.getName()); 2271 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2272 } else { 2273 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2274 : diag::err_omp_expected_var_arg) 2275 << Id.getName(); 2276 return ExprError(); 2277 } 2278 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2279 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2280 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2281 return ExprError(); 2282 } 2283 Lookup.suppressDiagnostics(); 2284 2285 // OpenMP [2.9.2, Syntax, C/C++] 2286 // Variables must be file-scope, namespace-scope, or static block-scope. 2287 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2288 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2289 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2290 bool IsDecl = 2291 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2292 Diag(VD->getLocation(), 2293 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2294 << VD; 2295 return ExprError(); 2296 } 2297 2298 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2299 NamedDecl *ND = CanonicalVD; 2300 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2301 // A threadprivate directive for file-scope variables must appear outside 2302 // any definition or declaration. 2303 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2304 !getCurLexicalContext()->isTranslationUnit()) { 2305 Diag(Id.getLoc(), diag::err_omp_var_scope) 2306 << getOpenMPDirectiveName(Kind) << VD; 2307 bool IsDecl = 2308 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2309 Diag(VD->getLocation(), 2310 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2311 << VD; 2312 return ExprError(); 2313 } 2314 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2315 // A threadprivate directive for static class member variables must appear 2316 // in the class definition, in the same scope in which the member 2317 // variables are declared. 2318 if (CanonicalVD->isStaticDataMember() && 2319 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2320 Diag(Id.getLoc(), diag::err_omp_var_scope) 2321 << getOpenMPDirectiveName(Kind) << VD; 2322 bool IsDecl = 2323 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2324 Diag(VD->getLocation(), 2325 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2326 << VD; 2327 return ExprError(); 2328 } 2329 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2330 // A threadprivate directive for namespace-scope variables must appear 2331 // outside any definition or declaration other than the namespace 2332 // definition itself. 2333 if (CanonicalVD->getDeclContext()->isNamespace() && 2334 (!getCurLexicalContext()->isFileContext() || 2335 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2336 Diag(Id.getLoc(), diag::err_omp_var_scope) 2337 << getOpenMPDirectiveName(Kind) << VD; 2338 bool IsDecl = 2339 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2340 Diag(VD->getLocation(), 2341 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2342 << VD; 2343 return ExprError(); 2344 } 2345 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2346 // A threadprivate directive for static block-scope variables must appear 2347 // in the scope of the variable and not in a nested scope. 2348 if (CanonicalVD->isLocalVarDecl() && CurScope && 2349 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2350 Diag(Id.getLoc(), diag::err_omp_var_scope) 2351 << getOpenMPDirectiveName(Kind) << VD; 2352 bool IsDecl = 2353 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2354 Diag(VD->getLocation(), 2355 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2356 << VD; 2357 return ExprError(); 2358 } 2359 2360 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2361 // A threadprivate directive must lexically precede all references to any 2362 // of the variables in its list. 2363 if (Kind == OMPD_threadprivate && VD->isUsed() && 2364 !DSAStack->isThreadPrivate(VD)) { 2365 Diag(Id.getLoc(), diag::err_omp_var_used) 2366 << getOpenMPDirectiveName(Kind) << VD; 2367 return ExprError(); 2368 } 2369 2370 QualType ExprType = VD->getType().getNonReferenceType(); 2371 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2372 SourceLocation(), VD, 2373 /*RefersToEnclosingVariableOrCapture=*/false, 2374 Id.getLoc(), ExprType, VK_LValue); 2375 } 2376 2377 Sema::DeclGroupPtrTy 2378 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2379 ArrayRef<Expr *> VarList) { 2380 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2381 CurContext->addDecl(D); 2382 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2383 } 2384 return nullptr; 2385 } 2386 2387 namespace { 2388 class LocalVarRefChecker final 2389 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2390 Sema &SemaRef; 2391 2392 public: 2393 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2394 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2395 if (VD->hasLocalStorage()) { 2396 SemaRef.Diag(E->getBeginLoc(), 2397 diag::err_omp_local_var_in_threadprivate_init) 2398 << E->getSourceRange(); 2399 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2400 << VD << VD->getSourceRange(); 2401 return true; 2402 } 2403 } 2404 return false; 2405 } 2406 bool VisitStmt(const Stmt *S) { 2407 for (const Stmt *Child : S->children()) { 2408 if (Child && Visit(Child)) 2409 return true; 2410 } 2411 return false; 2412 } 2413 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2414 }; 2415 } // namespace 2416 2417 OMPThreadPrivateDecl * 2418 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2419 SmallVector<Expr *, 8> Vars; 2420 for (Expr *RefExpr : VarList) { 2421 auto *DE = cast<DeclRefExpr>(RefExpr); 2422 auto *VD = cast<VarDecl>(DE->getDecl()); 2423 SourceLocation ILoc = DE->getExprLoc(); 2424 2425 // Mark variable as used. 2426 VD->setReferenced(); 2427 VD->markUsed(Context); 2428 2429 QualType QType = VD->getType(); 2430 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2431 // It will be analyzed later. 2432 Vars.push_back(DE); 2433 continue; 2434 } 2435 2436 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2437 // A threadprivate variable must not have an incomplete type. 2438 if (RequireCompleteType(ILoc, VD->getType(), 2439 diag::err_omp_threadprivate_incomplete_type)) { 2440 continue; 2441 } 2442 2443 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2444 // A threadprivate variable must not have a reference type. 2445 if (VD->getType()->isReferenceType()) { 2446 Diag(ILoc, diag::err_omp_ref_type_arg) 2447 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2448 bool IsDecl = 2449 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2450 Diag(VD->getLocation(), 2451 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2452 << VD; 2453 continue; 2454 } 2455 2456 // Check if this is a TLS variable. If TLS is not being supported, produce 2457 // the corresponding diagnostic. 2458 if ((VD->getTLSKind() != VarDecl::TLS_None && 2459 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2460 getLangOpts().OpenMPUseTLS && 2461 getASTContext().getTargetInfo().isTLSSupported())) || 2462 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2463 !VD->isLocalVarDecl())) { 2464 Diag(ILoc, diag::err_omp_var_thread_local) 2465 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2466 bool IsDecl = 2467 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2468 Diag(VD->getLocation(), 2469 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2470 << VD; 2471 continue; 2472 } 2473 2474 // Check if initial value of threadprivate variable reference variable with 2475 // local storage (it is not supported by runtime). 2476 if (const Expr *Init = VD->getAnyInitializer()) { 2477 LocalVarRefChecker Checker(*this); 2478 if (Checker.Visit(Init)) 2479 continue; 2480 } 2481 2482 Vars.push_back(RefExpr); 2483 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2484 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2485 Context, SourceRange(Loc, Loc))); 2486 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2487 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2488 } 2489 OMPThreadPrivateDecl *D = nullptr; 2490 if (!Vars.empty()) { 2491 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2492 Vars); 2493 D->setAccess(AS_public); 2494 } 2495 return D; 2496 } 2497 2498 static OMPAllocateDeclAttr::AllocatorTypeTy 2499 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2500 if (!Allocator) 2501 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2502 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2503 Allocator->isInstantiationDependent() || 2504 Allocator->containsUnexpandedParameterPack()) 2505 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2506 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2507 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2508 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2509 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2510 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2511 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2512 llvm::FoldingSetNodeID AEId, DAEId; 2513 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2514 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2515 if (AEId == DAEId) { 2516 AllocatorKindRes = AllocatorKind; 2517 break; 2518 } 2519 } 2520 return AllocatorKindRes; 2521 } 2522 2523 static bool checkPreviousOMPAllocateAttribute( 2524 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2525 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2526 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2527 return false; 2528 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2529 Expr *PrevAllocator = A->getAllocator(); 2530 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2531 getAllocatorKind(S, Stack, PrevAllocator); 2532 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2533 if (AllocatorsMatch && 2534 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2535 Allocator && PrevAllocator) { 2536 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2537 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2538 llvm::FoldingSetNodeID AEId, PAEId; 2539 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2540 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2541 AllocatorsMatch = AEId == PAEId; 2542 } 2543 if (!AllocatorsMatch) { 2544 SmallString<256> AllocatorBuffer; 2545 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2546 if (Allocator) 2547 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2548 SmallString<256> PrevAllocatorBuffer; 2549 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2550 if (PrevAllocator) 2551 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2552 S.getPrintingPolicy()); 2553 2554 SourceLocation AllocatorLoc = 2555 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2556 SourceRange AllocatorRange = 2557 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2558 SourceLocation PrevAllocatorLoc = 2559 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2560 SourceRange PrevAllocatorRange = 2561 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2562 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2563 << (Allocator ? 1 : 0) << AllocatorStream.str() 2564 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2565 << AllocatorRange; 2566 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2567 << PrevAllocatorRange; 2568 return true; 2569 } 2570 return false; 2571 } 2572 2573 static void 2574 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2575 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2576 Expr *Allocator, SourceRange SR) { 2577 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2578 return; 2579 if (Allocator && 2580 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2581 Allocator->isInstantiationDependent() || 2582 Allocator->containsUnexpandedParameterPack())) 2583 return; 2584 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2585 Allocator, SR); 2586 VD->addAttr(A); 2587 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2588 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2589 } 2590 2591 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2592 SourceLocation Loc, ArrayRef<Expr *> VarList, 2593 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2594 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2595 Expr *Allocator = nullptr; 2596 if (Clauses.empty()) { 2597 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2598 // allocate directives that appear in a target region must specify an 2599 // allocator clause unless a requires directive with the dynamic_allocators 2600 // clause is present in the same compilation unit. 2601 if (LangOpts.OpenMPIsDevice && 2602 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2603 targetDiag(Loc, diag::err_expected_allocator_clause); 2604 } else { 2605 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2606 } 2607 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2608 getAllocatorKind(*this, DSAStack, Allocator); 2609 SmallVector<Expr *, 8> Vars; 2610 for (Expr *RefExpr : VarList) { 2611 auto *DE = cast<DeclRefExpr>(RefExpr); 2612 auto *VD = cast<VarDecl>(DE->getDecl()); 2613 2614 // Check if this is a TLS variable or global register. 2615 if (VD->getTLSKind() != VarDecl::TLS_None || 2616 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2617 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2618 !VD->isLocalVarDecl())) 2619 continue; 2620 2621 // If the used several times in the allocate directive, the same allocator 2622 // must be used. 2623 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2624 AllocatorKind, Allocator)) 2625 continue; 2626 2627 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2628 // If a list item has a static storage type, the allocator expression in the 2629 // allocator clause must be a constant expression that evaluates to one of 2630 // the predefined memory allocator values. 2631 if (Allocator && VD->hasGlobalStorage()) { 2632 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2633 Diag(Allocator->getExprLoc(), 2634 diag::err_omp_expected_predefined_allocator) 2635 << Allocator->getSourceRange(); 2636 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2637 VarDecl::DeclarationOnly; 2638 Diag(VD->getLocation(), 2639 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2640 << VD; 2641 continue; 2642 } 2643 } 2644 2645 Vars.push_back(RefExpr); 2646 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2647 DE->getSourceRange()); 2648 } 2649 if (Vars.empty()) 2650 return nullptr; 2651 if (!Owner) 2652 Owner = getCurLexicalContext(); 2653 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2654 D->setAccess(AS_public); 2655 Owner->addDecl(D); 2656 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2657 } 2658 2659 Sema::DeclGroupPtrTy 2660 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2661 ArrayRef<OMPClause *> ClauseList) { 2662 OMPRequiresDecl *D = nullptr; 2663 if (!CurContext->isFileContext()) { 2664 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2665 } else { 2666 D = CheckOMPRequiresDecl(Loc, ClauseList); 2667 if (D) { 2668 CurContext->addDecl(D); 2669 DSAStack->addRequiresDecl(D); 2670 } 2671 } 2672 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2673 } 2674 2675 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2676 ArrayRef<OMPClause *> ClauseList) { 2677 /// For target specific clauses, the requires directive cannot be 2678 /// specified after the handling of any of the target regions in the 2679 /// current compilation unit. 2680 ArrayRef<SourceLocation> TargetLocations = 2681 DSAStack->getEncounteredTargetLocs(); 2682 if (!TargetLocations.empty()) { 2683 for (const OMPClause *CNew : ClauseList) { 2684 // Check if any of the requires clauses affect target regions. 2685 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2686 isa<OMPUnifiedAddressClause>(CNew) || 2687 isa<OMPReverseOffloadClause>(CNew) || 2688 isa<OMPDynamicAllocatorsClause>(CNew)) { 2689 Diag(Loc, diag::err_omp_target_before_requires) 2690 << getOpenMPClauseName(CNew->getClauseKind()); 2691 for (SourceLocation TargetLoc : TargetLocations) { 2692 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2693 } 2694 } 2695 } 2696 } 2697 2698 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2699 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2700 ClauseList); 2701 return nullptr; 2702 } 2703 2704 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2705 const ValueDecl *D, 2706 const DSAStackTy::DSAVarData &DVar, 2707 bool IsLoopIterVar = false) { 2708 if (DVar.RefExpr) { 2709 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2710 << getOpenMPClauseName(DVar.CKind); 2711 return; 2712 } 2713 enum { 2714 PDSA_StaticMemberShared, 2715 PDSA_StaticLocalVarShared, 2716 PDSA_LoopIterVarPrivate, 2717 PDSA_LoopIterVarLinear, 2718 PDSA_LoopIterVarLastprivate, 2719 PDSA_ConstVarShared, 2720 PDSA_GlobalVarShared, 2721 PDSA_TaskVarFirstprivate, 2722 PDSA_LocalVarPrivate, 2723 PDSA_Implicit 2724 } Reason = PDSA_Implicit; 2725 bool ReportHint = false; 2726 auto ReportLoc = D->getLocation(); 2727 auto *VD = dyn_cast<VarDecl>(D); 2728 if (IsLoopIterVar) { 2729 if (DVar.CKind == OMPC_private) 2730 Reason = PDSA_LoopIterVarPrivate; 2731 else if (DVar.CKind == OMPC_lastprivate) 2732 Reason = PDSA_LoopIterVarLastprivate; 2733 else 2734 Reason = PDSA_LoopIterVarLinear; 2735 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2736 DVar.CKind == OMPC_firstprivate) { 2737 Reason = PDSA_TaskVarFirstprivate; 2738 ReportLoc = DVar.ImplicitDSALoc; 2739 } else if (VD && VD->isStaticLocal()) 2740 Reason = PDSA_StaticLocalVarShared; 2741 else if (VD && VD->isStaticDataMember()) 2742 Reason = PDSA_StaticMemberShared; 2743 else if (VD && VD->isFileVarDecl()) 2744 Reason = PDSA_GlobalVarShared; 2745 else if (D->getType().isConstant(SemaRef.getASTContext())) 2746 Reason = PDSA_ConstVarShared; 2747 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2748 ReportHint = true; 2749 Reason = PDSA_LocalVarPrivate; 2750 } 2751 if (Reason != PDSA_Implicit) { 2752 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2753 << Reason << ReportHint 2754 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2755 } else if (DVar.ImplicitDSALoc.isValid()) { 2756 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2757 << getOpenMPClauseName(DVar.CKind); 2758 } 2759 } 2760 2761 namespace { 2762 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2763 DSAStackTy *Stack; 2764 Sema &SemaRef; 2765 bool ErrorFound = false; 2766 CapturedStmt *CS = nullptr; 2767 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2768 llvm::SmallVector<Expr *, 4> ImplicitMap; 2769 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2770 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2771 2772 void VisitSubCaptures(OMPExecutableDirective *S) { 2773 // Check implicitly captured variables. 2774 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2775 return; 2776 visitSubCaptures(S->getInnermostCapturedStmt()); 2777 } 2778 2779 public: 2780 void VisitDeclRefExpr(DeclRefExpr *E) { 2781 if (E->isTypeDependent() || E->isValueDependent() || 2782 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2783 return; 2784 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2785 // Check the datasharing rules for the expressions in the clauses. 2786 if (!CS) { 2787 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2788 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2789 Visit(CED->getInit()); 2790 return; 2791 } 2792 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2793 // Do not analyze internal variables and do not enclose them into 2794 // implicit clauses. 2795 return; 2796 VD = VD->getCanonicalDecl(); 2797 // Skip internally declared variables. 2798 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2799 return; 2800 2801 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2802 // Check if the variable has explicit DSA set and stop analysis if it so. 2803 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2804 return; 2805 2806 // Skip internally declared static variables. 2807 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2808 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2809 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2810 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2811 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2812 return; 2813 2814 SourceLocation ELoc = E->getExprLoc(); 2815 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2816 // The default(none) clause requires that each variable that is referenced 2817 // in the construct, and does not have a predetermined data-sharing 2818 // attribute, must have its data-sharing attribute explicitly determined 2819 // by being listed in a data-sharing attribute clause. 2820 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2821 isImplicitOrExplicitTaskingRegion(DKind) && 2822 VarsWithInheritedDSA.count(VD) == 0) { 2823 VarsWithInheritedDSA[VD] = E; 2824 return; 2825 } 2826 2827 if (isOpenMPTargetExecutionDirective(DKind) && 2828 !Stack->isLoopControlVariable(VD).first) { 2829 if (!Stack->checkMappableExprComponentListsForDecl( 2830 VD, /*CurrentRegionOnly=*/true, 2831 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2832 StackComponents, 2833 OpenMPClauseKind) { 2834 // Variable is used if it has been marked as an array, array 2835 // section or the variable iself. 2836 return StackComponents.size() == 1 || 2837 std::all_of( 2838 std::next(StackComponents.rbegin()), 2839 StackComponents.rend(), 2840 [](const OMPClauseMappableExprCommon:: 2841 MappableComponent &MC) { 2842 return MC.getAssociatedDeclaration() == 2843 nullptr && 2844 (isa<OMPArraySectionExpr>( 2845 MC.getAssociatedExpression()) || 2846 isa<ArraySubscriptExpr>( 2847 MC.getAssociatedExpression())); 2848 }); 2849 })) { 2850 bool IsFirstprivate = false; 2851 // By default lambdas are captured as firstprivates. 2852 if (const auto *RD = 2853 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2854 IsFirstprivate = RD->isLambda(); 2855 IsFirstprivate = 2856 IsFirstprivate || 2857 (VD->getType().getNonReferenceType()->isScalarType() && 2858 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2859 if (IsFirstprivate) 2860 ImplicitFirstprivate.emplace_back(E); 2861 else 2862 ImplicitMap.emplace_back(E); 2863 return; 2864 } 2865 } 2866 2867 // OpenMP [2.9.3.6, Restrictions, p.2] 2868 // A list item that appears in a reduction clause of the innermost 2869 // enclosing worksharing or parallel construct may not be accessed in an 2870 // explicit task. 2871 DVar = Stack->hasInnermostDSA( 2872 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2873 [](OpenMPDirectiveKind K) { 2874 return isOpenMPParallelDirective(K) || 2875 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2876 }, 2877 /*FromParent=*/true); 2878 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2879 ErrorFound = true; 2880 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2881 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2882 return; 2883 } 2884 2885 // Define implicit data-sharing attributes for task. 2886 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2887 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2888 !Stack->isLoopControlVariable(VD).first) { 2889 ImplicitFirstprivate.push_back(E); 2890 return; 2891 } 2892 2893 // Store implicitly used globals with declare target link for parent 2894 // target. 2895 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2896 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2897 Stack->addToParentTargetRegionLinkGlobals(E); 2898 return; 2899 } 2900 } 2901 } 2902 void VisitMemberExpr(MemberExpr *E) { 2903 if (E->isTypeDependent() || E->isValueDependent() || 2904 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2905 return; 2906 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2907 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2908 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2909 if (!FD) 2910 return; 2911 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2912 // Check if the variable has explicit DSA set and stop analysis if it 2913 // so. 2914 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2915 return; 2916 2917 if (isOpenMPTargetExecutionDirective(DKind) && 2918 !Stack->isLoopControlVariable(FD).first && 2919 !Stack->checkMappableExprComponentListsForDecl( 2920 FD, /*CurrentRegionOnly=*/true, 2921 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2922 StackComponents, 2923 OpenMPClauseKind) { 2924 return isa<CXXThisExpr>( 2925 cast<MemberExpr>( 2926 StackComponents.back().getAssociatedExpression()) 2927 ->getBase() 2928 ->IgnoreParens()); 2929 })) { 2930 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2931 // A bit-field cannot appear in a map clause. 2932 // 2933 if (FD->isBitField()) 2934 return; 2935 2936 // Check to see if the member expression is referencing a class that 2937 // has already been explicitly mapped 2938 if (Stack->isClassPreviouslyMapped(TE->getType())) 2939 return; 2940 2941 ImplicitMap.emplace_back(E); 2942 return; 2943 } 2944 2945 SourceLocation ELoc = E->getExprLoc(); 2946 // OpenMP [2.9.3.6, Restrictions, p.2] 2947 // A list item that appears in a reduction clause of the innermost 2948 // enclosing worksharing or parallel construct may not be accessed in 2949 // an explicit task. 2950 DVar = Stack->hasInnermostDSA( 2951 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2952 [](OpenMPDirectiveKind K) { 2953 return isOpenMPParallelDirective(K) || 2954 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2955 }, 2956 /*FromParent=*/true); 2957 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2958 ErrorFound = true; 2959 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2960 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2961 return; 2962 } 2963 2964 // Define implicit data-sharing attributes for task. 2965 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2966 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2967 !Stack->isLoopControlVariable(FD).first) { 2968 // Check if there is a captured expression for the current field in the 2969 // region. Do not mark it as firstprivate unless there is no captured 2970 // expression. 2971 // TODO: try to make it firstprivate. 2972 if (DVar.CKind != OMPC_unknown) 2973 ImplicitFirstprivate.push_back(E); 2974 } 2975 return; 2976 } 2977 if (isOpenMPTargetExecutionDirective(DKind)) { 2978 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2979 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2980 /*NoDiagnose=*/true)) 2981 return; 2982 const auto *VD = cast<ValueDecl>( 2983 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2984 if (!Stack->checkMappableExprComponentListsForDecl( 2985 VD, /*CurrentRegionOnly=*/true, 2986 [&CurComponents]( 2987 OMPClauseMappableExprCommon::MappableExprComponentListRef 2988 StackComponents, 2989 OpenMPClauseKind) { 2990 auto CCI = CurComponents.rbegin(); 2991 auto CCE = CurComponents.rend(); 2992 for (const auto &SC : llvm::reverse(StackComponents)) { 2993 // Do both expressions have the same kind? 2994 if (CCI->getAssociatedExpression()->getStmtClass() != 2995 SC.getAssociatedExpression()->getStmtClass()) 2996 if (!(isa<OMPArraySectionExpr>( 2997 SC.getAssociatedExpression()) && 2998 isa<ArraySubscriptExpr>( 2999 CCI->getAssociatedExpression()))) 3000 return false; 3001 3002 const Decl *CCD = CCI->getAssociatedDeclaration(); 3003 const Decl *SCD = SC.getAssociatedDeclaration(); 3004 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3005 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3006 if (SCD != CCD) 3007 return false; 3008 std::advance(CCI, 1); 3009 if (CCI == CCE) 3010 break; 3011 } 3012 return true; 3013 })) { 3014 Visit(E->getBase()); 3015 } 3016 } else { 3017 Visit(E->getBase()); 3018 } 3019 } 3020 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3021 for (OMPClause *C : S->clauses()) { 3022 // Skip analysis of arguments of implicitly defined firstprivate clause 3023 // for task|target directives. 3024 // Skip analysis of arguments of implicitly defined map clause for target 3025 // directives. 3026 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3027 C->isImplicit())) { 3028 for (Stmt *CC : C->children()) { 3029 if (CC) 3030 Visit(CC); 3031 } 3032 } 3033 } 3034 // Check implicitly captured variables. 3035 VisitSubCaptures(S); 3036 } 3037 void VisitStmt(Stmt *S) { 3038 for (Stmt *C : S->children()) { 3039 if (C) { 3040 // Check implicitly captured variables in the task-based directives to 3041 // check if they must be firstprivatized. 3042 Visit(C); 3043 } 3044 } 3045 } 3046 3047 void visitSubCaptures(CapturedStmt *S) { 3048 for (const CapturedStmt::Capture &Cap : S->captures()) { 3049 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3050 continue; 3051 VarDecl *VD = Cap.getCapturedVar(); 3052 // Do not try to map the variable if it or its sub-component was mapped 3053 // already. 3054 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3055 Stack->checkMappableExprComponentListsForDecl( 3056 VD, /*CurrentRegionOnly=*/true, 3057 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3058 OpenMPClauseKind) { return true; })) 3059 continue; 3060 DeclRefExpr *DRE = buildDeclRefExpr( 3061 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3062 Cap.getLocation(), /*RefersToCapture=*/true); 3063 Visit(DRE); 3064 } 3065 } 3066 bool isErrorFound() const { return ErrorFound; } 3067 ArrayRef<Expr *> getImplicitFirstprivate() const { 3068 return ImplicitFirstprivate; 3069 } 3070 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 3071 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3072 return VarsWithInheritedDSA; 3073 } 3074 3075 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3076 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3077 // Process declare target link variables for the target directives. 3078 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3079 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3080 Visit(E); 3081 } 3082 } 3083 }; 3084 } // namespace 3085 3086 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3087 switch (DKind) { 3088 case OMPD_parallel: 3089 case OMPD_parallel_for: 3090 case OMPD_parallel_for_simd: 3091 case OMPD_parallel_sections: 3092 case OMPD_teams: 3093 case OMPD_teams_distribute: 3094 case OMPD_teams_distribute_simd: { 3095 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3096 QualType KmpInt32PtrTy = 3097 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3098 Sema::CapturedParamNameType Params[] = { 3099 std::make_pair(".global_tid.", KmpInt32PtrTy), 3100 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3101 std::make_pair(StringRef(), QualType()) // __context with shared vars 3102 }; 3103 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3104 Params); 3105 break; 3106 } 3107 case OMPD_target_teams: 3108 case OMPD_target_parallel: 3109 case OMPD_target_parallel_for: 3110 case OMPD_target_parallel_for_simd: 3111 case OMPD_target_teams_distribute: 3112 case OMPD_target_teams_distribute_simd: { 3113 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3114 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3115 QualType KmpInt32PtrTy = 3116 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3117 QualType Args[] = {VoidPtrTy}; 3118 FunctionProtoType::ExtProtoInfo EPI; 3119 EPI.Variadic = true; 3120 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3121 Sema::CapturedParamNameType Params[] = { 3122 std::make_pair(".global_tid.", KmpInt32Ty), 3123 std::make_pair(".part_id.", KmpInt32PtrTy), 3124 std::make_pair(".privates.", VoidPtrTy), 3125 std::make_pair( 3126 ".copy_fn.", 3127 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3128 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3129 std::make_pair(StringRef(), QualType()) // __context with shared vars 3130 }; 3131 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3132 Params, /*OpenMPCaptureLevel=*/0); 3133 // Mark this captured region as inlined, because we don't use outlined 3134 // function directly. 3135 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3136 AlwaysInlineAttr::CreateImplicit( 3137 Context, {}, AttributeCommonInfo::AS_Keyword, 3138 AlwaysInlineAttr::Keyword_forceinline)); 3139 Sema::CapturedParamNameType ParamsTarget[] = { 3140 std::make_pair(StringRef(), QualType()) // __context with shared vars 3141 }; 3142 // Start a captured region for 'target' with no implicit parameters. 3143 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3144 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3145 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3146 std::make_pair(".global_tid.", KmpInt32PtrTy), 3147 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3148 std::make_pair(StringRef(), QualType()) // __context with shared vars 3149 }; 3150 // Start a captured region for 'teams' or 'parallel'. Both regions have 3151 // the same implicit parameters. 3152 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3153 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3154 break; 3155 } 3156 case OMPD_target: 3157 case OMPD_target_simd: { 3158 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3159 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3160 QualType KmpInt32PtrTy = 3161 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3162 QualType Args[] = {VoidPtrTy}; 3163 FunctionProtoType::ExtProtoInfo EPI; 3164 EPI.Variadic = true; 3165 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3166 Sema::CapturedParamNameType Params[] = { 3167 std::make_pair(".global_tid.", KmpInt32Ty), 3168 std::make_pair(".part_id.", KmpInt32PtrTy), 3169 std::make_pair(".privates.", VoidPtrTy), 3170 std::make_pair( 3171 ".copy_fn.", 3172 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3173 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3174 std::make_pair(StringRef(), QualType()) // __context with shared vars 3175 }; 3176 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3177 Params, /*OpenMPCaptureLevel=*/0); 3178 // Mark this captured region as inlined, because we don't use outlined 3179 // function directly. 3180 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3181 AlwaysInlineAttr::CreateImplicit( 3182 Context, {}, AttributeCommonInfo::AS_Keyword, 3183 AlwaysInlineAttr::Keyword_forceinline)); 3184 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3185 std::make_pair(StringRef(), QualType()), 3186 /*OpenMPCaptureLevel=*/1); 3187 break; 3188 } 3189 case OMPD_simd: 3190 case OMPD_for: 3191 case OMPD_for_simd: 3192 case OMPD_sections: 3193 case OMPD_section: 3194 case OMPD_single: 3195 case OMPD_master: 3196 case OMPD_critical: 3197 case OMPD_taskgroup: 3198 case OMPD_distribute: 3199 case OMPD_distribute_simd: 3200 case OMPD_ordered: 3201 case OMPD_atomic: 3202 case OMPD_target_data: { 3203 Sema::CapturedParamNameType Params[] = { 3204 std::make_pair(StringRef(), QualType()) // __context with shared vars 3205 }; 3206 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3207 Params); 3208 break; 3209 } 3210 case OMPD_task: { 3211 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3212 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3213 QualType KmpInt32PtrTy = 3214 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3215 QualType Args[] = {VoidPtrTy}; 3216 FunctionProtoType::ExtProtoInfo EPI; 3217 EPI.Variadic = true; 3218 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3219 Sema::CapturedParamNameType Params[] = { 3220 std::make_pair(".global_tid.", KmpInt32Ty), 3221 std::make_pair(".part_id.", KmpInt32PtrTy), 3222 std::make_pair(".privates.", VoidPtrTy), 3223 std::make_pair( 3224 ".copy_fn.", 3225 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3226 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3227 std::make_pair(StringRef(), QualType()) // __context with shared vars 3228 }; 3229 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3230 Params); 3231 // Mark this captured region as inlined, because we don't use outlined 3232 // function directly. 3233 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3234 AlwaysInlineAttr::CreateImplicit( 3235 Context, {}, AttributeCommonInfo::AS_Keyword, 3236 AlwaysInlineAttr::Keyword_forceinline)); 3237 break; 3238 } 3239 case OMPD_taskloop: 3240 case OMPD_taskloop_simd: 3241 case OMPD_master_taskloop: { 3242 QualType KmpInt32Ty = 3243 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3244 .withConst(); 3245 QualType KmpUInt64Ty = 3246 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3247 .withConst(); 3248 QualType KmpInt64Ty = 3249 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3250 .withConst(); 3251 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3252 QualType KmpInt32PtrTy = 3253 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3254 QualType Args[] = {VoidPtrTy}; 3255 FunctionProtoType::ExtProtoInfo EPI; 3256 EPI.Variadic = true; 3257 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3258 Sema::CapturedParamNameType Params[] = { 3259 std::make_pair(".global_tid.", KmpInt32Ty), 3260 std::make_pair(".part_id.", KmpInt32PtrTy), 3261 std::make_pair(".privates.", VoidPtrTy), 3262 std::make_pair( 3263 ".copy_fn.", 3264 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3265 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3266 std::make_pair(".lb.", KmpUInt64Ty), 3267 std::make_pair(".ub.", KmpUInt64Ty), 3268 std::make_pair(".st.", KmpInt64Ty), 3269 std::make_pair(".liter.", KmpInt32Ty), 3270 std::make_pair(".reductions.", VoidPtrTy), 3271 std::make_pair(StringRef(), QualType()) // __context with shared vars 3272 }; 3273 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3274 Params); 3275 // Mark this captured region as inlined, because we don't use outlined 3276 // function directly. 3277 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3278 AlwaysInlineAttr::CreateImplicit( 3279 Context, {}, AttributeCommonInfo::AS_Keyword, 3280 AlwaysInlineAttr::Keyword_forceinline)); 3281 break; 3282 } 3283 case OMPD_distribute_parallel_for_simd: 3284 case OMPD_distribute_parallel_for: { 3285 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3286 QualType KmpInt32PtrTy = 3287 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3288 Sema::CapturedParamNameType Params[] = { 3289 std::make_pair(".global_tid.", KmpInt32PtrTy), 3290 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3291 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3292 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3293 std::make_pair(StringRef(), QualType()) // __context with shared vars 3294 }; 3295 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3296 Params); 3297 break; 3298 } 3299 case OMPD_target_teams_distribute_parallel_for: 3300 case OMPD_target_teams_distribute_parallel_for_simd: { 3301 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3302 QualType KmpInt32PtrTy = 3303 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3304 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3305 3306 QualType Args[] = {VoidPtrTy}; 3307 FunctionProtoType::ExtProtoInfo EPI; 3308 EPI.Variadic = true; 3309 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3310 Sema::CapturedParamNameType Params[] = { 3311 std::make_pair(".global_tid.", KmpInt32Ty), 3312 std::make_pair(".part_id.", KmpInt32PtrTy), 3313 std::make_pair(".privates.", VoidPtrTy), 3314 std::make_pair( 3315 ".copy_fn.", 3316 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3317 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3318 std::make_pair(StringRef(), QualType()) // __context with shared vars 3319 }; 3320 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3321 Params, /*OpenMPCaptureLevel=*/0); 3322 // Mark this captured region as inlined, because we don't use outlined 3323 // function directly. 3324 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3325 AlwaysInlineAttr::CreateImplicit( 3326 Context, {}, AttributeCommonInfo::AS_Keyword, 3327 AlwaysInlineAttr::Keyword_forceinline)); 3328 Sema::CapturedParamNameType ParamsTarget[] = { 3329 std::make_pair(StringRef(), QualType()) // __context with shared vars 3330 }; 3331 // Start a captured region for 'target' with no implicit parameters. 3332 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3333 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3334 3335 Sema::CapturedParamNameType ParamsTeams[] = { 3336 std::make_pair(".global_tid.", KmpInt32PtrTy), 3337 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3338 std::make_pair(StringRef(), QualType()) // __context with shared vars 3339 }; 3340 // Start a captured region for 'target' with no implicit parameters. 3341 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3342 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3343 3344 Sema::CapturedParamNameType ParamsParallel[] = { 3345 std::make_pair(".global_tid.", KmpInt32PtrTy), 3346 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3347 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3348 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3349 std::make_pair(StringRef(), QualType()) // __context with shared vars 3350 }; 3351 // Start a captured region for 'teams' or 'parallel'. Both regions have 3352 // the same implicit parameters. 3353 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3354 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3355 break; 3356 } 3357 3358 case OMPD_teams_distribute_parallel_for: 3359 case OMPD_teams_distribute_parallel_for_simd: { 3360 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3361 QualType KmpInt32PtrTy = 3362 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3363 3364 Sema::CapturedParamNameType ParamsTeams[] = { 3365 std::make_pair(".global_tid.", KmpInt32PtrTy), 3366 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3367 std::make_pair(StringRef(), QualType()) // __context with shared vars 3368 }; 3369 // Start a captured region for 'target' with no implicit parameters. 3370 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3371 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3372 3373 Sema::CapturedParamNameType ParamsParallel[] = { 3374 std::make_pair(".global_tid.", KmpInt32PtrTy), 3375 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3376 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3377 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3378 std::make_pair(StringRef(), QualType()) // __context with shared vars 3379 }; 3380 // Start a captured region for 'teams' or 'parallel'. Both regions have 3381 // the same implicit parameters. 3382 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3383 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3384 break; 3385 } 3386 case OMPD_target_update: 3387 case OMPD_target_enter_data: 3388 case OMPD_target_exit_data: { 3389 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3390 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3391 QualType KmpInt32PtrTy = 3392 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3393 QualType Args[] = {VoidPtrTy}; 3394 FunctionProtoType::ExtProtoInfo EPI; 3395 EPI.Variadic = true; 3396 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3397 Sema::CapturedParamNameType Params[] = { 3398 std::make_pair(".global_tid.", KmpInt32Ty), 3399 std::make_pair(".part_id.", KmpInt32PtrTy), 3400 std::make_pair(".privates.", VoidPtrTy), 3401 std::make_pair( 3402 ".copy_fn.", 3403 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3404 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3405 std::make_pair(StringRef(), QualType()) // __context with shared vars 3406 }; 3407 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3408 Params); 3409 // Mark this captured region as inlined, because we don't use outlined 3410 // function directly. 3411 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3412 AlwaysInlineAttr::CreateImplicit( 3413 Context, {}, AttributeCommonInfo::AS_Keyword, 3414 AlwaysInlineAttr::Keyword_forceinline)); 3415 break; 3416 } 3417 case OMPD_threadprivate: 3418 case OMPD_allocate: 3419 case OMPD_taskyield: 3420 case OMPD_barrier: 3421 case OMPD_taskwait: 3422 case OMPD_cancellation_point: 3423 case OMPD_cancel: 3424 case OMPD_flush: 3425 case OMPD_declare_reduction: 3426 case OMPD_declare_mapper: 3427 case OMPD_declare_simd: 3428 case OMPD_declare_target: 3429 case OMPD_end_declare_target: 3430 case OMPD_requires: 3431 case OMPD_declare_variant: 3432 llvm_unreachable("OpenMP Directive is not allowed"); 3433 case OMPD_unknown: 3434 llvm_unreachable("Unknown OpenMP directive"); 3435 } 3436 } 3437 3438 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3439 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3440 getOpenMPCaptureRegions(CaptureRegions, DKind); 3441 return CaptureRegions.size(); 3442 } 3443 3444 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3445 Expr *CaptureExpr, bool WithInit, 3446 bool AsExpression) { 3447 assert(CaptureExpr); 3448 ASTContext &C = S.getASTContext(); 3449 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3450 QualType Ty = Init->getType(); 3451 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3452 if (S.getLangOpts().CPlusPlus) { 3453 Ty = C.getLValueReferenceType(Ty); 3454 } else { 3455 Ty = C.getPointerType(Ty); 3456 ExprResult Res = 3457 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3458 if (!Res.isUsable()) 3459 return nullptr; 3460 Init = Res.get(); 3461 } 3462 WithInit = true; 3463 } 3464 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3465 CaptureExpr->getBeginLoc()); 3466 if (!WithInit) 3467 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3468 S.CurContext->addHiddenDecl(CED); 3469 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3470 return CED; 3471 } 3472 3473 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3474 bool WithInit) { 3475 OMPCapturedExprDecl *CD; 3476 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3477 CD = cast<OMPCapturedExprDecl>(VD); 3478 else 3479 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3480 /*AsExpression=*/false); 3481 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3482 CaptureExpr->getExprLoc()); 3483 } 3484 3485 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3486 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3487 if (!Ref) { 3488 OMPCapturedExprDecl *CD = buildCaptureDecl( 3489 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3490 /*WithInit=*/true, /*AsExpression=*/true); 3491 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3492 CaptureExpr->getExprLoc()); 3493 } 3494 ExprResult Res = Ref; 3495 if (!S.getLangOpts().CPlusPlus && 3496 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3497 Ref->getType()->isPointerType()) { 3498 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3499 if (!Res.isUsable()) 3500 return ExprError(); 3501 } 3502 return S.DefaultLvalueConversion(Res.get()); 3503 } 3504 3505 namespace { 3506 // OpenMP directives parsed in this section are represented as a 3507 // CapturedStatement with an associated statement. If a syntax error 3508 // is detected during the parsing of the associated statement, the 3509 // compiler must abort processing and close the CapturedStatement. 3510 // 3511 // Combined directives such as 'target parallel' have more than one 3512 // nested CapturedStatements. This RAII ensures that we unwind out 3513 // of all the nested CapturedStatements when an error is found. 3514 class CaptureRegionUnwinderRAII { 3515 private: 3516 Sema &S; 3517 bool &ErrorFound; 3518 OpenMPDirectiveKind DKind = OMPD_unknown; 3519 3520 public: 3521 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3522 OpenMPDirectiveKind DKind) 3523 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3524 ~CaptureRegionUnwinderRAII() { 3525 if (ErrorFound) { 3526 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3527 while (--ThisCaptureLevel >= 0) 3528 S.ActOnCapturedRegionError(); 3529 } 3530 } 3531 }; 3532 } // namespace 3533 3534 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3535 // Capture variables captured by reference in lambdas for target-based 3536 // directives. 3537 if (!CurContext->isDependentContext() && 3538 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3539 isOpenMPTargetDataManagementDirective( 3540 DSAStack->getCurrentDirective()))) { 3541 QualType Type = V->getType(); 3542 if (const auto *RD = Type.getCanonicalType() 3543 .getNonReferenceType() 3544 ->getAsCXXRecordDecl()) { 3545 bool SavedForceCaptureByReferenceInTargetExecutable = 3546 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3547 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3548 /*V=*/true); 3549 if (RD->isLambda()) { 3550 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3551 FieldDecl *ThisCapture; 3552 RD->getCaptureFields(Captures, ThisCapture); 3553 for (const LambdaCapture &LC : RD->captures()) { 3554 if (LC.getCaptureKind() == LCK_ByRef) { 3555 VarDecl *VD = LC.getCapturedVar(); 3556 DeclContext *VDC = VD->getDeclContext(); 3557 if (!VDC->Encloses(CurContext)) 3558 continue; 3559 MarkVariableReferenced(LC.getLocation(), VD); 3560 } else if (LC.getCaptureKind() == LCK_This) { 3561 QualType ThisTy = getCurrentThisType(); 3562 if (!ThisTy.isNull() && 3563 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3564 CheckCXXThisCapture(LC.getLocation()); 3565 } 3566 } 3567 } 3568 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3569 SavedForceCaptureByReferenceInTargetExecutable); 3570 } 3571 } 3572 } 3573 3574 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3575 ArrayRef<OMPClause *> Clauses) { 3576 bool ErrorFound = false; 3577 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3578 *this, ErrorFound, DSAStack->getCurrentDirective()); 3579 if (!S.isUsable()) { 3580 ErrorFound = true; 3581 return StmtError(); 3582 } 3583 3584 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3585 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3586 OMPOrderedClause *OC = nullptr; 3587 OMPScheduleClause *SC = nullptr; 3588 SmallVector<const OMPLinearClause *, 4> LCs; 3589 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3590 // This is required for proper codegen. 3591 for (OMPClause *Clause : Clauses) { 3592 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3593 Clause->getClauseKind() == OMPC_in_reduction) { 3594 // Capture taskgroup task_reduction descriptors inside the tasking regions 3595 // with the corresponding in_reduction items. 3596 auto *IRC = cast<OMPInReductionClause>(Clause); 3597 for (Expr *E : IRC->taskgroup_descriptors()) 3598 if (E) 3599 MarkDeclarationsReferencedInExpr(E); 3600 } 3601 if (isOpenMPPrivate(Clause->getClauseKind()) || 3602 Clause->getClauseKind() == OMPC_copyprivate || 3603 (getLangOpts().OpenMPUseTLS && 3604 getASTContext().getTargetInfo().isTLSSupported() && 3605 Clause->getClauseKind() == OMPC_copyin)) { 3606 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3607 // Mark all variables in private list clauses as used in inner region. 3608 for (Stmt *VarRef : Clause->children()) { 3609 if (auto *E = cast_or_null<Expr>(VarRef)) { 3610 MarkDeclarationsReferencedInExpr(E); 3611 } 3612 } 3613 DSAStack->setForceVarCapturing(/*V=*/false); 3614 } else if (CaptureRegions.size() > 1 || 3615 CaptureRegions.back() != OMPD_unknown) { 3616 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3617 PICs.push_back(C); 3618 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3619 if (Expr *E = C->getPostUpdateExpr()) 3620 MarkDeclarationsReferencedInExpr(E); 3621 } 3622 } 3623 if (Clause->getClauseKind() == OMPC_schedule) 3624 SC = cast<OMPScheduleClause>(Clause); 3625 else if (Clause->getClauseKind() == OMPC_ordered) 3626 OC = cast<OMPOrderedClause>(Clause); 3627 else if (Clause->getClauseKind() == OMPC_linear) 3628 LCs.push_back(cast<OMPLinearClause>(Clause)); 3629 } 3630 // OpenMP, 2.7.1 Loop Construct, Restrictions 3631 // The nonmonotonic modifier cannot be specified if an ordered clause is 3632 // specified. 3633 if (SC && 3634 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3635 SC->getSecondScheduleModifier() == 3636 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3637 OC) { 3638 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3639 ? SC->getFirstScheduleModifierLoc() 3640 : SC->getSecondScheduleModifierLoc(), 3641 diag::err_omp_schedule_nonmonotonic_ordered) 3642 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3643 ErrorFound = true; 3644 } 3645 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3646 for (const OMPLinearClause *C : LCs) { 3647 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3648 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3649 } 3650 ErrorFound = true; 3651 } 3652 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3653 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3654 OC->getNumForLoops()) { 3655 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3656 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3657 ErrorFound = true; 3658 } 3659 if (ErrorFound) { 3660 return StmtError(); 3661 } 3662 StmtResult SR = S; 3663 unsigned CompletedRegions = 0; 3664 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3665 // Mark all variables in private list clauses as used in inner region. 3666 // Required for proper codegen of combined directives. 3667 // TODO: add processing for other clauses. 3668 if (ThisCaptureRegion != OMPD_unknown) { 3669 for (const clang::OMPClauseWithPreInit *C : PICs) { 3670 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3671 // Find the particular capture region for the clause if the 3672 // directive is a combined one with multiple capture regions. 3673 // If the directive is not a combined one, the capture region 3674 // associated with the clause is OMPD_unknown and is generated 3675 // only once. 3676 if (CaptureRegion == ThisCaptureRegion || 3677 CaptureRegion == OMPD_unknown) { 3678 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3679 for (Decl *D : DS->decls()) 3680 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3681 } 3682 } 3683 } 3684 } 3685 if (++CompletedRegions == CaptureRegions.size()) 3686 DSAStack->setBodyComplete(); 3687 SR = ActOnCapturedRegionEnd(SR.get()); 3688 } 3689 return SR; 3690 } 3691 3692 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3693 OpenMPDirectiveKind CancelRegion, 3694 SourceLocation StartLoc) { 3695 // CancelRegion is only needed for cancel and cancellation_point. 3696 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3697 return false; 3698 3699 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3700 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3701 return false; 3702 3703 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3704 << getOpenMPDirectiveName(CancelRegion); 3705 return true; 3706 } 3707 3708 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3709 OpenMPDirectiveKind CurrentRegion, 3710 const DeclarationNameInfo &CurrentName, 3711 OpenMPDirectiveKind CancelRegion, 3712 SourceLocation StartLoc) { 3713 if (Stack->getCurScope()) { 3714 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3715 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3716 bool NestingProhibited = false; 3717 bool CloseNesting = true; 3718 bool OrphanSeen = false; 3719 enum { 3720 NoRecommend, 3721 ShouldBeInParallelRegion, 3722 ShouldBeInOrderedRegion, 3723 ShouldBeInTargetRegion, 3724 ShouldBeInTeamsRegion 3725 } Recommend = NoRecommend; 3726 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3727 // OpenMP [2.16, Nesting of Regions] 3728 // OpenMP constructs may not be nested inside a simd region. 3729 // OpenMP [2.8.1,simd Construct, Restrictions] 3730 // An ordered construct with the simd clause is the only OpenMP 3731 // construct that can appear in the simd region. 3732 // Allowing a SIMD construct nested in another SIMD construct is an 3733 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3734 // message. 3735 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3736 ? diag::err_omp_prohibited_region_simd 3737 : diag::warn_omp_nesting_simd); 3738 return CurrentRegion != OMPD_simd; 3739 } 3740 if (ParentRegion == OMPD_atomic) { 3741 // OpenMP [2.16, Nesting of Regions] 3742 // OpenMP constructs may not be nested inside an atomic region. 3743 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3744 return true; 3745 } 3746 if (CurrentRegion == OMPD_section) { 3747 // OpenMP [2.7.2, sections Construct, Restrictions] 3748 // Orphaned section directives are prohibited. That is, the section 3749 // directives must appear within the sections construct and must not be 3750 // encountered elsewhere in the sections region. 3751 if (ParentRegion != OMPD_sections && 3752 ParentRegion != OMPD_parallel_sections) { 3753 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3754 << (ParentRegion != OMPD_unknown) 3755 << getOpenMPDirectiveName(ParentRegion); 3756 return true; 3757 } 3758 return false; 3759 } 3760 // Allow some constructs (except teams and cancellation constructs) to be 3761 // orphaned (they could be used in functions, called from OpenMP regions 3762 // with the required preconditions). 3763 if (ParentRegion == OMPD_unknown && 3764 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3765 CurrentRegion != OMPD_cancellation_point && 3766 CurrentRegion != OMPD_cancel) 3767 return false; 3768 if (CurrentRegion == OMPD_cancellation_point || 3769 CurrentRegion == OMPD_cancel) { 3770 // OpenMP [2.16, Nesting of Regions] 3771 // A cancellation point construct for which construct-type-clause is 3772 // taskgroup must be nested inside a task construct. A cancellation 3773 // point construct for which construct-type-clause is not taskgroup must 3774 // be closely nested inside an OpenMP construct that matches the type 3775 // specified in construct-type-clause. 3776 // A cancel construct for which construct-type-clause is taskgroup must be 3777 // nested inside a task construct. A cancel construct for which 3778 // construct-type-clause is not taskgroup must be closely nested inside an 3779 // OpenMP construct that matches the type specified in 3780 // construct-type-clause. 3781 NestingProhibited = 3782 !((CancelRegion == OMPD_parallel && 3783 (ParentRegion == OMPD_parallel || 3784 ParentRegion == OMPD_target_parallel)) || 3785 (CancelRegion == OMPD_for && 3786 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3787 ParentRegion == OMPD_target_parallel_for || 3788 ParentRegion == OMPD_distribute_parallel_for || 3789 ParentRegion == OMPD_teams_distribute_parallel_for || 3790 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3791 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3792 (CancelRegion == OMPD_sections && 3793 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3794 ParentRegion == OMPD_parallel_sections))); 3795 OrphanSeen = ParentRegion == OMPD_unknown; 3796 } else if (CurrentRegion == OMPD_master) { 3797 // OpenMP [2.16, Nesting of Regions] 3798 // A master region may not be closely nested inside a worksharing, 3799 // atomic, or explicit task region. 3800 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3801 isOpenMPTaskingDirective(ParentRegion); 3802 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3803 // OpenMP [2.16, Nesting of Regions] 3804 // A critical region may not be nested (closely or otherwise) inside a 3805 // critical region with the same name. Note that this restriction is not 3806 // sufficient to prevent deadlock. 3807 SourceLocation PreviousCriticalLoc; 3808 bool DeadLock = Stack->hasDirective( 3809 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3810 const DeclarationNameInfo &DNI, 3811 SourceLocation Loc) { 3812 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3813 PreviousCriticalLoc = Loc; 3814 return true; 3815 } 3816 return false; 3817 }, 3818 false /* skip top directive */); 3819 if (DeadLock) { 3820 SemaRef.Diag(StartLoc, 3821 diag::err_omp_prohibited_region_critical_same_name) 3822 << CurrentName.getName(); 3823 if (PreviousCriticalLoc.isValid()) 3824 SemaRef.Diag(PreviousCriticalLoc, 3825 diag::note_omp_previous_critical_region); 3826 return true; 3827 } 3828 } else if (CurrentRegion == OMPD_barrier) { 3829 // OpenMP [2.16, Nesting of Regions] 3830 // A barrier region may not be closely nested inside a worksharing, 3831 // explicit task, critical, ordered, atomic, or master region. 3832 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3833 isOpenMPTaskingDirective(ParentRegion) || 3834 ParentRegion == OMPD_master || 3835 ParentRegion == OMPD_critical || 3836 ParentRegion == OMPD_ordered; 3837 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3838 !isOpenMPParallelDirective(CurrentRegion) && 3839 !isOpenMPTeamsDirective(CurrentRegion)) { 3840 // OpenMP [2.16, Nesting of Regions] 3841 // A worksharing region may not be closely nested inside a worksharing, 3842 // explicit task, critical, ordered, atomic, or master region. 3843 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3844 isOpenMPTaskingDirective(ParentRegion) || 3845 ParentRegion == OMPD_master || 3846 ParentRegion == OMPD_critical || 3847 ParentRegion == OMPD_ordered; 3848 Recommend = ShouldBeInParallelRegion; 3849 } else if (CurrentRegion == OMPD_ordered) { 3850 // OpenMP [2.16, Nesting of Regions] 3851 // An ordered region may not be closely nested inside a critical, 3852 // atomic, or explicit task region. 3853 // An ordered region must be closely nested inside a loop region (or 3854 // parallel loop region) with an ordered clause. 3855 // OpenMP [2.8.1,simd Construct, Restrictions] 3856 // An ordered construct with the simd clause is the only OpenMP construct 3857 // that can appear in the simd region. 3858 NestingProhibited = ParentRegion == OMPD_critical || 3859 isOpenMPTaskingDirective(ParentRegion) || 3860 !(isOpenMPSimdDirective(ParentRegion) || 3861 Stack->isParentOrderedRegion()); 3862 Recommend = ShouldBeInOrderedRegion; 3863 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3864 // OpenMP [2.16, Nesting of Regions] 3865 // If specified, a teams construct must be contained within a target 3866 // construct. 3867 NestingProhibited = 3868 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 3869 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 3870 ParentRegion != OMPD_target); 3871 OrphanSeen = ParentRegion == OMPD_unknown; 3872 Recommend = ShouldBeInTargetRegion; 3873 } 3874 if (!NestingProhibited && 3875 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3876 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3877 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3878 // OpenMP [2.16, Nesting of Regions] 3879 // distribute, parallel, parallel sections, parallel workshare, and the 3880 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3881 // constructs that can be closely nested in the teams region. 3882 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3883 !isOpenMPDistributeDirective(CurrentRegion); 3884 Recommend = ShouldBeInParallelRegion; 3885 } 3886 if (!NestingProhibited && 3887 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3888 // OpenMP 4.5 [2.17 Nesting of Regions] 3889 // The region associated with the distribute construct must be strictly 3890 // nested inside a teams region 3891 NestingProhibited = 3892 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3893 Recommend = ShouldBeInTeamsRegion; 3894 } 3895 if (!NestingProhibited && 3896 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3897 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3898 // OpenMP 4.5 [2.17 Nesting of Regions] 3899 // If a target, target update, target data, target enter data, or 3900 // target exit data construct is encountered during execution of a 3901 // target region, the behavior is unspecified. 3902 NestingProhibited = Stack->hasDirective( 3903 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3904 SourceLocation) { 3905 if (isOpenMPTargetExecutionDirective(K)) { 3906 OffendingRegion = K; 3907 return true; 3908 } 3909 return false; 3910 }, 3911 false /* don't skip top directive */); 3912 CloseNesting = false; 3913 } 3914 if (NestingProhibited) { 3915 if (OrphanSeen) { 3916 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3917 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3918 } else { 3919 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3920 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3921 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3922 } 3923 return true; 3924 } 3925 } 3926 return false; 3927 } 3928 3929 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3930 ArrayRef<OMPClause *> Clauses, 3931 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3932 bool ErrorFound = false; 3933 unsigned NamedModifiersNumber = 0; 3934 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3935 OMPD_unknown + 1); 3936 SmallVector<SourceLocation, 4> NameModifierLoc; 3937 for (const OMPClause *C : Clauses) { 3938 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3939 // At most one if clause without a directive-name-modifier can appear on 3940 // the directive. 3941 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3942 if (FoundNameModifiers[CurNM]) { 3943 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3944 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3945 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3946 ErrorFound = true; 3947 } else if (CurNM != OMPD_unknown) { 3948 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3949 ++NamedModifiersNumber; 3950 } 3951 FoundNameModifiers[CurNM] = IC; 3952 if (CurNM == OMPD_unknown) 3953 continue; 3954 // Check if the specified name modifier is allowed for the current 3955 // directive. 3956 // At most one if clause with the particular directive-name-modifier can 3957 // appear on the directive. 3958 bool MatchFound = false; 3959 for (auto NM : AllowedNameModifiers) { 3960 if (CurNM == NM) { 3961 MatchFound = true; 3962 break; 3963 } 3964 } 3965 if (!MatchFound) { 3966 S.Diag(IC->getNameModifierLoc(), 3967 diag::err_omp_wrong_if_directive_name_modifier) 3968 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3969 ErrorFound = true; 3970 } 3971 } 3972 } 3973 // If any if clause on the directive includes a directive-name-modifier then 3974 // all if clauses on the directive must include a directive-name-modifier. 3975 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3976 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3977 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3978 diag::err_omp_no_more_if_clause); 3979 } else { 3980 std::string Values; 3981 std::string Sep(", "); 3982 unsigned AllowedCnt = 0; 3983 unsigned TotalAllowedNum = 3984 AllowedNameModifiers.size() - NamedModifiersNumber; 3985 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3986 ++Cnt) { 3987 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3988 if (!FoundNameModifiers[NM]) { 3989 Values += "'"; 3990 Values += getOpenMPDirectiveName(NM); 3991 Values += "'"; 3992 if (AllowedCnt + 2 == TotalAllowedNum) 3993 Values += " or "; 3994 else if (AllowedCnt + 1 != TotalAllowedNum) 3995 Values += Sep; 3996 ++AllowedCnt; 3997 } 3998 } 3999 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4000 diag::err_omp_unnamed_if_clause) 4001 << (TotalAllowedNum > 1) << Values; 4002 } 4003 for (SourceLocation Loc : NameModifierLoc) { 4004 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4005 } 4006 ErrorFound = true; 4007 } 4008 return ErrorFound; 4009 } 4010 4011 static std::pair<ValueDecl *, bool> 4012 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4013 SourceRange &ERange, bool AllowArraySection = false) { 4014 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4015 RefExpr->containsUnexpandedParameterPack()) 4016 return std::make_pair(nullptr, true); 4017 4018 // OpenMP [3.1, C/C++] 4019 // A list item is a variable name. 4020 // OpenMP [2.9.3.3, Restrictions, p.1] 4021 // A variable that is part of another variable (as an array or 4022 // structure element) cannot appear in a private clause. 4023 RefExpr = RefExpr->IgnoreParens(); 4024 enum { 4025 NoArrayExpr = -1, 4026 ArraySubscript = 0, 4027 OMPArraySection = 1 4028 } IsArrayExpr = NoArrayExpr; 4029 if (AllowArraySection) { 4030 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4031 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4032 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4033 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4034 RefExpr = Base; 4035 IsArrayExpr = ArraySubscript; 4036 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4037 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4038 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4039 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4040 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4041 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4042 RefExpr = Base; 4043 IsArrayExpr = OMPArraySection; 4044 } 4045 } 4046 ELoc = RefExpr->getExprLoc(); 4047 ERange = RefExpr->getSourceRange(); 4048 RefExpr = RefExpr->IgnoreParenImpCasts(); 4049 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4050 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4051 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4052 (S.getCurrentThisType().isNull() || !ME || 4053 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4054 !isa<FieldDecl>(ME->getMemberDecl()))) { 4055 if (IsArrayExpr != NoArrayExpr) { 4056 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4057 << ERange; 4058 } else { 4059 S.Diag(ELoc, 4060 AllowArraySection 4061 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4062 : diag::err_omp_expected_var_name_member_expr) 4063 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4064 } 4065 return std::make_pair(nullptr, false); 4066 } 4067 return std::make_pair( 4068 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4069 } 4070 4071 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4072 ArrayRef<OMPClause *> Clauses) { 4073 assert(!S.CurContext->isDependentContext() && 4074 "Expected non-dependent context."); 4075 auto AllocateRange = 4076 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4077 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4078 DeclToCopy; 4079 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4080 return isOpenMPPrivate(C->getClauseKind()); 4081 }); 4082 for (OMPClause *Cl : PrivateRange) { 4083 MutableArrayRef<Expr *>::iterator I, It, Et; 4084 if (Cl->getClauseKind() == OMPC_private) { 4085 auto *PC = cast<OMPPrivateClause>(Cl); 4086 I = PC->private_copies().begin(); 4087 It = PC->varlist_begin(); 4088 Et = PC->varlist_end(); 4089 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4090 auto *PC = cast<OMPFirstprivateClause>(Cl); 4091 I = PC->private_copies().begin(); 4092 It = PC->varlist_begin(); 4093 Et = PC->varlist_end(); 4094 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4095 auto *PC = cast<OMPLastprivateClause>(Cl); 4096 I = PC->private_copies().begin(); 4097 It = PC->varlist_begin(); 4098 Et = PC->varlist_end(); 4099 } else if (Cl->getClauseKind() == OMPC_linear) { 4100 auto *PC = cast<OMPLinearClause>(Cl); 4101 I = PC->privates().begin(); 4102 It = PC->varlist_begin(); 4103 Et = PC->varlist_end(); 4104 } else if (Cl->getClauseKind() == OMPC_reduction) { 4105 auto *PC = cast<OMPReductionClause>(Cl); 4106 I = PC->privates().begin(); 4107 It = PC->varlist_begin(); 4108 Et = PC->varlist_end(); 4109 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4110 auto *PC = cast<OMPTaskReductionClause>(Cl); 4111 I = PC->privates().begin(); 4112 It = PC->varlist_begin(); 4113 Et = PC->varlist_end(); 4114 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4115 auto *PC = cast<OMPInReductionClause>(Cl); 4116 I = PC->privates().begin(); 4117 It = PC->varlist_begin(); 4118 Et = PC->varlist_end(); 4119 } else { 4120 llvm_unreachable("Expected private clause."); 4121 } 4122 for (Expr *E : llvm::make_range(It, Et)) { 4123 if (!*I) { 4124 ++I; 4125 continue; 4126 } 4127 SourceLocation ELoc; 4128 SourceRange ERange; 4129 Expr *SimpleRefExpr = E; 4130 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4131 /*AllowArraySection=*/true); 4132 DeclToCopy.try_emplace(Res.first, 4133 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4134 ++I; 4135 } 4136 } 4137 for (OMPClause *C : AllocateRange) { 4138 auto *AC = cast<OMPAllocateClause>(C); 4139 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4140 getAllocatorKind(S, Stack, AC->getAllocator()); 4141 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4142 // For task, taskloop or target directives, allocation requests to memory 4143 // allocators with the trait access set to thread result in unspecified 4144 // behavior. 4145 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4146 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4147 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4148 S.Diag(AC->getAllocator()->getExprLoc(), 4149 diag::warn_omp_allocate_thread_on_task_target_directive) 4150 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4151 } 4152 for (Expr *E : AC->varlists()) { 4153 SourceLocation ELoc; 4154 SourceRange ERange; 4155 Expr *SimpleRefExpr = E; 4156 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4157 ValueDecl *VD = Res.first; 4158 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4159 if (!isOpenMPPrivate(Data.CKind)) { 4160 S.Diag(E->getExprLoc(), 4161 diag::err_omp_expected_private_copy_for_allocate); 4162 continue; 4163 } 4164 VarDecl *PrivateVD = DeclToCopy[VD]; 4165 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4166 AllocatorKind, AC->getAllocator())) 4167 continue; 4168 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4169 E->getSourceRange()); 4170 } 4171 } 4172 } 4173 4174 StmtResult Sema::ActOnOpenMPExecutableDirective( 4175 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4176 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4177 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4178 StmtResult Res = StmtError(); 4179 // First check CancelRegion which is then used in checkNestingOfRegions. 4180 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4181 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4182 StartLoc)) 4183 return StmtError(); 4184 4185 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4186 VarsWithInheritedDSAType VarsWithInheritedDSA; 4187 bool ErrorFound = false; 4188 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4189 if (AStmt && !CurContext->isDependentContext()) { 4190 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4191 4192 // Check default data sharing attributes for referenced variables. 4193 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4194 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4195 Stmt *S = AStmt; 4196 while (--ThisCaptureLevel >= 0) 4197 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4198 DSAChecker.Visit(S); 4199 if (!isOpenMPTargetDataManagementDirective(Kind) && 4200 !isOpenMPTaskingDirective(Kind)) { 4201 // Visit subcaptures to generate implicit clauses for captured vars. 4202 auto *CS = cast<CapturedStmt>(AStmt); 4203 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4204 getOpenMPCaptureRegions(CaptureRegions, Kind); 4205 // Ignore outer tasking regions for target directives. 4206 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4207 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4208 DSAChecker.visitSubCaptures(CS); 4209 } 4210 if (DSAChecker.isErrorFound()) 4211 return StmtError(); 4212 // Generate list of implicitly defined firstprivate variables. 4213 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4214 4215 SmallVector<Expr *, 4> ImplicitFirstprivates( 4216 DSAChecker.getImplicitFirstprivate().begin(), 4217 DSAChecker.getImplicitFirstprivate().end()); 4218 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4219 DSAChecker.getImplicitMap().end()); 4220 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4221 for (OMPClause *C : Clauses) { 4222 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4223 for (Expr *E : IRC->taskgroup_descriptors()) 4224 if (E) 4225 ImplicitFirstprivates.emplace_back(E); 4226 } 4227 } 4228 if (!ImplicitFirstprivates.empty()) { 4229 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4230 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4231 SourceLocation())) { 4232 ClausesWithImplicit.push_back(Implicit); 4233 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4234 ImplicitFirstprivates.size(); 4235 } else { 4236 ErrorFound = true; 4237 } 4238 } 4239 if (!ImplicitMaps.empty()) { 4240 CXXScopeSpec MapperIdScopeSpec; 4241 DeclarationNameInfo MapperId; 4242 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4243 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4244 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4245 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4246 ClausesWithImplicit.emplace_back(Implicit); 4247 ErrorFound |= 4248 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4249 } else { 4250 ErrorFound = true; 4251 } 4252 } 4253 } 4254 4255 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4256 switch (Kind) { 4257 case OMPD_parallel: 4258 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4259 EndLoc); 4260 AllowedNameModifiers.push_back(OMPD_parallel); 4261 break; 4262 case OMPD_simd: 4263 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4264 VarsWithInheritedDSA); 4265 break; 4266 case OMPD_for: 4267 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4268 VarsWithInheritedDSA); 4269 break; 4270 case OMPD_for_simd: 4271 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4272 EndLoc, VarsWithInheritedDSA); 4273 break; 4274 case OMPD_sections: 4275 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4276 EndLoc); 4277 break; 4278 case OMPD_section: 4279 assert(ClausesWithImplicit.empty() && 4280 "No clauses are allowed for 'omp section' directive"); 4281 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4282 break; 4283 case OMPD_single: 4284 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4285 EndLoc); 4286 break; 4287 case OMPD_master: 4288 assert(ClausesWithImplicit.empty() && 4289 "No clauses are allowed for 'omp master' directive"); 4290 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4291 break; 4292 case OMPD_critical: 4293 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4294 StartLoc, EndLoc); 4295 break; 4296 case OMPD_parallel_for: 4297 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4298 EndLoc, VarsWithInheritedDSA); 4299 AllowedNameModifiers.push_back(OMPD_parallel); 4300 break; 4301 case OMPD_parallel_for_simd: 4302 Res = ActOnOpenMPParallelForSimdDirective( 4303 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4304 AllowedNameModifiers.push_back(OMPD_parallel); 4305 break; 4306 case OMPD_parallel_sections: 4307 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4308 StartLoc, EndLoc); 4309 AllowedNameModifiers.push_back(OMPD_parallel); 4310 break; 4311 case OMPD_task: 4312 Res = 4313 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4314 AllowedNameModifiers.push_back(OMPD_task); 4315 break; 4316 case OMPD_taskyield: 4317 assert(ClausesWithImplicit.empty() && 4318 "No clauses are allowed for 'omp taskyield' directive"); 4319 assert(AStmt == nullptr && 4320 "No associated statement allowed for 'omp taskyield' directive"); 4321 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4322 break; 4323 case OMPD_barrier: 4324 assert(ClausesWithImplicit.empty() && 4325 "No clauses are allowed for 'omp barrier' directive"); 4326 assert(AStmt == nullptr && 4327 "No associated statement allowed for 'omp barrier' directive"); 4328 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4329 break; 4330 case OMPD_taskwait: 4331 assert(ClausesWithImplicit.empty() && 4332 "No clauses are allowed for 'omp taskwait' directive"); 4333 assert(AStmt == nullptr && 4334 "No associated statement allowed for 'omp taskwait' directive"); 4335 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4336 break; 4337 case OMPD_taskgroup: 4338 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4339 EndLoc); 4340 break; 4341 case OMPD_flush: 4342 assert(AStmt == nullptr && 4343 "No associated statement allowed for 'omp flush' directive"); 4344 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4345 break; 4346 case OMPD_ordered: 4347 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4348 EndLoc); 4349 break; 4350 case OMPD_atomic: 4351 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4352 EndLoc); 4353 break; 4354 case OMPD_teams: 4355 Res = 4356 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4357 break; 4358 case OMPD_target: 4359 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4360 EndLoc); 4361 AllowedNameModifiers.push_back(OMPD_target); 4362 break; 4363 case OMPD_target_parallel: 4364 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4365 StartLoc, EndLoc); 4366 AllowedNameModifiers.push_back(OMPD_target); 4367 AllowedNameModifiers.push_back(OMPD_parallel); 4368 break; 4369 case OMPD_target_parallel_for: 4370 Res = ActOnOpenMPTargetParallelForDirective( 4371 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4372 AllowedNameModifiers.push_back(OMPD_target); 4373 AllowedNameModifiers.push_back(OMPD_parallel); 4374 break; 4375 case OMPD_cancellation_point: 4376 assert(ClausesWithImplicit.empty() && 4377 "No clauses are allowed for 'omp cancellation point' directive"); 4378 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4379 "cancellation point' directive"); 4380 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4381 break; 4382 case OMPD_cancel: 4383 assert(AStmt == nullptr && 4384 "No associated statement allowed for 'omp cancel' directive"); 4385 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4386 CancelRegion); 4387 AllowedNameModifiers.push_back(OMPD_cancel); 4388 break; 4389 case OMPD_target_data: 4390 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4391 EndLoc); 4392 AllowedNameModifiers.push_back(OMPD_target_data); 4393 break; 4394 case OMPD_target_enter_data: 4395 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4396 EndLoc, AStmt); 4397 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4398 break; 4399 case OMPD_target_exit_data: 4400 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4401 EndLoc, AStmt); 4402 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4403 break; 4404 case OMPD_taskloop: 4405 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4406 EndLoc, VarsWithInheritedDSA); 4407 AllowedNameModifiers.push_back(OMPD_taskloop); 4408 break; 4409 case OMPD_taskloop_simd: 4410 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4411 EndLoc, VarsWithInheritedDSA); 4412 AllowedNameModifiers.push_back(OMPD_taskloop); 4413 break; 4414 case OMPD_master_taskloop: 4415 Res = ActOnOpenMPMasterTaskLoopDirective( 4416 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4417 AllowedNameModifiers.push_back(OMPD_taskloop); 4418 break; 4419 case OMPD_distribute: 4420 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4421 EndLoc, VarsWithInheritedDSA); 4422 break; 4423 case OMPD_target_update: 4424 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4425 EndLoc, AStmt); 4426 AllowedNameModifiers.push_back(OMPD_target_update); 4427 break; 4428 case OMPD_distribute_parallel_for: 4429 Res = ActOnOpenMPDistributeParallelForDirective( 4430 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4431 AllowedNameModifiers.push_back(OMPD_parallel); 4432 break; 4433 case OMPD_distribute_parallel_for_simd: 4434 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4435 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4436 AllowedNameModifiers.push_back(OMPD_parallel); 4437 break; 4438 case OMPD_distribute_simd: 4439 Res = ActOnOpenMPDistributeSimdDirective( 4440 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4441 break; 4442 case OMPD_target_parallel_for_simd: 4443 Res = ActOnOpenMPTargetParallelForSimdDirective( 4444 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4445 AllowedNameModifiers.push_back(OMPD_target); 4446 AllowedNameModifiers.push_back(OMPD_parallel); 4447 break; 4448 case OMPD_target_simd: 4449 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4450 EndLoc, VarsWithInheritedDSA); 4451 AllowedNameModifiers.push_back(OMPD_target); 4452 break; 4453 case OMPD_teams_distribute: 4454 Res = ActOnOpenMPTeamsDistributeDirective( 4455 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4456 break; 4457 case OMPD_teams_distribute_simd: 4458 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4459 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4460 break; 4461 case OMPD_teams_distribute_parallel_for_simd: 4462 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4463 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4464 AllowedNameModifiers.push_back(OMPD_parallel); 4465 break; 4466 case OMPD_teams_distribute_parallel_for: 4467 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4468 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4469 AllowedNameModifiers.push_back(OMPD_parallel); 4470 break; 4471 case OMPD_target_teams: 4472 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4473 EndLoc); 4474 AllowedNameModifiers.push_back(OMPD_target); 4475 break; 4476 case OMPD_target_teams_distribute: 4477 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4478 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4479 AllowedNameModifiers.push_back(OMPD_target); 4480 break; 4481 case OMPD_target_teams_distribute_parallel_for: 4482 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4483 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4484 AllowedNameModifiers.push_back(OMPD_target); 4485 AllowedNameModifiers.push_back(OMPD_parallel); 4486 break; 4487 case OMPD_target_teams_distribute_parallel_for_simd: 4488 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4489 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4490 AllowedNameModifiers.push_back(OMPD_target); 4491 AllowedNameModifiers.push_back(OMPD_parallel); 4492 break; 4493 case OMPD_target_teams_distribute_simd: 4494 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4495 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4496 AllowedNameModifiers.push_back(OMPD_target); 4497 break; 4498 case OMPD_declare_target: 4499 case OMPD_end_declare_target: 4500 case OMPD_threadprivate: 4501 case OMPD_allocate: 4502 case OMPD_declare_reduction: 4503 case OMPD_declare_mapper: 4504 case OMPD_declare_simd: 4505 case OMPD_requires: 4506 case OMPD_declare_variant: 4507 llvm_unreachable("OpenMP Directive is not allowed"); 4508 case OMPD_unknown: 4509 llvm_unreachable("Unknown OpenMP directive"); 4510 } 4511 4512 ErrorFound = Res.isInvalid() || ErrorFound; 4513 4514 // Check variables in the clauses if default(none) was specified. 4515 if (DSAStack->getDefaultDSA() == DSA_none) { 4516 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4517 for (OMPClause *C : Clauses) { 4518 switch (C->getClauseKind()) { 4519 case OMPC_num_threads: 4520 case OMPC_dist_schedule: 4521 // Do not analyse if no parent teams directive. 4522 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4523 break; 4524 continue; 4525 case OMPC_if: 4526 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4527 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4528 break; 4529 continue; 4530 case OMPC_schedule: 4531 break; 4532 case OMPC_ordered: 4533 case OMPC_device: 4534 case OMPC_num_teams: 4535 case OMPC_thread_limit: 4536 case OMPC_priority: 4537 case OMPC_grainsize: 4538 case OMPC_num_tasks: 4539 case OMPC_hint: 4540 case OMPC_collapse: 4541 case OMPC_safelen: 4542 case OMPC_simdlen: 4543 case OMPC_final: 4544 case OMPC_default: 4545 case OMPC_proc_bind: 4546 case OMPC_private: 4547 case OMPC_firstprivate: 4548 case OMPC_lastprivate: 4549 case OMPC_shared: 4550 case OMPC_reduction: 4551 case OMPC_task_reduction: 4552 case OMPC_in_reduction: 4553 case OMPC_linear: 4554 case OMPC_aligned: 4555 case OMPC_copyin: 4556 case OMPC_copyprivate: 4557 case OMPC_nowait: 4558 case OMPC_untied: 4559 case OMPC_mergeable: 4560 case OMPC_allocate: 4561 case OMPC_read: 4562 case OMPC_write: 4563 case OMPC_update: 4564 case OMPC_capture: 4565 case OMPC_seq_cst: 4566 case OMPC_depend: 4567 case OMPC_threads: 4568 case OMPC_simd: 4569 case OMPC_map: 4570 case OMPC_nogroup: 4571 case OMPC_defaultmap: 4572 case OMPC_to: 4573 case OMPC_from: 4574 case OMPC_use_device_ptr: 4575 case OMPC_is_device_ptr: 4576 continue; 4577 case OMPC_allocator: 4578 case OMPC_flush: 4579 case OMPC_threadprivate: 4580 case OMPC_uniform: 4581 case OMPC_unknown: 4582 case OMPC_unified_address: 4583 case OMPC_unified_shared_memory: 4584 case OMPC_reverse_offload: 4585 case OMPC_dynamic_allocators: 4586 case OMPC_atomic_default_mem_order: 4587 case OMPC_device_type: 4588 case OMPC_match: 4589 llvm_unreachable("Unexpected clause"); 4590 } 4591 for (Stmt *CC : C->children()) { 4592 if (CC) 4593 DSAChecker.Visit(CC); 4594 } 4595 } 4596 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4597 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4598 } 4599 for (const auto &P : VarsWithInheritedDSA) { 4600 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4601 continue; 4602 ErrorFound = true; 4603 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4604 << P.first << P.second->getSourceRange(); 4605 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4606 } 4607 4608 if (!AllowedNameModifiers.empty()) 4609 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4610 ErrorFound; 4611 4612 if (ErrorFound) 4613 return StmtError(); 4614 4615 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4616 Res.getAs<OMPExecutableDirective>() 4617 ->getStructuredBlock() 4618 ->setIsOMPStructuredBlock(true); 4619 } 4620 4621 if (!CurContext->isDependentContext() && 4622 isOpenMPTargetExecutionDirective(Kind) && 4623 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4624 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4625 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4626 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4627 // Register target to DSA Stack. 4628 DSAStack->addTargetDirLocation(StartLoc); 4629 } 4630 4631 return Res; 4632 } 4633 4634 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4635 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4636 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4637 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4638 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4639 assert(Aligneds.size() == Alignments.size()); 4640 assert(Linears.size() == LinModifiers.size()); 4641 assert(Linears.size() == Steps.size()); 4642 if (!DG || DG.get().isNull()) 4643 return DeclGroupPtrTy(); 4644 4645 const int SimdId = 0; 4646 if (!DG.get().isSingleDecl()) { 4647 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4648 << SimdId; 4649 return DG; 4650 } 4651 Decl *ADecl = DG.get().getSingleDecl(); 4652 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4653 ADecl = FTD->getTemplatedDecl(); 4654 4655 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4656 if (!FD) { 4657 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4658 return DeclGroupPtrTy(); 4659 } 4660 4661 // OpenMP [2.8.2, declare simd construct, Description] 4662 // The parameter of the simdlen clause must be a constant positive integer 4663 // expression. 4664 ExprResult SL; 4665 if (Simdlen) 4666 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4667 // OpenMP [2.8.2, declare simd construct, Description] 4668 // The special this pointer can be used as if was one of the arguments to the 4669 // function in any of the linear, aligned, or uniform clauses. 4670 // The uniform clause declares one or more arguments to have an invariant 4671 // value for all concurrent invocations of the function in the execution of a 4672 // single SIMD loop. 4673 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4674 const Expr *UniformedLinearThis = nullptr; 4675 for (const Expr *E : Uniforms) { 4676 E = E->IgnoreParenImpCasts(); 4677 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4678 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4679 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4680 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4681 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4682 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4683 continue; 4684 } 4685 if (isa<CXXThisExpr>(E)) { 4686 UniformedLinearThis = E; 4687 continue; 4688 } 4689 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4690 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4691 } 4692 // OpenMP [2.8.2, declare simd construct, Description] 4693 // The aligned clause declares that the object to which each list item points 4694 // is aligned to the number of bytes expressed in the optional parameter of 4695 // the aligned clause. 4696 // The special this pointer can be used as if was one of the arguments to the 4697 // function in any of the linear, aligned, or uniform clauses. 4698 // The type of list items appearing in the aligned clause must be array, 4699 // pointer, reference to array, or reference to pointer. 4700 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4701 const Expr *AlignedThis = nullptr; 4702 for (const Expr *E : Aligneds) { 4703 E = E->IgnoreParenImpCasts(); 4704 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4705 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4706 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4707 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4708 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4709 ->getCanonicalDecl() == CanonPVD) { 4710 // OpenMP [2.8.1, simd construct, Restrictions] 4711 // A list-item cannot appear in more than one aligned clause. 4712 if (AlignedArgs.count(CanonPVD) > 0) { 4713 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4714 << 1 << E->getSourceRange(); 4715 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4716 diag::note_omp_explicit_dsa) 4717 << getOpenMPClauseName(OMPC_aligned); 4718 continue; 4719 } 4720 AlignedArgs[CanonPVD] = E; 4721 QualType QTy = PVD->getType() 4722 .getNonReferenceType() 4723 .getUnqualifiedType() 4724 .getCanonicalType(); 4725 const Type *Ty = QTy.getTypePtrOrNull(); 4726 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4727 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4728 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4729 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4730 } 4731 continue; 4732 } 4733 } 4734 if (isa<CXXThisExpr>(E)) { 4735 if (AlignedThis) { 4736 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4737 << 2 << E->getSourceRange(); 4738 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4739 << getOpenMPClauseName(OMPC_aligned); 4740 } 4741 AlignedThis = E; 4742 continue; 4743 } 4744 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4745 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4746 } 4747 // The optional parameter of the aligned clause, alignment, must be a constant 4748 // positive integer expression. If no optional parameter is specified, 4749 // implementation-defined default alignments for SIMD instructions on the 4750 // target platforms are assumed. 4751 SmallVector<const Expr *, 4> NewAligns; 4752 for (Expr *E : Alignments) { 4753 ExprResult Align; 4754 if (E) 4755 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4756 NewAligns.push_back(Align.get()); 4757 } 4758 // OpenMP [2.8.2, declare simd construct, Description] 4759 // The linear clause declares one or more list items to be private to a SIMD 4760 // lane and to have a linear relationship with respect to the iteration space 4761 // of a loop. 4762 // The special this pointer can be used as if was one of the arguments to the 4763 // function in any of the linear, aligned, or uniform clauses. 4764 // When a linear-step expression is specified in a linear clause it must be 4765 // either a constant integer expression or an integer-typed parameter that is 4766 // specified in a uniform clause on the directive. 4767 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4768 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4769 auto MI = LinModifiers.begin(); 4770 for (const Expr *E : Linears) { 4771 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4772 ++MI; 4773 E = E->IgnoreParenImpCasts(); 4774 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4775 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4776 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4777 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4778 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4779 ->getCanonicalDecl() == CanonPVD) { 4780 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4781 // A list-item cannot appear in more than one linear clause. 4782 if (LinearArgs.count(CanonPVD) > 0) { 4783 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4784 << getOpenMPClauseName(OMPC_linear) 4785 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4786 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4787 diag::note_omp_explicit_dsa) 4788 << getOpenMPClauseName(OMPC_linear); 4789 continue; 4790 } 4791 // Each argument can appear in at most one uniform or linear clause. 4792 if (UniformedArgs.count(CanonPVD) > 0) { 4793 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4794 << getOpenMPClauseName(OMPC_linear) 4795 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4796 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4797 diag::note_omp_explicit_dsa) 4798 << getOpenMPClauseName(OMPC_uniform); 4799 continue; 4800 } 4801 LinearArgs[CanonPVD] = E; 4802 if (E->isValueDependent() || E->isTypeDependent() || 4803 E->isInstantiationDependent() || 4804 E->containsUnexpandedParameterPack()) 4805 continue; 4806 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4807 PVD->getOriginalType()); 4808 continue; 4809 } 4810 } 4811 if (isa<CXXThisExpr>(E)) { 4812 if (UniformedLinearThis) { 4813 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4814 << getOpenMPClauseName(OMPC_linear) 4815 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4816 << E->getSourceRange(); 4817 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4818 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4819 : OMPC_linear); 4820 continue; 4821 } 4822 UniformedLinearThis = E; 4823 if (E->isValueDependent() || E->isTypeDependent() || 4824 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4825 continue; 4826 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4827 E->getType()); 4828 continue; 4829 } 4830 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4831 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4832 } 4833 Expr *Step = nullptr; 4834 Expr *NewStep = nullptr; 4835 SmallVector<Expr *, 4> NewSteps; 4836 for (Expr *E : Steps) { 4837 // Skip the same step expression, it was checked already. 4838 if (Step == E || !E) { 4839 NewSteps.push_back(E ? NewStep : nullptr); 4840 continue; 4841 } 4842 Step = E; 4843 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4844 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4845 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4846 if (UniformedArgs.count(CanonPVD) == 0) { 4847 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4848 << Step->getSourceRange(); 4849 } else if (E->isValueDependent() || E->isTypeDependent() || 4850 E->isInstantiationDependent() || 4851 E->containsUnexpandedParameterPack() || 4852 CanonPVD->getType()->hasIntegerRepresentation()) { 4853 NewSteps.push_back(Step); 4854 } else { 4855 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4856 << Step->getSourceRange(); 4857 } 4858 continue; 4859 } 4860 NewStep = Step; 4861 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4862 !Step->isInstantiationDependent() && 4863 !Step->containsUnexpandedParameterPack()) { 4864 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4865 .get(); 4866 if (NewStep) 4867 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4868 } 4869 NewSteps.push_back(NewStep); 4870 } 4871 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4872 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4873 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4874 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4875 const_cast<Expr **>(Linears.data()), Linears.size(), 4876 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4877 NewSteps.data(), NewSteps.size(), SR); 4878 ADecl->addAttr(NewAttr); 4879 return DG; 4880 } 4881 4882 Optional<std::pair<FunctionDecl *, Expr *>> 4883 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 4884 Expr *VariantRef, SourceRange SR) { 4885 if (!DG || DG.get().isNull()) 4886 return None; 4887 4888 const int VariantId = 1; 4889 // Must be applied only to single decl. 4890 if (!DG.get().isSingleDecl()) { 4891 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4892 << VariantId << SR; 4893 return None; 4894 } 4895 Decl *ADecl = DG.get().getSingleDecl(); 4896 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4897 ADecl = FTD->getTemplatedDecl(); 4898 4899 // Decl must be a function. 4900 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4901 if (!FD) { 4902 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 4903 << VariantId << SR; 4904 return None; 4905 } 4906 4907 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 4908 return FD->hasAttrs() && 4909 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 4910 FD->hasAttr<TargetAttr>()); 4911 }; 4912 // OpenMP is not compatible with CPU-specific attributes. 4913 if (HasMultiVersionAttributes(FD)) { 4914 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 4915 << SR; 4916 return None; 4917 } 4918 4919 // Allow #pragma omp declare variant only if the function is not used. 4920 if (FD->isUsed(false)) 4921 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 4922 << FD->getLocation(); 4923 4924 // Check if the function was emitted already. 4925 const FunctionDecl *Definition; 4926 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 4927 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 4928 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 4929 << FD->getLocation(); 4930 4931 // The VariantRef must point to function. 4932 if (!VariantRef) { 4933 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 4934 return None; 4935 } 4936 4937 // Do not check templates, wait until instantiation. 4938 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 4939 VariantRef->containsUnexpandedParameterPack() || 4940 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 4941 return std::make_pair(FD, VariantRef); 4942 4943 // Convert VariantRef expression to the type of the original function to 4944 // resolve possible conflicts. 4945 ExprResult VariantRefCast; 4946 if (LangOpts.CPlusPlus) { 4947 QualType FnPtrType; 4948 auto *Method = dyn_cast<CXXMethodDecl>(FD); 4949 if (Method && !Method->isStatic()) { 4950 const Type *ClassType = 4951 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 4952 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 4953 ExprResult ER; 4954 { 4955 // Build adrr_of unary op to correctly handle type checks for member 4956 // functions. 4957 Sema::TentativeAnalysisScope Trap(*this); 4958 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 4959 VariantRef); 4960 } 4961 if (!ER.isUsable()) { 4962 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 4963 << VariantId << VariantRef->getSourceRange(); 4964 return None; 4965 } 4966 VariantRef = ER.get(); 4967 } else { 4968 FnPtrType = Context.getPointerType(FD->getType()); 4969 } 4970 ImplicitConversionSequence ICS = 4971 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 4972 /*SuppressUserConversions=*/false, 4973 /*AllowExplicit=*/false, 4974 /*InOverloadResolution=*/false, 4975 /*CStyle=*/false, 4976 /*AllowObjCWritebackConversion=*/false); 4977 if (ICS.isFailure()) { 4978 Diag(VariantRef->getExprLoc(), 4979 diag::err_omp_declare_variant_incompat_types) 4980 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 4981 return None; 4982 } 4983 VariantRefCast = PerformImplicitConversion( 4984 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 4985 if (!VariantRefCast.isUsable()) 4986 return None; 4987 // Drop previously built artificial addr_of unary op for member functions. 4988 if (Method && !Method->isStatic()) { 4989 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 4990 if (auto *UO = dyn_cast<UnaryOperator>( 4991 PossibleAddrOfVariantRef->IgnoreImplicit())) 4992 VariantRefCast = UO->getSubExpr(); 4993 } 4994 } else { 4995 VariantRefCast = VariantRef; 4996 } 4997 4998 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 4999 if (!ER.isUsable() || 5000 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5001 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5002 << VariantId << VariantRef->getSourceRange(); 5003 return None; 5004 } 5005 5006 // The VariantRef must point to function. 5007 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5008 if (!DRE) { 5009 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5010 << VariantId << VariantRef->getSourceRange(); 5011 return None; 5012 } 5013 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5014 if (!NewFD) { 5015 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5016 << VariantId << VariantRef->getSourceRange(); 5017 return None; 5018 } 5019 5020 // Check if variant function is not marked with declare variant directive. 5021 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5022 Diag(VariantRef->getExprLoc(), 5023 diag::warn_omp_declare_variant_marked_as_declare_variant) 5024 << VariantRef->getSourceRange(); 5025 SourceRange SR = 5026 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5027 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5028 return None; 5029 } 5030 5031 enum DoesntSupport { 5032 VirtFuncs = 1, 5033 Constructors = 3, 5034 Destructors = 4, 5035 DeletedFuncs = 5, 5036 DefaultedFuncs = 6, 5037 ConstexprFuncs = 7, 5038 ConstevalFuncs = 8, 5039 }; 5040 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5041 if (CXXFD->isVirtual()) { 5042 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5043 << VirtFuncs; 5044 return None; 5045 } 5046 5047 if (isa<CXXConstructorDecl>(FD)) { 5048 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5049 << Constructors; 5050 return None; 5051 } 5052 5053 if (isa<CXXDestructorDecl>(FD)) { 5054 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5055 << Destructors; 5056 return None; 5057 } 5058 } 5059 5060 if (FD->isDeleted()) { 5061 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5062 << DeletedFuncs; 5063 return None; 5064 } 5065 5066 if (FD->isDefaulted()) { 5067 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5068 << DefaultedFuncs; 5069 return None; 5070 } 5071 5072 if (FD->isConstexpr()) { 5073 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5074 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5075 return None; 5076 } 5077 5078 // Check general compatibility. 5079 if (areMultiversionVariantFunctionsCompatible( 5080 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5081 PartialDiagnosticAt( 5082 SR.getBegin(), 5083 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5084 PartialDiagnosticAt( 5085 VariantRef->getExprLoc(), 5086 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5087 PartialDiagnosticAt(VariantRef->getExprLoc(), 5088 PDiag(diag::err_omp_declare_variant_diff) 5089 << FD->getLocation()), 5090 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5091 /*CLinkageMayDiffer=*/true)) 5092 return None; 5093 return std::make_pair(FD, cast<Expr>(DRE)); 5094 } 5095 5096 void Sema::ActOnOpenMPDeclareVariantDirective( 5097 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5098 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { 5099 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || 5100 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) 5101 return; 5102 Expr *Score = nullptr; 5103 OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown; 5104 if (Data.CtxScore.isUsable()) { 5105 ST = OMPDeclareVariantAttr::ScoreSpecified; 5106 Score = Data.CtxScore.get(); 5107 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5108 !Score->isInstantiationDependent() && 5109 !Score->containsUnexpandedParameterPack()) { 5110 llvm::APSInt Result; 5111 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); 5112 if (ICE.isInvalid()) 5113 return; 5114 } 5115 } 5116 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5117 Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, 5118 Data.ImplVendors.begin(), Data.ImplVendors.size(), SR); 5119 FD->addAttr(NewAttr); 5120 } 5121 5122 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5123 FunctionDecl *Func, 5124 bool MightBeOdrUse) { 5125 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5126 5127 if (!Func->isDependentContext() && Func->hasAttrs()) { 5128 for (OMPDeclareVariantAttr *A : 5129 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5130 // TODO: add checks for active OpenMP context where possible. 5131 Expr *VariantRef = A->getVariantFuncRef(); 5132 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5133 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5134 if (!F->isDefined() && F->isTemplateInstantiation()) 5135 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5136 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5137 } 5138 } 5139 } 5140 5141 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5142 Stmt *AStmt, 5143 SourceLocation StartLoc, 5144 SourceLocation EndLoc) { 5145 if (!AStmt) 5146 return StmtError(); 5147 5148 auto *CS = cast<CapturedStmt>(AStmt); 5149 // 1.2.2 OpenMP Language Terminology 5150 // Structured block - An executable statement with a single entry at the 5151 // top and a single exit at the bottom. 5152 // The point of exit cannot be a branch out of the structured block. 5153 // longjmp() and throw() must not violate the entry/exit criteria. 5154 CS->getCapturedDecl()->setNothrow(); 5155 5156 setFunctionHasBranchProtectedScope(); 5157 5158 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5159 DSAStack->isCancelRegion()); 5160 } 5161 5162 namespace { 5163 /// Iteration space of a single for loop. 5164 struct LoopIterationSpace final { 5165 /// True if the condition operator is the strict compare operator (<, > or 5166 /// !=). 5167 bool IsStrictCompare = false; 5168 /// Condition of the loop. 5169 Expr *PreCond = nullptr; 5170 /// This expression calculates the number of iterations in the loop. 5171 /// It is always possible to calculate it before starting the loop. 5172 Expr *NumIterations = nullptr; 5173 /// The loop counter variable. 5174 Expr *CounterVar = nullptr; 5175 /// Private loop counter variable. 5176 Expr *PrivateCounterVar = nullptr; 5177 /// This is initializer for the initial value of #CounterVar. 5178 Expr *CounterInit = nullptr; 5179 /// This is step for the #CounterVar used to generate its update: 5180 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5181 Expr *CounterStep = nullptr; 5182 /// Should step be subtracted? 5183 bool Subtract = false; 5184 /// Source range of the loop init. 5185 SourceRange InitSrcRange; 5186 /// Source range of the loop condition. 5187 SourceRange CondSrcRange; 5188 /// Source range of the loop increment. 5189 SourceRange IncSrcRange; 5190 /// Minimum value that can have the loop control variable. Used to support 5191 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5192 /// since only such variables can be used in non-loop invariant expressions. 5193 Expr *MinValue = nullptr; 5194 /// Maximum value that can have the loop control variable. Used to support 5195 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5196 /// since only such variables can be used in non-loop invariant expressions. 5197 Expr *MaxValue = nullptr; 5198 /// true, if the lower bound depends on the outer loop control var. 5199 bool IsNonRectangularLB = false; 5200 /// true, if the upper bound depends on the outer loop control var. 5201 bool IsNonRectangularUB = false; 5202 /// Index of the loop this loop depends on and forms non-rectangular loop 5203 /// nest. 5204 unsigned LoopDependentIdx = 0; 5205 /// Final condition for the non-rectangular loop nest support. It is used to 5206 /// check that the number of iterations for this particular counter must be 5207 /// finished. 5208 Expr *FinalCondition = nullptr; 5209 }; 5210 5211 /// Helper class for checking canonical form of the OpenMP loops and 5212 /// extracting iteration space of each loop in the loop nest, that will be used 5213 /// for IR generation. 5214 class OpenMPIterationSpaceChecker { 5215 /// Reference to Sema. 5216 Sema &SemaRef; 5217 /// Data-sharing stack. 5218 DSAStackTy &Stack; 5219 /// A location for diagnostics (when there is no some better location). 5220 SourceLocation DefaultLoc; 5221 /// A location for diagnostics (when increment is not compatible). 5222 SourceLocation ConditionLoc; 5223 /// A source location for referring to loop init later. 5224 SourceRange InitSrcRange; 5225 /// A source location for referring to condition later. 5226 SourceRange ConditionSrcRange; 5227 /// A source location for referring to increment later. 5228 SourceRange IncrementSrcRange; 5229 /// Loop variable. 5230 ValueDecl *LCDecl = nullptr; 5231 /// Reference to loop variable. 5232 Expr *LCRef = nullptr; 5233 /// Lower bound (initializer for the var). 5234 Expr *LB = nullptr; 5235 /// Upper bound. 5236 Expr *UB = nullptr; 5237 /// Loop step (increment). 5238 Expr *Step = nullptr; 5239 /// This flag is true when condition is one of: 5240 /// Var < UB 5241 /// Var <= UB 5242 /// UB > Var 5243 /// UB >= Var 5244 /// This will have no value when the condition is != 5245 llvm::Optional<bool> TestIsLessOp; 5246 /// This flag is true when condition is strict ( < or > ). 5247 bool TestIsStrictOp = false; 5248 /// This flag is true when step is subtracted on each iteration. 5249 bool SubtractStep = false; 5250 /// The outer loop counter this loop depends on (if any). 5251 const ValueDecl *DepDecl = nullptr; 5252 /// Contains number of loop (starts from 1) on which loop counter init 5253 /// expression of this loop depends on. 5254 Optional<unsigned> InitDependOnLC; 5255 /// Contains number of loop (starts from 1) on which loop counter condition 5256 /// expression of this loop depends on. 5257 Optional<unsigned> CondDependOnLC; 5258 /// Checks if the provide statement depends on the loop counter. 5259 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5260 /// Original condition required for checking of the exit condition for 5261 /// non-rectangular loop. 5262 Expr *Condition = nullptr; 5263 5264 public: 5265 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5266 SourceLocation DefaultLoc) 5267 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5268 ConditionLoc(DefaultLoc) {} 5269 /// Check init-expr for canonical loop form and save loop counter 5270 /// variable - #Var and its initialization value - #LB. 5271 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5272 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5273 /// for less/greater and for strict/non-strict comparison. 5274 bool checkAndSetCond(Expr *S); 5275 /// Check incr-expr for canonical loop form and return true if it 5276 /// does not conform, otherwise save loop step (#Step). 5277 bool checkAndSetInc(Expr *S); 5278 /// Return the loop counter variable. 5279 ValueDecl *getLoopDecl() const { return LCDecl; } 5280 /// Return the reference expression to loop counter variable. 5281 Expr *getLoopDeclRefExpr() const { return LCRef; } 5282 /// Source range of the loop init. 5283 SourceRange getInitSrcRange() const { return InitSrcRange; } 5284 /// Source range of the loop condition. 5285 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5286 /// Source range of the loop increment. 5287 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5288 /// True if the step should be subtracted. 5289 bool shouldSubtractStep() const { return SubtractStep; } 5290 /// True, if the compare operator is strict (<, > or !=). 5291 bool isStrictTestOp() const { return TestIsStrictOp; } 5292 /// Build the expression to calculate the number of iterations. 5293 Expr *buildNumIterations( 5294 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5295 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5296 /// Build the precondition expression for the loops. 5297 Expr * 5298 buildPreCond(Scope *S, Expr *Cond, 5299 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5300 /// Build reference expression to the counter be used for codegen. 5301 DeclRefExpr * 5302 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5303 DSAStackTy &DSA) const; 5304 /// Build reference expression to the private counter be used for 5305 /// codegen. 5306 Expr *buildPrivateCounterVar() const; 5307 /// Build initialization of the counter be used for codegen. 5308 Expr *buildCounterInit() const; 5309 /// Build step of the counter be used for codegen. 5310 Expr *buildCounterStep() const; 5311 /// Build loop data with counter value for depend clauses in ordered 5312 /// directives. 5313 Expr * 5314 buildOrderedLoopData(Scope *S, Expr *Counter, 5315 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5316 SourceLocation Loc, Expr *Inc = nullptr, 5317 OverloadedOperatorKind OOK = OO_Amp); 5318 /// Builds the minimum value for the loop counter. 5319 std::pair<Expr *, Expr *> buildMinMaxValues( 5320 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5321 /// Builds final condition for the non-rectangular loops. 5322 Expr *buildFinalCondition(Scope *S) const; 5323 /// Return true if any expression is dependent. 5324 bool dependent() const; 5325 /// Returns true if the initializer forms non-rectangular loop. 5326 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5327 /// Returns true if the condition forms non-rectangular loop. 5328 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5329 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5330 unsigned getLoopDependentIdx() const { 5331 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5332 } 5333 5334 private: 5335 /// Check the right-hand side of an assignment in the increment 5336 /// expression. 5337 bool checkAndSetIncRHS(Expr *RHS); 5338 /// Helper to set loop counter variable and its initializer. 5339 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5340 bool EmitDiags); 5341 /// Helper to set upper bound. 5342 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5343 SourceRange SR, SourceLocation SL); 5344 /// Helper to set loop increment. 5345 bool setStep(Expr *NewStep, bool Subtract); 5346 }; 5347 5348 bool OpenMPIterationSpaceChecker::dependent() const { 5349 if (!LCDecl) { 5350 assert(!LB && !UB && !Step); 5351 return false; 5352 } 5353 return LCDecl->getType()->isDependentType() || 5354 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5355 (Step && Step->isValueDependent()); 5356 } 5357 5358 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5359 Expr *NewLCRefExpr, 5360 Expr *NewLB, bool EmitDiags) { 5361 // State consistency checking to ensure correct usage. 5362 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5363 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5364 if (!NewLCDecl || !NewLB) 5365 return true; 5366 LCDecl = getCanonicalDecl(NewLCDecl); 5367 LCRef = NewLCRefExpr; 5368 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5369 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5370 if ((Ctor->isCopyOrMoveConstructor() || 5371 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5372 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5373 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5374 LB = NewLB; 5375 if (EmitDiags) 5376 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5377 return false; 5378 } 5379 5380 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5381 llvm::Optional<bool> LessOp, 5382 bool StrictOp, SourceRange SR, 5383 SourceLocation SL) { 5384 // State consistency checking to ensure correct usage. 5385 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5386 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5387 if (!NewUB) 5388 return true; 5389 UB = NewUB; 5390 if (LessOp) 5391 TestIsLessOp = LessOp; 5392 TestIsStrictOp = StrictOp; 5393 ConditionSrcRange = SR; 5394 ConditionLoc = SL; 5395 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5396 return false; 5397 } 5398 5399 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5400 // State consistency checking to ensure correct usage. 5401 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5402 if (!NewStep) 5403 return true; 5404 if (!NewStep->isValueDependent()) { 5405 // Check that the step is integer expression. 5406 SourceLocation StepLoc = NewStep->getBeginLoc(); 5407 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5408 StepLoc, getExprAsWritten(NewStep)); 5409 if (Val.isInvalid()) 5410 return true; 5411 NewStep = Val.get(); 5412 5413 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5414 // If test-expr is of form var relational-op b and relational-op is < or 5415 // <= then incr-expr must cause var to increase on each iteration of the 5416 // loop. If test-expr is of form var relational-op b and relational-op is 5417 // > or >= then incr-expr must cause var to decrease on each iteration of 5418 // the loop. 5419 // If test-expr is of form b relational-op var and relational-op is < or 5420 // <= then incr-expr must cause var to decrease on each iteration of the 5421 // loop. If test-expr is of form b relational-op var and relational-op is 5422 // > or >= then incr-expr must cause var to increase on each iteration of 5423 // the loop. 5424 llvm::APSInt Result; 5425 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5426 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5427 bool IsConstNeg = 5428 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5429 bool IsConstPos = 5430 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5431 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5432 5433 // != with increment is treated as <; != with decrement is treated as > 5434 if (!TestIsLessOp.hasValue()) 5435 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5436 if (UB && (IsConstZero || 5437 (TestIsLessOp.getValue() ? 5438 (IsConstNeg || (IsUnsigned && Subtract)) : 5439 (IsConstPos || (IsUnsigned && !Subtract))))) { 5440 SemaRef.Diag(NewStep->getExprLoc(), 5441 diag::err_omp_loop_incr_not_compatible) 5442 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5443 SemaRef.Diag(ConditionLoc, 5444 diag::note_omp_loop_cond_requres_compatible_incr) 5445 << TestIsLessOp.getValue() << ConditionSrcRange; 5446 return true; 5447 } 5448 if (TestIsLessOp.getValue() == Subtract) { 5449 NewStep = 5450 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5451 .get(); 5452 Subtract = !Subtract; 5453 } 5454 } 5455 5456 Step = NewStep; 5457 SubtractStep = Subtract; 5458 return false; 5459 } 5460 5461 namespace { 5462 /// Checker for the non-rectangular loops. Checks if the initializer or 5463 /// condition expression references loop counter variable. 5464 class LoopCounterRefChecker final 5465 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5466 Sema &SemaRef; 5467 DSAStackTy &Stack; 5468 const ValueDecl *CurLCDecl = nullptr; 5469 const ValueDecl *DepDecl = nullptr; 5470 const ValueDecl *PrevDepDecl = nullptr; 5471 bool IsInitializer = true; 5472 unsigned BaseLoopId = 0; 5473 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5474 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5475 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5476 << (IsInitializer ? 0 : 1); 5477 return false; 5478 } 5479 const auto &&Data = Stack.isLoopControlVariable(VD); 5480 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5481 // The type of the loop iterator on which we depend may not have a random 5482 // access iterator type. 5483 if (Data.first && VD->getType()->isRecordType()) { 5484 SmallString<128> Name; 5485 llvm::raw_svector_ostream OS(Name); 5486 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5487 /*Qualified=*/true); 5488 SemaRef.Diag(E->getExprLoc(), 5489 diag::err_omp_wrong_dependency_iterator_type) 5490 << OS.str(); 5491 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5492 return false; 5493 } 5494 if (Data.first && 5495 (DepDecl || (PrevDepDecl && 5496 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5497 if (!DepDecl && PrevDepDecl) 5498 DepDecl = PrevDepDecl; 5499 SmallString<128> Name; 5500 llvm::raw_svector_ostream OS(Name); 5501 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5502 /*Qualified=*/true); 5503 SemaRef.Diag(E->getExprLoc(), 5504 diag::err_omp_invariant_or_linear_dependency) 5505 << OS.str(); 5506 return false; 5507 } 5508 if (Data.first) { 5509 DepDecl = VD; 5510 BaseLoopId = Data.first; 5511 } 5512 return Data.first; 5513 } 5514 5515 public: 5516 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5517 const ValueDecl *VD = E->getDecl(); 5518 if (isa<VarDecl>(VD)) 5519 return checkDecl(E, VD); 5520 return false; 5521 } 5522 bool VisitMemberExpr(const MemberExpr *E) { 5523 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5524 const ValueDecl *VD = E->getMemberDecl(); 5525 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5526 return checkDecl(E, VD); 5527 } 5528 return false; 5529 } 5530 bool VisitStmt(const Stmt *S) { 5531 bool Res = false; 5532 for (const Stmt *Child : S->children()) 5533 Res = (Child && Visit(Child)) || Res; 5534 return Res; 5535 } 5536 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5537 const ValueDecl *CurLCDecl, bool IsInitializer, 5538 const ValueDecl *PrevDepDecl = nullptr) 5539 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5540 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5541 unsigned getBaseLoopId() const { 5542 assert(CurLCDecl && "Expected loop dependency."); 5543 return BaseLoopId; 5544 } 5545 const ValueDecl *getDepDecl() const { 5546 assert(CurLCDecl && "Expected loop dependency."); 5547 return DepDecl; 5548 } 5549 }; 5550 } // namespace 5551 5552 Optional<unsigned> 5553 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5554 bool IsInitializer) { 5555 // Check for the non-rectangular loops. 5556 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5557 DepDecl); 5558 if (LoopStmtChecker.Visit(S)) { 5559 DepDecl = LoopStmtChecker.getDepDecl(); 5560 return LoopStmtChecker.getBaseLoopId(); 5561 } 5562 return llvm::None; 5563 } 5564 5565 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5566 // Check init-expr for canonical loop form and save loop counter 5567 // variable - #Var and its initialization value - #LB. 5568 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5569 // var = lb 5570 // integer-type var = lb 5571 // random-access-iterator-type var = lb 5572 // pointer-type var = lb 5573 // 5574 if (!S) { 5575 if (EmitDiags) { 5576 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5577 } 5578 return true; 5579 } 5580 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5581 if (!ExprTemp->cleanupsHaveSideEffects()) 5582 S = ExprTemp->getSubExpr(); 5583 5584 InitSrcRange = S->getSourceRange(); 5585 if (Expr *E = dyn_cast<Expr>(S)) 5586 S = E->IgnoreParens(); 5587 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5588 if (BO->getOpcode() == BO_Assign) { 5589 Expr *LHS = BO->getLHS()->IgnoreParens(); 5590 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5591 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5592 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5593 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5594 EmitDiags); 5595 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5596 } 5597 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5598 if (ME->isArrow() && 5599 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5600 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5601 EmitDiags); 5602 } 5603 } 5604 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5605 if (DS->isSingleDecl()) { 5606 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5607 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5608 // Accept non-canonical init form here but emit ext. warning. 5609 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5610 SemaRef.Diag(S->getBeginLoc(), 5611 diag::ext_omp_loop_not_canonical_init) 5612 << S->getSourceRange(); 5613 return setLCDeclAndLB( 5614 Var, 5615 buildDeclRefExpr(SemaRef, Var, 5616 Var->getType().getNonReferenceType(), 5617 DS->getBeginLoc()), 5618 Var->getInit(), EmitDiags); 5619 } 5620 } 5621 } 5622 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5623 if (CE->getOperator() == OO_Equal) { 5624 Expr *LHS = CE->getArg(0); 5625 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5626 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5627 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5628 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5629 EmitDiags); 5630 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5631 } 5632 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5633 if (ME->isArrow() && 5634 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5635 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5636 EmitDiags); 5637 } 5638 } 5639 } 5640 5641 if (dependent() || SemaRef.CurContext->isDependentContext()) 5642 return false; 5643 if (EmitDiags) { 5644 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5645 << S->getSourceRange(); 5646 } 5647 return true; 5648 } 5649 5650 /// Ignore parenthesizes, implicit casts, copy constructor and return the 5651 /// variable (which may be the loop variable) if possible. 5652 static const ValueDecl *getInitLCDecl(const Expr *E) { 5653 if (!E) 5654 return nullptr; 5655 E = getExprAsWritten(E); 5656 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5657 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5658 if ((Ctor->isCopyOrMoveConstructor() || 5659 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5660 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5661 E = CE->getArg(0)->IgnoreParenImpCasts(); 5662 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5663 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5664 return getCanonicalDecl(VD); 5665 } 5666 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5667 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5668 return getCanonicalDecl(ME->getMemberDecl()); 5669 return nullptr; 5670 } 5671 5672 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5673 // Check test-expr for canonical form, save upper-bound UB, flags for 5674 // less/greater and for strict/non-strict comparison. 5675 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5676 // var relational-op b 5677 // b relational-op var 5678 // 5679 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5680 if (!S) { 5681 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5682 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5683 return true; 5684 } 5685 Condition = S; 5686 S = getExprAsWritten(S); 5687 SourceLocation CondLoc = S->getBeginLoc(); 5688 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5689 if (BO->isRelationalOp()) { 5690 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5691 return setUB(BO->getRHS(), 5692 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5693 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5694 BO->getSourceRange(), BO->getOperatorLoc()); 5695 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5696 return setUB(BO->getLHS(), 5697 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5698 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5699 BO->getSourceRange(), BO->getOperatorLoc()); 5700 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5701 return setUB( 5702 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5703 /*LessOp=*/llvm::None, 5704 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5705 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5706 if (CE->getNumArgs() == 2) { 5707 auto Op = CE->getOperator(); 5708 switch (Op) { 5709 case OO_Greater: 5710 case OO_GreaterEqual: 5711 case OO_Less: 5712 case OO_LessEqual: 5713 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5714 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5715 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5716 CE->getOperatorLoc()); 5717 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5718 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5719 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5720 CE->getOperatorLoc()); 5721 break; 5722 case OO_ExclaimEqual: 5723 if (IneqCondIsCanonical) 5724 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5725 : CE->getArg(0), 5726 /*LessOp=*/llvm::None, 5727 /*StrictOp=*/true, CE->getSourceRange(), 5728 CE->getOperatorLoc()); 5729 break; 5730 default: 5731 break; 5732 } 5733 } 5734 } 5735 if (dependent() || SemaRef.CurContext->isDependentContext()) 5736 return false; 5737 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5738 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5739 return true; 5740 } 5741 5742 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5743 // RHS of canonical loop form increment can be: 5744 // var + incr 5745 // incr + var 5746 // var - incr 5747 // 5748 RHS = RHS->IgnoreParenImpCasts(); 5749 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5750 if (BO->isAdditiveOp()) { 5751 bool IsAdd = BO->getOpcode() == BO_Add; 5752 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5753 return setStep(BO->getRHS(), !IsAdd); 5754 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5755 return setStep(BO->getLHS(), /*Subtract=*/false); 5756 } 5757 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5758 bool IsAdd = CE->getOperator() == OO_Plus; 5759 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5760 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5761 return setStep(CE->getArg(1), !IsAdd); 5762 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5763 return setStep(CE->getArg(0), /*Subtract=*/false); 5764 } 5765 } 5766 if (dependent() || SemaRef.CurContext->isDependentContext()) 5767 return false; 5768 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5769 << RHS->getSourceRange() << LCDecl; 5770 return true; 5771 } 5772 5773 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5774 // Check incr-expr for canonical loop form and return true if it 5775 // does not conform. 5776 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5777 // ++var 5778 // var++ 5779 // --var 5780 // var-- 5781 // var += incr 5782 // var -= incr 5783 // var = var + incr 5784 // var = incr + var 5785 // var = var - incr 5786 // 5787 if (!S) { 5788 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5789 return true; 5790 } 5791 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5792 if (!ExprTemp->cleanupsHaveSideEffects()) 5793 S = ExprTemp->getSubExpr(); 5794 5795 IncrementSrcRange = S->getSourceRange(); 5796 S = S->IgnoreParens(); 5797 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5798 if (UO->isIncrementDecrementOp() && 5799 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5800 return setStep(SemaRef 5801 .ActOnIntegerConstant(UO->getBeginLoc(), 5802 (UO->isDecrementOp() ? -1 : 1)) 5803 .get(), 5804 /*Subtract=*/false); 5805 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5806 switch (BO->getOpcode()) { 5807 case BO_AddAssign: 5808 case BO_SubAssign: 5809 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5810 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5811 break; 5812 case BO_Assign: 5813 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5814 return checkAndSetIncRHS(BO->getRHS()); 5815 break; 5816 default: 5817 break; 5818 } 5819 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5820 switch (CE->getOperator()) { 5821 case OO_PlusPlus: 5822 case OO_MinusMinus: 5823 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5824 return setStep(SemaRef 5825 .ActOnIntegerConstant( 5826 CE->getBeginLoc(), 5827 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5828 .get(), 5829 /*Subtract=*/false); 5830 break; 5831 case OO_PlusEqual: 5832 case OO_MinusEqual: 5833 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5834 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5835 break; 5836 case OO_Equal: 5837 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5838 return checkAndSetIncRHS(CE->getArg(1)); 5839 break; 5840 default: 5841 break; 5842 } 5843 } 5844 if (dependent() || SemaRef.CurContext->isDependentContext()) 5845 return false; 5846 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5847 << S->getSourceRange() << LCDecl; 5848 return true; 5849 } 5850 5851 static ExprResult 5852 tryBuildCapture(Sema &SemaRef, Expr *Capture, 5853 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5854 if (SemaRef.CurContext->isDependentContext()) 5855 return ExprResult(Capture); 5856 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5857 return SemaRef.PerformImplicitConversion( 5858 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5859 /*AllowExplicit=*/true); 5860 auto I = Captures.find(Capture); 5861 if (I != Captures.end()) 5862 return buildCapture(SemaRef, Capture, I->second); 5863 DeclRefExpr *Ref = nullptr; 5864 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5865 Captures[Capture] = Ref; 5866 return Res; 5867 } 5868 5869 /// Build the expression to calculate the number of iterations. 5870 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5871 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5872 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5873 ExprResult Diff; 5874 QualType VarType = LCDecl->getType().getNonReferenceType(); 5875 if (VarType->isIntegerType() || VarType->isPointerType() || 5876 SemaRef.getLangOpts().CPlusPlus) { 5877 Expr *LBVal = LB; 5878 Expr *UBVal = UB; 5879 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5880 // max(LB(MinVal), LB(MaxVal)) 5881 if (InitDependOnLC) { 5882 const LoopIterationSpace &IS = 5883 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5884 InitDependOnLC.getValueOr( 5885 CondDependOnLC.getValueOr(0))]; 5886 if (!IS.MinValue || !IS.MaxValue) 5887 return nullptr; 5888 // OuterVar = Min 5889 ExprResult MinValue = 5890 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5891 if (!MinValue.isUsable()) 5892 return nullptr; 5893 5894 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5895 IS.CounterVar, MinValue.get()); 5896 if (!LBMinVal.isUsable()) 5897 return nullptr; 5898 // OuterVar = Min, LBVal 5899 LBMinVal = 5900 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5901 if (!LBMinVal.isUsable()) 5902 return nullptr; 5903 // (OuterVar = Min, LBVal) 5904 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5905 if (!LBMinVal.isUsable()) 5906 return nullptr; 5907 5908 // OuterVar = Max 5909 ExprResult MaxValue = 5910 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5911 if (!MaxValue.isUsable()) 5912 return nullptr; 5913 5914 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5915 IS.CounterVar, MaxValue.get()); 5916 if (!LBMaxVal.isUsable()) 5917 return nullptr; 5918 // OuterVar = Max, LBVal 5919 LBMaxVal = 5920 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5921 if (!LBMaxVal.isUsable()) 5922 return nullptr; 5923 // (OuterVar = Max, LBVal) 5924 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 5925 if (!LBMaxVal.isUsable()) 5926 return nullptr; 5927 5928 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 5929 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 5930 if (!LBMin || !LBMax) 5931 return nullptr; 5932 // LB(MinVal) < LB(MaxVal) 5933 ExprResult MinLessMaxRes = 5934 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 5935 if (!MinLessMaxRes.isUsable()) 5936 return nullptr; 5937 Expr *MinLessMax = 5938 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 5939 if (!MinLessMax) 5940 return nullptr; 5941 if (TestIsLessOp.getValue()) { 5942 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 5943 // LB(MaxVal)) 5944 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5945 MinLessMax, LBMin, LBMax); 5946 if (!MinLB.isUsable()) 5947 return nullptr; 5948 LBVal = MinLB.get(); 5949 } else { 5950 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 5951 // LB(MaxVal)) 5952 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 5953 MinLessMax, LBMax, LBMin); 5954 if (!MaxLB.isUsable()) 5955 return nullptr; 5956 LBVal = MaxLB.get(); 5957 } 5958 } 5959 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 5960 // min(UB(MinVal), UB(MaxVal)) 5961 if (CondDependOnLC) { 5962 const LoopIterationSpace &IS = 5963 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5964 InitDependOnLC.getValueOr( 5965 CondDependOnLC.getValueOr(0))]; 5966 if (!IS.MinValue || !IS.MaxValue) 5967 return nullptr; 5968 // OuterVar = Min 5969 ExprResult MinValue = 5970 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5971 if (!MinValue.isUsable()) 5972 return nullptr; 5973 5974 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5975 IS.CounterVar, MinValue.get()); 5976 if (!UBMinVal.isUsable()) 5977 return nullptr; 5978 // OuterVar = Min, UBVal 5979 UBMinVal = 5980 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 5981 if (!UBMinVal.isUsable()) 5982 return nullptr; 5983 // (OuterVar = Min, UBVal) 5984 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 5985 if (!UBMinVal.isUsable()) 5986 return nullptr; 5987 5988 // OuterVar = Max 5989 ExprResult MaxValue = 5990 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5991 if (!MaxValue.isUsable()) 5992 return nullptr; 5993 5994 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5995 IS.CounterVar, MaxValue.get()); 5996 if (!UBMaxVal.isUsable()) 5997 return nullptr; 5998 // OuterVar = Max, UBVal 5999 UBMaxVal = 6000 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6001 if (!UBMaxVal.isUsable()) 6002 return nullptr; 6003 // (OuterVar = Max, UBVal) 6004 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6005 if (!UBMaxVal.isUsable()) 6006 return nullptr; 6007 6008 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6009 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6010 if (!UBMin || !UBMax) 6011 return nullptr; 6012 // UB(MinVal) > UB(MaxVal) 6013 ExprResult MinGreaterMaxRes = 6014 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6015 if (!MinGreaterMaxRes.isUsable()) 6016 return nullptr; 6017 Expr *MinGreaterMax = 6018 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6019 if (!MinGreaterMax) 6020 return nullptr; 6021 if (TestIsLessOp.getValue()) { 6022 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6023 // UB(MaxVal)) 6024 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6025 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6026 if (!MaxUB.isUsable()) 6027 return nullptr; 6028 UBVal = MaxUB.get(); 6029 } else { 6030 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6031 // UB(MaxVal)) 6032 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6033 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6034 if (!MinUB.isUsable()) 6035 return nullptr; 6036 UBVal = MinUB.get(); 6037 } 6038 } 6039 // Upper - Lower 6040 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6041 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6042 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6043 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6044 if (!Upper || !Lower) 6045 return nullptr; 6046 6047 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6048 6049 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6050 // BuildBinOp already emitted error, this one is to point user to upper 6051 // and lower bound, and to tell what is passed to 'operator-'. 6052 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6053 << Upper->getSourceRange() << Lower->getSourceRange(); 6054 return nullptr; 6055 } 6056 } 6057 6058 if (!Diff.isUsable()) 6059 return nullptr; 6060 6061 // Upper - Lower [- 1] 6062 if (TestIsStrictOp) 6063 Diff = SemaRef.BuildBinOp( 6064 S, DefaultLoc, BO_Sub, Diff.get(), 6065 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6066 if (!Diff.isUsable()) 6067 return nullptr; 6068 6069 // Upper - Lower [- 1] + Step 6070 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6071 if (!NewStep.isUsable()) 6072 return nullptr; 6073 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6074 if (!Diff.isUsable()) 6075 return nullptr; 6076 6077 // Parentheses (for dumping/debugging purposes only). 6078 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6079 if (!Diff.isUsable()) 6080 return nullptr; 6081 6082 // (Upper - Lower [- 1] + Step) / Step 6083 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6084 if (!Diff.isUsable()) 6085 return nullptr; 6086 6087 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6088 QualType Type = Diff.get()->getType(); 6089 ASTContext &C = SemaRef.Context; 6090 bool UseVarType = VarType->hasIntegerRepresentation() && 6091 C.getTypeSize(Type) > C.getTypeSize(VarType); 6092 if (!Type->isIntegerType() || UseVarType) { 6093 unsigned NewSize = 6094 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6095 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6096 : Type->hasSignedIntegerRepresentation(); 6097 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6098 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6099 Diff = SemaRef.PerformImplicitConversion( 6100 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6101 if (!Diff.isUsable()) 6102 return nullptr; 6103 } 6104 } 6105 if (LimitedType) { 6106 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6107 if (NewSize != C.getTypeSize(Type)) { 6108 if (NewSize < C.getTypeSize(Type)) { 6109 assert(NewSize == 64 && "incorrect loop var size"); 6110 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6111 << InitSrcRange << ConditionSrcRange; 6112 } 6113 QualType NewType = C.getIntTypeForBitwidth( 6114 NewSize, Type->hasSignedIntegerRepresentation() || 6115 C.getTypeSize(Type) < NewSize); 6116 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6117 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6118 Sema::AA_Converting, true); 6119 if (!Diff.isUsable()) 6120 return nullptr; 6121 } 6122 } 6123 } 6124 6125 return Diff.get(); 6126 } 6127 6128 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6129 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6130 // Do not build for iterators, they cannot be used in non-rectangular loop 6131 // nests. 6132 if (LCDecl->getType()->isRecordType()) 6133 return std::make_pair(nullptr, nullptr); 6134 // If we subtract, the min is in the condition, otherwise the min is in the 6135 // init value. 6136 Expr *MinExpr = nullptr; 6137 Expr *MaxExpr = nullptr; 6138 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6139 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6140 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6141 : CondDependOnLC.hasValue(); 6142 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6143 : InitDependOnLC.hasValue(); 6144 Expr *Lower = 6145 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6146 Expr *Upper = 6147 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6148 if (!Upper || !Lower) 6149 return std::make_pair(nullptr, nullptr); 6150 6151 if (TestIsLessOp.getValue()) 6152 MinExpr = Lower; 6153 else 6154 MaxExpr = Upper; 6155 6156 // Build minimum/maximum value based on number of iterations. 6157 ExprResult Diff; 6158 QualType VarType = LCDecl->getType().getNonReferenceType(); 6159 6160 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6161 if (!Diff.isUsable()) 6162 return std::make_pair(nullptr, nullptr); 6163 6164 // Upper - Lower [- 1] 6165 if (TestIsStrictOp) 6166 Diff = SemaRef.BuildBinOp( 6167 S, DefaultLoc, BO_Sub, Diff.get(), 6168 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6169 if (!Diff.isUsable()) 6170 return std::make_pair(nullptr, nullptr); 6171 6172 // Upper - Lower [- 1] + Step 6173 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6174 if (!NewStep.isUsable()) 6175 return std::make_pair(nullptr, nullptr); 6176 6177 // Parentheses (for dumping/debugging purposes only). 6178 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6179 if (!Diff.isUsable()) 6180 return std::make_pair(nullptr, nullptr); 6181 6182 // (Upper - Lower [- 1]) / Step 6183 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6184 if (!Diff.isUsable()) 6185 return std::make_pair(nullptr, nullptr); 6186 6187 // ((Upper - Lower [- 1]) / Step) * Step 6188 // Parentheses (for dumping/debugging purposes only). 6189 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6190 if (!Diff.isUsable()) 6191 return std::make_pair(nullptr, nullptr); 6192 6193 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6194 if (!Diff.isUsable()) 6195 return std::make_pair(nullptr, nullptr); 6196 6197 // Convert to the original type or ptrdiff_t, if original type is pointer. 6198 if (!VarType->isAnyPointerType() && 6199 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6200 Diff = SemaRef.PerformImplicitConversion( 6201 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6202 } else if (VarType->isAnyPointerType() && 6203 !SemaRef.Context.hasSameType( 6204 Diff.get()->getType(), 6205 SemaRef.Context.getUnsignedPointerDiffType())) { 6206 Diff = SemaRef.PerformImplicitConversion( 6207 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6208 Sema::AA_Converting, /*AllowExplicit=*/true); 6209 } 6210 if (!Diff.isUsable()) 6211 return std::make_pair(nullptr, nullptr); 6212 6213 // Parentheses (for dumping/debugging purposes only). 6214 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6215 if (!Diff.isUsable()) 6216 return std::make_pair(nullptr, nullptr); 6217 6218 if (TestIsLessOp.getValue()) { 6219 // MinExpr = Lower; 6220 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6221 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6222 if (!Diff.isUsable()) 6223 return std::make_pair(nullptr, nullptr); 6224 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6225 if (!Diff.isUsable()) 6226 return std::make_pair(nullptr, nullptr); 6227 MaxExpr = Diff.get(); 6228 } else { 6229 // MaxExpr = Upper; 6230 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6231 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6232 if (!Diff.isUsable()) 6233 return std::make_pair(nullptr, nullptr); 6234 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6235 if (!Diff.isUsable()) 6236 return std::make_pair(nullptr, nullptr); 6237 MinExpr = Diff.get(); 6238 } 6239 6240 return std::make_pair(MinExpr, MaxExpr); 6241 } 6242 6243 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6244 if (InitDependOnLC || CondDependOnLC) 6245 return Condition; 6246 return nullptr; 6247 } 6248 6249 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6250 Scope *S, Expr *Cond, 6251 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6252 // Do not build a precondition when the condition/initialization is dependent 6253 // to prevent pessimistic early loop exit. 6254 // TODO: this can be improved by calculating min/max values but not sure that 6255 // it will be very effective. 6256 if (CondDependOnLC || InitDependOnLC) 6257 return SemaRef.PerformImplicitConversion( 6258 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6259 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6260 /*AllowExplicit=*/true).get(); 6261 6262 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6263 Sema::TentativeAnalysisScope Trap(SemaRef); 6264 6265 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6266 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6267 if (!NewLB.isUsable() || !NewUB.isUsable()) 6268 return nullptr; 6269 6270 ExprResult CondExpr = 6271 SemaRef.BuildBinOp(S, DefaultLoc, 6272 TestIsLessOp.getValue() ? 6273 (TestIsStrictOp ? BO_LT : BO_LE) : 6274 (TestIsStrictOp ? BO_GT : BO_GE), 6275 NewLB.get(), NewUB.get()); 6276 if (CondExpr.isUsable()) { 6277 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6278 SemaRef.Context.BoolTy)) 6279 CondExpr = SemaRef.PerformImplicitConversion( 6280 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6281 /*AllowExplicit=*/true); 6282 } 6283 6284 // Otherwise use original loop condition and evaluate it in runtime. 6285 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6286 } 6287 6288 /// Build reference expression to the counter be used for codegen. 6289 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6290 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6291 DSAStackTy &DSA) const { 6292 auto *VD = dyn_cast<VarDecl>(LCDecl); 6293 if (!VD) { 6294 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6295 DeclRefExpr *Ref = buildDeclRefExpr( 6296 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6297 const DSAStackTy::DSAVarData Data = 6298 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6299 // If the loop control decl is explicitly marked as private, do not mark it 6300 // as captured again. 6301 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6302 Captures.insert(std::make_pair(LCRef, Ref)); 6303 return Ref; 6304 } 6305 return cast<DeclRefExpr>(LCRef); 6306 } 6307 6308 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6309 if (LCDecl && !LCDecl->isInvalidDecl()) { 6310 QualType Type = LCDecl->getType().getNonReferenceType(); 6311 VarDecl *PrivateVar = buildVarDecl( 6312 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6313 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6314 isa<VarDecl>(LCDecl) 6315 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6316 : nullptr); 6317 if (PrivateVar->isInvalidDecl()) 6318 return nullptr; 6319 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6320 } 6321 return nullptr; 6322 } 6323 6324 /// Build initialization of the counter to be used for codegen. 6325 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6326 6327 /// Build step of the counter be used for codegen. 6328 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6329 6330 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6331 Scope *S, Expr *Counter, 6332 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6333 Expr *Inc, OverloadedOperatorKind OOK) { 6334 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6335 if (!Cnt) 6336 return nullptr; 6337 if (Inc) { 6338 assert((OOK == OO_Plus || OOK == OO_Minus) && 6339 "Expected only + or - operations for depend clauses."); 6340 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6341 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6342 if (!Cnt) 6343 return nullptr; 6344 } 6345 ExprResult Diff; 6346 QualType VarType = LCDecl->getType().getNonReferenceType(); 6347 if (VarType->isIntegerType() || VarType->isPointerType() || 6348 SemaRef.getLangOpts().CPlusPlus) { 6349 // Upper - Lower 6350 Expr *Upper = TestIsLessOp.getValue() 6351 ? Cnt 6352 : tryBuildCapture(SemaRef, UB, Captures).get(); 6353 Expr *Lower = TestIsLessOp.getValue() 6354 ? tryBuildCapture(SemaRef, LB, Captures).get() 6355 : Cnt; 6356 if (!Upper || !Lower) 6357 return nullptr; 6358 6359 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6360 6361 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6362 // BuildBinOp already emitted error, this one is to point user to upper 6363 // and lower bound, and to tell what is passed to 'operator-'. 6364 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6365 << Upper->getSourceRange() << Lower->getSourceRange(); 6366 return nullptr; 6367 } 6368 } 6369 6370 if (!Diff.isUsable()) 6371 return nullptr; 6372 6373 // Parentheses (for dumping/debugging purposes only). 6374 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6375 if (!Diff.isUsable()) 6376 return nullptr; 6377 6378 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6379 if (!NewStep.isUsable()) 6380 return nullptr; 6381 // (Upper - Lower) / Step 6382 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6383 if (!Diff.isUsable()) 6384 return nullptr; 6385 6386 return Diff.get(); 6387 } 6388 } // namespace 6389 6390 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6391 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6392 assert(Init && "Expected loop in canonical form."); 6393 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6394 if (AssociatedLoops > 0 && 6395 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6396 DSAStack->loopStart(); 6397 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6398 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6399 if (ValueDecl *D = ISC.getLoopDecl()) { 6400 auto *VD = dyn_cast<VarDecl>(D); 6401 DeclRefExpr *PrivateRef = nullptr; 6402 if (!VD) { 6403 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6404 VD = Private; 6405 } else { 6406 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6407 /*WithInit=*/false); 6408 VD = cast<VarDecl>(PrivateRef->getDecl()); 6409 } 6410 } 6411 DSAStack->addLoopControlVariable(D, VD); 6412 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6413 if (LD != D->getCanonicalDecl()) { 6414 DSAStack->resetPossibleLoopCounter(); 6415 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6416 MarkDeclarationsReferencedInExpr( 6417 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6418 Var->getType().getNonLValueExprType(Context), 6419 ForLoc, /*RefersToCapture=*/true)); 6420 } 6421 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6422 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6423 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6424 // associated for-loop of a simd construct with just one associated 6425 // for-loop may be listed in a linear clause with a constant-linear-step 6426 // that is the increment of the associated for-loop. The loop iteration 6427 // variable(s) in the associated for-loop(s) of a for or parallel for 6428 // construct may be listed in a private or lastprivate clause. 6429 DSAStackTy::DSAVarData DVar = 6430 DSAStack->getTopDSA(D, /*FromParent=*/false); 6431 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6432 // is declared in the loop and it is predetermined as a private. 6433 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6434 OpenMPClauseKind PredeterminedCKind = 6435 isOpenMPSimdDirective(DKind) 6436 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6437 : OMPC_private; 6438 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6439 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6440 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6441 DVar.CKind != OMPC_private))) || 6442 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6443 DKind == OMPD_master_taskloop || 6444 isOpenMPDistributeDirective(DKind)) && 6445 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6446 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6447 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6448 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6449 << getOpenMPClauseName(DVar.CKind) 6450 << getOpenMPDirectiveName(DKind) 6451 << getOpenMPClauseName(PredeterminedCKind); 6452 if (DVar.RefExpr == nullptr) 6453 DVar.CKind = PredeterminedCKind; 6454 reportOriginalDsa(*this, DSAStack, D, DVar, 6455 /*IsLoopIterVar=*/true); 6456 } else if (LoopDeclRefExpr) { 6457 // Make the loop iteration variable private (for worksharing 6458 // constructs), linear (for simd directives with the only one 6459 // associated loop) or lastprivate (for simd directives with several 6460 // collapsed or ordered loops). 6461 if (DVar.CKind == OMPC_unknown) 6462 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6463 PrivateRef); 6464 } 6465 } 6466 } 6467 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6468 } 6469 } 6470 6471 /// Called on a for stmt to check and extract its iteration space 6472 /// for further processing (such as collapsing). 6473 static bool checkOpenMPIterationSpace( 6474 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6475 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6476 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6477 Expr *OrderedLoopCountExpr, 6478 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6479 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6480 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6481 // OpenMP [2.9.1, Canonical Loop Form] 6482 // for (init-expr; test-expr; incr-expr) structured-block 6483 // for (range-decl: range-expr) structured-block 6484 auto *For = dyn_cast_or_null<ForStmt>(S); 6485 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6486 // Ranged for is supported only in OpenMP 5.0. 6487 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6488 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6489 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6490 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6491 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6492 if (TotalNestedLoopCount > 1) { 6493 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6494 SemaRef.Diag(DSA.getConstructLoc(), 6495 diag::note_omp_collapse_ordered_expr) 6496 << 2 << CollapseLoopCountExpr->getSourceRange() 6497 << OrderedLoopCountExpr->getSourceRange(); 6498 else if (CollapseLoopCountExpr) 6499 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6500 diag::note_omp_collapse_ordered_expr) 6501 << 0 << CollapseLoopCountExpr->getSourceRange(); 6502 else 6503 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6504 diag::note_omp_collapse_ordered_expr) 6505 << 1 << OrderedLoopCountExpr->getSourceRange(); 6506 } 6507 return true; 6508 } 6509 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6510 "No loop body."); 6511 6512 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6513 For ? For->getForLoc() : CXXFor->getForLoc()); 6514 6515 // Check init. 6516 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6517 if (ISC.checkAndSetInit(Init)) 6518 return true; 6519 6520 bool HasErrors = false; 6521 6522 // Check loop variable's type. 6523 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6524 // OpenMP [2.6, Canonical Loop Form] 6525 // Var is one of the following: 6526 // A variable of signed or unsigned integer type. 6527 // For C++, a variable of a random access iterator type. 6528 // For C, a variable of a pointer type. 6529 QualType VarType = LCDecl->getType().getNonReferenceType(); 6530 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6531 !VarType->isPointerType() && 6532 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6533 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6534 << SemaRef.getLangOpts().CPlusPlus; 6535 HasErrors = true; 6536 } 6537 6538 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6539 // a Construct 6540 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6541 // parallel for construct is (are) private. 6542 // The loop iteration variable in the associated for-loop of a simd 6543 // construct with just one associated for-loop is linear with a 6544 // constant-linear-step that is the increment of the associated for-loop. 6545 // Exclude loop var from the list of variables with implicitly defined data 6546 // sharing attributes. 6547 VarsWithImplicitDSA.erase(LCDecl); 6548 6549 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6550 6551 // Check test-expr. 6552 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6553 6554 // Check incr-expr. 6555 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6556 } 6557 6558 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6559 return HasErrors; 6560 6561 // Build the loop's iteration space representation. 6562 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6563 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6564 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6565 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6566 (isOpenMPWorksharingDirective(DKind) || 6567 isOpenMPTaskLoopDirective(DKind) || 6568 isOpenMPDistributeDirective(DKind)), 6569 Captures); 6570 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6571 ISC.buildCounterVar(Captures, DSA); 6572 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6573 ISC.buildPrivateCounterVar(); 6574 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6575 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6576 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6577 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6578 ISC.getConditionSrcRange(); 6579 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6580 ISC.getIncrementSrcRange(); 6581 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6582 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6583 ISC.isStrictTestOp(); 6584 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6585 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6586 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6587 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6588 ISC.buildFinalCondition(DSA.getCurScope()); 6589 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6590 ISC.doesInitDependOnLC(); 6591 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6592 ISC.doesCondDependOnLC(); 6593 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6594 ISC.getLoopDependentIdx(); 6595 6596 HasErrors |= 6597 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6598 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6599 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6600 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6601 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6602 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6603 if (!HasErrors && DSA.isOrderedRegion()) { 6604 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6605 if (CurrentNestedLoopCount < 6606 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6607 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6608 CurrentNestedLoopCount, 6609 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6610 DSA.getOrderedRegionParam().second->setLoopCounter( 6611 CurrentNestedLoopCount, 6612 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6613 } 6614 } 6615 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6616 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6617 // Erroneous case - clause has some problems. 6618 continue; 6619 } 6620 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6621 Pair.second.size() <= CurrentNestedLoopCount) { 6622 // Erroneous case - clause has some problems. 6623 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6624 continue; 6625 } 6626 Expr *CntValue; 6627 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6628 CntValue = ISC.buildOrderedLoopData( 6629 DSA.getCurScope(), 6630 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6631 Pair.first->getDependencyLoc()); 6632 else 6633 CntValue = ISC.buildOrderedLoopData( 6634 DSA.getCurScope(), 6635 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6636 Pair.first->getDependencyLoc(), 6637 Pair.second[CurrentNestedLoopCount].first, 6638 Pair.second[CurrentNestedLoopCount].second); 6639 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6640 } 6641 } 6642 6643 return HasErrors; 6644 } 6645 6646 /// Build 'VarRef = Start. 6647 static ExprResult 6648 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6649 ExprResult Start, bool IsNonRectangularLB, 6650 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6651 // Build 'VarRef = Start. 6652 ExprResult NewStart = IsNonRectangularLB 6653 ? Start.get() 6654 : tryBuildCapture(SemaRef, Start.get(), Captures); 6655 if (!NewStart.isUsable()) 6656 return ExprError(); 6657 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6658 VarRef.get()->getType())) { 6659 NewStart = SemaRef.PerformImplicitConversion( 6660 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6661 /*AllowExplicit=*/true); 6662 if (!NewStart.isUsable()) 6663 return ExprError(); 6664 } 6665 6666 ExprResult Init = 6667 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6668 return Init; 6669 } 6670 6671 /// Build 'VarRef = Start + Iter * Step'. 6672 static ExprResult buildCounterUpdate( 6673 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6674 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6675 bool IsNonRectangularLB, 6676 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6677 // Add parentheses (for debugging purposes only). 6678 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6679 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6680 !Step.isUsable()) 6681 return ExprError(); 6682 6683 ExprResult NewStep = Step; 6684 if (Captures) 6685 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6686 if (NewStep.isInvalid()) 6687 return ExprError(); 6688 ExprResult Update = 6689 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6690 if (!Update.isUsable()) 6691 return ExprError(); 6692 6693 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6694 // 'VarRef = Start (+|-) Iter * Step'. 6695 if (!Start.isUsable()) 6696 return ExprError(); 6697 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6698 if (!NewStart.isUsable()) 6699 return ExprError(); 6700 if (Captures && !IsNonRectangularLB) 6701 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6702 if (NewStart.isInvalid()) 6703 return ExprError(); 6704 6705 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6706 ExprResult SavedUpdate = Update; 6707 ExprResult UpdateVal; 6708 if (VarRef.get()->getType()->isOverloadableType() || 6709 NewStart.get()->getType()->isOverloadableType() || 6710 Update.get()->getType()->isOverloadableType()) { 6711 Sema::TentativeAnalysisScope Trap(SemaRef); 6712 6713 Update = 6714 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6715 if (Update.isUsable()) { 6716 UpdateVal = 6717 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6718 VarRef.get(), SavedUpdate.get()); 6719 if (UpdateVal.isUsable()) { 6720 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6721 UpdateVal.get()); 6722 } 6723 } 6724 } 6725 6726 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6727 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6728 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6729 NewStart.get(), SavedUpdate.get()); 6730 if (!Update.isUsable()) 6731 return ExprError(); 6732 6733 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6734 VarRef.get()->getType())) { 6735 Update = SemaRef.PerformImplicitConversion( 6736 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6737 if (!Update.isUsable()) 6738 return ExprError(); 6739 } 6740 6741 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6742 } 6743 return Update; 6744 } 6745 6746 /// Convert integer expression \a E to make it have at least \a Bits 6747 /// bits. 6748 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6749 if (E == nullptr) 6750 return ExprError(); 6751 ASTContext &C = SemaRef.Context; 6752 QualType OldType = E->getType(); 6753 unsigned HasBits = C.getTypeSize(OldType); 6754 if (HasBits >= Bits) 6755 return ExprResult(E); 6756 // OK to convert to signed, because new type has more bits than old. 6757 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6758 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6759 true); 6760 } 6761 6762 /// Check if the given expression \a E is a constant integer that fits 6763 /// into \a Bits bits. 6764 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6765 if (E == nullptr) 6766 return false; 6767 llvm::APSInt Result; 6768 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6769 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6770 return false; 6771 } 6772 6773 /// Build preinits statement for the given declarations. 6774 static Stmt *buildPreInits(ASTContext &Context, 6775 MutableArrayRef<Decl *> PreInits) { 6776 if (!PreInits.empty()) { 6777 return new (Context) DeclStmt( 6778 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6779 SourceLocation(), SourceLocation()); 6780 } 6781 return nullptr; 6782 } 6783 6784 /// Build preinits statement for the given declarations. 6785 static Stmt * 6786 buildPreInits(ASTContext &Context, 6787 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6788 if (!Captures.empty()) { 6789 SmallVector<Decl *, 16> PreInits; 6790 for (const auto &Pair : Captures) 6791 PreInits.push_back(Pair.second->getDecl()); 6792 return buildPreInits(Context, PreInits); 6793 } 6794 return nullptr; 6795 } 6796 6797 /// Build postupdate expression for the given list of postupdates expressions. 6798 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6799 Expr *PostUpdate = nullptr; 6800 if (!PostUpdates.empty()) { 6801 for (Expr *E : PostUpdates) { 6802 Expr *ConvE = S.BuildCStyleCastExpr( 6803 E->getExprLoc(), 6804 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6805 E->getExprLoc(), E) 6806 .get(); 6807 PostUpdate = PostUpdate 6808 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6809 PostUpdate, ConvE) 6810 .get() 6811 : ConvE; 6812 } 6813 } 6814 return PostUpdate; 6815 } 6816 6817 /// Called on a for stmt to check itself and nested loops (if any). 6818 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6819 /// number of collapsed loops otherwise. 6820 static unsigned 6821 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6822 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6823 DSAStackTy &DSA, 6824 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6825 OMPLoopDirective::HelperExprs &Built) { 6826 unsigned NestedLoopCount = 1; 6827 if (CollapseLoopCountExpr) { 6828 // Found 'collapse' clause - calculate collapse number. 6829 Expr::EvalResult Result; 6830 if (!CollapseLoopCountExpr->isValueDependent() && 6831 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6832 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6833 } else { 6834 Built.clear(/*Size=*/1); 6835 return 1; 6836 } 6837 } 6838 unsigned OrderedLoopCount = 1; 6839 if (OrderedLoopCountExpr) { 6840 // Found 'ordered' clause - calculate collapse number. 6841 Expr::EvalResult EVResult; 6842 if (!OrderedLoopCountExpr->isValueDependent() && 6843 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6844 SemaRef.getASTContext())) { 6845 llvm::APSInt Result = EVResult.Val.getInt(); 6846 if (Result.getLimitedValue() < NestedLoopCount) { 6847 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6848 diag::err_omp_wrong_ordered_loop_count) 6849 << OrderedLoopCountExpr->getSourceRange(); 6850 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6851 diag::note_collapse_loop_count) 6852 << CollapseLoopCountExpr->getSourceRange(); 6853 } 6854 OrderedLoopCount = Result.getLimitedValue(); 6855 } else { 6856 Built.clear(/*Size=*/1); 6857 return 1; 6858 } 6859 } 6860 // This is helper routine for loop directives (e.g., 'for', 'simd', 6861 // 'for simd', etc.). 6862 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6863 SmallVector<LoopIterationSpace, 4> IterSpaces( 6864 std::max(OrderedLoopCount, NestedLoopCount)); 6865 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6866 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6867 if (checkOpenMPIterationSpace( 6868 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6869 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6870 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6871 return 0; 6872 // Move on to the next nested for loop, or to the loop body. 6873 // OpenMP [2.8.1, simd construct, Restrictions] 6874 // All loops associated with the construct must be perfectly nested; that 6875 // is, there must be no intervening code nor any OpenMP directive between 6876 // any two loops. 6877 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6878 CurStmt = For->getBody(); 6879 } else { 6880 assert(isa<CXXForRangeStmt>(CurStmt) && 6881 "Expected canonical for or range-based for loops."); 6882 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6883 } 6884 CurStmt = CurStmt->IgnoreContainers(); 6885 } 6886 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6887 if (checkOpenMPIterationSpace( 6888 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6889 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6890 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6891 return 0; 6892 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6893 // Handle initialization of captured loop iterator variables. 6894 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6895 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6896 Captures[DRE] = DRE; 6897 } 6898 } 6899 // Move on to the next nested for loop, or to the loop body. 6900 // OpenMP [2.8.1, simd construct, Restrictions] 6901 // All loops associated with the construct must be perfectly nested; that 6902 // is, there must be no intervening code nor any OpenMP directive between 6903 // any two loops. 6904 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6905 CurStmt = For->getBody(); 6906 } else { 6907 assert(isa<CXXForRangeStmt>(CurStmt) && 6908 "Expected canonical for or range-based for loops."); 6909 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6910 } 6911 CurStmt = CurStmt->IgnoreContainers(); 6912 } 6913 6914 Built.clear(/* size */ NestedLoopCount); 6915 6916 if (SemaRef.CurContext->isDependentContext()) 6917 return NestedLoopCount; 6918 6919 // An example of what is generated for the following code: 6920 // 6921 // #pragma omp simd collapse(2) ordered(2) 6922 // for (i = 0; i < NI; ++i) 6923 // for (k = 0; k < NK; ++k) 6924 // for (j = J0; j < NJ; j+=2) { 6925 // <loop body> 6926 // } 6927 // 6928 // We generate the code below. 6929 // Note: the loop body may be outlined in CodeGen. 6930 // Note: some counters may be C++ classes, operator- is used to find number of 6931 // iterations and operator+= to calculate counter value. 6932 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 6933 // or i64 is currently supported). 6934 // 6935 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 6936 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 6937 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 6938 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 6939 // // similar updates for vars in clauses (e.g. 'linear') 6940 // <loop body (using local i and j)> 6941 // } 6942 // i = NI; // assign final values of counters 6943 // j = NJ; 6944 // 6945 6946 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 6947 // the iteration counts of the collapsed for loops. 6948 // Precondition tests if there is at least one iteration (all conditions are 6949 // true). 6950 auto PreCond = ExprResult(IterSpaces[0].PreCond); 6951 Expr *N0 = IterSpaces[0].NumIterations; 6952 ExprResult LastIteration32 = 6953 widenIterationCount(/*Bits=*/32, 6954 SemaRef 6955 .PerformImplicitConversion( 6956 N0->IgnoreImpCasts(), N0->getType(), 6957 Sema::AA_Converting, /*AllowExplicit=*/true) 6958 .get(), 6959 SemaRef); 6960 ExprResult LastIteration64 = widenIterationCount( 6961 /*Bits=*/64, 6962 SemaRef 6963 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 6964 Sema::AA_Converting, 6965 /*AllowExplicit=*/true) 6966 .get(), 6967 SemaRef); 6968 6969 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 6970 return NestedLoopCount; 6971 6972 ASTContext &C = SemaRef.Context; 6973 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 6974 6975 Scope *CurScope = DSA.getCurScope(); 6976 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 6977 if (PreCond.isUsable()) { 6978 PreCond = 6979 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 6980 PreCond.get(), IterSpaces[Cnt].PreCond); 6981 } 6982 Expr *N = IterSpaces[Cnt].NumIterations; 6983 SourceLocation Loc = N->getExprLoc(); 6984 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 6985 if (LastIteration32.isUsable()) 6986 LastIteration32 = SemaRef.BuildBinOp( 6987 CurScope, Loc, BO_Mul, LastIteration32.get(), 6988 SemaRef 6989 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6990 Sema::AA_Converting, 6991 /*AllowExplicit=*/true) 6992 .get()); 6993 if (LastIteration64.isUsable()) 6994 LastIteration64 = SemaRef.BuildBinOp( 6995 CurScope, Loc, BO_Mul, LastIteration64.get(), 6996 SemaRef 6997 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 6998 Sema::AA_Converting, 6999 /*AllowExplicit=*/true) 7000 .get()); 7001 } 7002 7003 // Choose either the 32-bit or 64-bit version. 7004 ExprResult LastIteration = LastIteration64; 7005 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7006 (LastIteration32.isUsable() && 7007 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7008 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7009 fitsInto( 7010 /*Bits=*/32, 7011 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7012 LastIteration64.get(), SemaRef)))) 7013 LastIteration = LastIteration32; 7014 QualType VType = LastIteration.get()->getType(); 7015 QualType RealVType = VType; 7016 QualType StrideVType = VType; 7017 if (isOpenMPTaskLoopDirective(DKind)) { 7018 VType = 7019 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7020 StrideVType = 7021 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7022 } 7023 7024 if (!LastIteration.isUsable()) 7025 return 0; 7026 7027 // Save the number of iterations. 7028 ExprResult NumIterations = LastIteration; 7029 { 7030 LastIteration = SemaRef.BuildBinOp( 7031 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7032 LastIteration.get(), 7033 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7034 if (!LastIteration.isUsable()) 7035 return 0; 7036 } 7037 7038 // Calculate the last iteration number beforehand instead of doing this on 7039 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7040 llvm::APSInt Result; 7041 bool IsConstant = 7042 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7043 ExprResult CalcLastIteration; 7044 if (!IsConstant) { 7045 ExprResult SaveRef = 7046 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7047 LastIteration = SaveRef; 7048 7049 // Prepare SaveRef + 1. 7050 NumIterations = SemaRef.BuildBinOp( 7051 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7052 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7053 if (!NumIterations.isUsable()) 7054 return 0; 7055 } 7056 7057 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7058 7059 // Build variables passed into runtime, necessary for worksharing directives. 7060 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7061 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7062 isOpenMPDistributeDirective(DKind)) { 7063 // Lower bound variable, initialized with zero. 7064 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7065 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7066 SemaRef.AddInitializerToDecl(LBDecl, 7067 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7068 /*DirectInit*/ false); 7069 7070 // Upper bound variable, initialized with last iteration number. 7071 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7072 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7073 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7074 /*DirectInit*/ false); 7075 7076 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7077 // This will be used to implement clause 'lastprivate'. 7078 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7079 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7080 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7081 SemaRef.AddInitializerToDecl(ILDecl, 7082 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7083 /*DirectInit*/ false); 7084 7085 // Stride variable returned by runtime (we initialize it to 1 by default). 7086 VarDecl *STDecl = 7087 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7088 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7089 SemaRef.AddInitializerToDecl(STDecl, 7090 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7091 /*DirectInit*/ false); 7092 7093 // Build expression: UB = min(UB, LastIteration) 7094 // It is necessary for CodeGen of directives with static scheduling. 7095 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7096 UB.get(), LastIteration.get()); 7097 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7098 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7099 LastIteration.get(), UB.get()); 7100 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7101 CondOp.get()); 7102 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7103 7104 // If we have a combined directive that combines 'distribute', 'for' or 7105 // 'simd' we need to be able to access the bounds of the schedule of the 7106 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7107 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7108 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7109 // Lower bound variable, initialized with zero. 7110 VarDecl *CombLBDecl = 7111 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7112 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7113 SemaRef.AddInitializerToDecl( 7114 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7115 /*DirectInit*/ false); 7116 7117 // Upper bound variable, initialized with last iteration number. 7118 VarDecl *CombUBDecl = 7119 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7120 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7121 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7122 /*DirectInit*/ false); 7123 7124 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7125 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7126 ExprResult CombCondOp = 7127 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7128 LastIteration.get(), CombUB.get()); 7129 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7130 CombCondOp.get()); 7131 CombEUB = 7132 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7133 7134 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7135 // We expect to have at least 2 more parameters than the 'parallel' 7136 // directive does - the lower and upper bounds of the previous schedule. 7137 assert(CD->getNumParams() >= 4 && 7138 "Unexpected number of parameters in loop combined directive"); 7139 7140 // Set the proper type for the bounds given what we learned from the 7141 // enclosed loops. 7142 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7143 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7144 7145 // Previous lower and upper bounds are obtained from the region 7146 // parameters. 7147 PrevLB = 7148 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7149 PrevUB = 7150 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7151 } 7152 } 7153 7154 // Build the iteration variable and its initialization before loop. 7155 ExprResult IV; 7156 ExprResult Init, CombInit; 7157 { 7158 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7159 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7160 Expr *RHS = 7161 (isOpenMPWorksharingDirective(DKind) || 7162 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7163 ? LB.get() 7164 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7165 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7166 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7167 7168 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7169 Expr *CombRHS = 7170 (isOpenMPWorksharingDirective(DKind) || 7171 isOpenMPTaskLoopDirective(DKind) || 7172 isOpenMPDistributeDirective(DKind)) 7173 ? CombLB.get() 7174 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7175 CombInit = 7176 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7177 CombInit = 7178 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7179 } 7180 } 7181 7182 bool UseStrictCompare = 7183 RealVType->hasUnsignedIntegerRepresentation() && 7184 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7185 return LIS.IsStrictCompare; 7186 }); 7187 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7188 // unsigned IV)) for worksharing loops. 7189 SourceLocation CondLoc = AStmt->getBeginLoc(); 7190 Expr *BoundUB = UB.get(); 7191 if (UseStrictCompare) { 7192 BoundUB = 7193 SemaRef 7194 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7195 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7196 .get(); 7197 BoundUB = 7198 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7199 } 7200 ExprResult Cond = 7201 (isOpenMPWorksharingDirective(DKind) || 7202 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7203 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7204 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7205 BoundUB) 7206 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7207 NumIterations.get()); 7208 ExprResult CombDistCond; 7209 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7210 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7211 NumIterations.get()); 7212 } 7213 7214 ExprResult CombCond; 7215 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7216 Expr *BoundCombUB = CombUB.get(); 7217 if (UseStrictCompare) { 7218 BoundCombUB = 7219 SemaRef 7220 .BuildBinOp( 7221 CurScope, CondLoc, BO_Add, BoundCombUB, 7222 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7223 .get(); 7224 BoundCombUB = 7225 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7226 .get(); 7227 } 7228 CombCond = 7229 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7230 IV.get(), BoundCombUB); 7231 } 7232 // Loop increment (IV = IV + 1) 7233 SourceLocation IncLoc = AStmt->getBeginLoc(); 7234 ExprResult Inc = 7235 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7236 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7237 if (!Inc.isUsable()) 7238 return 0; 7239 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7240 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7241 if (!Inc.isUsable()) 7242 return 0; 7243 7244 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7245 // Used for directives with static scheduling. 7246 // In combined construct, add combined version that use CombLB and CombUB 7247 // base variables for the update 7248 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7249 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7250 isOpenMPDistributeDirective(DKind)) { 7251 // LB + ST 7252 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7253 if (!NextLB.isUsable()) 7254 return 0; 7255 // LB = LB + ST 7256 NextLB = 7257 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7258 NextLB = 7259 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7260 if (!NextLB.isUsable()) 7261 return 0; 7262 // UB + ST 7263 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7264 if (!NextUB.isUsable()) 7265 return 0; 7266 // UB = UB + ST 7267 NextUB = 7268 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7269 NextUB = 7270 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7271 if (!NextUB.isUsable()) 7272 return 0; 7273 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7274 CombNextLB = 7275 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7276 if (!NextLB.isUsable()) 7277 return 0; 7278 // LB = LB + ST 7279 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7280 CombNextLB.get()); 7281 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7282 /*DiscardedValue*/ false); 7283 if (!CombNextLB.isUsable()) 7284 return 0; 7285 // UB + ST 7286 CombNextUB = 7287 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7288 if (!CombNextUB.isUsable()) 7289 return 0; 7290 // UB = UB + ST 7291 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7292 CombNextUB.get()); 7293 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7294 /*DiscardedValue*/ false); 7295 if (!CombNextUB.isUsable()) 7296 return 0; 7297 } 7298 } 7299 7300 // Create increment expression for distribute loop when combined in a same 7301 // directive with for as IV = IV + ST; ensure upper bound expression based 7302 // on PrevUB instead of NumIterations - used to implement 'for' when found 7303 // in combination with 'distribute', like in 'distribute parallel for' 7304 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7305 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7306 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7307 DistCond = SemaRef.BuildBinOp( 7308 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7309 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7310 7311 DistInc = 7312 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7313 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7314 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7315 DistInc.get()); 7316 DistInc = 7317 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7318 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7319 7320 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7321 // construct 7322 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7323 ExprResult IsUBGreater = 7324 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7325 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7326 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7327 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7328 CondOp.get()); 7329 PrevEUB = 7330 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7331 7332 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7333 // parallel for is in combination with a distribute directive with 7334 // schedule(static, 1) 7335 Expr *BoundPrevUB = PrevUB.get(); 7336 if (UseStrictCompare) { 7337 BoundPrevUB = 7338 SemaRef 7339 .BuildBinOp( 7340 CurScope, CondLoc, BO_Add, BoundPrevUB, 7341 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7342 .get(); 7343 BoundPrevUB = 7344 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7345 .get(); 7346 } 7347 ParForInDistCond = 7348 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7349 IV.get(), BoundPrevUB); 7350 } 7351 7352 // Build updates and final values of the loop counters. 7353 bool HasErrors = false; 7354 Built.Counters.resize(NestedLoopCount); 7355 Built.Inits.resize(NestedLoopCount); 7356 Built.Updates.resize(NestedLoopCount); 7357 Built.Finals.resize(NestedLoopCount); 7358 Built.DependentCounters.resize(NestedLoopCount); 7359 Built.DependentInits.resize(NestedLoopCount); 7360 Built.FinalsConditions.resize(NestedLoopCount); 7361 { 7362 // We implement the following algorithm for obtaining the 7363 // original loop iteration variable values based on the 7364 // value of the collapsed loop iteration variable IV. 7365 // 7366 // Let n+1 be the number of collapsed loops in the nest. 7367 // Iteration variables (I0, I1, .... In) 7368 // Iteration counts (N0, N1, ... Nn) 7369 // 7370 // Acc = IV; 7371 // 7372 // To compute Ik for loop k, 0 <= k <= n, generate: 7373 // Prod = N(k+1) * N(k+2) * ... * Nn; 7374 // Ik = Acc / Prod; 7375 // Acc -= Ik * Prod; 7376 // 7377 ExprResult Acc = IV; 7378 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7379 LoopIterationSpace &IS = IterSpaces[Cnt]; 7380 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7381 ExprResult Iter; 7382 7383 // Compute prod 7384 ExprResult Prod = 7385 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7386 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7387 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7388 IterSpaces[K].NumIterations); 7389 7390 // Iter = Acc / Prod 7391 // If there is at least one more inner loop to avoid 7392 // multiplication by 1. 7393 if (Cnt + 1 < NestedLoopCount) 7394 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7395 Acc.get(), Prod.get()); 7396 else 7397 Iter = Acc; 7398 if (!Iter.isUsable()) { 7399 HasErrors = true; 7400 break; 7401 } 7402 7403 // Update Acc: 7404 // Acc -= Iter * Prod 7405 // Check if there is at least one more inner loop to avoid 7406 // multiplication by 1. 7407 if (Cnt + 1 < NestedLoopCount) 7408 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7409 Iter.get(), Prod.get()); 7410 else 7411 Prod = Iter; 7412 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7413 Acc.get(), Prod.get()); 7414 7415 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7416 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7417 DeclRefExpr *CounterVar = buildDeclRefExpr( 7418 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7419 /*RefersToCapture=*/true); 7420 ExprResult Init = 7421 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7422 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7423 if (!Init.isUsable()) { 7424 HasErrors = true; 7425 break; 7426 } 7427 ExprResult Update = buildCounterUpdate( 7428 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7429 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7430 if (!Update.isUsable()) { 7431 HasErrors = true; 7432 break; 7433 } 7434 7435 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7436 ExprResult Final = 7437 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7438 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7439 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7440 if (!Final.isUsable()) { 7441 HasErrors = true; 7442 break; 7443 } 7444 7445 if (!Update.isUsable() || !Final.isUsable()) { 7446 HasErrors = true; 7447 break; 7448 } 7449 // Save results 7450 Built.Counters[Cnt] = IS.CounterVar; 7451 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7452 Built.Inits[Cnt] = Init.get(); 7453 Built.Updates[Cnt] = Update.get(); 7454 Built.Finals[Cnt] = Final.get(); 7455 Built.DependentCounters[Cnt] = nullptr; 7456 Built.DependentInits[Cnt] = nullptr; 7457 Built.FinalsConditions[Cnt] = nullptr; 7458 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7459 Built.DependentCounters[Cnt] = 7460 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7461 Built.DependentInits[Cnt] = 7462 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7463 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7464 } 7465 } 7466 } 7467 7468 if (HasErrors) 7469 return 0; 7470 7471 // Save results 7472 Built.IterationVarRef = IV.get(); 7473 Built.LastIteration = LastIteration.get(); 7474 Built.NumIterations = NumIterations.get(); 7475 Built.CalcLastIteration = SemaRef 7476 .ActOnFinishFullExpr(CalcLastIteration.get(), 7477 /*DiscardedValue=*/false) 7478 .get(); 7479 Built.PreCond = PreCond.get(); 7480 Built.PreInits = buildPreInits(C, Captures); 7481 Built.Cond = Cond.get(); 7482 Built.Init = Init.get(); 7483 Built.Inc = Inc.get(); 7484 Built.LB = LB.get(); 7485 Built.UB = UB.get(); 7486 Built.IL = IL.get(); 7487 Built.ST = ST.get(); 7488 Built.EUB = EUB.get(); 7489 Built.NLB = NextLB.get(); 7490 Built.NUB = NextUB.get(); 7491 Built.PrevLB = PrevLB.get(); 7492 Built.PrevUB = PrevUB.get(); 7493 Built.DistInc = DistInc.get(); 7494 Built.PrevEUB = PrevEUB.get(); 7495 Built.DistCombinedFields.LB = CombLB.get(); 7496 Built.DistCombinedFields.UB = CombUB.get(); 7497 Built.DistCombinedFields.EUB = CombEUB.get(); 7498 Built.DistCombinedFields.Init = CombInit.get(); 7499 Built.DistCombinedFields.Cond = CombCond.get(); 7500 Built.DistCombinedFields.NLB = CombNextLB.get(); 7501 Built.DistCombinedFields.NUB = CombNextUB.get(); 7502 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7503 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7504 7505 return NestedLoopCount; 7506 } 7507 7508 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7509 auto CollapseClauses = 7510 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7511 if (CollapseClauses.begin() != CollapseClauses.end()) 7512 return (*CollapseClauses.begin())->getNumForLoops(); 7513 return nullptr; 7514 } 7515 7516 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7517 auto OrderedClauses = 7518 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7519 if (OrderedClauses.begin() != OrderedClauses.end()) 7520 return (*OrderedClauses.begin())->getNumForLoops(); 7521 return nullptr; 7522 } 7523 7524 static bool checkSimdlenSafelenSpecified(Sema &S, 7525 const ArrayRef<OMPClause *> Clauses) { 7526 const OMPSafelenClause *Safelen = nullptr; 7527 const OMPSimdlenClause *Simdlen = nullptr; 7528 7529 for (const OMPClause *Clause : Clauses) { 7530 if (Clause->getClauseKind() == OMPC_safelen) 7531 Safelen = cast<OMPSafelenClause>(Clause); 7532 else if (Clause->getClauseKind() == OMPC_simdlen) 7533 Simdlen = cast<OMPSimdlenClause>(Clause); 7534 if (Safelen && Simdlen) 7535 break; 7536 } 7537 7538 if (Simdlen && Safelen) { 7539 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7540 const Expr *SafelenLength = Safelen->getSafelen(); 7541 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7542 SimdlenLength->isInstantiationDependent() || 7543 SimdlenLength->containsUnexpandedParameterPack()) 7544 return false; 7545 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7546 SafelenLength->isInstantiationDependent() || 7547 SafelenLength->containsUnexpandedParameterPack()) 7548 return false; 7549 Expr::EvalResult SimdlenResult, SafelenResult; 7550 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7551 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7552 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7553 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7554 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7555 // If both simdlen and safelen clauses are specified, the value of the 7556 // simdlen parameter must be less than or equal to the value of the safelen 7557 // parameter. 7558 if (SimdlenRes > SafelenRes) { 7559 S.Diag(SimdlenLength->getExprLoc(), 7560 diag::err_omp_wrong_simdlen_safelen_values) 7561 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7562 return true; 7563 } 7564 } 7565 return false; 7566 } 7567 7568 StmtResult 7569 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7570 SourceLocation StartLoc, SourceLocation EndLoc, 7571 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7572 if (!AStmt) 7573 return StmtError(); 7574 7575 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7576 OMPLoopDirective::HelperExprs B; 7577 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7578 // define the nested loops number. 7579 unsigned NestedLoopCount = checkOpenMPLoop( 7580 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7581 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7582 if (NestedLoopCount == 0) 7583 return StmtError(); 7584 7585 assert((CurContext->isDependentContext() || B.builtAll()) && 7586 "omp simd loop exprs were not built"); 7587 7588 if (!CurContext->isDependentContext()) { 7589 // Finalize the clauses that need pre-built expressions for CodeGen. 7590 for (OMPClause *C : Clauses) { 7591 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7592 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7593 B.NumIterations, *this, CurScope, 7594 DSAStack)) 7595 return StmtError(); 7596 } 7597 } 7598 7599 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7600 return StmtError(); 7601 7602 setFunctionHasBranchProtectedScope(); 7603 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7604 Clauses, AStmt, B); 7605 } 7606 7607 StmtResult 7608 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7609 SourceLocation StartLoc, SourceLocation EndLoc, 7610 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7611 if (!AStmt) 7612 return StmtError(); 7613 7614 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7615 OMPLoopDirective::HelperExprs B; 7616 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7617 // define the nested loops number. 7618 unsigned NestedLoopCount = checkOpenMPLoop( 7619 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7620 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7621 if (NestedLoopCount == 0) 7622 return StmtError(); 7623 7624 assert((CurContext->isDependentContext() || B.builtAll()) && 7625 "omp for loop exprs were not built"); 7626 7627 if (!CurContext->isDependentContext()) { 7628 // Finalize the clauses that need pre-built expressions for CodeGen. 7629 for (OMPClause *C : Clauses) { 7630 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7631 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7632 B.NumIterations, *this, CurScope, 7633 DSAStack)) 7634 return StmtError(); 7635 } 7636 } 7637 7638 setFunctionHasBranchProtectedScope(); 7639 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7640 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7641 } 7642 7643 StmtResult Sema::ActOnOpenMPForSimdDirective( 7644 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7645 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7646 if (!AStmt) 7647 return StmtError(); 7648 7649 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7650 OMPLoopDirective::HelperExprs B; 7651 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7652 // define the nested loops number. 7653 unsigned NestedLoopCount = 7654 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7655 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7656 VarsWithImplicitDSA, B); 7657 if (NestedLoopCount == 0) 7658 return StmtError(); 7659 7660 assert((CurContext->isDependentContext() || B.builtAll()) && 7661 "omp for simd loop exprs were not built"); 7662 7663 if (!CurContext->isDependentContext()) { 7664 // Finalize the clauses that need pre-built expressions for CodeGen. 7665 for (OMPClause *C : Clauses) { 7666 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7667 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7668 B.NumIterations, *this, CurScope, 7669 DSAStack)) 7670 return StmtError(); 7671 } 7672 } 7673 7674 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7675 return StmtError(); 7676 7677 setFunctionHasBranchProtectedScope(); 7678 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7679 Clauses, AStmt, B); 7680 } 7681 7682 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7683 Stmt *AStmt, 7684 SourceLocation StartLoc, 7685 SourceLocation EndLoc) { 7686 if (!AStmt) 7687 return StmtError(); 7688 7689 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7690 auto BaseStmt = AStmt; 7691 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7692 BaseStmt = CS->getCapturedStmt(); 7693 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7694 auto S = C->children(); 7695 if (S.begin() == S.end()) 7696 return StmtError(); 7697 // All associated statements must be '#pragma omp section' except for 7698 // the first one. 7699 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7700 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7701 if (SectionStmt) 7702 Diag(SectionStmt->getBeginLoc(), 7703 diag::err_omp_sections_substmt_not_section); 7704 return StmtError(); 7705 } 7706 cast<OMPSectionDirective>(SectionStmt) 7707 ->setHasCancel(DSAStack->isCancelRegion()); 7708 } 7709 } else { 7710 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7711 return StmtError(); 7712 } 7713 7714 setFunctionHasBranchProtectedScope(); 7715 7716 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7717 DSAStack->isCancelRegion()); 7718 } 7719 7720 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7721 SourceLocation StartLoc, 7722 SourceLocation EndLoc) { 7723 if (!AStmt) 7724 return StmtError(); 7725 7726 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7727 7728 setFunctionHasBranchProtectedScope(); 7729 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7730 7731 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7732 DSAStack->isCancelRegion()); 7733 } 7734 7735 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7736 Stmt *AStmt, 7737 SourceLocation StartLoc, 7738 SourceLocation EndLoc) { 7739 if (!AStmt) 7740 return StmtError(); 7741 7742 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7743 7744 setFunctionHasBranchProtectedScope(); 7745 7746 // OpenMP [2.7.3, single Construct, Restrictions] 7747 // The copyprivate clause must not be used with the nowait clause. 7748 const OMPClause *Nowait = nullptr; 7749 const OMPClause *Copyprivate = nullptr; 7750 for (const OMPClause *Clause : Clauses) { 7751 if (Clause->getClauseKind() == OMPC_nowait) 7752 Nowait = Clause; 7753 else if (Clause->getClauseKind() == OMPC_copyprivate) 7754 Copyprivate = Clause; 7755 if (Copyprivate && Nowait) { 7756 Diag(Copyprivate->getBeginLoc(), 7757 diag::err_omp_single_copyprivate_with_nowait); 7758 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7759 return StmtError(); 7760 } 7761 } 7762 7763 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7764 } 7765 7766 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7767 SourceLocation StartLoc, 7768 SourceLocation EndLoc) { 7769 if (!AStmt) 7770 return StmtError(); 7771 7772 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7773 7774 setFunctionHasBranchProtectedScope(); 7775 7776 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7777 } 7778 7779 StmtResult Sema::ActOnOpenMPCriticalDirective( 7780 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7781 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7782 if (!AStmt) 7783 return StmtError(); 7784 7785 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7786 7787 bool ErrorFound = false; 7788 llvm::APSInt Hint; 7789 SourceLocation HintLoc; 7790 bool DependentHint = false; 7791 for (const OMPClause *C : Clauses) { 7792 if (C->getClauseKind() == OMPC_hint) { 7793 if (!DirName.getName()) { 7794 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7795 ErrorFound = true; 7796 } 7797 Expr *E = cast<OMPHintClause>(C)->getHint(); 7798 if (E->isTypeDependent() || E->isValueDependent() || 7799 E->isInstantiationDependent()) { 7800 DependentHint = true; 7801 } else { 7802 Hint = E->EvaluateKnownConstInt(Context); 7803 HintLoc = C->getBeginLoc(); 7804 } 7805 } 7806 } 7807 if (ErrorFound) 7808 return StmtError(); 7809 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7810 if (Pair.first && DirName.getName() && !DependentHint) { 7811 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7812 Diag(StartLoc, diag::err_omp_critical_with_hint); 7813 if (HintLoc.isValid()) 7814 Diag(HintLoc, diag::note_omp_critical_hint_here) 7815 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7816 else 7817 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7818 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7819 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7820 << 1 7821 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7822 /*Radix=*/10, /*Signed=*/false); 7823 } else { 7824 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7825 } 7826 } 7827 } 7828 7829 setFunctionHasBranchProtectedScope(); 7830 7831 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7832 Clauses, AStmt); 7833 if (!Pair.first && DirName.getName() && !DependentHint) 7834 DSAStack->addCriticalWithHint(Dir, Hint); 7835 return Dir; 7836 } 7837 7838 StmtResult Sema::ActOnOpenMPParallelForDirective( 7839 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7840 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7841 if (!AStmt) 7842 return StmtError(); 7843 7844 auto *CS = cast<CapturedStmt>(AStmt); 7845 // 1.2.2 OpenMP Language Terminology 7846 // Structured block - An executable statement with a single entry at the 7847 // top and a single exit at the bottom. 7848 // The point of exit cannot be a branch out of the structured block. 7849 // longjmp() and throw() must not violate the entry/exit criteria. 7850 CS->getCapturedDecl()->setNothrow(); 7851 7852 OMPLoopDirective::HelperExprs B; 7853 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7854 // define the nested loops number. 7855 unsigned NestedLoopCount = 7856 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7857 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7858 VarsWithImplicitDSA, B); 7859 if (NestedLoopCount == 0) 7860 return StmtError(); 7861 7862 assert((CurContext->isDependentContext() || B.builtAll()) && 7863 "omp parallel for loop exprs were not built"); 7864 7865 if (!CurContext->isDependentContext()) { 7866 // Finalize the clauses that need pre-built expressions for CodeGen. 7867 for (OMPClause *C : Clauses) { 7868 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7869 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7870 B.NumIterations, *this, CurScope, 7871 DSAStack)) 7872 return StmtError(); 7873 } 7874 } 7875 7876 setFunctionHasBranchProtectedScope(); 7877 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7878 NestedLoopCount, Clauses, AStmt, B, 7879 DSAStack->isCancelRegion()); 7880 } 7881 7882 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7883 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7884 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7885 if (!AStmt) 7886 return StmtError(); 7887 7888 auto *CS = cast<CapturedStmt>(AStmt); 7889 // 1.2.2 OpenMP Language Terminology 7890 // Structured block - An executable statement with a single entry at the 7891 // top and a single exit at the bottom. 7892 // The point of exit cannot be a branch out of the structured block. 7893 // longjmp() and throw() must not violate the entry/exit criteria. 7894 CS->getCapturedDecl()->setNothrow(); 7895 7896 OMPLoopDirective::HelperExprs B; 7897 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7898 // define the nested loops number. 7899 unsigned NestedLoopCount = 7900 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7901 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7902 VarsWithImplicitDSA, B); 7903 if (NestedLoopCount == 0) 7904 return StmtError(); 7905 7906 if (!CurContext->isDependentContext()) { 7907 // Finalize the clauses that need pre-built expressions for CodeGen. 7908 for (OMPClause *C : Clauses) { 7909 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7910 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7911 B.NumIterations, *this, CurScope, 7912 DSAStack)) 7913 return StmtError(); 7914 } 7915 } 7916 7917 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7918 return StmtError(); 7919 7920 setFunctionHasBranchProtectedScope(); 7921 return OMPParallelForSimdDirective::Create( 7922 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7923 } 7924 7925 StmtResult 7926 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 7927 Stmt *AStmt, SourceLocation StartLoc, 7928 SourceLocation EndLoc) { 7929 if (!AStmt) 7930 return StmtError(); 7931 7932 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7933 auto BaseStmt = AStmt; 7934 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7935 BaseStmt = CS->getCapturedStmt(); 7936 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7937 auto S = C->children(); 7938 if (S.begin() == S.end()) 7939 return StmtError(); 7940 // All associated statements must be '#pragma omp section' except for 7941 // the first one. 7942 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7943 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7944 if (SectionStmt) 7945 Diag(SectionStmt->getBeginLoc(), 7946 diag::err_omp_parallel_sections_substmt_not_section); 7947 return StmtError(); 7948 } 7949 cast<OMPSectionDirective>(SectionStmt) 7950 ->setHasCancel(DSAStack->isCancelRegion()); 7951 } 7952 } else { 7953 Diag(AStmt->getBeginLoc(), 7954 diag::err_omp_parallel_sections_not_compound_stmt); 7955 return StmtError(); 7956 } 7957 7958 setFunctionHasBranchProtectedScope(); 7959 7960 return OMPParallelSectionsDirective::Create( 7961 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 7962 } 7963 7964 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 7965 Stmt *AStmt, SourceLocation StartLoc, 7966 SourceLocation EndLoc) { 7967 if (!AStmt) 7968 return StmtError(); 7969 7970 auto *CS = cast<CapturedStmt>(AStmt); 7971 // 1.2.2 OpenMP Language Terminology 7972 // Structured block - An executable statement with a single entry at the 7973 // top and a single exit at the bottom. 7974 // The point of exit cannot be a branch out of the structured block. 7975 // longjmp() and throw() must not violate the entry/exit criteria. 7976 CS->getCapturedDecl()->setNothrow(); 7977 7978 setFunctionHasBranchProtectedScope(); 7979 7980 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7981 DSAStack->isCancelRegion()); 7982 } 7983 7984 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 7985 SourceLocation EndLoc) { 7986 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 7987 } 7988 7989 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 7990 SourceLocation EndLoc) { 7991 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 7992 } 7993 7994 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 7995 SourceLocation EndLoc) { 7996 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 7997 } 7998 7999 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8000 Stmt *AStmt, 8001 SourceLocation StartLoc, 8002 SourceLocation EndLoc) { 8003 if (!AStmt) 8004 return StmtError(); 8005 8006 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8007 8008 setFunctionHasBranchProtectedScope(); 8009 8010 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8011 AStmt, 8012 DSAStack->getTaskgroupReductionRef()); 8013 } 8014 8015 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8016 SourceLocation StartLoc, 8017 SourceLocation EndLoc) { 8018 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8019 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8020 } 8021 8022 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8023 Stmt *AStmt, 8024 SourceLocation StartLoc, 8025 SourceLocation EndLoc) { 8026 const OMPClause *DependFound = nullptr; 8027 const OMPClause *DependSourceClause = nullptr; 8028 const OMPClause *DependSinkClause = nullptr; 8029 bool ErrorFound = false; 8030 const OMPThreadsClause *TC = nullptr; 8031 const OMPSIMDClause *SC = nullptr; 8032 for (const OMPClause *C : Clauses) { 8033 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8034 DependFound = C; 8035 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8036 if (DependSourceClause) { 8037 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8038 << getOpenMPDirectiveName(OMPD_ordered) 8039 << getOpenMPClauseName(OMPC_depend) << 2; 8040 ErrorFound = true; 8041 } else { 8042 DependSourceClause = C; 8043 } 8044 if (DependSinkClause) { 8045 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8046 << 0; 8047 ErrorFound = true; 8048 } 8049 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8050 if (DependSourceClause) { 8051 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8052 << 1; 8053 ErrorFound = true; 8054 } 8055 DependSinkClause = C; 8056 } 8057 } else if (C->getClauseKind() == OMPC_threads) { 8058 TC = cast<OMPThreadsClause>(C); 8059 } else if (C->getClauseKind() == OMPC_simd) { 8060 SC = cast<OMPSIMDClause>(C); 8061 } 8062 } 8063 if (!ErrorFound && !SC && 8064 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8065 // OpenMP [2.8.1,simd Construct, Restrictions] 8066 // An ordered construct with the simd clause is the only OpenMP construct 8067 // that can appear in the simd region. 8068 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 8069 ErrorFound = true; 8070 } else if (DependFound && (TC || SC)) { 8071 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8072 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8073 ErrorFound = true; 8074 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8075 Diag(DependFound->getBeginLoc(), 8076 diag::err_omp_ordered_directive_without_param); 8077 ErrorFound = true; 8078 } else if (TC || Clauses.empty()) { 8079 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8080 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8081 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8082 << (TC != nullptr); 8083 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8084 ErrorFound = true; 8085 } 8086 } 8087 if ((!AStmt && !DependFound) || ErrorFound) 8088 return StmtError(); 8089 8090 if (AStmt) { 8091 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8092 8093 setFunctionHasBranchProtectedScope(); 8094 } 8095 8096 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8097 } 8098 8099 namespace { 8100 /// Helper class for checking expression in 'omp atomic [update]' 8101 /// construct. 8102 class OpenMPAtomicUpdateChecker { 8103 /// Error results for atomic update expressions. 8104 enum ExprAnalysisErrorCode { 8105 /// A statement is not an expression statement. 8106 NotAnExpression, 8107 /// Expression is not builtin binary or unary operation. 8108 NotABinaryOrUnaryExpression, 8109 /// Unary operation is not post-/pre- increment/decrement operation. 8110 NotAnUnaryIncDecExpression, 8111 /// An expression is not of scalar type. 8112 NotAScalarType, 8113 /// A binary operation is not an assignment operation. 8114 NotAnAssignmentOp, 8115 /// RHS part of the binary operation is not a binary expression. 8116 NotABinaryExpression, 8117 /// RHS part is not additive/multiplicative/shift/biwise binary 8118 /// expression. 8119 NotABinaryOperator, 8120 /// RHS binary operation does not have reference to the updated LHS 8121 /// part. 8122 NotAnUpdateExpression, 8123 /// No errors is found. 8124 NoError 8125 }; 8126 /// Reference to Sema. 8127 Sema &SemaRef; 8128 /// A location for note diagnostics (when error is found). 8129 SourceLocation NoteLoc; 8130 /// 'x' lvalue part of the source atomic expression. 8131 Expr *X; 8132 /// 'expr' rvalue part of the source atomic expression. 8133 Expr *E; 8134 /// Helper expression of the form 8135 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8136 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8137 Expr *UpdateExpr; 8138 /// Is 'x' a LHS in a RHS part of full update expression. It is 8139 /// important for non-associative operations. 8140 bool IsXLHSInRHSPart; 8141 BinaryOperatorKind Op; 8142 SourceLocation OpLoc; 8143 /// true if the source expression is a postfix unary operation, false 8144 /// if it is a prefix unary operation. 8145 bool IsPostfixUpdate; 8146 8147 public: 8148 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8149 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8150 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8151 /// Check specified statement that it is suitable for 'atomic update' 8152 /// constructs and extract 'x', 'expr' and Operation from the original 8153 /// expression. If DiagId and NoteId == 0, then only check is performed 8154 /// without error notification. 8155 /// \param DiagId Diagnostic which should be emitted if error is found. 8156 /// \param NoteId Diagnostic note for the main error message. 8157 /// \return true if statement is not an update expression, false otherwise. 8158 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8159 /// Return the 'x' lvalue part of the source atomic expression. 8160 Expr *getX() const { return X; } 8161 /// Return the 'expr' rvalue part of the source atomic expression. 8162 Expr *getExpr() const { return E; } 8163 /// Return the update expression used in calculation of the updated 8164 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8165 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8166 Expr *getUpdateExpr() const { return UpdateExpr; } 8167 /// Return true if 'x' is LHS in RHS part of full update expression, 8168 /// false otherwise. 8169 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8170 8171 /// true if the source expression is a postfix unary operation, false 8172 /// if it is a prefix unary operation. 8173 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8174 8175 private: 8176 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8177 unsigned NoteId = 0); 8178 }; 8179 } // namespace 8180 8181 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8182 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8183 ExprAnalysisErrorCode ErrorFound = NoError; 8184 SourceLocation ErrorLoc, NoteLoc; 8185 SourceRange ErrorRange, NoteRange; 8186 // Allowed constructs are: 8187 // x = x binop expr; 8188 // x = expr binop x; 8189 if (AtomicBinOp->getOpcode() == BO_Assign) { 8190 X = AtomicBinOp->getLHS(); 8191 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8192 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8193 if (AtomicInnerBinOp->isMultiplicativeOp() || 8194 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8195 AtomicInnerBinOp->isBitwiseOp()) { 8196 Op = AtomicInnerBinOp->getOpcode(); 8197 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8198 Expr *LHS = AtomicInnerBinOp->getLHS(); 8199 Expr *RHS = AtomicInnerBinOp->getRHS(); 8200 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8201 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8202 /*Canonical=*/true); 8203 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8204 /*Canonical=*/true); 8205 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8206 /*Canonical=*/true); 8207 if (XId == LHSId) { 8208 E = RHS; 8209 IsXLHSInRHSPart = true; 8210 } else if (XId == RHSId) { 8211 E = LHS; 8212 IsXLHSInRHSPart = false; 8213 } else { 8214 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8215 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8216 NoteLoc = X->getExprLoc(); 8217 NoteRange = X->getSourceRange(); 8218 ErrorFound = NotAnUpdateExpression; 8219 } 8220 } else { 8221 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8222 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8223 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8224 NoteRange = SourceRange(NoteLoc, NoteLoc); 8225 ErrorFound = NotABinaryOperator; 8226 } 8227 } else { 8228 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8229 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8230 ErrorFound = NotABinaryExpression; 8231 } 8232 } else { 8233 ErrorLoc = AtomicBinOp->getExprLoc(); 8234 ErrorRange = AtomicBinOp->getSourceRange(); 8235 NoteLoc = AtomicBinOp->getOperatorLoc(); 8236 NoteRange = SourceRange(NoteLoc, NoteLoc); 8237 ErrorFound = NotAnAssignmentOp; 8238 } 8239 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8240 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8241 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8242 return true; 8243 } 8244 if (SemaRef.CurContext->isDependentContext()) 8245 E = X = UpdateExpr = nullptr; 8246 return ErrorFound != NoError; 8247 } 8248 8249 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8250 unsigned NoteId) { 8251 ExprAnalysisErrorCode ErrorFound = NoError; 8252 SourceLocation ErrorLoc, NoteLoc; 8253 SourceRange ErrorRange, NoteRange; 8254 // Allowed constructs are: 8255 // x++; 8256 // x--; 8257 // ++x; 8258 // --x; 8259 // x binop= expr; 8260 // x = x binop expr; 8261 // x = expr binop x; 8262 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8263 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8264 if (AtomicBody->getType()->isScalarType() || 8265 AtomicBody->isInstantiationDependent()) { 8266 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8267 AtomicBody->IgnoreParenImpCasts())) { 8268 // Check for Compound Assignment Operation 8269 Op = BinaryOperator::getOpForCompoundAssignment( 8270 AtomicCompAssignOp->getOpcode()); 8271 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8272 E = AtomicCompAssignOp->getRHS(); 8273 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8274 IsXLHSInRHSPart = true; 8275 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8276 AtomicBody->IgnoreParenImpCasts())) { 8277 // Check for Binary Operation 8278 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8279 return true; 8280 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8281 AtomicBody->IgnoreParenImpCasts())) { 8282 // Check for Unary Operation 8283 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8284 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8285 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8286 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8287 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8288 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8289 IsXLHSInRHSPart = true; 8290 } else { 8291 ErrorFound = NotAnUnaryIncDecExpression; 8292 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8293 ErrorRange = AtomicUnaryOp->getSourceRange(); 8294 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8295 NoteRange = SourceRange(NoteLoc, NoteLoc); 8296 } 8297 } else if (!AtomicBody->isInstantiationDependent()) { 8298 ErrorFound = NotABinaryOrUnaryExpression; 8299 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8300 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8301 } 8302 } else { 8303 ErrorFound = NotAScalarType; 8304 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8305 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8306 } 8307 } else { 8308 ErrorFound = NotAnExpression; 8309 NoteLoc = ErrorLoc = S->getBeginLoc(); 8310 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8311 } 8312 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8313 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8314 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8315 return true; 8316 } 8317 if (SemaRef.CurContext->isDependentContext()) 8318 E = X = UpdateExpr = nullptr; 8319 if (ErrorFound == NoError && E && X) { 8320 // Build an update expression of form 'OpaqueValueExpr(x) binop 8321 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8322 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8323 auto *OVEX = new (SemaRef.getASTContext()) 8324 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8325 auto *OVEExpr = new (SemaRef.getASTContext()) 8326 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8327 ExprResult Update = 8328 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8329 IsXLHSInRHSPart ? OVEExpr : OVEX); 8330 if (Update.isInvalid()) 8331 return true; 8332 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8333 Sema::AA_Casting); 8334 if (Update.isInvalid()) 8335 return true; 8336 UpdateExpr = Update.get(); 8337 } 8338 return ErrorFound != NoError; 8339 } 8340 8341 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8342 Stmt *AStmt, 8343 SourceLocation StartLoc, 8344 SourceLocation EndLoc) { 8345 if (!AStmt) 8346 return StmtError(); 8347 8348 auto *CS = cast<CapturedStmt>(AStmt); 8349 // 1.2.2 OpenMP Language Terminology 8350 // Structured block - An executable statement with a single entry at the 8351 // top and a single exit at the bottom. 8352 // The point of exit cannot be a branch out of the structured block. 8353 // longjmp() and throw() must not violate the entry/exit criteria. 8354 OpenMPClauseKind AtomicKind = OMPC_unknown; 8355 SourceLocation AtomicKindLoc; 8356 for (const OMPClause *C : Clauses) { 8357 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8358 C->getClauseKind() == OMPC_update || 8359 C->getClauseKind() == OMPC_capture) { 8360 if (AtomicKind != OMPC_unknown) { 8361 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8362 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8363 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8364 << getOpenMPClauseName(AtomicKind); 8365 } else { 8366 AtomicKind = C->getClauseKind(); 8367 AtomicKindLoc = C->getBeginLoc(); 8368 } 8369 } 8370 } 8371 8372 Stmt *Body = CS->getCapturedStmt(); 8373 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8374 Body = EWC->getSubExpr(); 8375 8376 Expr *X = nullptr; 8377 Expr *V = nullptr; 8378 Expr *E = nullptr; 8379 Expr *UE = nullptr; 8380 bool IsXLHSInRHSPart = false; 8381 bool IsPostfixUpdate = false; 8382 // OpenMP [2.12.6, atomic Construct] 8383 // In the next expressions: 8384 // * x and v (as applicable) are both l-value expressions with scalar type. 8385 // * During the execution of an atomic region, multiple syntactic 8386 // occurrences of x must designate the same storage location. 8387 // * Neither of v and expr (as applicable) may access the storage location 8388 // designated by x. 8389 // * Neither of x and expr (as applicable) may access the storage location 8390 // designated by v. 8391 // * expr is an expression with scalar type. 8392 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8393 // * binop, binop=, ++, and -- are not overloaded operators. 8394 // * The expression x binop expr must be numerically equivalent to x binop 8395 // (expr). This requirement is satisfied if the operators in expr have 8396 // precedence greater than binop, or by using parentheses around expr or 8397 // subexpressions of expr. 8398 // * The expression expr binop x must be numerically equivalent to (expr) 8399 // binop x. This requirement is satisfied if the operators in expr have 8400 // precedence equal to or greater than binop, or by using parentheses around 8401 // expr or subexpressions of expr. 8402 // * For forms that allow multiple occurrences of x, the number of times 8403 // that x is evaluated is unspecified. 8404 if (AtomicKind == OMPC_read) { 8405 enum { 8406 NotAnExpression, 8407 NotAnAssignmentOp, 8408 NotAScalarType, 8409 NotAnLValue, 8410 NoError 8411 } ErrorFound = NoError; 8412 SourceLocation ErrorLoc, NoteLoc; 8413 SourceRange ErrorRange, NoteRange; 8414 // If clause is read: 8415 // v = x; 8416 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8417 const auto *AtomicBinOp = 8418 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8419 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8420 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8421 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8422 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8423 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8424 if (!X->isLValue() || !V->isLValue()) { 8425 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8426 ErrorFound = NotAnLValue; 8427 ErrorLoc = AtomicBinOp->getExprLoc(); 8428 ErrorRange = AtomicBinOp->getSourceRange(); 8429 NoteLoc = NotLValueExpr->getExprLoc(); 8430 NoteRange = NotLValueExpr->getSourceRange(); 8431 } 8432 } else if (!X->isInstantiationDependent() || 8433 !V->isInstantiationDependent()) { 8434 const Expr *NotScalarExpr = 8435 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8436 ? V 8437 : X; 8438 ErrorFound = NotAScalarType; 8439 ErrorLoc = AtomicBinOp->getExprLoc(); 8440 ErrorRange = AtomicBinOp->getSourceRange(); 8441 NoteLoc = NotScalarExpr->getExprLoc(); 8442 NoteRange = NotScalarExpr->getSourceRange(); 8443 } 8444 } else if (!AtomicBody->isInstantiationDependent()) { 8445 ErrorFound = NotAnAssignmentOp; 8446 ErrorLoc = AtomicBody->getExprLoc(); 8447 ErrorRange = AtomicBody->getSourceRange(); 8448 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8449 : AtomicBody->getExprLoc(); 8450 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8451 : AtomicBody->getSourceRange(); 8452 } 8453 } else { 8454 ErrorFound = NotAnExpression; 8455 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8456 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8457 } 8458 if (ErrorFound != NoError) { 8459 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8460 << ErrorRange; 8461 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8462 << NoteRange; 8463 return StmtError(); 8464 } 8465 if (CurContext->isDependentContext()) 8466 V = X = nullptr; 8467 } else if (AtomicKind == OMPC_write) { 8468 enum { 8469 NotAnExpression, 8470 NotAnAssignmentOp, 8471 NotAScalarType, 8472 NotAnLValue, 8473 NoError 8474 } ErrorFound = NoError; 8475 SourceLocation ErrorLoc, NoteLoc; 8476 SourceRange ErrorRange, NoteRange; 8477 // If clause is write: 8478 // x = expr; 8479 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8480 const auto *AtomicBinOp = 8481 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8482 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8483 X = AtomicBinOp->getLHS(); 8484 E = AtomicBinOp->getRHS(); 8485 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8486 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8487 if (!X->isLValue()) { 8488 ErrorFound = NotAnLValue; 8489 ErrorLoc = AtomicBinOp->getExprLoc(); 8490 ErrorRange = AtomicBinOp->getSourceRange(); 8491 NoteLoc = X->getExprLoc(); 8492 NoteRange = X->getSourceRange(); 8493 } 8494 } else if (!X->isInstantiationDependent() || 8495 !E->isInstantiationDependent()) { 8496 const Expr *NotScalarExpr = 8497 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8498 ? E 8499 : X; 8500 ErrorFound = NotAScalarType; 8501 ErrorLoc = AtomicBinOp->getExprLoc(); 8502 ErrorRange = AtomicBinOp->getSourceRange(); 8503 NoteLoc = NotScalarExpr->getExprLoc(); 8504 NoteRange = NotScalarExpr->getSourceRange(); 8505 } 8506 } else if (!AtomicBody->isInstantiationDependent()) { 8507 ErrorFound = NotAnAssignmentOp; 8508 ErrorLoc = AtomicBody->getExprLoc(); 8509 ErrorRange = AtomicBody->getSourceRange(); 8510 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8511 : AtomicBody->getExprLoc(); 8512 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8513 : AtomicBody->getSourceRange(); 8514 } 8515 } else { 8516 ErrorFound = NotAnExpression; 8517 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8518 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8519 } 8520 if (ErrorFound != NoError) { 8521 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8522 << ErrorRange; 8523 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8524 << NoteRange; 8525 return StmtError(); 8526 } 8527 if (CurContext->isDependentContext()) 8528 E = X = nullptr; 8529 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8530 // If clause is update: 8531 // x++; 8532 // x--; 8533 // ++x; 8534 // --x; 8535 // x binop= expr; 8536 // x = x binop expr; 8537 // x = expr binop x; 8538 OpenMPAtomicUpdateChecker Checker(*this); 8539 if (Checker.checkStatement( 8540 Body, (AtomicKind == OMPC_update) 8541 ? diag::err_omp_atomic_update_not_expression_statement 8542 : diag::err_omp_atomic_not_expression_statement, 8543 diag::note_omp_atomic_update)) 8544 return StmtError(); 8545 if (!CurContext->isDependentContext()) { 8546 E = Checker.getExpr(); 8547 X = Checker.getX(); 8548 UE = Checker.getUpdateExpr(); 8549 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8550 } 8551 } else if (AtomicKind == OMPC_capture) { 8552 enum { 8553 NotAnAssignmentOp, 8554 NotACompoundStatement, 8555 NotTwoSubstatements, 8556 NotASpecificExpression, 8557 NoError 8558 } ErrorFound = NoError; 8559 SourceLocation ErrorLoc, NoteLoc; 8560 SourceRange ErrorRange, NoteRange; 8561 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8562 // If clause is a capture: 8563 // v = x++; 8564 // v = x--; 8565 // v = ++x; 8566 // v = --x; 8567 // v = x binop= expr; 8568 // v = x = x binop expr; 8569 // v = x = expr binop x; 8570 const auto *AtomicBinOp = 8571 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8572 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8573 V = AtomicBinOp->getLHS(); 8574 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8575 OpenMPAtomicUpdateChecker Checker(*this); 8576 if (Checker.checkStatement( 8577 Body, diag::err_omp_atomic_capture_not_expression_statement, 8578 diag::note_omp_atomic_update)) 8579 return StmtError(); 8580 E = Checker.getExpr(); 8581 X = Checker.getX(); 8582 UE = Checker.getUpdateExpr(); 8583 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8584 IsPostfixUpdate = Checker.isPostfixUpdate(); 8585 } else if (!AtomicBody->isInstantiationDependent()) { 8586 ErrorLoc = AtomicBody->getExprLoc(); 8587 ErrorRange = AtomicBody->getSourceRange(); 8588 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8589 : AtomicBody->getExprLoc(); 8590 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8591 : AtomicBody->getSourceRange(); 8592 ErrorFound = NotAnAssignmentOp; 8593 } 8594 if (ErrorFound != NoError) { 8595 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8596 << ErrorRange; 8597 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8598 return StmtError(); 8599 } 8600 if (CurContext->isDependentContext()) 8601 UE = V = E = X = nullptr; 8602 } else { 8603 // If clause is a capture: 8604 // { v = x; x = expr; } 8605 // { v = x; x++; } 8606 // { v = x; x--; } 8607 // { v = x; ++x; } 8608 // { v = x; --x; } 8609 // { v = x; x binop= expr; } 8610 // { v = x; x = x binop expr; } 8611 // { v = x; x = expr binop x; } 8612 // { x++; v = x; } 8613 // { x--; v = x; } 8614 // { ++x; v = x; } 8615 // { --x; v = x; } 8616 // { x binop= expr; v = x; } 8617 // { x = x binop expr; v = x; } 8618 // { x = expr binop x; v = x; } 8619 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8620 // Check that this is { expr1; expr2; } 8621 if (CS->size() == 2) { 8622 Stmt *First = CS->body_front(); 8623 Stmt *Second = CS->body_back(); 8624 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8625 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8626 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8627 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8628 // Need to find what subexpression is 'v' and what is 'x'. 8629 OpenMPAtomicUpdateChecker Checker(*this); 8630 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8631 BinaryOperator *BinOp = nullptr; 8632 if (IsUpdateExprFound) { 8633 BinOp = dyn_cast<BinaryOperator>(First); 8634 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8635 } 8636 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8637 // { v = x; x++; } 8638 // { v = x; x--; } 8639 // { v = x; ++x; } 8640 // { v = x; --x; } 8641 // { v = x; x binop= expr; } 8642 // { v = x; x = x binop expr; } 8643 // { v = x; x = expr binop x; } 8644 // Check that the first expression has form v = x. 8645 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8646 llvm::FoldingSetNodeID XId, PossibleXId; 8647 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8648 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8649 IsUpdateExprFound = XId == PossibleXId; 8650 if (IsUpdateExprFound) { 8651 V = BinOp->getLHS(); 8652 X = Checker.getX(); 8653 E = Checker.getExpr(); 8654 UE = Checker.getUpdateExpr(); 8655 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8656 IsPostfixUpdate = true; 8657 } 8658 } 8659 if (!IsUpdateExprFound) { 8660 IsUpdateExprFound = !Checker.checkStatement(First); 8661 BinOp = nullptr; 8662 if (IsUpdateExprFound) { 8663 BinOp = dyn_cast<BinaryOperator>(Second); 8664 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8665 } 8666 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8667 // { x++; v = x; } 8668 // { x--; v = x; } 8669 // { ++x; v = x; } 8670 // { --x; v = x; } 8671 // { x binop= expr; v = x; } 8672 // { x = x binop expr; v = x; } 8673 // { x = expr binop x; v = x; } 8674 // Check that the second expression has form v = x. 8675 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8676 llvm::FoldingSetNodeID XId, PossibleXId; 8677 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8678 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8679 IsUpdateExprFound = XId == PossibleXId; 8680 if (IsUpdateExprFound) { 8681 V = BinOp->getLHS(); 8682 X = Checker.getX(); 8683 E = Checker.getExpr(); 8684 UE = Checker.getUpdateExpr(); 8685 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8686 IsPostfixUpdate = false; 8687 } 8688 } 8689 } 8690 if (!IsUpdateExprFound) { 8691 // { v = x; x = expr; } 8692 auto *FirstExpr = dyn_cast<Expr>(First); 8693 auto *SecondExpr = dyn_cast<Expr>(Second); 8694 if (!FirstExpr || !SecondExpr || 8695 !(FirstExpr->isInstantiationDependent() || 8696 SecondExpr->isInstantiationDependent())) { 8697 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8698 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8699 ErrorFound = NotAnAssignmentOp; 8700 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8701 : First->getBeginLoc(); 8702 NoteRange = ErrorRange = FirstBinOp 8703 ? FirstBinOp->getSourceRange() 8704 : SourceRange(ErrorLoc, ErrorLoc); 8705 } else { 8706 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8707 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8708 ErrorFound = NotAnAssignmentOp; 8709 NoteLoc = ErrorLoc = SecondBinOp 8710 ? SecondBinOp->getOperatorLoc() 8711 : Second->getBeginLoc(); 8712 NoteRange = ErrorRange = 8713 SecondBinOp ? SecondBinOp->getSourceRange() 8714 : SourceRange(ErrorLoc, ErrorLoc); 8715 } else { 8716 Expr *PossibleXRHSInFirst = 8717 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8718 Expr *PossibleXLHSInSecond = 8719 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8720 llvm::FoldingSetNodeID X1Id, X2Id; 8721 PossibleXRHSInFirst->Profile(X1Id, Context, 8722 /*Canonical=*/true); 8723 PossibleXLHSInSecond->Profile(X2Id, Context, 8724 /*Canonical=*/true); 8725 IsUpdateExprFound = X1Id == X2Id; 8726 if (IsUpdateExprFound) { 8727 V = FirstBinOp->getLHS(); 8728 X = SecondBinOp->getLHS(); 8729 E = SecondBinOp->getRHS(); 8730 UE = nullptr; 8731 IsXLHSInRHSPart = false; 8732 IsPostfixUpdate = true; 8733 } else { 8734 ErrorFound = NotASpecificExpression; 8735 ErrorLoc = FirstBinOp->getExprLoc(); 8736 ErrorRange = FirstBinOp->getSourceRange(); 8737 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8738 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8739 } 8740 } 8741 } 8742 } 8743 } 8744 } else { 8745 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8746 NoteRange = ErrorRange = 8747 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8748 ErrorFound = NotTwoSubstatements; 8749 } 8750 } else { 8751 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8752 NoteRange = ErrorRange = 8753 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8754 ErrorFound = NotACompoundStatement; 8755 } 8756 if (ErrorFound != NoError) { 8757 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8758 << ErrorRange; 8759 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8760 return StmtError(); 8761 } 8762 if (CurContext->isDependentContext()) 8763 UE = V = E = X = nullptr; 8764 } 8765 } 8766 8767 setFunctionHasBranchProtectedScope(); 8768 8769 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8770 X, V, E, UE, IsXLHSInRHSPart, 8771 IsPostfixUpdate); 8772 } 8773 8774 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8775 Stmt *AStmt, 8776 SourceLocation StartLoc, 8777 SourceLocation EndLoc) { 8778 if (!AStmt) 8779 return StmtError(); 8780 8781 auto *CS = cast<CapturedStmt>(AStmt); 8782 // 1.2.2 OpenMP Language Terminology 8783 // Structured block - An executable statement with a single entry at the 8784 // top and a single exit at the bottom. 8785 // The point of exit cannot be a branch out of the structured block. 8786 // longjmp() and throw() must not violate the entry/exit criteria. 8787 CS->getCapturedDecl()->setNothrow(); 8788 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8789 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8790 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8791 // 1.2.2 OpenMP Language Terminology 8792 // Structured block - An executable statement with a single entry at the 8793 // top and a single exit at the bottom. 8794 // The point of exit cannot be a branch out of the structured block. 8795 // longjmp() and throw() must not violate the entry/exit criteria. 8796 CS->getCapturedDecl()->setNothrow(); 8797 } 8798 8799 // OpenMP [2.16, Nesting of Regions] 8800 // If specified, a teams construct must be contained within a target 8801 // construct. That target construct must contain no statements or directives 8802 // outside of the teams construct. 8803 if (DSAStack->hasInnerTeamsRegion()) { 8804 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8805 bool OMPTeamsFound = true; 8806 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8807 auto I = CS->body_begin(); 8808 while (I != CS->body_end()) { 8809 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8810 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8811 OMPTeamsFound) { 8812 8813 OMPTeamsFound = false; 8814 break; 8815 } 8816 ++I; 8817 } 8818 assert(I != CS->body_end() && "Not found statement"); 8819 S = *I; 8820 } else { 8821 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8822 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8823 } 8824 if (!OMPTeamsFound) { 8825 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8826 Diag(DSAStack->getInnerTeamsRegionLoc(), 8827 diag::note_omp_nested_teams_construct_here); 8828 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8829 << isa<OMPExecutableDirective>(S); 8830 return StmtError(); 8831 } 8832 } 8833 8834 setFunctionHasBranchProtectedScope(); 8835 8836 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8837 } 8838 8839 StmtResult 8840 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8841 Stmt *AStmt, SourceLocation StartLoc, 8842 SourceLocation EndLoc) { 8843 if (!AStmt) 8844 return StmtError(); 8845 8846 auto *CS = cast<CapturedStmt>(AStmt); 8847 // 1.2.2 OpenMP Language Terminology 8848 // Structured block - An executable statement with a single entry at the 8849 // top and a single exit at the bottom. 8850 // The point of exit cannot be a branch out of the structured block. 8851 // longjmp() and throw() must not violate the entry/exit criteria. 8852 CS->getCapturedDecl()->setNothrow(); 8853 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8854 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8855 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8856 // 1.2.2 OpenMP Language Terminology 8857 // Structured block - An executable statement with a single entry at the 8858 // top and a single exit at the bottom. 8859 // The point of exit cannot be a branch out of the structured block. 8860 // longjmp() and throw() must not violate the entry/exit criteria. 8861 CS->getCapturedDecl()->setNothrow(); 8862 } 8863 8864 setFunctionHasBranchProtectedScope(); 8865 8866 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8867 AStmt); 8868 } 8869 8870 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8871 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8872 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8873 if (!AStmt) 8874 return StmtError(); 8875 8876 auto *CS = cast<CapturedStmt>(AStmt); 8877 // 1.2.2 OpenMP Language Terminology 8878 // Structured block - An executable statement with a single entry at the 8879 // top and a single exit at the bottom. 8880 // The point of exit cannot be a branch out of the structured block. 8881 // longjmp() and throw() must not violate the entry/exit criteria. 8882 CS->getCapturedDecl()->setNothrow(); 8883 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8884 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8885 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8886 // 1.2.2 OpenMP Language Terminology 8887 // Structured block - An executable statement with a single entry at the 8888 // top and a single exit at the bottom. 8889 // The point of exit cannot be a branch out of the structured block. 8890 // longjmp() and throw() must not violate the entry/exit criteria. 8891 CS->getCapturedDecl()->setNothrow(); 8892 } 8893 8894 OMPLoopDirective::HelperExprs B; 8895 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8896 // define the nested loops number. 8897 unsigned NestedLoopCount = 8898 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8899 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8900 VarsWithImplicitDSA, B); 8901 if (NestedLoopCount == 0) 8902 return StmtError(); 8903 8904 assert((CurContext->isDependentContext() || B.builtAll()) && 8905 "omp target parallel for loop exprs were not built"); 8906 8907 if (!CurContext->isDependentContext()) { 8908 // Finalize the clauses that need pre-built expressions for CodeGen. 8909 for (OMPClause *C : Clauses) { 8910 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8911 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8912 B.NumIterations, *this, CurScope, 8913 DSAStack)) 8914 return StmtError(); 8915 } 8916 } 8917 8918 setFunctionHasBranchProtectedScope(); 8919 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8920 NestedLoopCount, Clauses, AStmt, 8921 B, DSAStack->isCancelRegion()); 8922 } 8923 8924 /// Check for existence of a map clause in the list of clauses. 8925 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 8926 const OpenMPClauseKind K) { 8927 return llvm::any_of( 8928 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 8929 } 8930 8931 template <typename... Params> 8932 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 8933 const Params... ClauseTypes) { 8934 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 8935 } 8936 8937 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 8938 Stmt *AStmt, 8939 SourceLocation StartLoc, 8940 SourceLocation EndLoc) { 8941 if (!AStmt) 8942 return StmtError(); 8943 8944 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8945 8946 // OpenMP [2.10.1, Restrictions, p. 97] 8947 // At least one map clause must appear on the directive. 8948 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 8949 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8950 << "'map' or 'use_device_ptr'" 8951 << getOpenMPDirectiveName(OMPD_target_data); 8952 return StmtError(); 8953 } 8954 8955 setFunctionHasBranchProtectedScope(); 8956 8957 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8958 AStmt); 8959 } 8960 8961 StmtResult 8962 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 8963 SourceLocation StartLoc, 8964 SourceLocation EndLoc, Stmt *AStmt) { 8965 if (!AStmt) 8966 return StmtError(); 8967 8968 auto *CS = cast<CapturedStmt>(AStmt); 8969 // 1.2.2 OpenMP Language Terminology 8970 // Structured block - An executable statement with a single entry at the 8971 // top and a single exit at the bottom. 8972 // The point of exit cannot be a branch out of the structured block. 8973 // longjmp() and throw() must not violate the entry/exit criteria. 8974 CS->getCapturedDecl()->setNothrow(); 8975 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 8976 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8977 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8978 // 1.2.2 OpenMP Language Terminology 8979 // Structured block - An executable statement with a single entry at the 8980 // top and a single exit at the bottom. 8981 // The point of exit cannot be a branch out of the structured block. 8982 // longjmp() and throw() must not violate the entry/exit criteria. 8983 CS->getCapturedDecl()->setNothrow(); 8984 } 8985 8986 // OpenMP [2.10.2, Restrictions, p. 99] 8987 // At least one map clause must appear on the directive. 8988 if (!hasClauses(Clauses, OMPC_map)) { 8989 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 8990 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 8991 return StmtError(); 8992 } 8993 8994 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 8995 AStmt); 8996 } 8997 8998 StmtResult 8999 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9000 SourceLocation StartLoc, 9001 SourceLocation EndLoc, Stmt *AStmt) { 9002 if (!AStmt) 9003 return StmtError(); 9004 9005 auto *CS = cast<CapturedStmt>(AStmt); 9006 // 1.2.2 OpenMP Language Terminology 9007 // Structured block - An executable statement with a single entry at the 9008 // top and a single exit at the bottom. 9009 // The point of exit cannot be a branch out of the structured block. 9010 // longjmp() and throw() must not violate the entry/exit criteria. 9011 CS->getCapturedDecl()->setNothrow(); 9012 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9013 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9014 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9015 // 1.2.2 OpenMP Language Terminology 9016 // Structured block - An executable statement with a single entry at the 9017 // top and a single exit at the bottom. 9018 // The point of exit cannot be a branch out of the structured block. 9019 // longjmp() and throw() must not violate the entry/exit criteria. 9020 CS->getCapturedDecl()->setNothrow(); 9021 } 9022 9023 // OpenMP [2.10.3, Restrictions, p. 102] 9024 // At least one map clause must appear on the directive. 9025 if (!hasClauses(Clauses, OMPC_map)) { 9026 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9027 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9028 return StmtError(); 9029 } 9030 9031 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9032 AStmt); 9033 } 9034 9035 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9036 SourceLocation StartLoc, 9037 SourceLocation EndLoc, 9038 Stmt *AStmt) { 9039 if (!AStmt) 9040 return StmtError(); 9041 9042 auto *CS = cast<CapturedStmt>(AStmt); 9043 // 1.2.2 OpenMP Language Terminology 9044 // Structured block - An executable statement with a single entry at the 9045 // top and a single exit at the bottom. 9046 // The point of exit cannot be a branch out of the structured block. 9047 // longjmp() and throw() must not violate the entry/exit criteria. 9048 CS->getCapturedDecl()->setNothrow(); 9049 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9050 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9051 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9052 // 1.2.2 OpenMP Language Terminology 9053 // Structured block - An executable statement with a single entry at the 9054 // top and a single exit at the bottom. 9055 // The point of exit cannot be a branch out of the structured block. 9056 // longjmp() and throw() must not violate the entry/exit criteria. 9057 CS->getCapturedDecl()->setNothrow(); 9058 } 9059 9060 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9061 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9062 return StmtError(); 9063 } 9064 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9065 AStmt); 9066 } 9067 9068 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9069 Stmt *AStmt, SourceLocation StartLoc, 9070 SourceLocation EndLoc) { 9071 if (!AStmt) 9072 return StmtError(); 9073 9074 auto *CS = cast<CapturedStmt>(AStmt); 9075 // 1.2.2 OpenMP Language Terminology 9076 // Structured block - An executable statement with a single entry at the 9077 // top and a single exit at the bottom. 9078 // The point of exit cannot be a branch out of the structured block. 9079 // longjmp() and throw() must not violate the entry/exit criteria. 9080 CS->getCapturedDecl()->setNothrow(); 9081 9082 setFunctionHasBranchProtectedScope(); 9083 9084 DSAStack->setParentTeamsRegionLoc(StartLoc); 9085 9086 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9087 } 9088 9089 StmtResult 9090 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9091 SourceLocation EndLoc, 9092 OpenMPDirectiveKind CancelRegion) { 9093 if (DSAStack->isParentNowaitRegion()) { 9094 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9095 return StmtError(); 9096 } 9097 if (DSAStack->isParentOrderedRegion()) { 9098 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9099 return StmtError(); 9100 } 9101 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9102 CancelRegion); 9103 } 9104 9105 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9106 SourceLocation StartLoc, 9107 SourceLocation EndLoc, 9108 OpenMPDirectiveKind CancelRegion) { 9109 if (DSAStack->isParentNowaitRegion()) { 9110 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9111 return StmtError(); 9112 } 9113 if (DSAStack->isParentOrderedRegion()) { 9114 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9115 return StmtError(); 9116 } 9117 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9118 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9119 CancelRegion); 9120 } 9121 9122 static bool checkGrainsizeNumTasksClauses(Sema &S, 9123 ArrayRef<OMPClause *> Clauses) { 9124 const OMPClause *PrevClause = nullptr; 9125 bool ErrorFound = false; 9126 for (const OMPClause *C : Clauses) { 9127 if (C->getClauseKind() == OMPC_grainsize || 9128 C->getClauseKind() == OMPC_num_tasks) { 9129 if (!PrevClause) 9130 PrevClause = C; 9131 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9132 S.Diag(C->getBeginLoc(), 9133 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9134 << getOpenMPClauseName(C->getClauseKind()) 9135 << getOpenMPClauseName(PrevClause->getClauseKind()); 9136 S.Diag(PrevClause->getBeginLoc(), 9137 diag::note_omp_previous_grainsize_num_tasks) 9138 << getOpenMPClauseName(PrevClause->getClauseKind()); 9139 ErrorFound = true; 9140 } 9141 } 9142 } 9143 return ErrorFound; 9144 } 9145 9146 static bool checkReductionClauseWithNogroup(Sema &S, 9147 ArrayRef<OMPClause *> Clauses) { 9148 const OMPClause *ReductionClause = nullptr; 9149 const OMPClause *NogroupClause = nullptr; 9150 for (const OMPClause *C : Clauses) { 9151 if (C->getClauseKind() == OMPC_reduction) { 9152 ReductionClause = C; 9153 if (NogroupClause) 9154 break; 9155 continue; 9156 } 9157 if (C->getClauseKind() == OMPC_nogroup) { 9158 NogroupClause = C; 9159 if (ReductionClause) 9160 break; 9161 continue; 9162 } 9163 } 9164 if (ReductionClause && NogroupClause) { 9165 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9166 << SourceRange(NogroupClause->getBeginLoc(), 9167 NogroupClause->getEndLoc()); 9168 return true; 9169 } 9170 return false; 9171 } 9172 9173 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9174 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9175 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9176 if (!AStmt) 9177 return StmtError(); 9178 9179 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9180 OMPLoopDirective::HelperExprs B; 9181 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9182 // define the nested loops number. 9183 unsigned NestedLoopCount = 9184 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9185 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9186 VarsWithImplicitDSA, B); 9187 if (NestedLoopCount == 0) 9188 return StmtError(); 9189 9190 assert((CurContext->isDependentContext() || B.builtAll()) && 9191 "omp for loop exprs were not built"); 9192 9193 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9194 // The grainsize clause and num_tasks clause are mutually exclusive and may 9195 // not appear on the same taskloop directive. 9196 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9197 return StmtError(); 9198 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9199 // If a reduction clause is present on the taskloop directive, the nogroup 9200 // clause must not be specified. 9201 if (checkReductionClauseWithNogroup(*this, Clauses)) 9202 return StmtError(); 9203 9204 setFunctionHasBranchProtectedScope(); 9205 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9206 NestedLoopCount, Clauses, AStmt, B); 9207 } 9208 9209 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9210 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9211 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9212 if (!AStmt) 9213 return StmtError(); 9214 9215 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9216 OMPLoopDirective::HelperExprs B; 9217 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9218 // define the nested loops number. 9219 unsigned NestedLoopCount = 9220 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9221 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9222 VarsWithImplicitDSA, B); 9223 if (NestedLoopCount == 0) 9224 return StmtError(); 9225 9226 assert((CurContext->isDependentContext() || B.builtAll()) && 9227 "omp for loop exprs were not built"); 9228 9229 if (!CurContext->isDependentContext()) { 9230 // Finalize the clauses that need pre-built expressions for CodeGen. 9231 for (OMPClause *C : Clauses) { 9232 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9233 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9234 B.NumIterations, *this, CurScope, 9235 DSAStack)) 9236 return StmtError(); 9237 } 9238 } 9239 9240 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9241 // The grainsize clause and num_tasks clause are mutually exclusive and may 9242 // not appear on the same taskloop directive. 9243 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9244 return StmtError(); 9245 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9246 // If a reduction clause is present on the taskloop directive, the nogroup 9247 // clause must not be specified. 9248 if (checkReductionClauseWithNogroup(*this, Clauses)) 9249 return StmtError(); 9250 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9251 return StmtError(); 9252 9253 setFunctionHasBranchProtectedScope(); 9254 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9255 NestedLoopCount, Clauses, AStmt, B); 9256 } 9257 9258 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9259 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9260 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9261 if (!AStmt) 9262 return StmtError(); 9263 9264 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9265 OMPLoopDirective::HelperExprs B; 9266 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9267 // define the nested loops number. 9268 unsigned NestedLoopCount = 9269 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9270 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9271 VarsWithImplicitDSA, B); 9272 if (NestedLoopCount == 0) 9273 return StmtError(); 9274 9275 assert((CurContext->isDependentContext() || B.builtAll()) && 9276 "omp for loop exprs were not built"); 9277 9278 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9279 // The grainsize clause and num_tasks clause are mutually exclusive and may 9280 // not appear on the same taskloop directive. 9281 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9282 return StmtError(); 9283 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9284 // If a reduction clause is present on the taskloop directive, the nogroup 9285 // clause must not be specified. 9286 if (checkReductionClauseWithNogroup(*this, Clauses)) 9287 return StmtError(); 9288 9289 setFunctionHasBranchProtectedScope(); 9290 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9291 NestedLoopCount, Clauses, AStmt, B); 9292 } 9293 9294 StmtResult Sema::ActOnOpenMPDistributeDirective( 9295 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9296 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9297 if (!AStmt) 9298 return StmtError(); 9299 9300 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9301 OMPLoopDirective::HelperExprs B; 9302 // In presence of clause 'collapse' with number of loops, it will 9303 // define the nested loops number. 9304 unsigned NestedLoopCount = 9305 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9306 nullptr /*ordered not a clause on distribute*/, AStmt, 9307 *this, *DSAStack, VarsWithImplicitDSA, B); 9308 if (NestedLoopCount == 0) 9309 return StmtError(); 9310 9311 assert((CurContext->isDependentContext() || B.builtAll()) && 9312 "omp for loop exprs were not built"); 9313 9314 setFunctionHasBranchProtectedScope(); 9315 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9316 NestedLoopCount, Clauses, AStmt, B); 9317 } 9318 9319 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9320 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9321 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9322 if (!AStmt) 9323 return StmtError(); 9324 9325 auto *CS = cast<CapturedStmt>(AStmt); 9326 // 1.2.2 OpenMP Language Terminology 9327 // Structured block - An executable statement with a single entry at the 9328 // top and a single exit at the bottom. 9329 // The point of exit cannot be a branch out of the structured block. 9330 // longjmp() and throw() must not violate the entry/exit criteria. 9331 CS->getCapturedDecl()->setNothrow(); 9332 for (int ThisCaptureLevel = 9333 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9334 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9335 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9336 // 1.2.2 OpenMP Language Terminology 9337 // Structured block - An executable statement with a single entry at the 9338 // top and a single exit at the bottom. 9339 // The point of exit cannot be a branch out of the structured block. 9340 // longjmp() and throw() must not violate the entry/exit criteria. 9341 CS->getCapturedDecl()->setNothrow(); 9342 } 9343 9344 OMPLoopDirective::HelperExprs B; 9345 // In presence of clause 'collapse' with number of loops, it will 9346 // define the nested loops number. 9347 unsigned NestedLoopCount = checkOpenMPLoop( 9348 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9349 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9350 VarsWithImplicitDSA, B); 9351 if (NestedLoopCount == 0) 9352 return StmtError(); 9353 9354 assert((CurContext->isDependentContext() || B.builtAll()) && 9355 "omp for loop exprs were not built"); 9356 9357 setFunctionHasBranchProtectedScope(); 9358 return OMPDistributeParallelForDirective::Create( 9359 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9360 DSAStack->isCancelRegion()); 9361 } 9362 9363 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9364 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9365 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9366 if (!AStmt) 9367 return StmtError(); 9368 9369 auto *CS = cast<CapturedStmt>(AStmt); 9370 // 1.2.2 OpenMP Language Terminology 9371 // Structured block - An executable statement with a single entry at the 9372 // top and a single exit at the bottom. 9373 // The point of exit cannot be a branch out of the structured block. 9374 // longjmp() and throw() must not violate the entry/exit criteria. 9375 CS->getCapturedDecl()->setNothrow(); 9376 for (int ThisCaptureLevel = 9377 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9378 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9379 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9380 // 1.2.2 OpenMP Language Terminology 9381 // Structured block - An executable statement with a single entry at the 9382 // top and a single exit at the bottom. 9383 // The point of exit cannot be a branch out of the structured block. 9384 // longjmp() and throw() must not violate the entry/exit criteria. 9385 CS->getCapturedDecl()->setNothrow(); 9386 } 9387 9388 OMPLoopDirective::HelperExprs B; 9389 // In presence of clause 'collapse' with number of loops, it will 9390 // define the nested loops number. 9391 unsigned NestedLoopCount = checkOpenMPLoop( 9392 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9393 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9394 VarsWithImplicitDSA, B); 9395 if (NestedLoopCount == 0) 9396 return StmtError(); 9397 9398 assert((CurContext->isDependentContext() || B.builtAll()) && 9399 "omp for loop exprs were not built"); 9400 9401 if (!CurContext->isDependentContext()) { 9402 // Finalize the clauses that need pre-built expressions for CodeGen. 9403 for (OMPClause *C : Clauses) { 9404 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9405 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9406 B.NumIterations, *this, CurScope, 9407 DSAStack)) 9408 return StmtError(); 9409 } 9410 } 9411 9412 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9413 return StmtError(); 9414 9415 setFunctionHasBranchProtectedScope(); 9416 return OMPDistributeParallelForSimdDirective::Create( 9417 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9418 } 9419 9420 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9421 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9422 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9423 if (!AStmt) 9424 return StmtError(); 9425 9426 auto *CS = cast<CapturedStmt>(AStmt); 9427 // 1.2.2 OpenMP Language Terminology 9428 // Structured block - An executable statement with a single entry at the 9429 // top and a single exit at the bottom. 9430 // The point of exit cannot be a branch out of the structured block. 9431 // longjmp() and throw() must not violate the entry/exit criteria. 9432 CS->getCapturedDecl()->setNothrow(); 9433 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9434 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9435 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9436 // 1.2.2 OpenMP Language Terminology 9437 // Structured block - An executable statement with a single entry at the 9438 // top and a single exit at the bottom. 9439 // The point of exit cannot be a branch out of the structured block. 9440 // longjmp() and throw() must not violate the entry/exit criteria. 9441 CS->getCapturedDecl()->setNothrow(); 9442 } 9443 9444 OMPLoopDirective::HelperExprs B; 9445 // In presence of clause 'collapse' with number of loops, it will 9446 // define the nested loops number. 9447 unsigned NestedLoopCount = 9448 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9449 nullptr /*ordered not a clause on distribute*/, CS, *this, 9450 *DSAStack, VarsWithImplicitDSA, B); 9451 if (NestedLoopCount == 0) 9452 return StmtError(); 9453 9454 assert((CurContext->isDependentContext() || B.builtAll()) && 9455 "omp for loop exprs were not built"); 9456 9457 if (!CurContext->isDependentContext()) { 9458 // Finalize the clauses that need pre-built expressions for CodeGen. 9459 for (OMPClause *C : Clauses) { 9460 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9461 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9462 B.NumIterations, *this, CurScope, 9463 DSAStack)) 9464 return StmtError(); 9465 } 9466 } 9467 9468 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9469 return StmtError(); 9470 9471 setFunctionHasBranchProtectedScope(); 9472 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9473 NestedLoopCount, Clauses, AStmt, B); 9474 } 9475 9476 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9477 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9478 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9479 if (!AStmt) 9480 return StmtError(); 9481 9482 auto *CS = cast<CapturedStmt>(AStmt); 9483 // 1.2.2 OpenMP Language Terminology 9484 // Structured block - An executable statement with a single entry at the 9485 // top and a single exit at the bottom. 9486 // The point of exit cannot be a branch out of the structured block. 9487 // longjmp() and throw() must not violate the entry/exit criteria. 9488 CS->getCapturedDecl()->setNothrow(); 9489 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9490 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9491 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9492 // 1.2.2 OpenMP Language Terminology 9493 // Structured block - An executable statement with a single entry at the 9494 // top and a single exit at the bottom. 9495 // The point of exit cannot be a branch out of the structured block. 9496 // longjmp() and throw() must not violate the entry/exit criteria. 9497 CS->getCapturedDecl()->setNothrow(); 9498 } 9499 9500 OMPLoopDirective::HelperExprs B; 9501 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9502 // define the nested loops number. 9503 unsigned NestedLoopCount = checkOpenMPLoop( 9504 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9505 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9506 VarsWithImplicitDSA, B); 9507 if (NestedLoopCount == 0) 9508 return StmtError(); 9509 9510 assert((CurContext->isDependentContext() || B.builtAll()) && 9511 "omp target parallel for simd loop exprs were not built"); 9512 9513 if (!CurContext->isDependentContext()) { 9514 // Finalize the clauses that need pre-built expressions for CodeGen. 9515 for (OMPClause *C : Clauses) { 9516 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9517 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9518 B.NumIterations, *this, CurScope, 9519 DSAStack)) 9520 return StmtError(); 9521 } 9522 } 9523 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9524 return StmtError(); 9525 9526 setFunctionHasBranchProtectedScope(); 9527 return OMPTargetParallelForSimdDirective::Create( 9528 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9529 } 9530 9531 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9532 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9533 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9534 if (!AStmt) 9535 return StmtError(); 9536 9537 auto *CS = cast<CapturedStmt>(AStmt); 9538 // 1.2.2 OpenMP Language Terminology 9539 // Structured block - An executable statement with a single entry at the 9540 // top and a single exit at the bottom. 9541 // The point of exit cannot be a branch out of the structured block. 9542 // longjmp() and throw() must not violate the entry/exit criteria. 9543 CS->getCapturedDecl()->setNothrow(); 9544 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9545 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9546 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9547 // 1.2.2 OpenMP Language Terminology 9548 // Structured block - An executable statement with a single entry at the 9549 // top and a single exit at the bottom. 9550 // The point of exit cannot be a branch out of the structured block. 9551 // longjmp() and throw() must not violate the entry/exit criteria. 9552 CS->getCapturedDecl()->setNothrow(); 9553 } 9554 9555 OMPLoopDirective::HelperExprs B; 9556 // In presence of clause 'collapse' with number of loops, it will define the 9557 // nested loops number. 9558 unsigned NestedLoopCount = 9559 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9560 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9561 VarsWithImplicitDSA, B); 9562 if (NestedLoopCount == 0) 9563 return StmtError(); 9564 9565 assert((CurContext->isDependentContext() || B.builtAll()) && 9566 "omp target simd loop exprs were not built"); 9567 9568 if (!CurContext->isDependentContext()) { 9569 // Finalize the clauses that need pre-built expressions for CodeGen. 9570 for (OMPClause *C : Clauses) { 9571 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9572 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9573 B.NumIterations, *this, CurScope, 9574 DSAStack)) 9575 return StmtError(); 9576 } 9577 } 9578 9579 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9580 return StmtError(); 9581 9582 setFunctionHasBranchProtectedScope(); 9583 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9584 NestedLoopCount, Clauses, AStmt, B); 9585 } 9586 9587 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9588 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9589 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9590 if (!AStmt) 9591 return StmtError(); 9592 9593 auto *CS = cast<CapturedStmt>(AStmt); 9594 // 1.2.2 OpenMP Language Terminology 9595 // Structured block - An executable statement with a single entry at the 9596 // top and a single exit at the bottom. 9597 // The point of exit cannot be a branch out of the structured block. 9598 // longjmp() and throw() must not violate the entry/exit criteria. 9599 CS->getCapturedDecl()->setNothrow(); 9600 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9601 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9602 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9603 // 1.2.2 OpenMP Language Terminology 9604 // Structured block - An executable statement with a single entry at the 9605 // top and a single exit at the bottom. 9606 // The point of exit cannot be a branch out of the structured block. 9607 // longjmp() and throw() must not violate the entry/exit criteria. 9608 CS->getCapturedDecl()->setNothrow(); 9609 } 9610 9611 OMPLoopDirective::HelperExprs B; 9612 // In presence of clause 'collapse' with number of loops, it will 9613 // define the nested loops number. 9614 unsigned NestedLoopCount = 9615 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9616 nullptr /*ordered not a clause on distribute*/, CS, *this, 9617 *DSAStack, VarsWithImplicitDSA, B); 9618 if (NestedLoopCount == 0) 9619 return StmtError(); 9620 9621 assert((CurContext->isDependentContext() || B.builtAll()) && 9622 "omp teams distribute loop exprs were not built"); 9623 9624 setFunctionHasBranchProtectedScope(); 9625 9626 DSAStack->setParentTeamsRegionLoc(StartLoc); 9627 9628 return OMPTeamsDistributeDirective::Create( 9629 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9630 } 9631 9632 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9633 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9634 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9635 if (!AStmt) 9636 return StmtError(); 9637 9638 auto *CS = cast<CapturedStmt>(AStmt); 9639 // 1.2.2 OpenMP Language Terminology 9640 // Structured block - An executable statement with a single entry at the 9641 // top and a single exit at the bottom. 9642 // The point of exit cannot be a branch out of the structured block. 9643 // longjmp() and throw() must not violate the entry/exit criteria. 9644 CS->getCapturedDecl()->setNothrow(); 9645 for (int ThisCaptureLevel = 9646 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9647 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9648 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9649 // 1.2.2 OpenMP Language Terminology 9650 // Structured block - An executable statement with a single entry at the 9651 // top and a single exit at the bottom. 9652 // The point of exit cannot be a branch out of the structured block. 9653 // longjmp() and throw() must not violate the entry/exit criteria. 9654 CS->getCapturedDecl()->setNothrow(); 9655 } 9656 9657 9658 OMPLoopDirective::HelperExprs B; 9659 // In presence of clause 'collapse' with number of loops, it will 9660 // define the nested loops number. 9661 unsigned NestedLoopCount = checkOpenMPLoop( 9662 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9663 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9664 VarsWithImplicitDSA, B); 9665 9666 if (NestedLoopCount == 0) 9667 return StmtError(); 9668 9669 assert((CurContext->isDependentContext() || B.builtAll()) && 9670 "omp teams distribute simd loop exprs were not built"); 9671 9672 if (!CurContext->isDependentContext()) { 9673 // Finalize the clauses that need pre-built expressions for CodeGen. 9674 for (OMPClause *C : Clauses) { 9675 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9676 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9677 B.NumIterations, *this, CurScope, 9678 DSAStack)) 9679 return StmtError(); 9680 } 9681 } 9682 9683 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9684 return StmtError(); 9685 9686 setFunctionHasBranchProtectedScope(); 9687 9688 DSAStack->setParentTeamsRegionLoc(StartLoc); 9689 9690 return OMPTeamsDistributeSimdDirective::Create( 9691 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9692 } 9693 9694 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9695 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9696 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9697 if (!AStmt) 9698 return StmtError(); 9699 9700 auto *CS = cast<CapturedStmt>(AStmt); 9701 // 1.2.2 OpenMP Language Terminology 9702 // Structured block - An executable statement with a single entry at the 9703 // top and a single exit at the bottom. 9704 // The point of exit cannot be a branch out of the structured block. 9705 // longjmp() and throw() must not violate the entry/exit criteria. 9706 CS->getCapturedDecl()->setNothrow(); 9707 9708 for (int ThisCaptureLevel = 9709 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9710 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9711 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9712 // 1.2.2 OpenMP Language Terminology 9713 // Structured block - An executable statement with a single entry at the 9714 // top and a single exit at the bottom. 9715 // The point of exit cannot be a branch out of the structured block. 9716 // longjmp() and throw() must not violate the entry/exit criteria. 9717 CS->getCapturedDecl()->setNothrow(); 9718 } 9719 9720 OMPLoopDirective::HelperExprs B; 9721 // In presence of clause 'collapse' with number of loops, it will 9722 // define the nested loops number. 9723 unsigned NestedLoopCount = checkOpenMPLoop( 9724 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9725 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9726 VarsWithImplicitDSA, B); 9727 9728 if (NestedLoopCount == 0) 9729 return StmtError(); 9730 9731 assert((CurContext->isDependentContext() || B.builtAll()) && 9732 "omp for loop exprs were not built"); 9733 9734 if (!CurContext->isDependentContext()) { 9735 // Finalize the clauses that need pre-built expressions for CodeGen. 9736 for (OMPClause *C : Clauses) { 9737 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9738 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9739 B.NumIterations, *this, CurScope, 9740 DSAStack)) 9741 return StmtError(); 9742 } 9743 } 9744 9745 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9746 return StmtError(); 9747 9748 setFunctionHasBranchProtectedScope(); 9749 9750 DSAStack->setParentTeamsRegionLoc(StartLoc); 9751 9752 return OMPTeamsDistributeParallelForSimdDirective::Create( 9753 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9754 } 9755 9756 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9757 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9758 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9759 if (!AStmt) 9760 return StmtError(); 9761 9762 auto *CS = cast<CapturedStmt>(AStmt); 9763 // 1.2.2 OpenMP Language Terminology 9764 // Structured block - An executable statement with a single entry at the 9765 // top and a single exit at the bottom. 9766 // The point of exit cannot be a branch out of the structured block. 9767 // longjmp() and throw() must not violate the entry/exit criteria. 9768 CS->getCapturedDecl()->setNothrow(); 9769 9770 for (int ThisCaptureLevel = 9771 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9772 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9773 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9774 // 1.2.2 OpenMP Language Terminology 9775 // Structured block - An executable statement with a single entry at the 9776 // top and a single exit at the bottom. 9777 // The point of exit cannot be a branch out of the structured block. 9778 // longjmp() and throw() must not violate the entry/exit criteria. 9779 CS->getCapturedDecl()->setNothrow(); 9780 } 9781 9782 OMPLoopDirective::HelperExprs B; 9783 // In presence of clause 'collapse' with number of loops, it will 9784 // define the nested loops number. 9785 unsigned NestedLoopCount = checkOpenMPLoop( 9786 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9787 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9788 VarsWithImplicitDSA, B); 9789 9790 if (NestedLoopCount == 0) 9791 return StmtError(); 9792 9793 assert((CurContext->isDependentContext() || B.builtAll()) && 9794 "omp for loop exprs were not built"); 9795 9796 setFunctionHasBranchProtectedScope(); 9797 9798 DSAStack->setParentTeamsRegionLoc(StartLoc); 9799 9800 return OMPTeamsDistributeParallelForDirective::Create( 9801 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9802 DSAStack->isCancelRegion()); 9803 } 9804 9805 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9806 Stmt *AStmt, 9807 SourceLocation StartLoc, 9808 SourceLocation EndLoc) { 9809 if (!AStmt) 9810 return StmtError(); 9811 9812 auto *CS = cast<CapturedStmt>(AStmt); 9813 // 1.2.2 OpenMP Language Terminology 9814 // Structured block - An executable statement with a single entry at the 9815 // top and a single exit at the bottom. 9816 // The point of exit cannot be a branch out of the structured block. 9817 // longjmp() and throw() must not violate the entry/exit criteria. 9818 CS->getCapturedDecl()->setNothrow(); 9819 9820 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 9821 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9822 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9823 // 1.2.2 OpenMP Language Terminology 9824 // Structured block - An executable statement with a single entry at the 9825 // top and a single exit at the bottom. 9826 // The point of exit cannot be a branch out of the structured block. 9827 // longjmp() and throw() must not violate the entry/exit criteria. 9828 CS->getCapturedDecl()->setNothrow(); 9829 } 9830 setFunctionHasBranchProtectedScope(); 9831 9832 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 9833 AStmt); 9834 } 9835 9836 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 9837 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9838 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9839 if (!AStmt) 9840 return StmtError(); 9841 9842 auto *CS = cast<CapturedStmt>(AStmt); 9843 // 1.2.2 OpenMP Language Terminology 9844 // Structured block - An executable statement with a single entry at the 9845 // top and a single exit at the bottom. 9846 // The point of exit cannot be a branch out of the structured block. 9847 // longjmp() and throw() must not violate the entry/exit criteria. 9848 CS->getCapturedDecl()->setNothrow(); 9849 for (int ThisCaptureLevel = 9850 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 9851 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9852 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9853 // 1.2.2 OpenMP Language Terminology 9854 // Structured block - An executable statement with a single entry at the 9855 // top and a single exit at the bottom. 9856 // The point of exit cannot be a branch out of the structured block. 9857 // longjmp() and throw() must not violate the entry/exit criteria. 9858 CS->getCapturedDecl()->setNothrow(); 9859 } 9860 9861 OMPLoopDirective::HelperExprs B; 9862 // In presence of clause 'collapse' with number of loops, it will 9863 // define the nested loops number. 9864 unsigned NestedLoopCount = checkOpenMPLoop( 9865 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 9866 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9867 VarsWithImplicitDSA, B); 9868 if (NestedLoopCount == 0) 9869 return StmtError(); 9870 9871 assert((CurContext->isDependentContext() || B.builtAll()) && 9872 "omp target teams distribute loop exprs were not built"); 9873 9874 setFunctionHasBranchProtectedScope(); 9875 return OMPTargetTeamsDistributeDirective::Create( 9876 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9877 } 9878 9879 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 9880 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9881 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9882 if (!AStmt) 9883 return StmtError(); 9884 9885 auto *CS = cast<CapturedStmt>(AStmt); 9886 // 1.2.2 OpenMP Language Terminology 9887 // Structured block - An executable statement with a single entry at the 9888 // top and a single exit at the bottom. 9889 // The point of exit cannot be a branch out of the structured block. 9890 // longjmp() and throw() must not violate the entry/exit criteria. 9891 CS->getCapturedDecl()->setNothrow(); 9892 for (int ThisCaptureLevel = 9893 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 9894 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9895 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9896 // 1.2.2 OpenMP Language Terminology 9897 // Structured block - An executable statement with a single entry at the 9898 // top and a single exit at the bottom. 9899 // The point of exit cannot be a branch out of the structured block. 9900 // longjmp() and throw() must not violate the entry/exit criteria. 9901 CS->getCapturedDecl()->setNothrow(); 9902 } 9903 9904 OMPLoopDirective::HelperExprs B; 9905 // In presence of clause 'collapse' with number of loops, it will 9906 // define the nested loops number. 9907 unsigned NestedLoopCount = checkOpenMPLoop( 9908 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9909 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9910 VarsWithImplicitDSA, B); 9911 if (NestedLoopCount == 0) 9912 return StmtError(); 9913 9914 assert((CurContext->isDependentContext() || B.builtAll()) && 9915 "omp target teams distribute parallel for loop exprs were not built"); 9916 9917 if (!CurContext->isDependentContext()) { 9918 // Finalize the clauses that need pre-built expressions for CodeGen. 9919 for (OMPClause *C : Clauses) { 9920 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9921 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9922 B.NumIterations, *this, CurScope, 9923 DSAStack)) 9924 return StmtError(); 9925 } 9926 } 9927 9928 setFunctionHasBranchProtectedScope(); 9929 return OMPTargetTeamsDistributeParallelForDirective::Create( 9930 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9931 DSAStack->isCancelRegion()); 9932 } 9933 9934 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 9935 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9936 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9937 if (!AStmt) 9938 return StmtError(); 9939 9940 auto *CS = cast<CapturedStmt>(AStmt); 9941 // 1.2.2 OpenMP Language Terminology 9942 // Structured block - An executable statement with a single entry at the 9943 // top and a single exit at the bottom. 9944 // The point of exit cannot be a branch out of the structured block. 9945 // longjmp() and throw() must not violate the entry/exit criteria. 9946 CS->getCapturedDecl()->setNothrow(); 9947 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 9948 OMPD_target_teams_distribute_parallel_for_simd); 9949 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9950 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9951 // 1.2.2 OpenMP Language Terminology 9952 // Structured block - An executable statement with a single entry at the 9953 // top and a single exit at the bottom. 9954 // The point of exit cannot be a branch out of the structured block. 9955 // longjmp() and throw() must not violate the entry/exit criteria. 9956 CS->getCapturedDecl()->setNothrow(); 9957 } 9958 9959 OMPLoopDirective::HelperExprs B; 9960 // In presence of clause 'collapse' with number of loops, it will 9961 // define the nested loops number. 9962 unsigned NestedLoopCount = 9963 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 9964 getCollapseNumberExpr(Clauses), 9965 nullptr /*ordered not a clause on distribute*/, CS, *this, 9966 *DSAStack, VarsWithImplicitDSA, B); 9967 if (NestedLoopCount == 0) 9968 return StmtError(); 9969 9970 assert((CurContext->isDependentContext() || B.builtAll()) && 9971 "omp target teams distribute parallel for simd loop exprs were not " 9972 "built"); 9973 9974 if (!CurContext->isDependentContext()) { 9975 // Finalize the clauses that need pre-built expressions for CodeGen. 9976 for (OMPClause *C : Clauses) { 9977 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9978 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9979 B.NumIterations, *this, CurScope, 9980 DSAStack)) 9981 return StmtError(); 9982 } 9983 } 9984 9985 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9986 return StmtError(); 9987 9988 setFunctionHasBranchProtectedScope(); 9989 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 9990 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9991 } 9992 9993 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 9994 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9995 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9996 if (!AStmt) 9997 return StmtError(); 9998 9999 auto *CS = cast<CapturedStmt>(AStmt); 10000 // 1.2.2 OpenMP Language Terminology 10001 // Structured block - An executable statement with a single entry at the 10002 // top and a single exit at the bottom. 10003 // The point of exit cannot be a branch out of the structured block. 10004 // longjmp() and throw() must not violate the entry/exit criteria. 10005 CS->getCapturedDecl()->setNothrow(); 10006 for (int ThisCaptureLevel = 10007 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10008 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10009 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10010 // 1.2.2 OpenMP Language Terminology 10011 // Structured block - An executable statement with a single entry at the 10012 // top and a single exit at the bottom. 10013 // The point of exit cannot be a branch out of the structured block. 10014 // longjmp() and throw() must not violate the entry/exit criteria. 10015 CS->getCapturedDecl()->setNothrow(); 10016 } 10017 10018 OMPLoopDirective::HelperExprs B; 10019 // In presence of clause 'collapse' with number of loops, it will 10020 // define the nested loops number. 10021 unsigned NestedLoopCount = checkOpenMPLoop( 10022 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10023 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10024 VarsWithImplicitDSA, B); 10025 if (NestedLoopCount == 0) 10026 return StmtError(); 10027 10028 assert((CurContext->isDependentContext() || B.builtAll()) && 10029 "omp target teams distribute simd loop exprs were not built"); 10030 10031 if (!CurContext->isDependentContext()) { 10032 // Finalize the clauses that need pre-built expressions for CodeGen. 10033 for (OMPClause *C : Clauses) { 10034 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10035 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10036 B.NumIterations, *this, CurScope, 10037 DSAStack)) 10038 return StmtError(); 10039 } 10040 } 10041 10042 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10043 return StmtError(); 10044 10045 setFunctionHasBranchProtectedScope(); 10046 return OMPTargetTeamsDistributeSimdDirective::Create( 10047 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10048 } 10049 10050 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10051 SourceLocation StartLoc, 10052 SourceLocation LParenLoc, 10053 SourceLocation EndLoc) { 10054 OMPClause *Res = nullptr; 10055 switch (Kind) { 10056 case OMPC_final: 10057 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10058 break; 10059 case OMPC_num_threads: 10060 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10061 break; 10062 case OMPC_safelen: 10063 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10064 break; 10065 case OMPC_simdlen: 10066 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10067 break; 10068 case OMPC_allocator: 10069 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10070 break; 10071 case OMPC_collapse: 10072 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10073 break; 10074 case OMPC_ordered: 10075 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10076 break; 10077 case OMPC_device: 10078 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10079 break; 10080 case OMPC_num_teams: 10081 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10082 break; 10083 case OMPC_thread_limit: 10084 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10085 break; 10086 case OMPC_priority: 10087 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10088 break; 10089 case OMPC_grainsize: 10090 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10091 break; 10092 case OMPC_num_tasks: 10093 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10094 break; 10095 case OMPC_hint: 10096 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10097 break; 10098 case OMPC_if: 10099 case OMPC_default: 10100 case OMPC_proc_bind: 10101 case OMPC_schedule: 10102 case OMPC_private: 10103 case OMPC_firstprivate: 10104 case OMPC_lastprivate: 10105 case OMPC_shared: 10106 case OMPC_reduction: 10107 case OMPC_task_reduction: 10108 case OMPC_in_reduction: 10109 case OMPC_linear: 10110 case OMPC_aligned: 10111 case OMPC_copyin: 10112 case OMPC_copyprivate: 10113 case OMPC_nowait: 10114 case OMPC_untied: 10115 case OMPC_mergeable: 10116 case OMPC_threadprivate: 10117 case OMPC_allocate: 10118 case OMPC_flush: 10119 case OMPC_read: 10120 case OMPC_write: 10121 case OMPC_update: 10122 case OMPC_capture: 10123 case OMPC_seq_cst: 10124 case OMPC_depend: 10125 case OMPC_threads: 10126 case OMPC_simd: 10127 case OMPC_map: 10128 case OMPC_nogroup: 10129 case OMPC_dist_schedule: 10130 case OMPC_defaultmap: 10131 case OMPC_unknown: 10132 case OMPC_uniform: 10133 case OMPC_to: 10134 case OMPC_from: 10135 case OMPC_use_device_ptr: 10136 case OMPC_is_device_ptr: 10137 case OMPC_unified_address: 10138 case OMPC_unified_shared_memory: 10139 case OMPC_reverse_offload: 10140 case OMPC_dynamic_allocators: 10141 case OMPC_atomic_default_mem_order: 10142 case OMPC_device_type: 10143 case OMPC_match: 10144 llvm_unreachable("Clause is not allowed."); 10145 } 10146 return Res; 10147 } 10148 10149 // An OpenMP directive such as 'target parallel' has two captured regions: 10150 // for the 'target' and 'parallel' respectively. This function returns 10151 // the region in which to capture expressions associated with a clause. 10152 // A return value of OMPD_unknown signifies that the expression should not 10153 // be captured. 10154 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10155 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10156 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10157 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10158 switch (CKind) { 10159 case OMPC_if: 10160 switch (DKind) { 10161 case OMPD_target_parallel: 10162 case OMPD_target_parallel_for: 10163 case OMPD_target_parallel_for_simd: 10164 // If this clause applies to the nested 'parallel' region, capture within 10165 // the 'target' region, otherwise do not capture. 10166 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10167 CaptureRegion = OMPD_target; 10168 break; 10169 case OMPD_target_teams_distribute_parallel_for: 10170 case OMPD_target_teams_distribute_parallel_for_simd: 10171 // If this clause applies to the nested 'parallel' region, capture within 10172 // the 'teams' region, otherwise do not capture. 10173 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10174 CaptureRegion = OMPD_teams; 10175 break; 10176 case OMPD_teams_distribute_parallel_for: 10177 case OMPD_teams_distribute_parallel_for_simd: 10178 CaptureRegion = OMPD_teams; 10179 break; 10180 case OMPD_target_update: 10181 case OMPD_target_enter_data: 10182 case OMPD_target_exit_data: 10183 CaptureRegion = OMPD_task; 10184 break; 10185 case OMPD_cancel: 10186 case OMPD_parallel: 10187 case OMPD_parallel_sections: 10188 case OMPD_parallel_for: 10189 case OMPD_parallel_for_simd: 10190 case OMPD_target: 10191 case OMPD_target_simd: 10192 case OMPD_target_teams: 10193 case OMPD_target_teams_distribute: 10194 case OMPD_target_teams_distribute_simd: 10195 case OMPD_distribute_parallel_for: 10196 case OMPD_distribute_parallel_for_simd: 10197 case OMPD_task: 10198 case OMPD_taskloop: 10199 case OMPD_taskloop_simd: 10200 case OMPD_master_taskloop: 10201 case OMPD_target_data: 10202 // Do not capture if-clause expressions. 10203 break; 10204 case OMPD_threadprivate: 10205 case OMPD_allocate: 10206 case OMPD_taskyield: 10207 case OMPD_barrier: 10208 case OMPD_taskwait: 10209 case OMPD_cancellation_point: 10210 case OMPD_flush: 10211 case OMPD_declare_reduction: 10212 case OMPD_declare_mapper: 10213 case OMPD_declare_simd: 10214 case OMPD_declare_variant: 10215 case OMPD_declare_target: 10216 case OMPD_end_declare_target: 10217 case OMPD_teams: 10218 case OMPD_simd: 10219 case OMPD_for: 10220 case OMPD_for_simd: 10221 case OMPD_sections: 10222 case OMPD_section: 10223 case OMPD_single: 10224 case OMPD_master: 10225 case OMPD_critical: 10226 case OMPD_taskgroup: 10227 case OMPD_distribute: 10228 case OMPD_ordered: 10229 case OMPD_atomic: 10230 case OMPD_distribute_simd: 10231 case OMPD_teams_distribute: 10232 case OMPD_teams_distribute_simd: 10233 case OMPD_requires: 10234 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10235 case OMPD_unknown: 10236 llvm_unreachable("Unknown OpenMP directive"); 10237 } 10238 break; 10239 case OMPC_num_threads: 10240 switch (DKind) { 10241 case OMPD_target_parallel: 10242 case OMPD_target_parallel_for: 10243 case OMPD_target_parallel_for_simd: 10244 CaptureRegion = OMPD_target; 10245 break; 10246 case OMPD_teams_distribute_parallel_for: 10247 case OMPD_teams_distribute_parallel_for_simd: 10248 case OMPD_target_teams_distribute_parallel_for: 10249 case OMPD_target_teams_distribute_parallel_for_simd: 10250 CaptureRegion = OMPD_teams; 10251 break; 10252 case OMPD_parallel: 10253 case OMPD_parallel_sections: 10254 case OMPD_parallel_for: 10255 case OMPD_parallel_for_simd: 10256 case OMPD_distribute_parallel_for: 10257 case OMPD_distribute_parallel_for_simd: 10258 // Do not capture num_threads-clause expressions. 10259 break; 10260 case OMPD_target_data: 10261 case OMPD_target_enter_data: 10262 case OMPD_target_exit_data: 10263 case OMPD_target_update: 10264 case OMPD_target: 10265 case OMPD_target_simd: 10266 case OMPD_target_teams: 10267 case OMPD_target_teams_distribute: 10268 case OMPD_target_teams_distribute_simd: 10269 case OMPD_cancel: 10270 case OMPD_task: 10271 case OMPD_taskloop: 10272 case OMPD_taskloop_simd: 10273 case OMPD_master_taskloop: 10274 case OMPD_threadprivate: 10275 case OMPD_allocate: 10276 case OMPD_taskyield: 10277 case OMPD_barrier: 10278 case OMPD_taskwait: 10279 case OMPD_cancellation_point: 10280 case OMPD_flush: 10281 case OMPD_declare_reduction: 10282 case OMPD_declare_mapper: 10283 case OMPD_declare_simd: 10284 case OMPD_declare_variant: 10285 case OMPD_declare_target: 10286 case OMPD_end_declare_target: 10287 case OMPD_teams: 10288 case OMPD_simd: 10289 case OMPD_for: 10290 case OMPD_for_simd: 10291 case OMPD_sections: 10292 case OMPD_section: 10293 case OMPD_single: 10294 case OMPD_master: 10295 case OMPD_critical: 10296 case OMPD_taskgroup: 10297 case OMPD_distribute: 10298 case OMPD_ordered: 10299 case OMPD_atomic: 10300 case OMPD_distribute_simd: 10301 case OMPD_teams_distribute: 10302 case OMPD_teams_distribute_simd: 10303 case OMPD_requires: 10304 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10305 case OMPD_unknown: 10306 llvm_unreachable("Unknown OpenMP directive"); 10307 } 10308 break; 10309 case OMPC_num_teams: 10310 switch (DKind) { 10311 case OMPD_target_teams: 10312 case OMPD_target_teams_distribute: 10313 case OMPD_target_teams_distribute_simd: 10314 case OMPD_target_teams_distribute_parallel_for: 10315 case OMPD_target_teams_distribute_parallel_for_simd: 10316 CaptureRegion = OMPD_target; 10317 break; 10318 case OMPD_teams_distribute_parallel_for: 10319 case OMPD_teams_distribute_parallel_for_simd: 10320 case OMPD_teams: 10321 case OMPD_teams_distribute: 10322 case OMPD_teams_distribute_simd: 10323 // Do not capture num_teams-clause expressions. 10324 break; 10325 case OMPD_distribute_parallel_for: 10326 case OMPD_distribute_parallel_for_simd: 10327 case OMPD_task: 10328 case OMPD_taskloop: 10329 case OMPD_taskloop_simd: 10330 case OMPD_master_taskloop: 10331 case OMPD_target_data: 10332 case OMPD_target_enter_data: 10333 case OMPD_target_exit_data: 10334 case OMPD_target_update: 10335 case OMPD_cancel: 10336 case OMPD_parallel: 10337 case OMPD_parallel_sections: 10338 case OMPD_parallel_for: 10339 case OMPD_parallel_for_simd: 10340 case OMPD_target: 10341 case OMPD_target_simd: 10342 case OMPD_target_parallel: 10343 case OMPD_target_parallel_for: 10344 case OMPD_target_parallel_for_simd: 10345 case OMPD_threadprivate: 10346 case OMPD_allocate: 10347 case OMPD_taskyield: 10348 case OMPD_barrier: 10349 case OMPD_taskwait: 10350 case OMPD_cancellation_point: 10351 case OMPD_flush: 10352 case OMPD_declare_reduction: 10353 case OMPD_declare_mapper: 10354 case OMPD_declare_simd: 10355 case OMPD_declare_variant: 10356 case OMPD_declare_target: 10357 case OMPD_end_declare_target: 10358 case OMPD_simd: 10359 case OMPD_for: 10360 case OMPD_for_simd: 10361 case OMPD_sections: 10362 case OMPD_section: 10363 case OMPD_single: 10364 case OMPD_master: 10365 case OMPD_critical: 10366 case OMPD_taskgroup: 10367 case OMPD_distribute: 10368 case OMPD_ordered: 10369 case OMPD_atomic: 10370 case OMPD_distribute_simd: 10371 case OMPD_requires: 10372 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10373 case OMPD_unknown: 10374 llvm_unreachable("Unknown OpenMP directive"); 10375 } 10376 break; 10377 case OMPC_thread_limit: 10378 switch (DKind) { 10379 case OMPD_target_teams: 10380 case OMPD_target_teams_distribute: 10381 case OMPD_target_teams_distribute_simd: 10382 case OMPD_target_teams_distribute_parallel_for: 10383 case OMPD_target_teams_distribute_parallel_for_simd: 10384 CaptureRegion = OMPD_target; 10385 break; 10386 case OMPD_teams_distribute_parallel_for: 10387 case OMPD_teams_distribute_parallel_for_simd: 10388 case OMPD_teams: 10389 case OMPD_teams_distribute: 10390 case OMPD_teams_distribute_simd: 10391 // Do not capture thread_limit-clause expressions. 10392 break; 10393 case OMPD_distribute_parallel_for: 10394 case OMPD_distribute_parallel_for_simd: 10395 case OMPD_task: 10396 case OMPD_taskloop: 10397 case OMPD_taskloop_simd: 10398 case OMPD_master_taskloop: 10399 case OMPD_target_data: 10400 case OMPD_target_enter_data: 10401 case OMPD_target_exit_data: 10402 case OMPD_target_update: 10403 case OMPD_cancel: 10404 case OMPD_parallel: 10405 case OMPD_parallel_sections: 10406 case OMPD_parallel_for: 10407 case OMPD_parallel_for_simd: 10408 case OMPD_target: 10409 case OMPD_target_simd: 10410 case OMPD_target_parallel: 10411 case OMPD_target_parallel_for: 10412 case OMPD_target_parallel_for_simd: 10413 case OMPD_threadprivate: 10414 case OMPD_allocate: 10415 case OMPD_taskyield: 10416 case OMPD_barrier: 10417 case OMPD_taskwait: 10418 case OMPD_cancellation_point: 10419 case OMPD_flush: 10420 case OMPD_declare_reduction: 10421 case OMPD_declare_mapper: 10422 case OMPD_declare_simd: 10423 case OMPD_declare_variant: 10424 case OMPD_declare_target: 10425 case OMPD_end_declare_target: 10426 case OMPD_simd: 10427 case OMPD_for: 10428 case OMPD_for_simd: 10429 case OMPD_sections: 10430 case OMPD_section: 10431 case OMPD_single: 10432 case OMPD_master: 10433 case OMPD_critical: 10434 case OMPD_taskgroup: 10435 case OMPD_distribute: 10436 case OMPD_ordered: 10437 case OMPD_atomic: 10438 case OMPD_distribute_simd: 10439 case OMPD_requires: 10440 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10441 case OMPD_unknown: 10442 llvm_unreachable("Unknown OpenMP directive"); 10443 } 10444 break; 10445 case OMPC_schedule: 10446 switch (DKind) { 10447 case OMPD_parallel_for: 10448 case OMPD_parallel_for_simd: 10449 case OMPD_distribute_parallel_for: 10450 case OMPD_distribute_parallel_for_simd: 10451 case OMPD_teams_distribute_parallel_for: 10452 case OMPD_teams_distribute_parallel_for_simd: 10453 case OMPD_target_parallel_for: 10454 case OMPD_target_parallel_for_simd: 10455 case OMPD_target_teams_distribute_parallel_for: 10456 case OMPD_target_teams_distribute_parallel_for_simd: 10457 CaptureRegion = OMPD_parallel; 10458 break; 10459 case OMPD_for: 10460 case OMPD_for_simd: 10461 // Do not capture schedule-clause expressions. 10462 break; 10463 case OMPD_task: 10464 case OMPD_taskloop: 10465 case OMPD_taskloop_simd: 10466 case OMPD_master_taskloop: 10467 case OMPD_target_data: 10468 case OMPD_target_enter_data: 10469 case OMPD_target_exit_data: 10470 case OMPD_target_update: 10471 case OMPD_teams: 10472 case OMPD_teams_distribute: 10473 case OMPD_teams_distribute_simd: 10474 case OMPD_target_teams_distribute: 10475 case OMPD_target_teams_distribute_simd: 10476 case OMPD_target: 10477 case OMPD_target_simd: 10478 case OMPD_target_parallel: 10479 case OMPD_cancel: 10480 case OMPD_parallel: 10481 case OMPD_parallel_sections: 10482 case OMPD_threadprivate: 10483 case OMPD_allocate: 10484 case OMPD_taskyield: 10485 case OMPD_barrier: 10486 case OMPD_taskwait: 10487 case OMPD_cancellation_point: 10488 case OMPD_flush: 10489 case OMPD_declare_reduction: 10490 case OMPD_declare_mapper: 10491 case OMPD_declare_simd: 10492 case OMPD_declare_variant: 10493 case OMPD_declare_target: 10494 case OMPD_end_declare_target: 10495 case OMPD_simd: 10496 case OMPD_sections: 10497 case OMPD_section: 10498 case OMPD_single: 10499 case OMPD_master: 10500 case OMPD_critical: 10501 case OMPD_taskgroup: 10502 case OMPD_distribute: 10503 case OMPD_ordered: 10504 case OMPD_atomic: 10505 case OMPD_distribute_simd: 10506 case OMPD_target_teams: 10507 case OMPD_requires: 10508 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10509 case OMPD_unknown: 10510 llvm_unreachable("Unknown OpenMP directive"); 10511 } 10512 break; 10513 case OMPC_dist_schedule: 10514 switch (DKind) { 10515 case OMPD_teams_distribute_parallel_for: 10516 case OMPD_teams_distribute_parallel_for_simd: 10517 case OMPD_teams_distribute: 10518 case OMPD_teams_distribute_simd: 10519 case OMPD_target_teams_distribute_parallel_for: 10520 case OMPD_target_teams_distribute_parallel_for_simd: 10521 case OMPD_target_teams_distribute: 10522 case OMPD_target_teams_distribute_simd: 10523 CaptureRegion = OMPD_teams; 10524 break; 10525 case OMPD_distribute_parallel_for: 10526 case OMPD_distribute_parallel_for_simd: 10527 case OMPD_distribute: 10528 case OMPD_distribute_simd: 10529 // Do not capture thread_limit-clause expressions. 10530 break; 10531 case OMPD_parallel_for: 10532 case OMPD_parallel_for_simd: 10533 case OMPD_target_parallel_for_simd: 10534 case OMPD_target_parallel_for: 10535 case OMPD_task: 10536 case OMPD_taskloop: 10537 case OMPD_taskloop_simd: 10538 case OMPD_master_taskloop: 10539 case OMPD_target_data: 10540 case OMPD_target_enter_data: 10541 case OMPD_target_exit_data: 10542 case OMPD_target_update: 10543 case OMPD_teams: 10544 case OMPD_target: 10545 case OMPD_target_simd: 10546 case OMPD_target_parallel: 10547 case OMPD_cancel: 10548 case OMPD_parallel: 10549 case OMPD_parallel_sections: 10550 case OMPD_threadprivate: 10551 case OMPD_allocate: 10552 case OMPD_taskyield: 10553 case OMPD_barrier: 10554 case OMPD_taskwait: 10555 case OMPD_cancellation_point: 10556 case OMPD_flush: 10557 case OMPD_declare_reduction: 10558 case OMPD_declare_mapper: 10559 case OMPD_declare_simd: 10560 case OMPD_declare_variant: 10561 case OMPD_declare_target: 10562 case OMPD_end_declare_target: 10563 case OMPD_simd: 10564 case OMPD_for: 10565 case OMPD_for_simd: 10566 case OMPD_sections: 10567 case OMPD_section: 10568 case OMPD_single: 10569 case OMPD_master: 10570 case OMPD_critical: 10571 case OMPD_taskgroup: 10572 case OMPD_ordered: 10573 case OMPD_atomic: 10574 case OMPD_target_teams: 10575 case OMPD_requires: 10576 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10577 case OMPD_unknown: 10578 llvm_unreachable("Unknown OpenMP directive"); 10579 } 10580 break; 10581 case OMPC_device: 10582 switch (DKind) { 10583 case OMPD_target_update: 10584 case OMPD_target_enter_data: 10585 case OMPD_target_exit_data: 10586 case OMPD_target: 10587 case OMPD_target_simd: 10588 case OMPD_target_teams: 10589 case OMPD_target_parallel: 10590 case OMPD_target_teams_distribute: 10591 case OMPD_target_teams_distribute_simd: 10592 case OMPD_target_parallel_for: 10593 case OMPD_target_parallel_for_simd: 10594 case OMPD_target_teams_distribute_parallel_for: 10595 case OMPD_target_teams_distribute_parallel_for_simd: 10596 CaptureRegion = OMPD_task; 10597 break; 10598 case OMPD_target_data: 10599 // Do not capture device-clause expressions. 10600 break; 10601 case OMPD_teams_distribute_parallel_for: 10602 case OMPD_teams_distribute_parallel_for_simd: 10603 case OMPD_teams: 10604 case OMPD_teams_distribute: 10605 case OMPD_teams_distribute_simd: 10606 case OMPD_distribute_parallel_for: 10607 case OMPD_distribute_parallel_for_simd: 10608 case OMPD_task: 10609 case OMPD_taskloop: 10610 case OMPD_taskloop_simd: 10611 case OMPD_master_taskloop: 10612 case OMPD_cancel: 10613 case OMPD_parallel: 10614 case OMPD_parallel_sections: 10615 case OMPD_parallel_for: 10616 case OMPD_parallel_for_simd: 10617 case OMPD_threadprivate: 10618 case OMPD_allocate: 10619 case OMPD_taskyield: 10620 case OMPD_barrier: 10621 case OMPD_taskwait: 10622 case OMPD_cancellation_point: 10623 case OMPD_flush: 10624 case OMPD_declare_reduction: 10625 case OMPD_declare_mapper: 10626 case OMPD_declare_simd: 10627 case OMPD_declare_variant: 10628 case OMPD_declare_target: 10629 case OMPD_end_declare_target: 10630 case OMPD_simd: 10631 case OMPD_for: 10632 case OMPD_for_simd: 10633 case OMPD_sections: 10634 case OMPD_section: 10635 case OMPD_single: 10636 case OMPD_master: 10637 case OMPD_critical: 10638 case OMPD_taskgroup: 10639 case OMPD_distribute: 10640 case OMPD_ordered: 10641 case OMPD_atomic: 10642 case OMPD_distribute_simd: 10643 case OMPD_requires: 10644 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10645 case OMPD_unknown: 10646 llvm_unreachable("Unknown OpenMP directive"); 10647 } 10648 break; 10649 case OMPC_firstprivate: 10650 case OMPC_lastprivate: 10651 case OMPC_reduction: 10652 case OMPC_task_reduction: 10653 case OMPC_in_reduction: 10654 case OMPC_linear: 10655 case OMPC_default: 10656 case OMPC_proc_bind: 10657 case OMPC_final: 10658 case OMPC_safelen: 10659 case OMPC_simdlen: 10660 case OMPC_allocator: 10661 case OMPC_collapse: 10662 case OMPC_private: 10663 case OMPC_shared: 10664 case OMPC_aligned: 10665 case OMPC_copyin: 10666 case OMPC_copyprivate: 10667 case OMPC_ordered: 10668 case OMPC_nowait: 10669 case OMPC_untied: 10670 case OMPC_mergeable: 10671 case OMPC_threadprivate: 10672 case OMPC_allocate: 10673 case OMPC_flush: 10674 case OMPC_read: 10675 case OMPC_write: 10676 case OMPC_update: 10677 case OMPC_capture: 10678 case OMPC_seq_cst: 10679 case OMPC_depend: 10680 case OMPC_threads: 10681 case OMPC_simd: 10682 case OMPC_map: 10683 case OMPC_priority: 10684 case OMPC_grainsize: 10685 case OMPC_nogroup: 10686 case OMPC_num_tasks: 10687 case OMPC_hint: 10688 case OMPC_defaultmap: 10689 case OMPC_unknown: 10690 case OMPC_uniform: 10691 case OMPC_to: 10692 case OMPC_from: 10693 case OMPC_use_device_ptr: 10694 case OMPC_is_device_ptr: 10695 case OMPC_unified_address: 10696 case OMPC_unified_shared_memory: 10697 case OMPC_reverse_offload: 10698 case OMPC_dynamic_allocators: 10699 case OMPC_atomic_default_mem_order: 10700 case OMPC_device_type: 10701 case OMPC_match: 10702 llvm_unreachable("Unexpected OpenMP clause."); 10703 } 10704 return CaptureRegion; 10705 } 10706 10707 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10708 Expr *Condition, SourceLocation StartLoc, 10709 SourceLocation LParenLoc, 10710 SourceLocation NameModifierLoc, 10711 SourceLocation ColonLoc, 10712 SourceLocation EndLoc) { 10713 Expr *ValExpr = Condition; 10714 Stmt *HelperValStmt = nullptr; 10715 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10716 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10717 !Condition->isInstantiationDependent() && 10718 !Condition->containsUnexpandedParameterPack()) { 10719 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10720 if (Val.isInvalid()) 10721 return nullptr; 10722 10723 ValExpr = Val.get(); 10724 10725 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10726 CaptureRegion = 10727 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10728 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10729 ValExpr = MakeFullExpr(ValExpr).get(); 10730 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10731 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10732 HelperValStmt = buildPreInits(Context, Captures); 10733 } 10734 } 10735 10736 return new (Context) 10737 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 10738 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 10739 } 10740 10741 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 10742 SourceLocation StartLoc, 10743 SourceLocation LParenLoc, 10744 SourceLocation EndLoc) { 10745 Expr *ValExpr = Condition; 10746 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10747 !Condition->isInstantiationDependent() && 10748 !Condition->containsUnexpandedParameterPack()) { 10749 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10750 if (Val.isInvalid()) 10751 return nullptr; 10752 10753 ValExpr = MakeFullExpr(Val.get()).get(); 10754 } 10755 10756 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10757 } 10758 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 10759 Expr *Op) { 10760 if (!Op) 10761 return ExprError(); 10762 10763 class IntConvertDiagnoser : public ICEConvertDiagnoser { 10764 public: 10765 IntConvertDiagnoser() 10766 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 10767 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 10768 QualType T) override { 10769 return S.Diag(Loc, diag::err_omp_not_integral) << T; 10770 } 10771 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 10772 QualType T) override { 10773 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 10774 } 10775 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 10776 QualType T, 10777 QualType ConvTy) override { 10778 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 10779 } 10780 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 10781 QualType ConvTy) override { 10782 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10783 << ConvTy->isEnumeralType() << ConvTy; 10784 } 10785 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 10786 QualType T) override { 10787 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 10788 } 10789 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 10790 QualType ConvTy) override { 10791 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 10792 << ConvTy->isEnumeralType() << ConvTy; 10793 } 10794 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 10795 QualType) override { 10796 llvm_unreachable("conversion functions are permitted"); 10797 } 10798 } ConvertDiagnoser; 10799 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 10800 } 10801 10802 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 10803 OpenMPClauseKind CKind, 10804 bool StrictlyPositive) { 10805 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 10806 !ValExpr->isInstantiationDependent()) { 10807 SourceLocation Loc = ValExpr->getExprLoc(); 10808 ExprResult Value = 10809 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 10810 if (Value.isInvalid()) 10811 return false; 10812 10813 ValExpr = Value.get(); 10814 // The expression must evaluate to a non-negative integer value. 10815 llvm::APSInt Result; 10816 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 10817 Result.isSigned() && 10818 !((!StrictlyPositive && Result.isNonNegative()) || 10819 (StrictlyPositive && Result.isStrictlyPositive()))) { 10820 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 10821 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10822 << ValExpr->getSourceRange(); 10823 return false; 10824 } 10825 } 10826 return true; 10827 } 10828 10829 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 10830 SourceLocation StartLoc, 10831 SourceLocation LParenLoc, 10832 SourceLocation EndLoc) { 10833 Expr *ValExpr = NumThreads; 10834 Stmt *HelperValStmt = nullptr; 10835 10836 // OpenMP [2.5, Restrictions] 10837 // The num_threads expression must evaluate to a positive integer value. 10838 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 10839 /*StrictlyPositive=*/true)) 10840 return nullptr; 10841 10842 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10843 OpenMPDirectiveKind CaptureRegion = 10844 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 10845 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10846 ValExpr = MakeFullExpr(ValExpr).get(); 10847 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10848 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10849 HelperValStmt = buildPreInits(Context, Captures); 10850 } 10851 10852 return new (Context) OMPNumThreadsClause( 10853 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 10854 } 10855 10856 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 10857 OpenMPClauseKind CKind, 10858 bool StrictlyPositive) { 10859 if (!E) 10860 return ExprError(); 10861 if (E->isValueDependent() || E->isTypeDependent() || 10862 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 10863 return E; 10864 llvm::APSInt Result; 10865 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 10866 if (ICE.isInvalid()) 10867 return ExprError(); 10868 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 10869 (!StrictlyPositive && !Result.isNonNegative())) { 10870 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 10871 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 10872 << E->getSourceRange(); 10873 return ExprError(); 10874 } 10875 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 10876 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 10877 << E->getSourceRange(); 10878 return ExprError(); 10879 } 10880 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 10881 DSAStack->setAssociatedLoops(Result.getExtValue()); 10882 else if (CKind == OMPC_ordered) 10883 DSAStack->setAssociatedLoops(Result.getExtValue()); 10884 return ICE; 10885 } 10886 10887 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 10888 SourceLocation LParenLoc, 10889 SourceLocation EndLoc) { 10890 // OpenMP [2.8.1, simd construct, Description] 10891 // The parameter of the safelen clause must be a constant 10892 // positive integer expression. 10893 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 10894 if (Safelen.isInvalid()) 10895 return nullptr; 10896 return new (Context) 10897 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 10898 } 10899 10900 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 10901 SourceLocation LParenLoc, 10902 SourceLocation EndLoc) { 10903 // OpenMP [2.8.1, simd construct, Description] 10904 // The parameter of the simdlen clause must be a constant 10905 // positive integer expression. 10906 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 10907 if (Simdlen.isInvalid()) 10908 return nullptr; 10909 return new (Context) 10910 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 10911 } 10912 10913 /// Tries to find omp_allocator_handle_t type. 10914 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 10915 DSAStackTy *Stack) { 10916 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 10917 if (!OMPAllocatorHandleT.isNull()) 10918 return true; 10919 // Build the predefined allocator expressions. 10920 bool ErrorFound = false; 10921 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 10922 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 10923 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 10924 StringRef Allocator = 10925 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 10926 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 10927 auto *VD = dyn_cast_or_null<ValueDecl>( 10928 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 10929 if (!VD) { 10930 ErrorFound = true; 10931 break; 10932 } 10933 QualType AllocatorType = 10934 VD->getType().getNonLValueExprType(S.getASTContext()); 10935 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 10936 if (!Res.isUsable()) { 10937 ErrorFound = true; 10938 break; 10939 } 10940 if (OMPAllocatorHandleT.isNull()) 10941 OMPAllocatorHandleT = AllocatorType; 10942 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 10943 ErrorFound = true; 10944 break; 10945 } 10946 Stack->setAllocator(AllocatorKind, Res.get()); 10947 } 10948 if (ErrorFound) { 10949 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 10950 return false; 10951 } 10952 OMPAllocatorHandleT.addConst(); 10953 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 10954 return true; 10955 } 10956 10957 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 10958 SourceLocation LParenLoc, 10959 SourceLocation EndLoc) { 10960 // OpenMP [2.11.3, allocate Directive, Description] 10961 // allocator is an expression of omp_allocator_handle_t type. 10962 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 10963 return nullptr; 10964 10965 ExprResult Allocator = DefaultLvalueConversion(A); 10966 if (Allocator.isInvalid()) 10967 return nullptr; 10968 Allocator = PerformImplicitConversion(Allocator.get(), 10969 DSAStack->getOMPAllocatorHandleT(), 10970 Sema::AA_Initializing, 10971 /*AllowExplicit=*/true); 10972 if (Allocator.isInvalid()) 10973 return nullptr; 10974 return new (Context) 10975 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 10976 } 10977 10978 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 10979 SourceLocation StartLoc, 10980 SourceLocation LParenLoc, 10981 SourceLocation EndLoc) { 10982 // OpenMP [2.7.1, loop construct, Description] 10983 // OpenMP [2.8.1, simd construct, Description] 10984 // OpenMP [2.9.6, distribute construct, Description] 10985 // The parameter of the collapse clause must be a constant 10986 // positive integer expression. 10987 ExprResult NumForLoopsResult = 10988 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 10989 if (NumForLoopsResult.isInvalid()) 10990 return nullptr; 10991 return new (Context) 10992 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 10993 } 10994 10995 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 10996 SourceLocation EndLoc, 10997 SourceLocation LParenLoc, 10998 Expr *NumForLoops) { 10999 // OpenMP [2.7.1, loop construct, Description] 11000 // OpenMP [2.8.1, simd construct, Description] 11001 // OpenMP [2.9.6, distribute construct, Description] 11002 // The parameter of the ordered clause must be a constant 11003 // positive integer expression if any. 11004 if (NumForLoops && LParenLoc.isValid()) { 11005 ExprResult NumForLoopsResult = 11006 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11007 if (NumForLoopsResult.isInvalid()) 11008 return nullptr; 11009 NumForLoops = NumForLoopsResult.get(); 11010 } else { 11011 NumForLoops = nullptr; 11012 } 11013 auto *Clause = OMPOrderedClause::Create( 11014 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11015 StartLoc, LParenLoc, EndLoc); 11016 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11017 return Clause; 11018 } 11019 11020 OMPClause *Sema::ActOnOpenMPSimpleClause( 11021 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11022 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11023 OMPClause *Res = nullptr; 11024 switch (Kind) { 11025 case OMPC_default: 11026 Res = 11027 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11028 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11029 break; 11030 case OMPC_proc_bind: 11031 Res = ActOnOpenMPProcBindClause( 11032 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11033 LParenLoc, EndLoc); 11034 break; 11035 case OMPC_atomic_default_mem_order: 11036 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11037 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11038 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11039 break; 11040 case OMPC_if: 11041 case OMPC_final: 11042 case OMPC_num_threads: 11043 case OMPC_safelen: 11044 case OMPC_simdlen: 11045 case OMPC_allocator: 11046 case OMPC_collapse: 11047 case OMPC_schedule: 11048 case OMPC_private: 11049 case OMPC_firstprivate: 11050 case OMPC_lastprivate: 11051 case OMPC_shared: 11052 case OMPC_reduction: 11053 case OMPC_task_reduction: 11054 case OMPC_in_reduction: 11055 case OMPC_linear: 11056 case OMPC_aligned: 11057 case OMPC_copyin: 11058 case OMPC_copyprivate: 11059 case OMPC_ordered: 11060 case OMPC_nowait: 11061 case OMPC_untied: 11062 case OMPC_mergeable: 11063 case OMPC_threadprivate: 11064 case OMPC_allocate: 11065 case OMPC_flush: 11066 case OMPC_read: 11067 case OMPC_write: 11068 case OMPC_update: 11069 case OMPC_capture: 11070 case OMPC_seq_cst: 11071 case OMPC_depend: 11072 case OMPC_device: 11073 case OMPC_threads: 11074 case OMPC_simd: 11075 case OMPC_map: 11076 case OMPC_num_teams: 11077 case OMPC_thread_limit: 11078 case OMPC_priority: 11079 case OMPC_grainsize: 11080 case OMPC_nogroup: 11081 case OMPC_num_tasks: 11082 case OMPC_hint: 11083 case OMPC_dist_schedule: 11084 case OMPC_defaultmap: 11085 case OMPC_unknown: 11086 case OMPC_uniform: 11087 case OMPC_to: 11088 case OMPC_from: 11089 case OMPC_use_device_ptr: 11090 case OMPC_is_device_ptr: 11091 case OMPC_unified_address: 11092 case OMPC_unified_shared_memory: 11093 case OMPC_reverse_offload: 11094 case OMPC_dynamic_allocators: 11095 case OMPC_device_type: 11096 case OMPC_match: 11097 llvm_unreachable("Clause is not allowed."); 11098 } 11099 return Res; 11100 } 11101 11102 static std::string 11103 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11104 ArrayRef<unsigned> Exclude = llvm::None) { 11105 SmallString<256> Buffer; 11106 llvm::raw_svector_ostream Out(Buffer); 11107 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11108 unsigned Skipped = Exclude.size(); 11109 auto S = Exclude.begin(), E = Exclude.end(); 11110 for (unsigned I = First; I < Last; ++I) { 11111 if (std::find(S, E, I) != E) { 11112 --Skipped; 11113 continue; 11114 } 11115 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11116 if (I == Bound - Skipped) 11117 Out << " or "; 11118 else if (I != Bound + 1 - Skipped) 11119 Out << ", "; 11120 } 11121 return Out.str(); 11122 } 11123 11124 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11125 SourceLocation KindKwLoc, 11126 SourceLocation StartLoc, 11127 SourceLocation LParenLoc, 11128 SourceLocation EndLoc) { 11129 if (Kind == OMPC_DEFAULT_unknown) { 11130 static_assert(OMPC_DEFAULT_unknown > 0, 11131 "OMPC_DEFAULT_unknown not greater than 0"); 11132 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11133 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11134 /*Last=*/OMPC_DEFAULT_unknown) 11135 << getOpenMPClauseName(OMPC_default); 11136 return nullptr; 11137 } 11138 switch (Kind) { 11139 case OMPC_DEFAULT_none: 11140 DSAStack->setDefaultDSANone(KindKwLoc); 11141 break; 11142 case OMPC_DEFAULT_shared: 11143 DSAStack->setDefaultDSAShared(KindKwLoc); 11144 break; 11145 case OMPC_DEFAULT_unknown: 11146 llvm_unreachable("Clause kind is not allowed."); 11147 break; 11148 } 11149 return new (Context) 11150 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11151 } 11152 11153 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11154 SourceLocation KindKwLoc, 11155 SourceLocation StartLoc, 11156 SourceLocation LParenLoc, 11157 SourceLocation EndLoc) { 11158 if (Kind == OMPC_PROC_BIND_unknown) { 11159 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11160 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11161 /*Last=*/OMPC_PROC_BIND_unknown) 11162 << getOpenMPClauseName(OMPC_proc_bind); 11163 return nullptr; 11164 } 11165 return new (Context) 11166 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11167 } 11168 11169 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11170 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11171 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11172 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11173 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11174 << getListOfPossibleValues( 11175 OMPC_atomic_default_mem_order, /*First=*/0, 11176 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11177 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11178 return nullptr; 11179 } 11180 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11181 LParenLoc, EndLoc); 11182 } 11183 11184 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11185 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11186 SourceLocation StartLoc, SourceLocation LParenLoc, 11187 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11188 SourceLocation EndLoc) { 11189 OMPClause *Res = nullptr; 11190 switch (Kind) { 11191 case OMPC_schedule: 11192 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11193 assert(Argument.size() == NumberOfElements && 11194 ArgumentLoc.size() == NumberOfElements); 11195 Res = ActOnOpenMPScheduleClause( 11196 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11197 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11198 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11199 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11200 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11201 break; 11202 case OMPC_if: 11203 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11204 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11205 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11206 DelimLoc, EndLoc); 11207 break; 11208 case OMPC_dist_schedule: 11209 Res = ActOnOpenMPDistScheduleClause( 11210 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11211 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11212 break; 11213 case OMPC_defaultmap: 11214 enum { Modifier, DefaultmapKind }; 11215 Res = ActOnOpenMPDefaultmapClause( 11216 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11217 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11218 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11219 EndLoc); 11220 break; 11221 case OMPC_final: 11222 case OMPC_num_threads: 11223 case OMPC_safelen: 11224 case OMPC_simdlen: 11225 case OMPC_allocator: 11226 case OMPC_collapse: 11227 case OMPC_default: 11228 case OMPC_proc_bind: 11229 case OMPC_private: 11230 case OMPC_firstprivate: 11231 case OMPC_lastprivate: 11232 case OMPC_shared: 11233 case OMPC_reduction: 11234 case OMPC_task_reduction: 11235 case OMPC_in_reduction: 11236 case OMPC_linear: 11237 case OMPC_aligned: 11238 case OMPC_copyin: 11239 case OMPC_copyprivate: 11240 case OMPC_ordered: 11241 case OMPC_nowait: 11242 case OMPC_untied: 11243 case OMPC_mergeable: 11244 case OMPC_threadprivate: 11245 case OMPC_allocate: 11246 case OMPC_flush: 11247 case OMPC_read: 11248 case OMPC_write: 11249 case OMPC_update: 11250 case OMPC_capture: 11251 case OMPC_seq_cst: 11252 case OMPC_depend: 11253 case OMPC_device: 11254 case OMPC_threads: 11255 case OMPC_simd: 11256 case OMPC_map: 11257 case OMPC_num_teams: 11258 case OMPC_thread_limit: 11259 case OMPC_priority: 11260 case OMPC_grainsize: 11261 case OMPC_nogroup: 11262 case OMPC_num_tasks: 11263 case OMPC_hint: 11264 case OMPC_unknown: 11265 case OMPC_uniform: 11266 case OMPC_to: 11267 case OMPC_from: 11268 case OMPC_use_device_ptr: 11269 case OMPC_is_device_ptr: 11270 case OMPC_unified_address: 11271 case OMPC_unified_shared_memory: 11272 case OMPC_reverse_offload: 11273 case OMPC_dynamic_allocators: 11274 case OMPC_atomic_default_mem_order: 11275 case OMPC_device_type: 11276 case OMPC_match: 11277 llvm_unreachable("Clause is not allowed."); 11278 } 11279 return Res; 11280 } 11281 11282 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11283 OpenMPScheduleClauseModifier M2, 11284 SourceLocation M1Loc, SourceLocation M2Loc) { 11285 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11286 SmallVector<unsigned, 2> Excluded; 11287 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11288 Excluded.push_back(M2); 11289 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11290 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11291 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11292 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11293 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11294 << getListOfPossibleValues(OMPC_schedule, 11295 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11296 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11297 Excluded) 11298 << getOpenMPClauseName(OMPC_schedule); 11299 return true; 11300 } 11301 return false; 11302 } 11303 11304 OMPClause *Sema::ActOnOpenMPScheduleClause( 11305 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11306 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11307 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11308 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11309 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11310 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11311 return nullptr; 11312 // OpenMP, 2.7.1, Loop Construct, Restrictions 11313 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11314 // but not both. 11315 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11316 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11317 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11318 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11319 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11320 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11321 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11322 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11323 return nullptr; 11324 } 11325 if (Kind == OMPC_SCHEDULE_unknown) { 11326 std::string Values; 11327 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11328 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11329 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11330 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11331 Exclude); 11332 } else { 11333 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11334 /*Last=*/OMPC_SCHEDULE_unknown); 11335 } 11336 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11337 << Values << getOpenMPClauseName(OMPC_schedule); 11338 return nullptr; 11339 } 11340 // OpenMP, 2.7.1, Loop Construct, Restrictions 11341 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11342 // schedule(guided). 11343 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11344 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11345 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11346 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11347 diag::err_omp_schedule_nonmonotonic_static); 11348 return nullptr; 11349 } 11350 Expr *ValExpr = ChunkSize; 11351 Stmt *HelperValStmt = nullptr; 11352 if (ChunkSize) { 11353 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11354 !ChunkSize->isInstantiationDependent() && 11355 !ChunkSize->containsUnexpandedParameterPack()) { 11356 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11357 ExprResult Val = 11358 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11359 if (Val.isInvalid()) 11360 return nullptr; 11361 11362 ValExpr = Val.get(); 11363 11364 // OpenMP [2.7.1, Restrictions] 11365 // chunk_size must be a loop invariant integer expression with a positive 11366 // value. 11367 llvm::APSInt Result; 11368 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11369 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11370 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11371 << "schedule" << 1 << ChunkSize->getSourceRange(); 11372 return nullptr; 11373 } 11374 } else if (getOpenMPCaptureRegionForClause( 11375 DSAStack->getCurrentDirective(), OMPC_schedule) != 11376 OMPD_unknown && 11377 !CurContext->isDependentContext()) { 11378 ValExpr = MakeFullExpr(ValExpr).get(); 11379 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11380 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11381 HelperValStmt = buildPreInits(Context, Captures); 11382 } 11383 } 11384 } 11385 11386 return new (Context) 11387 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11388 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11389 } 11390 11391 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11392 SourceLocation StartLoc, 11393 SourceLocation EndLoc) { 11394 OMPClause *Res = nullptr; 11395 switch (Kind) { 11396 case OMPC_ordered: 11397 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11398 break; 11399 case OMPC_nowait: 11400 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11401 break; 11402 case OMPC_untied: 11403 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11404 break; 11405 case OMPC_mergeable: 11406 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11407 break; 11408 case OMPC_read: 11409 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11410 break; 11411 case OMPC_write: 11412 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11413 break; 11414 case OMPC_update: 11415 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11416 break; 11417 case OMPC_capture: 11418 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11419 break; 11420 case OMPC_seq_cst: 11421 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11422 break; 11423 case OMPC_threads: 11424 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11425 break; 11426 case OMPC_simd: 11427 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11428 break; 11429 case OMPC_nogroup: 11430 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11431 break; 11432 case OMPC_unified_address: 11433 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11434 break; 11435 case OMPC_unified_shared_memory: 11436 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11437 break; 11438 case OMPC_reverse_offload: 11439 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11440 break; 11441 case OMPC_dynamic_allocators: 11442 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11443 break; 11444 case OMPC_if: 11445 case OMPC_final: 11446 case OMPC_num_threads: 11447 case OMPC_safelen: 11448 case OMPC_simdlen: 11449 case OMPC_allocator: 11450 case OMPC_collapse: 11451 case OMPC_schedule: 11452 case OMPC_private: 11453 case OMPC_firstprivate: 11454 case OMPC_lastprivate: 11455 case OMPC_shared: 11456 case OMPC_reduction: 11457 case OMPC_task_reduction: 11458 case OMPC_in_reduction: 11459 case OMPC_linear: 11460 case OMPC_aligned: 11461 case OMPC_copyin: 11462 case OMPC_copyprivate: 11463 case OMPC_default: 11464 case OMPC_proc_bind: 11465 case OMPC_threadprivate: 11466 case OMPC_allocate: 11467 case OMPC_flush: 11468 case OMPC_depend: 11469 case OMPC_device: 11470 case OMPC_map: 11471 case OMPC_num_teams: 11472 case OMPC_thread_limit: 11473 case OMPC_priority: 11474 case OMPC_grainsize: 11475 case OMPC_num_tasks: 11476 case OMPC_hint: 11477 case OMPC_dist_schedule: 11478 case OMPC_defaultmap: 11479 case OMPC_unknown: 11480 case OMPC_uniform: 11481 case OMPC_to: 11482 case OMPC_from: 11483 case OMPC_use_device_ptr: 11484 case OMPC_is_device_ptr: 11485 case OMPC_atomic_default_mem_order: 11486 case OMPC_device_type: 11487 case OMPC_match: 11488 llvm_unreachable("Clause is not allowed."); 11489 } 11490 return Res; 11491 } 11492 11493 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11494 SourceLocation EndLoc) { 11495 DSAStack->setNowaitRegion(); 11496 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11497 } 11498 11499 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11500 SourceLocation EndLoc) { 11501 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11502 } 11503 11504 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11505 SourceLocation EndLoc) { 11506 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11507 } 11508 11509 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11510 SourceLocation EndLoc) { 11511 return new (Context) OMPReadClause(StartLoc, EndLoc); 11512 } 11513 11514 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11515 SourceLocation EndLoc) { 11516 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11517 } 11518 11519 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11520 SourceLocation EndLoc) { 11521 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11522 } 11523 11524 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11525 SourceLocation EndLoc) { 11526 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11527 } 11528 11529 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11530 SourceLocation EndLoc) { 11531 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11532 } 11533 11534 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11535 SourceLocation EndLoc) { 11536 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11537 } 11538 11539 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11540 SourceLocation EndLoc) { 11541 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11542 } 11543 11544 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11545 SourceLocation EndLoc) { 11546 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11547 } 11548 11549 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11550 SourceLocation EndLoc) { 11551 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11552 } 11553 11554 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11555 SourceLocation EndLoc) { 11556 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11557 } 11558 11559 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11560 SourceLocation EndLoc) { 11561 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11562 } 11563 11564 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11565 SourceLocation EndLoc) { 11566 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11567 } 11568 11569 OMPClause *Sema::ActOnOpenMPVarListClause( 11570 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11571 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11572 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11573 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11574 OpenMPLinearClauseKind LinKind, 11575 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11576 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11577 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11578 SourceLocation StartLoc = Locs.StartLoc; 11579 SourceLocation LParenLoc = Locs.LParenLoc; 11580 SourceLocation EndLoc = Locs.EndLoc; 11581 OMPClause *Res = nullptr; 11582 switch (Kind) { 11583 case OMPC_private: 11584 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11585 break; 11586 case OMPC_firstprivate: 11587 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11588 break; 11589 case OMPC_lastprivate: 11590 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11591 break; 11592 case OMPC_shared: 11593 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11594 break; 11595 case OMPC_reduction: 11596 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11597 EndLoc, ReductionOrMapperIdScopeSpec, 11598 ReductionOrMapperId); 11599 break; 11600 case OMPC_task_reduction: 11601 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11602 EndLoc, ReductionOrMapperIdScopeSpec, 11603 ReductionOrMapperId); 11604 break; 11605 case OMPC_in_reduction: 11606 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11607 EndLoc, ReductionOrMapperIdScopeSpec, 11608 ReductionOrMapperId); 11609 break; 11610 case OMPC_linear: 11611 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11612 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11613 break; 11614 case OMPC_aligned: 11615 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11616 ColonLoc, EndLoc); 11617 break; 11618 case OMPC_copyin: 11619 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11620 break; 11621 case OMPC_copyprivate: 11622 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11623 break; 11624 case OMPC_flush: 11625 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11626 break; 11627 case OMPC_depend: 11628 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11629 StartLoc, LParenLoc, EndLoc); 11630 break; 11631 case OMPC_map: 11632 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11633 ReductionOrMapperIdScopeSpec, 11634 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11635 DepLinMapLoc, ColonLoc, VarList, Locs); 11636 break; 11637 case OMPC_to: 11638 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11639 ReductionOrMapperId, Locs); 11640 break; 11641 case OMPC_from: 11642 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11643 ReductionOrMapperId, Locs); 11644 break; 11645 case OMPC_use_device_ptr: 11646 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11647 break; 11648 case OMPC_is_device_ptr: 11649 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11650 break; 11651 case OMPC_allocate: 11652 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11653 ColonLoc, EndLoc); 11654 break; 11655 case OMPC_if: 11656 case OMPC_final: 11657 case OMPC_num_threads: 11658 case OMPC_safelen: 11659 case OMPC_simdlen: 11660 case OMPC_allocator: 11661 case OMPC_collapse: 11662 case OMPC_default: 11663 case OMPC_proc_bind: 11664 case OMPC_schedule: 11665 case OMPC_ordered: 11666 case OMPC_nowait: 11667 case OMPC_untied: 11668 case OMPC_mergeable: 11669 case OMPC_threadprivate: 11670 case OMPC_read: 11671 case OMPC_write: 11672 case OMPC_update: 11673 case OMPC_capture: 11674 case OMPC_seq_cst: 11675 case OMPC_device: 11676 case OMPC_threads: 11677 case OMPC_simd: 11678 case OMPC_num_teams: 11679 case OMPC_thread_limit: 11680 case OMPC_priority: 11681 case OMPC_grainsize: 11682 case OMPC_nogroup: 11683 case OMPC_num_tasks: 11684 case OMPC_hint: 11685 case OMPC_dist_schedule: 11686 case OMPC_defaultmap: 11687 case OMPC_unknown: 11688 case OMPC_uniform: 11689 case OMPC_unified_address: 11690 case OMPC_unified_shared_memory: 11691 case OMPC_reverse_offload: 11692 case OMPC_dynamic_allocators: 11693 case OMPC_atomic_default_mem_order: 11694 case OMPC_device_type: 11695 case OMPC_match: 11696 llvm_unreachable("Clause is not allowed."); 11697 } 11698 return Res; 11699 } 11700 11701 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11702 ExprObjectKind OK, SourceLocation Loc) { 11703 ExprResult Res = BuildDeclRefExpr( 11704 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11705 if (!Res.isUsable()) 11706 return ExprError(); 11707 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11708 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 11709 if (!Res.isUsable()) 11710 return ExprError(); 11711 } 11712 if (VK != VK_LValue && Res.get()->isGLValue()) { 11713 Res = DefaultLvalueConversion(Res.get()); 11714 if (!Res.isUsable()) 11715 return ExprError(); 11716 } 11717 return Res; 11718 } 11719 11720 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 11721 SourceLocation StartLoc, 11722 SourceLocation LParenLoc, 11723 SourceLocation EndLoc) { 11724 SmallVector<Expr *, 8> Vars; 11725 SmallVector<Expr *, 8> PrivateCopies; 11726 for (Expr *RefExpr : VarList) { 11727 assert(RefExpr && "NULL expr in OpenMP private clause."); 11728 SourceLocation ELoc; 11729 SourceRange ERange; 11730 Expr *SimpleRefExpr = RefExpr; 11731 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11732 if (Res.second) { 11733 // It will be analyzed later. 11734 Vars.push_back(RefExpr); 11735 PrivateCopies.push_back(nullptr); 11736 } 11737 ValueDecl *D = Res.first; 11738 if (!D) 11739 continue; 11740 11741 QualType Type = D->getType(); 11742 auto *VD = dyn_cast<VarDecl>(D); 11743 11744 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11745 // A variable that appears in a private clause must not have an incomplete 11746 // type or a reference type. 11747 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 11748 continue; 11749 Type = Type.getNonReferenceType(); 11750 11751 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11752 // A variable that is privatized must not have a const-qualified type 11753 // unless it is of class type with a mutable member. This restriction does 11754 // not apply to the firstprivate clause. 11755 // 11756 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 11757 // A variable that appears in a private clause must not have a 11758 // const-qualified type unless it is of class type with a mutable member. 11759 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 11760 continue; 11761 11762 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11763 // in a Construct] 11764 // Variables with the predetermined data-sharing attributes may not be 11765 // listed in data-sharing attributes clauses, except for the cases 11766 // listed below. For these exceptions only, listing a predetermined 11767 // variable in a data-sharing attribute clause is allowed and overrides 11768 // the variable's predetermined data-sharing attributes. 11769 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11770 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 11771 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11772 << getOpenMPClauseName(OMPC_private); 11773 reportOriginalDsa(*this, DSAStack, D, DVar); 11774 continue; 11775 } 11776 11777 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11778 // Variably modified types are not supported for tasks. 11779 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 11780 isOpenMPTaskingDirective(CurrDir)) { 11781 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11782 << getOpenMPClauseName(OMPC_private) << Type 11783 << getOpenMPDirectiveName(CurrDir); 11784 bool IsDecl = 11785 !VD || 11786 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11787 Diag(D->getLocation(), 11788 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11789 << D; 11790 continue; 11791 } 11792 11793 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11794 // A list item cannot appear in both a map clause and a data-sharing 11795 // attribute clause on the same construct 11796 // 11797 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 11798 // A list item cannot appear in both a map clause and a data-sharing 11799 // attribute clause on the same construct unless the construct is a 11800 // combined construct. 11801 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 11802 CurrDir == OMPD_target) { 11803 OpenMPClauseKind ConflictKind; 11804 if (DSAStack->checkMappableExprComponentListsForDecl( 11805 VD, /*CurrentRegionOnly=*/true, 11806 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 11807 OpenMPClauseKind WhereFoundClauseKind) -> bool { 11808 ConflictKind = WhereFoundClauseKind; 11809 return true; 11810 })) { 11811 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11812 << getOpenMPClauseName(OMPC_private) 11813 << getOpenMPClauseName(ConflictKind) 11814 << getOpenMPDirectiveName(CurrDir); 11815 reportOriginalDsa(*this, DSAStack, D, DVar); 11816 continue; 11817 } 11818 } 11819 11820 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 11821 // A variable of class type (or array thereof) that appears in a private 11822 // clause requires an accessible, unambiguous default constructor for the 11823 // class type. 11824 // Generate helper private variable and initialize it with the default 11825 // value. The address of the original variable is replaced by the address of 11826 // the new private variable in CodeGen. This new variable is not added to 11827 // IdResolver, so the code in the OpenMP region uses original variable for 11828 // proper diagnostics. 11829 Type = Type.getUnqualifiedType(); 11830 VarDecl *VDPrivate = 11831 buildVarDecl(*this, ELoc, Type, D->getName(), 11832 D->hasAttrs() ? &D->getAttrs() : nullptr, 11833 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11834 ActOnUninitializedDecl(VDPrivate); 11835 if (VDPrivate->isInvalidDecl()) 11836 continue; 11837 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 11838 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11839 11840 DeclRefExpr *Ref = nullptr; 11841 if (!VD && !CurContext->isDependentContext()) 11842 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 11843 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 11844 Vars.push_back((VD || CurContext->isDependentContext()) 11845 ? RefExpr->IgnoreParens() 11846 : Ref); 11847 PrivateCopies.push_back(VDPrivateRefExpr); 11848 } 11849 11850 if (Vars.empty()) 11851 return nullptr; 11852 11853 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11854 PrivateCopies); 11855 } 11856 11857 namespace { 11858 class DiagsUninitializedSeveretyRAII { 11859 private: 11860 DiagnosticsEngine &Diags; 11861 SourceLocation SavedLoc; 11862 bool IsIgnored = false; 11863 11864 public: 11865 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 11866 bool IsIgnored) 11867 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 11868 if (!IsIgnored) { 11869 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 11870 /*Map*/ diag::Severity::Ignored, Loc); 11871 } 11872 } 11873 ~DiagsUninitializedSeveretyRAII() { 11874 if (!IsIgnored) 11875 Diags.popMappings(SavedLoc); 11876 } 11877 }; 11878 } 11879 11880 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 11881 SourceLocation StartLoc, 11882 SourceLocation LParenLoc, 11883 SourceLocation EndLoc) { 11884 SmallVector<Expr *, 8> Vars; 11885 SmallVector<Expr *, 8> PrivateCopies; 11886 SmallVector<Expr *, 8> Inits; 11887 SmallVector<Decl *, 4> ExprCaptures; 11888 bool IsImplicitClause = 11889 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 11890 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 11891 11892 for (Expr *RefExpr : VarList) { 11893 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 11894 SourceLocation ELoc; 11895 SourceRange ERange; 11896 Expr *SimpleRefExpr = RefExpr; 11897 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11898 if (Res.second) { 11899 // It will be analyzed later. 11900 Vars.push_back(RefExpr); 11901 PrivateCopies.push_back(nullptr); 11902 Inits.push_back(nullptr); 11903 } 11904 ValueDecl *D = Res.first; 11905 if (!D) 11906 continue; 11907 11908 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 11909 QualType Type = D->getType(); 11910 auto *VD = dyn_cast<VarDecl>(D); 11911 11912 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11913 // A variable that appears in a private clause must not have an incomplete 11914 // type or a reference type. 11915 if (RequireCompleteType(ELoc, Type, 11916 diag::err_omp_firstprivate_incomplete_type)) 11917 continue; 11918 Type = Type.getNonReferenceType(); 11919 11920 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 11921 // A variable of class type (or array thereof) that appears in a private 11922 // clause requires an accessible, unambiguous copy constructor for the 11923 // class type. 11924 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11925 11926 // If an implicit firstprivate variable found it was checked already. 11927 DSAStackTy::DSAVarData TopDVar; 11928 if (!IsImplicitClause) { 11929 DSAStackTy::DSAVarData DVar = 11930 DSAStack->getTopDSA(D, /*FromParent=*/false); 11931 TopDVar = DVar; 11932 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 11933 bool IsConstant = ElemType.isConstant(Context); 11934 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 11935 // A list item that specifies a given variable may not appear in more 11936 // than one clause on the same directive, except that a variable may be 11937 // specified in both firstprivate and lastprivate clauses. 11938 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 11939 // A list item may appear in a firstprivate or lastprivate clause but not 11940 // both. 11941 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 11942 (isOpenMPDistributeDirective(CurrDir) || 11943 DVar.CKind != OMPC_lastprivate) && 11944 DVar.RefExpr) { 11945 Diag(ELoc, diag::err_omp_wrong_dsa) 11946 << getOpenMPClauseName(DVar.CKind) 11947 << getOpenMPClauseName(OMPC_firstprivate); 11948 reportOriginalDsa(*this, DSAStack, D, DVar); 11949 continue; 11950 } 11951 11952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11953 // in a Construct] 11954 // Variables with the predetermined data-sharing attributes may not be 11955 // listed in data-sharing attributes clauses, except for the cases 11956 // listed below. For these exceptions only, listing a predetermined 11957 // variable in a data-sharing attribute clause is allowed and overrides 11958 // the variable's predetermined data-sharing attributes. 11959 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 11960 // in a Construct, C/C++, p.2] 11961 // Variables with const-qualified type having no mutable member may be 11962 // listed in a firstprivate clause, even if they are static data members. 11963 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 11964 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 11965 Diag(ELoc, diag::err_omp_wrong_dsa) 11966 << getOpenMPClauseName(DVar.CKind) 11967 << getOpenMPClauseName(OMPC_firstprivate); 11968 reportOriginalDsa(*this, DSAStack, D, DVar); 11969 continue; 11970 } 11971 11972 // OpenMP [2.9.3.4, Restrictions, p.2] 11973 // A list item that is private within a parallel region must not appear 11974 // in a firstprivate clause on a worksharing construct if any of the 11975 // worksharing regions arising from the worksharing construct ever bind 11976 // to any of the parallel regions arising from the parallel construct. 11977 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11978 // A list item that is private within a teams region must not appear in a 11979 // firstprivate clause on a distribute construct if any of the distribute 11980 // regions arising from the distribute construct ever bind to any of the 11981 // teams regions arising from the teams construct. 11982 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 11983 // A list item that appears in a reduction clause of a teams construct 11984 // must not appear in a firstprivate clause on a distribute construct if 11985 // any of the distribute regions arising from the distribute construct 11986 // ever bind to any of the teams regions arising from the teams construct. 11987 if ((isOpenMPWorksharingDirective(CurrDir) || 11988 isOpenMPDistributeDirective(CurrDir)) && 11989 !isOpenMPParallelDirective(CurrDir) && 11990 !isOpenMPTeamsDirective(CurrDir)) { 11991 DVar = DSAStack->getImplicitDSA(D, true); 11992 if (DVar.CKind != OMPC_shared && 11993 (isOpenMPParallelDirective(DVar.DKind) || 11994 isOpenMPTeamsDirective(DVar.DKind) || 11995 DVar.DKind == OMPD_unknown)) { 11996 Diag(ELoc, diag::err_omp_required_access) 11997 << getOpenMPClauseName(OMPC_firstprivate) 11998 << getOpenMPClauseName(OMPC_shared); 11999 reportOriginalDsa(*this, DSAStack, D, DVar); 12000 continue; 12001 } 12002 } 12003 // OpenMP [2.9.3.4, Restrictions, p.3] 12004 // A list item that appears in a reduction clause of a parallel construct 12005 // must not appear in a firstprivate clause on a worksharing or task 12006 // construct if any of the worksharing or task regions arising from the 12007 // worksharing or task construct ever bind to any of the parallel regions 12008 // arising from the parallel construct. 12009 // OpenMP [2.9.3.4, Restrictions, p.4] 12010 // A list item that appears in a reduction clause in worksharing 12011 // construct must not appear in a firstprivate clause in a task construct 12012 // encountered during execution of any of the worksharing regions arising 12013 // from the worksharing construct. 12014 if (isOpenMPTaskingDirective(CurrDir)) { 12015 DVar = DSAStack->hasInnermostDSA( 12016 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12017 [](OpenMPDirectiveKind K) { 12018 return isOpenMPParallelDirective(K) || 12019 isOpenMPWorksharingDirective(K) || 12020 isOpenMPTeamsDirective(K); 12021 }, 12022 /*FromParent=*/true); 12023 if (DVar.CKind == OMPC_reduction && 12024 (isOpenMPParallelDirective(DVar.DKind) || 12025 isOpenMPWorksharingDirective(DVar.DKind) || 12026 isOpenMPTeamsDirective(DVar.DKind))) { 12027 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12028 << getOpenMPDirectiveName(DVar.DKind); 12029 reportOriginalDsa(*this, DSAStack, D, DVar); 12030 continue; 12031 } 12032 } 12033 12034 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12035 // A list item cannot appear in both a map clause and a data-sharing 12036 // attribute clause on the same construct 12037 // 12038 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12039 // A list item cannot appear in both a map clause and a data-sharing 12040 // attribute clause on the same construct unless the construct is a 12041 // combined construct. 12042 if ((LangOpts.OpenMP <= 45 && 12043 isOpenMPTargetExecutionDirective(CurrDir)) || 12044 CurrDir == OMPD_target) { 12045 OpenMPClauseKind ConflictKind; 12046 if (DSAStack->checkMappableExprComponentListsForDecl( 12047 VD, /*CurrentRegionOnly=*/true, 12048 [&ConflictKind]( 12049 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12050 OpenMPClauseKind WhereFoundClauseKind) { 12051 ConflictKind = WhereFoundClauseKind; 12052 return true; 12053 })) { 12054 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12055 << getOpenMPClauseName(OMPC_firstprivate) 12056 << getOpenMPClauseName(ConflictKind) 12057 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12058 reportOriginalDsa(*this, DSAStack, D, DVar); 12059 continue; 12060 } 12061 } 12062 } 12063 12064 // Variably modified types are not supported for tasks. 12065 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12066 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12067 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12068 << getOpenMPClauseName(OMPC_firstprivate) << Type 12069 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12070 bool IsDecl = 12071 !VD || 12072 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12073 Diag(D->getLocation(), 12074 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12075 << D; 12076 continue; 12077 } 12078 12079 Type = Type.getUnqualifiedType(); 12080 VarDecl *VDPrivate = 12081 buildVarDecl(*this, ELoc, Type, D->getName(), 12082 D->hasAttrs() ? &D->getAttrs() : nullptr, 12083 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12084 // Generate helper private variable and initialize it with the value of the 12085 // original variable. The address of the original variable is replaced by 12086 // the address of the new private variable in the CodeGen. This new variable 12087 // is not added to IdResolver, so the code in the OpenMP region uses 12088 // original variable for proper diagnostics and variable capturing. 12089 Expr *VDInitRefExpr = nullptr; 12090 // For arrays generate initializer for single element and replace it by the 12091 // original array element in CodeGen. 12092 if (Type->isArrayType()) { 12093 VarDecl *VDInit = 12094 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12095 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12096 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12097 ElemType = ElemType.getUnqualifiedType(); 12098 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12099 ".firstprivate.temp"); 12100 InitializedEntity Entity = 12101 InitializedEntity::InitializeVariable(VDInitTemp); 12102 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12103 12104 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12105 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12106 if (Result.isInvalid()) 12107 VDPrivate->setInvalidDecl(); 12108 else 12109 VDPrivate->setInit(Result.getAs<Expr>()); 12110 // Remove temp variable declaration. 12111 Context.Deallocate(VDInitTemp); 12112 } else { 12113 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12114 ".firstprivate.temp"); 12115 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12116 RefExpr->getExprLoc()); 12117 AddInitializerToDecl(VDPrivate, 12118 DefaultLvalueConversion(VDInitRefExpr).get(), 12119 /*DirectInit=*/false); 12120 } 12121 if (VDPrivate->isInvalidDecl()) { 12122 if (IsImplicitClause) { 12123 Diag(RefExpr->getExprLoc(), 12124 diag::note_omp_task_predetermined_firstprivate_here); 12125 } 12126 continue; 12127 } 12128 CurContext->addDecl(VDPrivate); 12129 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12130 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12131 RefExpr->getExprLoc()); 12132 DeclRefExpr *Ref = nullptr; 12133 if (!VD && !CurContext->isDependentContext()) { 12134 if (TopDVar.CKind == OMPC_lastprivate) { 12135 Ref = TopDVar.PrivateCopy; 12136 } else { 12137 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12138 if (!isOpenMPCapturedDecl(D)) 12139 ExprCaptures.push_back(Ref->getDecl()); 12140 } 12141 } 12142 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12143 Vars.push_back((VD || CurContext->isDependentContext()) 12144 ? RefExpr->IgnoreParens() 12145 : Ref); 12146 PrivateCopies.push_back(VDPrivateRefExpr); 12147 Inits.push_back(VDInitRefExpr); 12148 } 12149 12150 if (Vars.empty()) 12151 return nullptr; 12152 12153 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12154 Vars, PrivateCopies, Inits, 12155 buildPreInits(Context, ExprCaptures)); 12156 } 12157 12158 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12159 SourceLocation StartLoc, 12160 SourceLocation LParenLoc, 12161 SourceLocation EndLoc) { 12162 SmallVector<Expr *, 8> Vars; 12163 SmallVector<Expr *, 8> SrcExprs; 12164 SmallVector<Expr *, 8> DstExprs; 12165 SmallVector<Expr *, 8> AssignmentOps; 12166 SmallVector<Decl *, 4> ExprCaptures; 12167 SmallVector<Expr *, 4> ExprPostUpdates; 12168 for (Expr *RefExpr : VarList) { 12169 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12170 SourceLocation ELoc; 12171 SourceRange ERange; 12172 Expr *SimpleRefExpr = RefExpr; 12173 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12174 if (Res.second) { 12175 // It will be analyzed later. 12176 Vars.push_back(RefExpr); 12177 SrcExprs.push_back(nullptr); 12178 DstExprs.push_back(nullptr); 12179 AssignmentOps.push_back(nullptr); 12180 } 12181 ValueDecl *D = Res.first; 12182 if (!D) 12183 continue; 12184 12185 QualType Type = D->getType(); 12186 auto *VD = dyn_cast<VarDecl>(D); 12187 12188 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12189 // A variable that appears in a lastprivate clause must not have an 12190 // incomplete type or a reference type. 12191 if (RequireCompleteType(ELoc, Type, 12192 diag::err_omp_lastprivate_incomplete_type)) 12193 continue; 12194 Type = Type.getNonReferenceType(); 12195 12196 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12197 // A variable that is privatized must not have a const-qualified type 12198 // unless it is of class type with a mutable member. This restriction does 12199 // not apply to the firstprivate clause. 12200 // 12201 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12202 // A variable that appears in a lastprivate clause must not have a 12203 // const-qualified type unless it is of class type with a mutable member. 12204 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12205 continue; 12206 12207 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12208 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12209 // in a Construct] 12210 // Variables with the predetermined data-sharing attributes may not be 12211 // listed in data-sharing attributes clauses, except for the cases 12212 // listed below. 12213 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12214 // A list item may appear in a firstprivate or lastprivate clause but not 12215 // both. 12216 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12217 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12218 (isOpenMPDistributeDirective(CurrDir) || 12219 DVar.CKind != OMPC_firstprivate) && 12220 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12221 Diag(ELoc, diag::err_omp_wrong_dsa) 12222 << getOpenMPClauseName(DVar.CKind) 12223 << getOpenMPClauseName(OMPC_lastprivate); 12224 reportOriginalDsa(*this, DSAStack, D, DVar); 12225 continue; 12226 } 12227 12228 // OpenMP [2.14.3.5, Restrictions, p.2] 12229 // A list item that is private within a parallel region, or that appears in 12230 // the reduction clause of a parallel construct, must not appear in a 12231 // lastprivate clause on a worksharing construct if any of the corresponding 12232 // worksharing regions ever binds to any of the corresponding parallel 12233 // regions. 12234 DSAStackTy::DSAVarData TopDVar = DVar; 12235 if (isOpenMPWorksharingDirective(CurrDir) && 12236 !isOpenMPParallelDirective(CurrDir) && 12237 !isOpenMPTeamsDirective(CurrDir)) { 12238 DVar = DSAStack->getImplicitDSA(D, true); 12239 if (DVar.CKind != OMPC_shared) { 12240 Diag(ELoc, diag::err_omp_required_access) 12241 << getOpenMPClauseName(OMPC_lastprivate) 12242 << getOpenMPClauseName(OMPC_shared); 12243 reportOriginalDsa(*this, DSAStack, D, DVar); 12244 continue; 12245 } 12246 } 12247 12248 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12249 // A variable of class type (or array thereof) that appears in a 12250 // lastprivate clause requires an accessible, unambiguous default 12251 // constructor for the class type, unless the list item is also specified 12252 // in a firstprivate clause. 12253 // A variable of class type (or array thereof) that appears in a 12254 // lastprivate clause requires an accessible, unambiguous copy assignment 12255 // operator for the class type. 12256 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12257 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12258 Type.getUnqualifiedType(), ".lastprivate.src", 12259 D->hasAttrs() ? &D->getAttrs() : nullptr); 12260 DeclRefExpr *PseudoSrcExpr = 12261 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12262 VarDecl *DstVD = 12263 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12264 D->hasAttrs() ? &D->getAttrs() : nullptr); 12265 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12266 // For arrays generate assignment operation for single element and replace 12267 // it by the original array element in CodeGen. 12268 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12269 PseudoDstExpr, PseudoSrcExpr); 12270 if (AssignmentOp.isInvalid()) 12271 continue; 12272 AssignmentOp = 12273 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12274 if (AssignmentOp.isInvalid()) 12275 continue; 12276 12277 DeclRefExpr *Ref = nullptr; 12278 if (!VD && !CurContext->isDependentContext()) { 12279 if (TopDVar.CKind == OMPC_firstprivate) { 12280 Ref = TopDVar.PrivateCopy; 12281 } else { 12282 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12283 if (!isOpenMPCapturedDecl(D)) 12284 ExprCaptures.push_back(Ref->getDecl()); 12285 } 12286 if (TopDVar.CKind == OMPC_firstprivate || 12287 (!isOpenMPCapturedDecl(D) && 12288 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12289 ExprResult RefRes = DefaultLvalueConversion(Ref); 12290 if (!RefRes.isUsable()) 12291 continue; 12292 ExprResult PostUpdateRes = 12293 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12294 RefRes.get()); 12295 if (!PostUpdateRes.isUsable()) 12296 continue; 12297 ExprPostUpdates.push_back( 12298 IgnoredValueConversions(PostUpdateRes.get()).get()); 12299 } 12300 } 12301 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12302 Vars.push_back((VD || CurContext->isDependentContext()) 12303 ? RefExpr->IgnoreParens() 12304 : Ref); 12305 SrcExprs.push_back(PseudoSrcExpr); 12306 DstExprs.push_back(PseudoDstExpr); 12307 AssignmentOps.push_back(AssignmentOp.get()); 12308 } 12309 12310 if (Vars.empty()) 12311 return nullptr; 12312 12313 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12314 Vars, SrcExprs, DstExprs, AssignmentOps, 12315 buildPreInits(Context, ExprCaptures), 12316 buildPostUpdate(*this, ExprPostUpdates)); 12317 } 12318 12319 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12320 SourceLocation StartLoc, 12321 SourceLocation LParenLoc, 12322 SourceLocation EndLoc) { 12323 SmallVector<Expr *, 8> Vars; 12324 for (Expr *RefExpr : VarList) { 12325 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12326 SourceLocation ELoc; 12327 SourceRange ERange; 12328 Expr *SimpleRefExpr = RefExpr; 12329 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12330 if (Res.second) { 12331 // It will be analyzed later. 12332 Vars.push_back(RefExpr); 12333 } 12334 ValueDecl *D = Res.first; 12335 if (!D) 12336 continue; 12337 12338 auto *VD = dyn_cast<VarDecl>(D); 12339 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12340 // in a Construct] 12341 // Variables with the predetermined data-sharing attributes may not be 12342 // listed in data-sharing attributes clauses, except for the cases 12343 // listed below. For these exceptions only, listing a predetermined 12344 // variable in a data-sharing attribute clause is allowed and overrides 12345 // the variable's predetermined data-sharing attributes. 12346 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12347 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12348 DVar.RefExpr) { 12349 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12350 << getOpenMPClauseName(OMPC_shared); 12351 reportOriginalDsa(*this, DSAStack, D, DVar); 12352 continue; 12353 } 12354 12355 DeclRefExpr *Ref = nullptr; 12356 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12357 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12358 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12359 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12360 ? RefExpr->IgnoreParens() 12361 : Ref); 12362 } 12363 12364 if (Vars.empty()) 12365 return nullptr; 12366 12367 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12368 } 12369 12370 namespace { 12371 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12372 DSAStackTy *Stack; 12373 12374 public: 12375 bool VisitDeclRefExpr(DeclRefExpr *E) { 12376 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12377 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12378 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12379 return false; 12380 if (DVar.CKind != OMPC_unknown) 12381 return true; 12382 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12383 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12384 /*FromParent=*/true); 12385 return DVarPrivate.CKind != OMPC_unknown; 12386 } 12387 return false; 12388 } 12389 bool VisitStmt(Stmt *S) { 12390 for (Stmt *Child : S->children()) { 12391 if (Child && Visit(Child)) 12392 return true; 12393 } 12394 return false; 12395 } 12396 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12397 }; 12398 } // namespace 12399 12400 namespace { 12401 // Transform MemberExpression for specified FieldDecl of current class to 12402 // DeclRefExpr to specified OMPCapturedExprDecl. 12403 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12404 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12405 ValueDecl *Field = nullptr; 12406 DeclRefExpr *CapturedExpr = nullptr; 12407 12408 public: 12409 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12410 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12411 12412 ExprResult TransformMemberExpr(MemberExpr *E) { 12413 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12414 E->getMemberDecl() == Field) { 12415 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12416 return CapturedExpr; 12417 } 12418 return BaseTransform::TransformMemberExpr(E); 12419 } 12420 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12421 }; 12422 } // namespace 12423 12424 template <typename T, typename U> 12425 static T filterLookupForUDReductionAndMapper( 12426 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12427 for (U &Set : Lookups) { 12428 for (auto *D : Set) { 12429 if (T Res = Gen(cast<ValueDecl>(D))) 12430 return Res; 12431 } 12432 } 12433 return T(); 12434 } 12435 12436 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12437 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12438 12439 for (auto RD : D->redecls()) { 12440 // Don't bother with extra checks if we already know this one isn't visible. 12441 if (RD == D) 12442 continue; 12443 12444 auto ND = cast<NamedDecl>(RD); 12445 if (LookupResult::isVisible(SemaRef, ND)) 12446 return ND; 12447 } 12448 12449 return nullptr; 12450 } 12451 12452 static void 12453 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12454 SourceLocation Loc, QualType Ty, 12455 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12456 // Find all of the associated namespaces and classes based on the 12457 // arguments we have. 12458 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12459 Sema::AssociatedClassSet AssociatedClasses; 12460 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12461 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12462 AssociatedClasses); 12463 12464 // C++ [basic.lookup.argdep]p3: 12465 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12466 // and let Y be the lookup set produced by argument dependent 12467 // lookup (defined as follows). If X contains [...] then Y is 12468 // empty. Otherwise Y is the set of declarations found in the 12469 // namespaces associated with the argument types as described 12470 // below. The set of declarations found by the lookup of the name 12471 // is the union of X and Y. 12472 // 12473 // Here, we compute Y and add its members to the overloaded 12474 // candidate set. 12475 for (auto *NS : AssociatedNamespaces) { 12476 // When considering an associated namespace, the lookup is the 12477 // same as the lookup performed when the associated namespace is 12478 // used as a qualifier (3.4.3.2) except that: 12479 // 12480 // -- Any using-directives in the associated namespace are 12481 // ignored. 12482 // 12483 // -- Any namespace-scope friend functions declared in 12484 // associated classes are visible within their respective 12485 // namespaces even if they are not visible during an ordinary 12486 // lookup (11.4). 12487 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12488 for (auto *D : R) { 12489 auto *Underlying = D; 12490 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12491 Underlying = USD->getTargetDecl(); 12492 12493 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12494 !isa<OMPDeclareMapperDecl>(Underlying)) 12495 continue; 12496 12497 if (!SemaRef.isVisible(D)) { 12498 D = findAcceptableDecl(SemaRef, D); 12499 if (!D) 12500 continue; 12501 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12502 Underlying = USD->getTargetDecl(); 12503 } 12504 Lookups.emplace_back(); 12505 Lookups.back().addDecl(Underlying); 12506 } 12507 } 12508 } 12509 12510 static ExprResult 12511 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12512 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12513 const DeclarationNameInfo &ReductionId, QualType Ty, 12514 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12515 if (ReductionIdScopeSpec.isInvalid()) 12516 return ExprError(); 12517 SmallVector<UnresolvedSet<8>, 4> Lookups; 12518 if (S) { 12519 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12520 Lookup.suppressDiagnostics(); 12521 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12522 NamedDecl *D = Lookup.getRepresentativeDecl(); 12523 do { 12524 S = S->getParent(); 12525 } while (S && !S->isDeclScope(D)); 12526 if (S) 12527 S = S->getParent(); 12528 Lookups.emplace_back(); 12529 Lookups.back().append(Lookup.begin(), Lookup.end()); 12530 Lookup.clear(); 12531 } 12532 } else if (auto *ULE = 12533 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12534 Lookups.push_back(UnresolvedSet<8>()); 12535 Decl *PrevD = nullptr; 12536 for (NamedDecl *D : ULE->decls()) { 12537 if (D == PrevD) 12538 Lookups.push_back(UnresolvedSet<8>()); 12539 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12540 Lookups.back().addDecl(DRD); 12541 PrevD = D; 12542 } 12543 } 12544 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12545 Ty->isInstantiationDependentType() || 12546 Ty->containsUnexpandedParameterPack() || 12547 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12548 return !D->isInvalidDecl() && 12549 (D->getType()->isDependentType() || 12550 D->getType()->isInstantiationDependentType() || 12551 D->getType()->containsUnexpandedParameterPack()); 12552 })) { 12553 UnresolvedSet<8> ResSet; 12554 for (const UnresolvedSet<8> &Set : Lookups) { 12555 if (Set.empty()) 12556 continue; 12557 ResSet.append(Set.begin(), Set.end()); 12558 // The last item marks the end of all declarations at the specified scope. 12559 ResSet.addDecl(Set[Set.size() - 1]); 12560 } 12561 return UnresolvedLookupExpr::Create( 12562 SemaRef.Context, /*NamingClass=*/nullptr, 12563 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12564 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12565 } 12566 // Lookup inside the classes. 12567 // C++ [over.match.oper]p3: 12568 // For a unary operator @ with an operand of a type whose 12569 // cv-unqualified version is T1, and for a binary operator @ with 12570 // a left operand of a type whose cv-unqualified version is T1 and 12571 // a right operand of a type whose cv-unqualified version is T2, 12572 // three sets of candidate functions, designated member 12573 // candidates, non-member candidates and built-in candidates, are 12574 // constructed as follows: 12575 // -- If T1 is a complete class type or a class currently being 12576 // defined, the set of member candidates is the result of the 12577 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12578 // the set of member candidates is empty. 12579 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12580 Lookup.suppressDiagnostics(); 12581 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12582 // Complete the type if it can be completed. 12583 // If the type is neither complete nor being defined, bail out now. 12584 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12585 TyRec->getDecl()->getDefinition()) { 12586 Lookup.clear(); 12587 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12588 if (Lookup.empty()) { 12589 Lookups.emplace_back(); 12590 Lookups.back().append(Lookup.begin(), Lookup.end()); 12591 } 12592 } 12593 } 12594 // Perform ADL. 12595 if (SemaRef.getLangOpts().CPlusPlus) 12596 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12597 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12598 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12599 if (!D->isInvalidDecl() && 12600 SemaRef.Context.hasSameType(D->getType(), Ty)) 12601 return D; 12602 return nullptr; 12603 })) 12604 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12605 VK_LValue, Loc); 12606 if (SemaRef.getLangOpts().CPlusPlus) { 12607 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12608 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12609 if (!D->isInvalidDecl() && 12610 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12611 !Ty.isMoreQualifiedThan(D->getType())) 12612 return D; 12613 return nullptr; 12614 })) { 12615 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12616 /*DetectVirtual=*/false); 12617 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12618 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12619 VD->getType().getUnqualifiedType()))) { 12620 if (SemaRef.CheckBaseClassAccess( 12621 Loc, VD->getType(), Ty, Paths.front(), 12622 /*DiagID=*/0) != Sema::AR_inaccessible) { 12623 SemaRef.BuildBasePathArray(Paths, BasePath); 12624 return SemaRef.BuildDeclRefExpr( 12625 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12626 } 12627 } 12628 } 12629 } 12630 } 12631 if (ReductionIdScopeSpec.isSet()) { 12632 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12633 return ExprError(); 12634 } 12635 return ExprEmpty(); 12636 } 12637 12638 namespace { 12639 /// Data for the reduction-based clauses. 12640 struct ReductionData { 12641 /// List of original reduction items. 12642 SmallVector<Expr *, 8> Vars; 12643 /// List of private copies of the reduction items. 12644 SmallVector<Expr *, 8> Privates; 12645 /// LHS expressions for the reduction_op expressions. 12646 SmallVector<Expr *, 8> LHSs; 12647 /// RHS expressions for the reduction_op expressions. 12648 SmallVector<Expr *, 8> RHSs; 12649 /// Reduction operation expression. 12650 SmallVector<Expr *, 8> ReductionOps; 12651 /// Taskgroup descriptors for the corresponding reduction items in 12652 /// in_reduction clauses. 12653 SmallVector<Expr *, 8> TaskgroupDescriptors; 12654 /// List of captures for clause. 12655 SmallVector<Decl *, 4> ExprCaptures; 12656 /// List of postupdate expressions. 12657 SmallVector<Expr *, 4> ExprPostUpdates; 12658 ReductionData() = delete; 12659 /// Reserves required memory for the reduction data. 12660 ReductionData(unsigned Size) { 12661 Vars.reserve(Size); 12662 Privates.reserve(Size); 12663 LHSs.reserve(Size); 12664 RHSs.reserve(Size); 12665 ReductionOps.reserve(Size); 12666 TaskgroupDescriptors.reserve(Size); 12667 ExprCaptures.reserve(Size); 12668 ExprPostUpdates.reserve(Size); 12669 } 12670 /// Stores reduction item and reduction operation only (required for dependent 12671 /// reduction item). 12672 void push(Expr *Item, Expr *ReductionOp) { 12673 Vars.emplace_back(Item); 12674 Privates.emplace_back(nullptr); 12675 LHSs.emplace_back(nullptr); 12676 RHSs.emplace_back(nullptr); 12677 ReductionOps.emplace_back(ReductionOp); 12678 TaskgroupDescriptors.emplace_back(nullptr); 12679 } 12680 /// Stores reduction data. 12681 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12682 Expr *TaskgroupDescriptor) { 12683 Vars.emplace_back(Item); 12684 Privates.emplace_back(Private); 12685 LHSs.emplace_back(LHS); 12686 RHSs.emplace_back(RHS); 12687 ReductionOps.emplace_back(ReductionOp); 12688 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12689 } 12690 }; 12691 } // namespace 12692 12693 static bool checkOMPArraySectionConstantForReduction( 12694 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12695 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12696 const Expr *Length = OASE->getLength(); 12697 if (Length == nullptr) { 12698 // For array sections of the form [1:] or [:], we would need to analyze 12699 // the lower bound... 12700 if (OASE->getColonLoc().isValid()) 12701 return false; 12702 12703 // This is an array subscript which has implicit length 1! 12704 SingleElement = true; 12705 ArraySizes.push_back(llvm::APSInt::get(1)); 12706 } else { 12707 Expr::EvalResult Result; 12708 if (!Length->EvaluateAsInt(Result, Context)) 12709 return false; 12710 12711 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12712 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 12713 ArraySizes.push_back(ConstantLengthValue); 12714 } 12715 12716 // Get the base of this array section and walk up from there. 12717 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 12718 12719 // We require length = 1 for all array sections except the right-most to 12720 // guarantee that the memory region is contiguous and has no holes in it. 12721 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 12722 Length = TempOASE->getLength(); 12723 if (Length == nullptr) { 12724 // For array sections of the form [1:] or [:], we would need to analyze 12725 // the lower bound... 12726 if (OASE->getColonLoc().isValid()) 12727 return false; 12728 12729 // This is an array subscript which has implicit length 1! 12730 ArraySizes.push_back(llvm::APSInt::get(1)); 12731 } else { 12732 Expr::EvalResult Result; 12733 if (!Length->EvaluateAsInt(Result, Context)) 12734 return false; 12735 12736 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 12737 if (ConstantLengthValue.getSExtValue() != 1) 12738 return false; 12739 12740 ArraySizes.push_back(ConstantLengthValue); 12741 } 12742 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 12743 } 12744 12745 // If we have a single element, we don't need to add the implicit lengths. 12746 if (!SingleElement) { 12747 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 12748 // Has implicit length 1! 12749 ArraySizes.push_back(llvm::APSInt::get(1)); 12750 Base = TempASE->getBase()->IgnoreParenImpCasts(); 12751 } 12752 } 12753 12754 // This array section can be privatized as a single value or as a constant 12755 // sized array. 12756 return true; 12757 } 12758 12759 static bool actOnOMPReductionKindClause( 12760 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 12761 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 12762 SourceLocation ColonLoc, SourceLocation EndLoc, 12763 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 12764 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 12765 DeclarationName DN = ReductionId.getName(); 12766 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 12767 BinaryOperatorKind BOK = BO_Comma; 12768 12769 ASTContext &Context = S.Context; 12770 // OpenMP [2.14.3.6, reduction clause] 12771 // C 12772 // reduction-identifier is either an identifier or one of the following 12773 // operators: +, -, *, &, |, ^, && and || 12774 // C++ 12775 // reduction-identifier is either an id-expression or one of the following 12776 // operators: +, -, *, &, |, ^, && and || 12777 switch (OOK) { 12778 case OO_Plus: 12779 case OO_Minus: 12780 BOK = BO_Add; 12781 break; 12782 case OO_Star: 12783 BOK = BO_Mul; 12784 break; 12785 case OO_Amp: 12786 BOK = BO_And; 12787 break; 12788 case OO_Pipe: 12789 BOK = BO_Or; 12790 break; 12791 case OO_Caret: 12792 BOK = BO_Xor; 12793 break; 12794 case OO_AmpAmp: 12795 BOK = BO_LAnd; 12796 break; 12797 case OO_PipePipe: 12798 BOK = BO_LOr; 12799 break; 12800 case OO_New: 12801 case OO_Delete: 12802 case OO_Array_New: 12803 case OO_Array_Delete: 12804 case OO_Slash: 12805 case OO_Percent: 12806 case OO_Tilde: 12807 case OO_Exclaim: 12808 case OO_Equal: 12809 case OO_Less: 12810 case OO_Greater: 12811 case OO_LessEqual: 12812 case OO_GreaterEqual: 12813 case OO_PlusEqual: 12814 case OO_MinusEqual: 12815 case OO_StarEqual: 12816 case OO_SlashEqual: 12817 case OO_PercentEqual: 12818 case OO_CaretEqual: 12819 case OO_AmpEqual: 12820 case OO_PipeEqual: 12821 case OO_LessLess: 12822 case OO_GreaterGreater: 12823 case OO_LessLessEqual: 12824 case OO_GreaterGreaterEqual: 12825 case OO_EqualEqual: 12826 case OO_ExclaimEqual: 12827 case OO_Spaceship: 12828 case OO_PlusPlus: 12829 case OO_MinusMinus: 12830 case OO_Comma: 12831 case OO_ArrowStar: 12832 case OO_Arrow: 12833 case OO_Call: 12834 case OO_Subscript: 12835 case OO_Conditional: 12836 case OO_Coawait: 12837 case NUM_OVERLOADED_OPERATORS: 12838 llvm_unreachable("Unexpected reduction identifier"); 12839 case OO_None: 12840 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 12841 if (II->isStr("max")) 12842 BOK = BO_GT; 12843 else if (II->isStr("min")) 12844 BOK = BO_LT; 12845 } 12846 break; 12847 } 12848 SourceRange ReductionIdRange; 12849 if (ReductionIdScopeSpec.isValid()) 12850 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 12851 else 12852 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 12853 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 12854 12855 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 12856 bool FirstIter = true; 12857 for (Expr *RefExpr : VarList) { 12858 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 12859 // OpenMP [2.1, C/C++] 12860 // A list item is a variable or array section, subject to the restrictions 12861 // specified in Section 2.4 on page 42 and in each of the sections 12862 // describing clauses and directives for which a list appears. 12863 // OpenMP [2.14.3.3, Restrictions, p.1] 12864 // A variable that is part of another variable (as an array or 12865 // structure element) cannot appear in a private clause. 12866 if (!FirstIter && IR != ER) 12867 ++IR; 12868 FirstIter = false; 12869 SourceLocation ELoc; 12870 SourceRange ERange; 12871 Expr *SimpleRefExpr = RefExpr; 12872 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 12873 /*AllowArraySection=*/true); 12874 if (Res.second) { 12875 // Try to find 'declare reduction' corresponding construct before using 12876 // builtin/overloaded operators. 12877 QualType Type = Context.DependentTy; 12878 CXXCastPath BasePath; 12879 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12880 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12881 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12882 Expr *ReductionOp = nullptr; 12883 if (S.CurContext->isDependentContext() && 12884 (DeclareReductionRef.isUnset() || 12885 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 12886 ReductionOp = DeclareReductionRef.get(); 12887 // It will be analyzed later. 12888 RD.push(RefExpr, ReductionOp); 12889 } 12890 ValueDecl *D = Res.first; 12891 if (!D) 12892 continue; 12893 12894 Expr *TaskgroupDescriptor = nullptr; 12895 QualType Type; 12896 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 12897 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 12898 if (ASE) { 12899 Type = ASE->getType().getNonReferenceType(); 12900 } else if (OASE) { 12901 QualType BaseType = 12902 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 12903 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 12904 Type = ATy->getElementType(); 12905 else 12906 Type = BaseType->getPointeeType(); 12907 Type = Type.getNonReferenceType(); 12908 } else { 12909 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 12910 } 12911 auto *VD = dyn_cast<VarDecl>(D); 12912 12913 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12914 // A variable that appears in a private clause must not have an incomplete 12915 // type or a reference type. 12916 if (S.RequireCompleteType(ELoc, D->getType(), 12917 diag::err_omp_reduction_incomplete_type)) 12918 continue; 12919 // OpenMP [2.14.3.6, reduction clause, Restrictions] 12920 // A list item that appears in a reduction clause must not be 12921 // const-qualified. 12922 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 12923 /*AcceptIfMutable*/ false, ASE || OASE)) 12924 continue; 12925 12926 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 12927 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 12928 // If a list-item is a reference type then it must bind to the same object 12929 // for all threads of the team. 12930 if (!ASE && !OASE) { 12931 if (VD) { 12932 VarDecl *VDDef = VD->getDefinition(); 12933 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 12934 DSARefChecker Check(Stack); 12935 if (Check.Visit(VDDef->getInit())) { 12936 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 12937 << getOpenMPClauseName(ClauseKind) << ERange; 12938 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 12939 continue; 12940 } 12941 } 12942 } 12943 12944 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12945 // in a Construct] 12946 // Variables with the predetermined data-sharing attributes may not be 12947 // listed in data-sharing attributes clauses, except for the cases 12948 // listed below. For these exceptions only, listing a predetermined 12949 // variable in a data-sharing attribute clause is allowed and overrides 12950 // the variable's predetermined data-sharing attributes. 12951 // OpenMP [2.14.3.6, Restrictions, p.3] 12952 // Any number of reduction clauses can be specified on the directive, 12953 // but a list item can appear only once in the reduction clauses for that 12954 // directive. 12955 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 12956 if (DVar.CKind == OMPC_reduction) { 12957 S.Diag(ELoc, diag::err_omp_once_referenced) 12958 << getOpenMPClauseName(ClauseKind); 12959 if (DVar.RefExpr) 12960 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 12961 continue; 12962 } 12963 if (DVar.CKind != OMPC_unknown) { 12964 S.Diag(ELoc, diag::err_omp_wrong_dsa) 12965 << getOpenMPClauseName(DVar.CKind) 12966 << getOpenMPClauseName(OMPC_reduction); 12967 reportOriginalDsa(S, Stack, D, DVar); 12968 continue; 12969 } 12970 12971 // OpenMP [2.14.3.6, Restrictions, p.1] 12972 // A list item that appears in a reduction clause of a worksharing 12973 // construct must be shared in the parallel regions to which any of the 12974 // worksharing regions arising from the worksharing construct bind. 12975 if (isOpenMPWorksharingDirective(CurrDir) && 12976 !isOpenMPParallelDirective(CurrDir) && 12977 !isOpenMPTeamsDirective(CurrDir)) { 12978 DVar = Stack->getImplicitDSA(D, true); 12979 if (DVar.CKind != OMPC_shared) { 12980 S.Diag(ELoc, diag::err_omp_required_access) 12981 << getOpenMPClauseName(OMPC_reduction) 12982 << getOpenMPClauseName(OMPC_shared); 12983 reportOriginalDsa(S, Stack, D, DVar); 12984 continue; 12985 } 12986 } 12987 } 12988 12989 // Try to find 'declare reduction' corresponding construct before using 12990 // builtin/overloaded operators. 12991 CXXCastPath BasePath; 12992 ExprResult DeclareReductionRef = buildDeclareReductionRef( 12993 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 12994 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 12995 if (DeclareReductionRef.isInvalid()) 12996 continue; 12997 if (S.CurContext->isDependentContext() && 12998 (DeclareReductionRef.isUnset() || 12999 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13000 RD.push(RefExpr, DeclareReductionRef.get()); 13001 continue; 13002 } 13003 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13004 // Not allowed reduction identifier is found. 13005 S.Diag(ReductionId.getBeginLoc(), 13006 diag::err_omp_unknown_reduction_identifier) 13007 << Type << ReductionIdRange; 13008 continue; 13009 } 13010 13011 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13012 // The type of a list item that appears in a reduction clause must be valid 13013 // for the reduction-identifier. For a max or min reduction in C, the type 13014 // of the list item must be an allowed arithmetic data type: char, int, 13015 // float, double, or _Bool, possibly modified with long, short, signed, or 13016 // unsigned. For a max or min reduction in C++, the type of the list item 13017 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13018 // double, or bool, possibly modified with long, short, signed, or unsigned. 13019 if (DeclareReductionRef.isUnset()) { 13020 if ((BOK == BO_GT || BOK == BO_LT) && 13021 !(Type->isScalarType() || 13022 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13023 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13024 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13025 if (!ASE && !OASE) { 13026 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13027 VarDecl::DeclarationOnly; 13028 S.Diag(D->getLocation(), 13029 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13030 << D; 13031 } 13032 continue; 13033 } 13034 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13035 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13036 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13037 << getOpenMPClauseName(ClauseKind); 13038 if (!ASE && !OASE) { 13039 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13040 VarDecl::DeclarationOnly; 13041 S.Diag(D->getLocation(), 13042 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13043 << D; 13044 } 13045 continue; 13046 } 13047 } 13048 13049 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13050 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13051 D->hasAttrs() ? &D->getAttrs() : nullptr); 13052 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13053 D->hasAttrs() ? &D->getAttrs() : nullptr); 13054 QualType PrivateTy = Type; 13055 13056 // Try if we can determine constant lengths for all array sections and avoid 13057 // the VLA. 13058 bool ConstantLengthOASE = false; 13059 if (OASE) { 13060 bool SingleElement; 13061 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13062 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13063 Context, OASE, SingleElement, ArraySizes); 13064 13065 // If we don't have a single element, we must emit a constant array type. 13066 if (ConstantLengthOASE && !SingleElement) { 13067 for (llvm::APSInt &Size : ArraySizes) 13068 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13069 ArrayType::Normal, 13070 /*IndexTypeQuals=*/0); 13071 } 13072 } 13073 13074 if ((OASE && !ConstantLengthOASE) || 13075 (!OASE && !ASE && 13076 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13077 if (!Context.getTargetInfo().isVLASupported()) { 13078 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13079 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13080 S.Diag(ELoc, diag::note_vla_unsupported); 13081 } else { 13082 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13083 S.targetDiag(ELoc, diag::note_vla_unsupported); 13084 } 13085 continue; 13086 } 13087 // For arrays/array sections only: 13088 // Create pseudo array type for private copy. The size for this array will 13089 // be generated during codegen. 13090 // For array subscripts or single variables Private Ty is the same as Type 13091 // (type of the variable or single array element). 13092 PrivateTy = Context.getVariableArrayType( 13093 Type, 13094 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13095 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13096 } else if (!ASE && !OASE && 13097 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13098 PrivateTy = D->getType().getNonReferenceType(); 13099 } 13100 // Private copy. 13101 VarDecl *PrivateVD = 13102 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13103 D->hasAttrs() ? &D->getAttrs() : nullptr, 13104 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13105 // Add initializer for private variable. 13106 Expr *Init = nullptr; 13107 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13108 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13109 if (DeclareReductionRef.isUsable()) { 13110 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13111 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13112 if (DRD->getInitializer()) { 13113 Init = DRDRef; 13114 RHSVD->setInit(DRDRef); 13115 RHSVD->setInitStyle(VarDecl::CallInit); 13116 } 13117 } else { 13118 switch (BOK) { 13119 case BO_Add: 13120 case BO_Xor: 13121 case BO_Or: 13122 case BO_LOr: 13123 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13124 if (Type->isScalarType() || Type->isAnyComplexType()) 13125 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13126 break; 13127 case BO_Mul: 13128 case BO_LAnd: 13129 if (Type->isScalarType() || Type->isAnyComplexType()) { 13130 // '*' and '&&' reduction ops - initializer is '1'. 13131 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13132 } 13133 break; 13134 case BO_And: { 13135 // '&' reduction op - initializer is '~0'. 13136 QualType OrigType = Type; 13137 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13138 Type = ComplexTy->getElementType(); 13139 if (Type->isRealFloatingType()) { 13140 llvm::APFloat InitValue = 13141 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13142 /*isIEEE=*/true); 13143 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13144 Type, ELoc); 13145 } else if (Type->isScalarType()) { 13146 uint64_t Size = Context.getTypeSize(Type); 13147 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13148 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13149 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13150 } 13151 if (Init && OrigType->isAnyComplexType()) { 13152 // Init = 0xFFFF + 0xFFFFi; 13153 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13154 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13155 } 13156 Type = OrigType; 13157 break; 13158 } 13159 case BO_LT: 13160 case BO_GT: { 13161 // 'min' reduction op - initializer is 'Largest representable number in 13162 // the reduction list item type'. 13163 // 'max' reduction op - initializer is 'Least representable number in 13164 // the reduction list item type'. 13165 if (Type->isIntegerType() || Type->isPointerType()) { 13166 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13167 uint64_t Size = Context.getTypeSize(Type); 13168 QualType IntTy = 13169 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13170 llvm::APInt InitValue = 13171 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13172 : llvm::APInt::getMinValue(Size) 13173 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13174 : llvm::APInt::getMaxValue(Size); 13175 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13176 if (Type->isPointerType()) { 13177 // Cast to pointer type. 13178 ExprResult CastExpr = S.BuildCStyleCastExpr( 13179 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13180 if (CastExpr.isInvalid()) 13181 continue; 13182 Init = CastExpr.get(); 13183 } 13184 } else if (Type->isRealFloatingType()) { 13185 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13186 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13187 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13188 Type, ELoc); 13189 } 13190 break; 13191 } 13192 case BO_PtrMemD: 13193 case BO_PtrMemI: 13194 case BO_MulAssign: 13195 case BO_Div: 13196 case BO_Rem: 13197 case BO_Sub: 13198 case BO_Shl: 13199 case BO_Shr: 13200 case BO_LE: 13201 case BO_GE: 13202 case BO_EQ: 13203 case BO_NE: 13204 case BO_Cmp: 13205 case BO_AndAssign: 13206 case BO_XorAssign: 13207 case BO_OrAssign: 13208 case BO_Assign: 13209 case BO_AddAssign: 13210 case BO_SubAssign: 13211 case BO_DivAssign: 13212 case BO_RemAssign: 13213 case BO_ShlAssign: 13214 case BO_ShrAssign: 13215 case BO_Comma: 13216 llvm_unreachable("Unexpected reduction operation"); 13217 } 13218 } 13219 if (Init && DeclareReductionRef.isUnset()) 13220 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13221 else if (!Init) 13222 S.ActOnUninitializedDecl(RHSVD); 13223 if (RHSVD->isInvalidDecl()) 13224 continue; 13225 if (!RHSVD->hasInit() && 13226 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13227 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13228 << Type << ReductionIdRange; 13229 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13230 VarDecl::DeclarationOnly; 13231 S.Diag(D->getLocation(), 13232 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13233 << D; 13234 continue; 13235 } 13236 // Store initializer for single element in private copy. Will be used during 13237 // codegen. 13238 PrivateVD->setInit(RHSVD->getInit()); 13239 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13240 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13241 ExprResult ReductionOp; 13242 if (DeclareReductionRef.isUsable()) { 13243 QualType RedTy = DeclareReductionRef.get()->getType(); 13244 QualType PtrRedTy = Context.getPointerType(RedTy); 13245 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13246 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13247 if (!BasePath.empty()) { 13248 LHS = S.DefaultLvalueConversion(LHS.get()); 13249 RHS = S.DefaultLvalueConversion(RHS.get()); 13250 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13251 CK_UncheckedDerivedToBase, LHS.get(), 13252 &BasePath, LHS.get()->getValueKind()); 13253 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13254 CK_UncheckedDerivedToBase, RHS.get(), 13255 &BasePath, RHS.get()->getValueKind()); 13256 } 13257 FunctionProtoType::ExtProtoInfo EPI; 13258 QualType Params[] = {PtrRedTy, PtrRedTy}; 13259 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13260 auto *OVE = new (Context) OpaqueValueExpr( 13261 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13262 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13263 Expr *Args[] = {LHS.get(), RHS.get()}; 13264 ReductionOp = 13265 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13266 } else { 13267 ReductionOp = S.BuildBinOp( 13268 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13269 if (ReductionOp.isUsable()) { 13270 if (BOK != BO_LT && BOK != BO_GT) { 13271 ReductionOp = 13272 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13273 BO_Assign, LHSDRE, ReductionOp.get()); 13274 } else { 13275 auto *ConditionalOp = new (Context) 13276 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13277 Type, VK_LValue, OK_Ordinary); 13278 ReductionOp = 13279 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13280 BO_Assign, LHSDRE, ConditionalOp); 13281 } 13282 if (ReductionOp.isUsable()) 13283 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13284 /*DiscardedValue*/ false); 13285 } 13286 if (!ReductionOp.isUsable()) 13287 continue; 13288 } 13289 13290 // OpenMP [2.15.4.6, Restrictions, p.2] 13291 // A list item that appears in an in_reduction clause of a task construct 13292 // must appear in a task_reduction clause of a construct associated with a 13293 // taskgroup region that includes the participating task in its taskgroup 13294 // set. The construct associated with the innermost region that meets this 13295 // condition must specify the same reduction-identifier as the in_reduction 13296 // clause. 13297 if (ClauseKind == OMPC_in_reduction) { 13298 SourceRange ParentSR; 13299 BinaryOperatorKind ParentBOK; 13300 const Expr *ParentReductionOp; 13301 Expr *ParentBOKTD, *ParentReductionOpTD; 13302 DSAStackTy::DSAVarData ParentBOKDSA = 13303 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13304 ParentBOKTD); 13305 DSAStackTy::DSAVarData ParentReductionOpDSA = 13306 Stack->getTopMostTaskgroupReductionData( 13307 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13308 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13309 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13310 if (!IsParentBOK && !IsParentReductionOp) { 13311 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13312 continue; 13313 } 13314 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13315 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13316 IsParentReductionOp) { 13317 bool EmitError = true; 13318 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13319 llvm::FoldingSetNodeID RedId, ParentRedId; 13320 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13321 DeclareReductionRef.get()->Profile(RedId, Context, 13322 /*Canonical=*/true); 13323 EmitError = RedId != ParentRedId; 13324 } 13325 if (EmitError) { 13326 S.Diag(ReductionId.getBeginLoc(), 13327 diag::err_omp_reduction_identifier_mismatch) 13328 << ReductionIdRange << RefExpr->getSourceRange(); 13329 S.Diag(ParentSR.getBegin(), 13330 diag::note_omp_previous_reduction_identifier) 13331 << ParentSR 13332 << (IsParentBOK ? ParentBOKDSA.RefExpr 13333 : ParentReductionOpDSA.RefExpr) 13334 ->getSourceRange(); 13335 continue; 13336 } 13337 } 13338 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13339 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13340 } 13341 13342 DeclRefExpr *Ref = nullptr; 13343 Expr *VarsExpr = RefExpr->IgnoreParens(); 13344 if (!VD && !S.CurContext->isDependentContext()) { 13345 if (ASE || OASE) { 13346 TransformExprToCaptures RebuildToCapture(S, D); 13347 VarsExpr = 13348 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13349 Ref = RebuildToCapture.getCapturedExpr(); 13350 } else { 13351 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13352 } 13353 if (!S.isOpenMPCapturedDecl(D)) { 13354 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13355 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13356 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13357 if (!RefRes.isUsable()) 13358 continue; 13359 ExprResult PostUpdateRes = 13360 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13361 RefRes.get()); 13362 if (!PostUpdateRes.isUsable()) 13363 continue; 13364 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13365 Stack->getCurrentDirective() == OMPD_taskgroup) { 13366 S.Diag(RefExpr->getExprLoc(), 13367 diag::err_omp_reduction_non_addressable_expression) 13368 << RefExpr->getSourceRange(); 13369 continue; 13370 } 13371 RD.ExprPostUpdates.emplace_back( 13372 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13373 } 13374 } 13375 } 13376 // All reduction items are still marked as reduction (to do not increase 13377 // code base size). 13378 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13379 if (CurrDir == OMPD_taskgroup) { 13380 if (DeclareReductionRef.isUsable()) 13381 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13382 DeclareReductionRef.get()); 13383 else 13384 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13385 } 13386 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13387 TaskgroupDescriptor); 13388 } 13389 return RD.Vars.empty(); 13390 } 13391 13392 OMPClause *Sema::ActOnOpenMPReductionClause( 13393 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13394 SourceLocation ColonLoc, SourceLocation EndLoc, 13395 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13396 ArrayRef<Expr *> UnresolvedReductions) { 13397 ReductionData RD(VarList.size()); 13398 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13399 StartLoc, LParenLoc, ColonLoc, EndLoc, 13400 ReductionIdScopeSpec, ReductionId, 13401 UnresolvedReductions, RD)) 13402 return nullptr; 13403 13404 return OMPReductionClause::Create( 13405 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13406 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13407 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13408 buildPreInits(Context, RD.ExprCaptures), 13409 buildPostUpdate(*this, RD.ExprPostUpdates)); 13410 } 13411 13412 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13413 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13414 SourceLocation ColonLoc, SourceLocation EndLoc, 13415 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13416 ArrayRef<Expr *> UnresolvedReductions) { 13417 ReductionData RD(VarList.size()); 13418 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13419 StartLoc, LParenLoc, ColonLoc, EndLoc, 13420 ReductionIdScopeSpec, ReductionId, 13421 UnresolvedReductions, RD)) 13422 return nullptr; 13423 13424 return OMPTaskReductionClause::Create( 13425 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13426 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13427 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13428 buildPreInits(Context, RD.ExprCaptures), 13429 buildPostUpdate(*this, RD.ExprPostUpdates)); 13430 } 13431 13432 OMPClause *Sema::ActOnOpenMPInReductionClause( 13433 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13434 SourceLocation ColonLoc, SourceLocation EndLoc, 13435 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13436 ArrayRef<Expr *> UnresolvedReductions) { 13437 ReductionData RD(VarList.size()); 13438 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13439 StartLoc, LParenLoc, ColonLoc, EndLoc, 13440 ReductionIdScopeSpec, ReductionId, 13441 UnresolvedReductions, RD)) 13442 return nullptr; 13443 13444 return OMPInReductionClause::Create( 13445 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13446 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13447 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13448 buildPreInits(Context, RD.ExprCaptures), 13449 buildPostUpdate(*this, RD.ExprPostUpdates)); 13450 } 13451 13452 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13453 SourceLocation LinLoc) { 13454 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13455 LinKind == OMPC_LINEAR_unknown) { 13456 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13457 return true; 13458 } 13459 return false; 13460 } 13461 13462 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13463 OpenMPLinearClauseKind LinKind, 13464 QualType Type) { 13465 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13466 // A variable must not have an incomplete type or a reference type. 13467 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13468 return true; 13469 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13470 !Type->isReferenceType()) { 13471 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13472 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13473 return true; 13474 } 13475 Type = Type.getNonReferenceType(); 13476 13477 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13478 // A variable that is privatized must not have a const-qualified type 13479 // unless it is of class type with a mutable member. This restriction does 13480 // not apply to the firstprivate clause. 13481 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13482 return true; 13483 13484 // A list item must be of integral or pointer type. 13485 Type = Type.getUnqualifiedType().getCanonicalType(); 13486 const auto *Ty = Type.getTypePtrOrNull(); 13487 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13488 !Ty->isPointerType())) { 13489 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13490 if (D) { 13491 bool IsDecl = 13492 !VD || 13493 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13494 Diag(D->getLocation(), 13495 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13496 << D; 13497 } 13498 return true; 13499 } 13500 return false; 13501 } 13502 13503 OMPClause *Sema::ActOnOpenMPLinearClause( 13504 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13505 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13506 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13507 SmallVector<Expr *, 8> Vars; 13508 SmallVector<Expr *, 8> Privates; 13509 SmallVector<Expr *, 8> Inits; 13510 SmallVector<Decl *, 4> ExprCaptures; 13511 SmallVector<Expr *, 4> ExprPostUpdates; 13512 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13513 LinKind = OMPC_LINEAR_val; 13514 for (Expr *RefExpr : VarList) { 13515 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13516 SourceLocation ELoc; 13517 SourceRange ERange; 13518 Expr *SimpleRefExpr = RefExpr; 13519 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13520 if (Res.second) { 13521 // It will be analyzed later. 13522 Vars.push_back(RefExpr); 13523 Privates.push_back(nullptr); 13524 Inits.push_back(nullptr); 13525 } 13526 ValueDecl *D = Res.first; 13527 if (!D) 13528 continue; 13529 13530 QualType Type = D->getType(); 13531 auto *VD = dyn_cast<VarDecl>(D); 13532 13533 // OpenMP [2.14.3.7, linear clause] 13534 // A list-item cannot appear in more than one linear clause. 13535 // A list-item that appears in a linear clause cannot appear in any 13536 // other data-sharing attribute clause. 13537 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13538 if (DVar.RefExpr) { 13539 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13540 << getOpenMPClauseName(OMPC_linear); 13541 reportOriginalDsa(*this, DSAStack, D, DVar); 13542 continue; 13543 } 13544 13545 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13546 continue; 13547 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13548 13549 // Build private copy of original var. 13550 VarDecl *Private = 13551 buildVarDecl(*this, ELoc, Type, D->getName(), 13552 D->hasAttrs() ? &D->getAttrs() : nullptr, 13553 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13554 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13555 // Build var to save initial value. 13556 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13557 Expr *InitExpr; 13558 DeclRefExpr *Ref = nullptr; 13559 if (!VD && !CurContext->isDependentContext()) { 13560 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13561 if (!isOpenMPCapturedDecl(D)) { 13562 ExprCaptures.push_back(Ref->getDecl()); 13563 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13564 ExprResult RefRes = DefaultLvalueConversion(Ref); 13565 if (!RefRes.isUsable()) 13566 continue; 13567 ExprResult PostUpdateRes = 13568 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13569 SimpleRefExpr, RefRes.get()); 13570 if (!PostUpdateRes.isUsable()) 13571 continue; 13572 ExprPostUpdates.push_back( 13573 IgnoredValueConversions(PostUpdateRes.get()).get()); 13574 } 13575 } 13576 } 13577 if (LinKind == OMPC_LINEAR_uval) 13578 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13579 else 13580 InitExpr = VD ? SimpleRefExpr : Ref; 13581 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13582 /*DirectInit=*/false); 13583 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13584 13585 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13586 Vars.push_back((VD || CurContext->isDependentContext()) 13587 ? RefExpr->IgnoreParens() 13588 : Ref); 13589 Privates.push_back(PrivateRef); 13590 Inits.push_back(InitRef); 13591 } 13592 13593 if (Vars.empty()) 13594 return nullptr; 13595 13596 Expr *StepExpr = Step; 13597 Expr *CalcStepExpr = nullptr; 13598 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13599 !Step->isInstantiationDependent() && 13600 !Step->containsUnexpandedParameterPack()) { 13601 SourceLocation StepLoc = Step->getBeginLoc(); 13602 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13603 if (Val.isInvalid()) 13604 return nullptr; 13605 StepExpr = Val.get(); 13606 13607 // Build var to save the step value. 13608 VarDecl *SaveVar = 13609 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13610 ExprResult SaveRef = 13611 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13612 ExprResult CalcStep = 13613 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13614 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13615 13616 // Warn about zero linear step (it would be probably better specified as 13617 // making corresponding variables 'const'). 13618 llvm::APSInt Result; 13619 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13620 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13621 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13622 << (Vars.size() > 1); 13623 if (!IsConstant && CalcStep.isUsable()) { 13624 // Calculate the step beforehand instead of doing this on each iteration. 13625 // (This is not used if the number of iterations may be kfold-ed). 13626 CalcStepExpr = CalcStep.get(); 13627 } 13628 } 13629 13630 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13631 ColonLoc, EndLoc, Vars, Privates, Inits, 13632 StepExpr, CalcStepExpr, 13633 buildPreInits(Context, ExprCaptures), 13634 buildPostUpdate(*this, ExprPostUpdates)); 13635 } 13636 13637 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13638 Expr *NumIterations, Sema &SemaRef, 13639 Scope *S, DSAStackTy *Stack) { 13640 // Walk the vars and build update/final expressions for the CodeGen. 13641 SmallVector<Expr *, 8> Updates; 13642 SmallVector<Expr *, 8> Finals; 13643 SmallVector<Expr *, 8> UsedExprs; 13644 Expr *Step = Clause.getStep(); 13645 Expr *CalcStep = Clause.getCalcStep(); 13646 // OpenMP [2.14.3.7, linear clause] 13647 // If linear-step is not specified it is assumed to be 1. 13648 if (!Step) 13649 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13650 else if (CalcStep) 13651 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13652 bool HasErrors = false; 13653 auto CurInit = Clause.inits().begin(); 13654 auto CurPrivate = Clause.privates().begin(); 13655 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13656 for (Expr *RefExpr : Clause.varlists()) { 13657 SourceLocation ELoc; 13658 SourceRange ERange; 13659 Expr *SimpleRefExpr = RefExpr; 13660 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13661 ValueDecl *D = Res.first; 13662 if (Res.second || !D) { 13663 Updates.push_back(nullptr); 13664 Finals.push_back(nullptr); 13665 HasErrors = true; 13666 continue; 13667 } 13668 auto &&Info = Stack->isLoopControlVariable(D); 13669 // OpenMP [2.15.11, distribute simd Construct] 13670 // A list item may not appear in a linear clause, unless it is the loop 13671 // iteration variable. 13672 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13673 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13674 SemaRef.Diag(ELoc, 13675 diag::err_omp_linear_distribute_var_non_loop_iteration); 13676 Updates.push_back(nullptr); 13677 Finals.push_back(nullptr); 13678 HasErrors = true; 13679 continue; 13680 } 13681 Expr *InitExpr = *CurInit; 13682 13683 // Build privatized reference to the current linear var. 13684 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13685 Expr *CapturedRef; 13686 if (LinKind == OMPC_LINEAR_uval) 13687 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13688 else 13689 CapturedRef = 13690 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13691 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13692 /*RefersToCapture=*/true); 13693 13694 // Build update: Var = InitExpr + IV * Step 13695 ExprResult Update; 13696 if (!Info.first) 13697 Update = buildCounterUpdate( 13698 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13699 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13700 else 13701 Update = *CurPrivate; 13702 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13703 /*DiscardedValue*/ false); 13704 13705 // Build final: Var = InitExpr + NumIterations * Step 13706 ExprResult Final; 13707 if (!Info.first) 13708 Final = 13709 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 13710 InitExpr, NumIterations, Step, /*Subtract=*/false, 13711 /*IsNonRectangularLB=*/false); 13712 else 13713 Final = *CurPrivate; 13714 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 13715 /*DiscardedValue*/ false); 13716 13717 if (!Update.isUsable() || !Final.isUsable()) { 13718 Updates.push_back(nullptr); 13719 Finals.push_back(nullptr); 13720 UsedExprs.push_back(nullptr); 13721 HasErrors = true; 13722 } else { 13723 Updates.push_back(Update.get()); 13724 Finals.push_back(Final.get()); 13725 if (!Info.first) 13726 UsedExprs.push_back(SimpleRefExpr); 13727 } 13728 ++CurInit; 13729 ++CurPrivate; 13730 } 13731 if (Expr *S = Clause.getStep()) 13732 UsedExprs.push_back(S); 13733 // Fill the remaining part with the nullptr. 13734 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 13735 Clause.setUpdates(Updates); 13736 Clause.setFinals(Finals); 13737 Clause.setUsedExprs(UsedExprs); 13738 return HasErrors; 13739 } 13740 13741 OMPClause *Sema::ActOnOpenMPAlignedClause( 13742 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 13743 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13744 SmallVector<Expr *, 8> Vars; 13745 for (Expr *RefExpr : VarList) { 13746 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13747 SourceLocation ELoc; 13748 SourceRange ERange; 13749 Expr *SimpleRefExpr = RefExpr; 13750 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13751 if (Res.second) { 13752 // It will be analyzed later. 13753 Vars.push_back(RefExpr); 13754 } 13755 ValueDecl *D = Res.first; 13756 if (!D) 13757 continue; 13758 13759 QualType QType = D->getType(); 13760 auto *VD = dyn_cast<VarDecl>(D); 13761 13762 // OpenMP [2.8.1, simd construct, Restrictions] 13763 // The type of list items appearing in the aligned clause must be 13764 // array, pointer, reference to array, or reference to pointer. 13765 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13766 const Type *Ty = QType.getTypePtrOrNull(); 13767 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 13768 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 13769 << QType << getLangOpts().CPlusPlus << ERange; 13770 bool IsDecl = 13771 !VD || 13772 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13773 Diag(D->getLocation(), 13774 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13775 << D; 13776 continue; 13777 } 13778 13779 // OpenMP [2.8.1, simd construct, Restrictions] 13780 // A list-item cannot appear in more than one aligned clause. 13781 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 13782 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 13783 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 13784 << getOpenMPClauseName(OMPC_aligned); 13785 continue; 13786 } 13787 13788 DeclRefExpr *Ref = nullptr; 13789 if (!VD && isOpenMPCapturedDecl(D)) 13790 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13791 Vars.push_back(DefaultFunctionArrayConversion( 13792 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 13793 .get()); 13794 } 13795 13796 // OpenMP [2.8.1, simd construct, Description] 13797 // The parameter of the aligned clause, alignment, must be a constant 13798 // positive integer expression. 13799 // If no optional parameter is specified, implementation-defined default 13800 // alignments for SIMD instructions on the target platforms are assumed. 13801 if (Alignment != nullptr) { 13802 ExprResult AlignResult = 13803 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 13804 if (AlignResult.isInvalid()) 13805 return nullptr; 13806 Alignment = AlignResult.get(); 13807 } 13808 if (Vars.empty()) 13809 return nullptr; 13810 13811 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 13812 EndLoc, Vars, Alignment); 13813 } 13814 13815 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 13816 SourceLocation StartLoc, 13817 SourceLocation LParenLoc, 13818 SourceLocation EndLoc) { 13819 SmallVector<Expr *, 8> Vars; 13820 SmallVector<Expr *, 8> SrcExprs; 13821 SmallVector<Expr *, 8> DstExprs; 13822 SmallVector<Expr *, 8> AssignmentOps; 13823 for (Expr *RefExpr : VarList) { 13824 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 13825 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 13826 // It will be analyzed later. 13827 Vars.push_back(RefExpr); 13828 SrcExprs.push_back(nullptr); 13829 DstExprs.push_back(nullptr); 13830 AssignmentOps.push_back(nullptr); 13831 continue; 13832 } 13833 13834 SourceLocation ELoc = RefExpr->getExprLoc(); 13835 // OpenMP [2.1, C/C++] 13836 // A list item is a variable name. 13837 // OpenMP [2.14.4.1, Restrictions, p.1] 13838 // A list item that appears in a copyin clause must be threadprivate. 13839 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 13840 if (!DE || !isa<VarDecl>(DE->getDecl())) { 13841 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 13842 << 0 << RefExpr->getSourceRange(); 13843 continue; 13844 } 13845 13846 Decl *D = DE->getDecl(); 13847 auto *VD = cast<VarDecl>(D); 13848 13849 QualType Type = VD->getType(); 13850 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 13851 // It will be analyzed later. 13852 Vars.push_back(DE); 13853 SrcExprs.push_back(nullptr); 13854 DstExprs.push_back(nullptr); 13855 AssignmentOps.push_back(nullptr); 13856 continue; 13857 } 13858 13859 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 13860 // A list item that appears in a copyin clause must be threadprivate. 13861 if (!DSAStack->isThreadPrivate(VD)) { 13862 Diag(ELoc, diag::err_omp_required_access) 13863 << getOpenMPClauseName(OMPC_copyin) 13864 << getOpenMPDirectiveName(OMPD_threadprivate); 13865 continue; 13866 } 13867 13868 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13869 // A variable of class type (or array thereof) that appears in a 13870 // copyin clause requires an accessible, unambiguous copy assignment 13871 // operator for the class type. 13872 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13873 VarDecl *SrcVD = 13874 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 13875 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13876 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 13877 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 13878 VarDecl *DstVD = 13879 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 13880 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 13881 DeclRefExpr *PseudoDstExpr = 13882 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 13883 // For arrays generate assignment operation for single element and replace 13884 // it by the original array element in CodeGen. 13885 ExprResult AssignmentOp = 13886 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 13887 PseudoSrcExpr); 13888 if (AssignmentOp.isInvalid()) 13889 continue; 13890 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 13891 /*DiscardedValue*/ false); 13892 if (AssignmentOp.isInvalid()) 13893 continue; 13894 13895 DSAStack->addDSA(VD, DE, OMPC_copyin); 13896 Vars.push_back(DE); 13897 SrcExprs.push_back(PseudoSrcExpr); 13898 DstExprs.push_back(PseudoDstExpr); 13899 AssignmentOps.push_back(AssignmentOp.get()); 13900 } 13901 13902 if (Vars.empty()) 13903 return nullptr; 13904 13905 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13906 SrcExprs, DstExprs, AssignmentOps); 13907 } 13908 13909 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 13910 SourceLocation StartLoc, 13911 SourceLocation LParenLoc, 13912 SourceLocation EndLoc) { 13913 SmallVector<Expr *, 8> Vars; 13914 SmallVector<Expr *, 8> SrcExprs; 13915 SmallVector<Expr *, 8> DstExprs; 13916 SmallVector<Expr *, 8> AssignmentOps; 13917 for (Expr *RefExpr : VarList) { 13918 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13919 SourceLocation ELoc; 13920 SourceRange ERange; 13921 Expr *SimpleRefExpr = RefExpr; 13922 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13923 if (Res.second) { 13924 // It will be analyzed later. 13925 Vars.push_back(RefExpr); 13926 SrcExprs.push_back(nullptr); 13927 DstExprs.push_back(nullptr); 13928 AssignmentOps.push_back(nullptr); 13929 } 13930 ValueDecl *D = Res.first; 13931 if (!D) 13932 continue; 13933 13934 QualType Type = D->getType(); 13935 auto *VD = dyn_cast<VarDecl>(D); 13936 13937 // OpenMP [2.14.4.2, Restrictions, p.2] 13938 // A list item that appears in a copyprivate clause may not appear in a 13939 // private or firstprivate clause on the single construct. 13940 if (!VD || !DSAStack->isThreadPrivate(VD)) { 13941 DSAStackTy::DSAVarData DVar = 13942 DSAStack->getTopDSA(D, /*FromParent=*/false); 13943 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 13944 DVar.RefExpr) { 13945 Diag(ELoc, diag::err_omp_wrong_dsa) 13946 << getOpenMPClauseName(DVar.CKind) 13947 << getOpenMPClauseName(OMPC_copyprivate); 13948 reportOriginalDsa(*this, DSAStack, D, DVar); 13949 continue; 13950 } 13951 13952 // OpenMP [2.11.4.2, Restrictions, p.1] 13953 // All list items that appear in a copyprivate clause must be either 13954 // threadprivate or private in the enclosing context. 13955 if (DVar.CKind == OMPC_unknown) { 13956 DVar = DSAStack->getImplicitDSA(D, false); 13957 if (DVar.CKind == OMPC_shared) { 13958 Diag(ELoc, diag::err_omp_required_access) 13959 << getOpenMPClauseName(OMPC_copyprivate) 13960 << "threadprivate or private in the enclosing context"; 13961 reportOriginalDsa(*this, DSAStack, D, DVar); 13962 continue; 13963 } 13964 } 13965 } 13966 13967 // Variably modified types are not supported. 13968 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 13969 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13970 << getOpenMPClauseName(OMPC_copyprivate) << Type 13971 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13972 bool IsDecl = 13973 !VD || 13974 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13975 Diag(D->getLocation(), 13976 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13977 << D; 13978 continue; 13979 } 13980 13981 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 13982 // A variable of class type (or array thereof) that appears in a 13983 // copyin clause requires an accessible, unambiguous copy assignment 13984 // operator for the class type. 13985 Type = Context.getBaseElementType(Type.getNonReferenceType()) 13986 .getUnqualifiedType(); 13987 VarDecl *SrcVD = 13988 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 13989 D->hasAttrs() ? &D->getAttrs() : nullptr); 13990 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 13991 VarDecl *DstVD = 13992 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 13993 D->hasAttrs() ? &D->getAttrs() : nullptr); 13994 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13995 ExprResult AssignmentOp = BuildBinOp( 13996 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 13997 if (AssignmentOp.isInvalid()) 13998 continue; 13999 AssignmentOp = 14000 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14001 if (AssignmentOp.isInvalid()) 14002 continue; 14003 14004 // No need to mark vars as copyprivate, they are already threadprivate or 14005 // implicitly private. 14006 assert(VD || isOpenMPCapturedDecl(D)); 14007 Vars.push_back( 14008 VD ? RefExpr->IgnoreParens() 14009 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14010 SrcExprs.push_back(PseudoSrcExpr); 14011 DstExprs.push_back(PseudoDstExpr); 14012 AssignmentOps.push_back(AssignmentOp.get()); 14013 } 14014 14015 if (Vars.empty()) 14016 return nullptr; 14017 14018 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14019 Vars, SrcExprs, DstExprs, AssignmentOps); 14020 } 14021 14022 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14023 SourceLocation StartLoc, 14024 SourceLocation LParenLoc, 14025 SourceLocation EndLoc) { 14026 if (VarList.empty()) 14027 return nullptr; 14028 14029 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14030 } 14031 14032 OMPClause * 14033 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14034 SourceLocation DepLoc, SourceLocation ColonLoc, 14035 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14036 SourceLocation LParenLoc, SourceLocation EndLoc) { 14037 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14038 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14039 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14040 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14041 return nullptr; 14042 } 14043 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14044 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14045 DepKind == OMPC_DEPEND_sink)) { 14046 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14047 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14048 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14049 /*Last=*/OMPC_DEPEND_unknown, Except) 14050 << getOpenMPClauseName(OMPC_depend); 14051 return nullptr; 14052 } 14053 SmallVector<Expr *, 8> Vars; 14054 DSAStackTy::OperatorOffsetTy OpsOffs; 14055 llvm::APSInt DepCounter(/*BitWidth=*/32); 14056 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14057 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14058 if (const Expr *OrderedCountExpr = 14059 DSAStack->getParentOrderedRegionParam().first) { 14060 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14061 TotalDepCount.setIsUnsigned(/*Val=*/true); 14062 } 14063 } 14064 for (Expr *RefExpr : VarList) { 14065 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14066 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14067 // It will be analyzed later. 14068 Vars.push_back(RefExpr); 14069 continue; 14070 } 14071 14072 SourceLocation ELoc = RefExpr->getExprLoc(); 14073 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14074 if (DepKind == OMPC_DEPEND_sink) { 14075 if (DSAStack->getParentOrderedRegionParam().first && 14076 DepCounter >= TotalDepCount) { 14077 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14078 continue; 14079 } 14080 ++DepCounter; 14081 // OpenMP [2.13.9, Summary] 14082 // depend(dependence-type : vec), where dependence-type is: 14083 // 'sink' and where vec is the iteration vector, which has the form: 14084 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14085 // where n is the value specified by the ordered clause in the loop 14086 // directive, xi denotes the loop iteration variable of the i-th nested 14087 // loop associated with the loop directive, and di is a constant 14088 // non-negative integer. 14089 if (CurContext->isDependentContext()) { 14090 // It will be analyzed later. 14091 Vars.push_back(RefExpr); 14092 continue; 14093 } 14094 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14095 OverloadedOperatorKind OOK = OO_None; 14096 SourceLocation OOLoc; 14097 Expr *LHS = SimpleExpr; 14098 Expr *RHS = nullptr; 14099 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14100 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14101 OOLoc = BO->getOperatorLoc(); 14102 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14103 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14104 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14105 OOK = OCE->getOperator(); 14106 OOLoc = OCE->getOperatorLoc(); 14107 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14108 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14109 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14110 OOK = MCE->getMethodDecl() 14111 ->getNameInfo() 14112 .getName() 14113 .getCXXOverloadedOperator(); 14114 OOLoc = MCE->getCallee()->getExprLoc(); 14115 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14116 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14117 } 14118 SourceLocation ELoc; 14119 SourceRange ERange; 14120 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14121 if (Res.second) { 14122 // It will be analyzed later. 14123 Vars.push_back(RefExpr); 14124 } 14125 ValueDecl *D = Res.first; 14126 if (!D) 14127 continue; 14128 14129 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14130 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14131 continue; 14132 } 14133 if (RHS) { 14134 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14135 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14136 if (RHSRes.isInvalid()) 14137 continue; 14138 } 14139 if (!CurContext->isDependentContext() && 14140 DSAStack->getParentOrderedRegionParam().first && 14141 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14142 const ValueDecl *VD = 14143 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14144 if (VD) 14145 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14146 << 1 << VD; 14147 else 14148 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14149 continue; 14150 } 14151 OpsOffs.emplace_back(RHS, OOK); 14152 } else { 14153 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14154 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14155 (ASE && 14156 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14157 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14158 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14159 << RefExpr->getSourceRange(); 14160 continue; 14161 } 14162 14163 ExprResult Res; 14164 { 14165 Sema::TentativeAnalysisScope Trap(*this); 14166 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14167 RefExpr->IgnoreParenImpCasts()); 14168 } 14169 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14170 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14171 << RefExpr->getSourceRange(); 14172 continue; 14173 } 14174 } 14175 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14176 } 14177 14178 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14179 TotalDepCount > VarList.size() && 14180 DSAStack->getParentOrderedRegionParam().first && 14181 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14182 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14183 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14184 } 14185 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14186 Vars.empty()) 14187 return nullptr; 14188 14189 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14190 DepKind, DepLoc, ColonLoc, Vars, 14191 TotalDepCount.getZExtValue()); 14192 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14193 DSAStack->isParentOrderedRegion()) 14194 DSAStack->addDoacrossDependClause(C, OpsOffs); 14195 return C; 14196 } 14197 14198 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14199 SourceLocation LParenLoc, 14200 SourceLocation EndLoc) { 14201 Expr *ValExpr = Device; 14202 Stmt *HelperValStmt = nullptr; 14203 14204 // OpenMP [2.9.1, Restrictions] 14205 // The device expression must evaluate to a non-negative integer value. 14206 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14207 /*StrictlyPositive=*/false)) 14208 return nullptr; 14209 14210 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14211 OpenMPDirectiveKind CaptureRegion = 14212 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14213 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14214 ValExpr = MakeFullExpr(ValExpr).get(); 14215 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14216 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14217 HelperValStmt = buildPreInits(Context, Captures); 14218 } 14219 14220 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14221 StartLoc, LParenLoc, EndLoc); 14222 } 14223 14224 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14225 DSAStackTy *Stack, QualType QTy, 14226 bool FullCheck = true) { 14227 NamedDecl *ND; 14228 if (QTy->isIncompleteType(&ND)) { 14229 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14230 return false; 14231 } 14232 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14233 !QTy.isTrivialType(SemaRef.Context)) 14234 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14235 return true; 14236 } 14237 14238 /// Return true if it can be proven that the provided array expression 14239 /// (array section or array subscript) does NOT specify the whole size of the 14240 /// array whose base type is \a BaseQTy. 14241 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14242 const Expr *E, 14243 QualType BaseQTy) { 14244 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14245 14246 // If this is an array subscript, it refers to the whole size if the size of 14247 // the dimension is constant and equals 1. Also, an array section assumes the 14248 // format of an array subscript if no colon is used. 14249 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14250 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14251 return ATy->getSize().getSExtValue() != 1; 14252 // Size can't be evaluated statically. 14253 return false; 14254 } 14255 14256 assert(OASE && "Expecting array section if not an array subscript."); 14257 const Expr *LowerBound = OASE->getLowerBound(); 14258 const Expr *Length = OASE->getLength(); 14259 14260 // If there is a lower bound that does not evaluates to zero, we are not 14261 // covering the whole dimension. 14262 if (LowerBound) { 14263 Expr::EvalResult Result; 14264 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14265 return false; // Can't get the integer value as a constant. 14266 14267 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14268 if (ConstLowerBound.getSExtValue()) 14269 return true; 14270 } 14271 14272 // If we don't have a length we covering the whole dimension. 14273 if (!Length) 14274 return false; 14275 14276 // If the base is a pointer, we don't have a way to get the size of the 14277 // pointee. 14278 if (BaseQTy->isPointerType()) 14279 return false; 14280 14281 // We can only check if the length is the same as the size of the dimension 14282 // if we have a constant array. 14283 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14284 if (!CATy) 14285 return false; 14286 14287 Expr::EvalResult Result; 14288 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14289 return false; // Can't get the integer value as a constant. 14290 14291 llvm::APSInt ConstLength = Result.Val.getInt(); 14292 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14293 } 14294 14295 // Return true if it can be proven that the provided array expression (array 14296 // section or array subscript) does NOT specify a single element of the array 14297 // whose base type is \a BaseQTy. 14298 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14299 const Expr *E, 14300 QualType BaseQTy) { 14301 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14302 14303 // An array subscript always refer to a single element. Also, an array section 14304 // assumes the format of an array subscript if no colon is used. 14305 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14306 return false; 14307 14308 assert(OASE && "Expecting array section if not an array subscript."); 14309 const Expr *Length = OASE->getLength(); 14310 14311 // If we don't have a length we have to check if the array has unitary size 14312 // for this dimension. Also, we should always expect a length if the base type 14313 // is pointer. 14314 if (!Length) { 14315 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14316 return ATy->getSize().getSExtValue() != 1; 14317 // We cannot assume anything. 14318 return false; 14319 } 14320 14321 // Check if the length evaluates to 1. 14322 Expr::EvalResult Result; 14323 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14324 return false; // Can't get the integer value as a constant. 14325 14326 llvm::APSInt ConstLength = Result.Val.getInt(); 14327 return ConstLength.getSExtValue() != 1; 14328 } 14329 14330 // Return the expression of the base of the mappable expression or null if it 14331 // cannot be determined and do all the necessary checks to see if the expression 14332 // is valid as a standalone mappable expression. In the process, record all the 14333 // components of the expression. 14334 static const Expr *checkMapClauseExpressionBase( 14335 Sema &SemaRef, Expr *E, 14336 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14337 OpenMPClauseKind CKind, bool NoDiagnose) { 14338 SourceLocation ELoc = E->getExprLoc(); 14339 SourceRange ERange = E->getSourceRange(); 14340 14341 // The base of elements of list in a map clause have to be either: 14342 // - a reference to variable or field. 14343 // - a member expression. 14344 // - an array expression. 14345 // 14346 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14347 // reference to 'r'. 14348 // 14349 // If we have: 14350 // 14351 // struct SS { 14352 // Bla S; 14353 // foo() { 14354 // #pragma omp target map (S.Arr[:12]); 14355 // } 14356 // } 14357 // 14358 // We want to retrieve the member expression 'this->S'; 14359 14360 const Expr *RelevantExpr = nullptr; 14361 14362 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14363 // If a list item is an array section, it must specify contiguous storage. 14364 // 14365 // For this restriction it is sufficient that we make sure only references 14366 // to variables or fields and array expressions, and that no array sections 14367 // exist except in the rightmost expression (unless they cover the whole 14368 // dimension of the array). E.g. these would be invalid: 14369 // 14370 // r.ArrS[3:5].Arr[6:7] 14371 // 14372 // r.ArrS[3:5].x 14373 // 14374 // but these would be valid: 14375 // r.ArrS[3].Arr[6:7] 14376 // 14377 // r.ArrS[3].x 14378 14379 bool AllowUnitySizeArraySection = true; 14380 bool AllowWholeSizeArraySection = true; 14381 14382 while (!RelevantExpr) { 14383 E = E->IgnoreParenImpCasts(); 14384 14385 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14386 if (!isa<VarDecl>(CurE->getDecl())) 14387 return nullptr; 14388 14389 RelevantExpr = CurE; 14390 14391 // If we got a reference to a declaration, we should not expect any array 14392 // section before that. 14393 AllowUnitySizeArraySection = false; 14394 AllowWholeSizeArraySection = false; 14395 14396 // Record the component. 14397 CurComponents.emplace_back(CurE, CurE->getDecl()); 14398 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14399 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14400 14401 if (isa<CXXThisExpr>(BaseE)) 14402 // We found a base expression: this->Val. 14403 RelevantExpr = CurE; 14404 else 14405 E = BaseE; 14406 14407 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14408 if (!NoDiagnose) { 14409 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14410 << CurE->getSourceRange(); 14411 return nullptr; 14412 } 14413 if (RelevantExpr) 14414 return nullptr; 14415 continue; 14416 } 14417 14418 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14419 14420 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14421 // A bit-field cannot appear in a map clause. 14422 // 14423 if (FD->isBitField()) { 14424 if (!NoDiagnose) { 14425 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14426 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14427 return nullptr; 14428 } 14429 if (RelevantExpr) 14430 return nullptr; 14431 continue; 14432 } 14433 14434 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14435 // If the type of a list item is a reference to a type T then the type 14436 // will be considered to be T for all purposes of this clause. 14437 QualType CurType = BaseE->getType().getNonReferenceType(); 14438 14439 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14440 // A list item cannot be a variable that is a member of a structure with 14441 // a union type. 14442 // 14443 if (CurType->isUnionType()) { 14444 if (!NoDiagnose) { 14445 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14446 << CurE->getSourceRange(); 14447 return nullptr; 14448 } 14449 continue; 14450 } 14451 14452 // If we got a member expression, we should not expect any array section 14453 // before that: 14454 // 14455 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14456 // If a list item is an element of a structure, only the rightmost symbol 14457 // of the variable reference can be an array section. 14458 // 14459 AllowUnitySizeArraySection = false; 14460 AllowWholeSizeArraySection = false; 14461 14462 // Record the component. 14463 CurComponents.emplace_back(CurE, FD); 14464 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14465 E = CurE->getBase()->IgnoreParenImpCasts(); 14466 14467 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14468 if (!NoDiagnose) { 14469 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14470 << 0 << CurE->getSourceRange(); 14471 return nullptr; 14472 } 14473 continue; 14474 } 14475 14476 // If we got an array subscript that express the whole dimension we 14477 // can have any array expressions before. If it only expressing part of 14478 // the dimension, we can only have unitary-size array expressions. 14479 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14480 E->getType())) 14481 AllowWholeSizeArraySection = false; 14482 14483 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14484 Expr::EvalResult Result; 14485 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14486 if (!Result.Val.getInt().isNullValue()) { 14487 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14488 diag::err_omp_invalid_map_this_expr); 14489 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14490 diag::note_omp_invalid_subscript_on_this_ptr_map); 14491 } 14492 } 14493 RelevantExpr = TE; 14494 } 14495 14496 // Record the component - we don't have any declaration associated. 14497 CurComponents.emplace_back(CurE, nullptr); 14498 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14499 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14500 E = CurE->getBase()->IgnoreParenImpCasts(); 14501 14502 QualType CurType = 14503 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14504 14505 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14506 // If the type of a list item is a reference to a type T then the type 14507 // will be considered to be T for all purposes of this clause. 14508 if (CurType->isReferenceType()) 14509 CurType = CurType->getPointeeType(); 14510 14511 bool IsPointer = CurType->isAnyPointerType(); 14512 14513 if (!IsPointer && !CurType->isArrayType()) { 14514 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14515 << 0 << CurE->getSourceRange(); 14516 return nullptr; 14517 } 14518 14519 bool NotWhole = 14520 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14521 bool NotUnity = 14522 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14523 14524 if (AllowWholeSizeArraySection) { 14525 // Any array section is currently allowed. Allowing a whole size array 14526 // section implies allowing a unity array section as well. 14527 // 14528 // If this array section refers to the whole dimension we can still 14529 // accept other array sections before this one, except if the base is a 14530 // pointer. Otherwise, only unitary sections are accepted. 14531 if (NotWhole || IsPointer) 14532 AllowWholeSizeArraySection = false; 14533 } else if (AllowUnitySizeArraySection && NotUnity) { 14534 // A unity or whole array section is not allowed and that is not 14535 // compatible with the properties of the current array section. 14536 SemaRef.Diag( 14537 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14538 << CurE->getSourceRange(); 14539 return nullptr; 14540 } 14541 14542 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14543 Expr::EvalResult ResultR; 14544 Expr::EvalResult ResultL; 14545 if (CurE->getLength()->EvaluateAsInt(ResultR, 14546 SemaRef.getASTContext())) { 14547 if (!ResultR.Val.getInt().isOneValue()) { 14548 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14549 diag::err_omp_invalid_map_this_expr); 14550 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14551 diag::note_omp_invalid_length_on_this_ptr_mapping); 14552 } 14553 } 14554 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14555 ResultL, SemaRef.getASTContext())) { 14556 if (!ResultL.Val.getInt().isNullValue()) { 14557 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14558 diag::err_omp_invalid_map_this_expr); 14559 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14560 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14561 } 14562 } 14563 RelevantExpr = TE; 14564 } 14565 14566 // Record the component - we don't have any declaration associated. 14567 CurComponents.emplace_back(CurE, nullptr); 14568 } else { 14569 if (!NoDiagnose) { 14570 // If nothing else worked, this is not a valid map clause expression. 14571 SemaRef.Diag( 14572 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14573 << ERange; 14574 } 14575 return nullptr; 14576 } 14577 } 14578 14579 return RelevantExpr; 14580 } 14581 14582 // Return true if expression E associated with value VD has conflicts with other 14583 // map information. 14584 static bool checkMapConflicts( 14585 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14586 bool CurrentRegionOnly, 14587 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14588 OpenMPClauseKind CKind) { 14589 assert(VD && E); 14590 SourceLocation ELoc = E->getExprLoc(); 14591 SourceRange ERange = E->getSourceRange(); 14592 14593 // In order to easily check the conflicts we need to match each component of 14594 // the expression under test with the components of the expressions that are 14595 // already in the stack. 14596 14597 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14598 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14599 "Map clause expression with unexpected base!"); 14600 14601 // Variables to help detecting enclosing problems in data environment nests. 14602 bool IsEnclosedByDataEnvironmentExpr = false; 14603 const Expr *EnclosingExpr = nullptr; 14604 14605 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14606 VD, CurrentRegionOnly, 14607 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14608 ERange, CKind, &EnclosingExpr, 14609 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14610 StackComponents, 14611 OpenMPClauseKind) { 14612 assert(!StackComponents.empty() && 14613 "Map clause expression with no components!"); 14614 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14615 "Map clause expression with unexpected base!"); 14616 (void)VD; 14617 14618 // The whole expression in the stack. 14619 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14620 14621 // Expressions must start from the same base. Here we detect at which 14622 // point both expressions diverge from each other and see if we can 14623 // detect if the memory referred to both expressions is contiguous and 14624 // do not overlap. 14625 auto CI = CurComponents.rbegin(); 14626 auto CE = CurComponents.rend(); 14627 auto SI = StackComponents.rbegin(); 14628 auto SE = StackComponents.rend(); 14629 for (; CI != CE && SI != SE; ++CI, ++SI) { 14630 14631 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14632 // At most one list item can be an array item derived from a given 14633 // variable in map clauses of the same construct. 14634 if (CurrentRegionOnly && 14635 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14636 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14637 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14638 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14639 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14640 diag::err_omp_multiple_array_items_in_map_clause) 14641 << CI->getAssociatedExpression()->getSourceRange(); 14642 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14643 diag::note_used_here) 14644 << SI->getAssociatedExpression()->getSourceRange(); 14645 return true; 14646 } 14647 14648 // Do both expressions have the same kind? 14649 if (CI->getAssociatedExpression()->getStmtClass() != 14650 SI->getAssociatedExpression()->getStmtClass()) 14651 break; 14652 14653 // Are we dealing with different variables/fields? 14654 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14655 break; 14656 } 14657 // Check if the extra components of the expressions in the enclosing 14658 // data environment are redundant for the current base declaration. 14659 // If they are, the maps completely overlap, which is legal. 14660 for (; SI != SE; ++SI) { 14661 QualType Type; 14662 if (const auto *ASE = 14663 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14664 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14665 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14666 SI->getAssociatedExpression())) { 14667 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14668 Type = 14669 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14670 } 14671 if (Type.isNull() || Type->isAnyPointerType() || 14672 checkArrayExpressionDoesNotReferToWholeSize( 14673 SemaRef, SI->getAssociatedExpression(), Type)) 14674 break; 14675 } 14676 14677 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14678 // List items of map clauses in the same construct must not share 14679 // original storage. 14680 // 14681 // If the expressions are exactly the same or one is a subset of the 14682 // other, it means they are sharing storage. 14683 if (CI == CE && SI == SE) { 14684 if (CurrentRegionOnly) { 14685 if (CKind == OMPC_map) { 14686 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14687 } else { 14688 assert(CKind == OMPC_to || CKind == OMPC_from); 14689 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14690 << ERange; 14691 } 14692 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14693 << RE->getSourceRange(); 14694 return true; 14695 } 14696 // If we find the same expression in the enclosing data environment, 14697 // that is legal. 14698 IsEnclosedByDataEnvironmentExpr = true; 14699 return false; 14700 } 14701 14702 QualType DerivedType = 14703 std::prev(CI)->getAssociatedDeclaration()->getType(); 14704 SourceLocation DerivedLoc = 14705 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14706 14707 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14708 // If the type of a list item is a reference to a type T then the type 14709 // will be considered to be T for all purposes of this clause. 14710 DerivedType = DerivedType.getNonReferenceType(); 14711 14712 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 14713 // A variable for which the type is pointer and an array section 14714 // derived from that variable must not appear as list items of map 14715 // clauses of the same construct. 14716 // 14717 // Also, cover one of the cases in: 14718 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14719 // If any part of the original storage of a list item has corresponding 14720 // storage in the device data environment, all of the original storage 14721 // must have corresponding storage in the device data environment. 14722 // 14723 if (DerivedType->isAnyPointerType()) { 14724 if (CI == CE || SI == SE) { 14725 SemaRef.Diag( 14726 DerivedLoc, 14727 diag::err_omp_pointer_mapped_along_with_derived_section) 14728 << DerivedLoc; 14729 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14730 << RE->getSourceRange(); 14731 return true; 14732 } 14733 if (CI->getAssociatedExpression()->getStmtClass() != 14734 SI->getAssociatedExpression()->getStmtClass() || 14735 CI->getAssociatedDeclaration()->getCanonicalDecl() == 14736 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 14737 assert(CI != CE && SI != SE); 14738 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 14739 << DerivedLoc; 14740 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14741 << RE->getSourceRange(); 14742 return true; 14743 } 14744 } 14745 14746 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14747 // List items of map clauses in the same construct must not share 14748 // original storage. 14749 // 14750 // An expression is a subset of the other. 14751 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 14752 if (CKind == OMPC_map) { 14753 if (CI != CE || SI != SE) { 14754 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 14755 // a pointer. 14756 auto Begin = 14757 CI != CE ? CurComponents.begin() : StackComponents.begin(); 14758 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 14759 auto It = Begin; 14760 while (It != End && !It->getAssociatedDeclaration()) 14761 std::advance(It, 1); 14762 assert(It != End && 14763 "Expected at least one component with the declaration."); 14764 if (It != Begin && It->getAssociatedDeclaration() 14765 ->getType() 14766 .getCanonicalType() 14767 ->isAnyPointerType()) { 14768 IsEnclosedByDataEnvironmentExpr = false; 14769 EnclosingExpr = nullptr; 14770 return false; 14771 } 14772 } 14773 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14774 } else { 14775 assert(CKind == OMPC_to || CKind == OMPC_from); 14776 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14777 << ERange; 14778 } 14779 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14780 << RE->getSourceRange(); 14781 return true; 14782 } 14783 14784 // The current expression uses the same base as other expression in the 14785 // data environment but does not contain it completely. 14786 if (!CurrentRegionOnly && SI != SE) 14787 EnclosingExpr = RE; 14788 14789 // The current expression is a subset of the expression in the data 14790 // environment. 14791 IsEnclosedByDataEnvironmentExpr |= 14792 (!CurrentRegionOnly && CI != CE && SI == SE); 14793 14794 return false; 14795 }); 14796 14797 if (CurrentRegionOnly) 14798 return FoundError; 14799 14800 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 14801 // If any part of the original storage of a list item has corresponding 14802 // storage in the device data environment, all of the original storage must 14803 // have corresponding storage in the device data environment. 14804 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 14805 // If a list item is an element of a structure, and a different element of 14806 // the structure has a corresponding list item in the device data environment 14807 // prior to a task encountering the construct associated with the map clause, 14808 // then the list item must also have a corresponding list item in the device 14809 // data environment prior to the task encountering the construct. 14810 // 14811 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 14812 SemaRef.Diag(ELoc, 14813 diag::err_omp_original_storage_is_shared_and_does_not_contain) 14814 << ERange; 14815 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 14816 << EnclosingExpr->getSourceRange(); 14817 return true; 14818 } 14819 14820 return FoundError; 14821 } 14822 14823 // Look up the user-defined mapper given the mapper name and mapped type, and 14824 // build a reference to it. 14825 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 14826 CXXScopeSpec &MapperIdScopeSpec, 14827 const DeclarationNameInfo &MapperId, 14828 QualType Type, 14829 Expr *UnresolvedMapper) { 14830 if (MapperIdScopeSpec.isInvalid()) 14831 return ExprError(); 14832 // Get the actual type for the array type. 14833 if (Type->isArrayType()) { 14834 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 14835 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 14836 } 14837 // Find all user-defined mappers with the given MapperId. 14838 SmallVector<UnresolvedSet<8>, 4> Lookups; 14839 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 14840 Lookup.suppressDiagnostics(); 14841 if (S) { 14842 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 14843 NamedDecl *D = Lookup.getRepresentativeDecl(); 14844 while (S && !S->isDeclScope(D)) 14845 S = S->getParent(); 14846 if (S) 14847 S = S->getParent(); 14848 Lookups.emplace_back(); 14849 Lookups.back().append(Lookup.begin(), Lookup.end()); 14850 Lookup.clear(); 14851 } 14852 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 14853 // Extract the user-defined mappers with the given MapperId. 14854 Lookups.push_back(UnresolvedSet<8>()); 14855 for (NamedDecl *D : ULE->decls()) { 14856 auto *DMD = cast<OMPDeclareMapperDecl>(D); 14857 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 14858 Lookups.back().addDecl(DMD); 14859 } 14860 } 14861 // Defer the lookup for dependent types. The results will be passed through 14862 // UnresolvedMapper on instantiation. 14863 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 14864 Type->isInstantiationDependentType() || 14865 Type->containsUnexpandedParameterPack() || 14866 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14867 return !D->isInvalidDecl() && 14868 (D->getType()->isDependentType() || 14869 D->getType()->isInstantiationDependentType() || 14870 D->getType()->containsUnexpandedParameterPack()); 14871 })) { 14872 UnresolvedSet<8> URS; 14873 for (const UnresolvedSet<8> &Set : Lookups) { 14874 if (Set.empty()) 14875 continue; 14876 URS.append(Set.begin(), Set.end()); 14877 } 14878 return UnresolvedLookupExpr::Create( 14879 SemaRef.Context, /*NamingClass=*/nullptr, 14880 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 14881 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 14882 } 14883 SourceLocation Loc = MapperId.getLoc(); 14884 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14885 // The type must be of struct, union or class type in C and C++ 14886 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 14887 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 14888 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 14889 return ExprError(); 14890 } 14891 // Perform argument dependent lookup. 14892 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 14893 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 14894 // Return the first user-defined mapper with the desired type. 14895 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14896 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 14897 if (!D->isInvalidDecl() && 14898 SemaRef.Context.hasSameType(D->getType(), Type)) 14899 return D; 14900 return nullptr; 14901 })) 14902 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14903 // Find the first user-defined mapper with a type derived from the desired 14904 // type. 14905 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14906 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 14907 if (!D->isInvalidDecl() && 14908 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 14909 !Type.isMoreQualifiedThan(D->getType())) 14910 return D; 14911 return nullptr; 14912 })) { 14913 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14914 /*DetectVirtual=*/false); 14915 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 14916 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14917 VD->getType().getUnqualifiedType()))) { 14918 if (SemaRef.CheckBaseClassAccess( 14919 Loc, VD->getType(), Type, Paths.front(), 14920 /*DiagID=*/0) != Sema::AR_inaccessible) { 14921 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 14922 } 14923 } 14924 } 14925 } 14926 // Report error if a mapper is specified, but cannot be found. 14927 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 14928 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 14929 << Type << MapperId.getName(); 14930 return ExprError(); 14931 } 14932 return ExprEmpty(); 14933 } 14934 14935 namespace { 14936 // Utility struct that gathers all the related lists associated with a mappable 14937 // expression. 14938 struct MappableVarListInfo { 14939 // The list of expressions. 14940 ArrayRef<Expr *> VarList; 14941 // The list of processed expressions. 14942 SmallVector<Expr *, 16> ProcessedVarList; 14943 // The mappble components for each expression. 14944 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 14945 // The base declaration of the variable. 14946 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 14947 // The reference to the user-defined mapper associated with every expression. 14948 SmallVector<Expr *, 16> UDMapperList; 14949 14950 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 14951 // We have a list of components and base declarations for each entry in the 14952 // variable list. 14953 VarComponents.reserve(VarList.size()); 14954 VarBaseDeclarations.reserve(VarList.size()); 14955 } 14956 }; 14957 } 14958 14959 // Check the validity of the provided variable list for the provided clause kind 14960 // \a CKind. In the check process the valid expressions, mappable expression 14961 // components, variables, and user-defined mappers are extracted and used to 14962 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 14963 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 14964 // and \a MapperId are expected to be valid if the clause kind is 'map'. 14965 static void checkMappableExpressionList( 14966 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 14967 MappableVarListInfo &MVLI, SourceLocation StartLoc, 14968 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 14969 ArrayRef<Expr *> UnresolvedMappers, 14970 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 14971 bool IsMapTypeImplicit = false) { 14972 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 14973 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 14974 "Unexpected clause kind with mappable expressions!"); 14975 14976 // If the identifier of user-defined mapper is not specified, it is "default". 14977 // We do not change the actual name in this clause to distinguish whether a 14978 // mapper is specified explicitly, i.e., it is not explicitly specified when 14979 // MapperId.getName() is empty. 14980 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 14981 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 14982 MapperId.setName(DeclNames.getIdentifier( 14983 &SemaRef.getASTContext().Idents.get("default"))); 14984 } 14985 14986 // Iterators to find the current unresolved mapper expression. 14987 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 14988 bool UpdateUMIt = false; 14989 Expr *UnresolvedMapper = nullptr; 14990 14991 // Keep track of the mappable components and base declarations in this clause. 14992 // Each entry in the list is going to have a list of components associated. We 14993 // record each set of the components so that we can build the clause later on. 14994 // In the end we should have the same amount of declarations and component 14995 // lists. 14996 14997 for (Expr *RE : MVLI.VarList) { 14998 assert(RE && "Null expr in omp to/from/map clause"); 14999 SourceLocation ELoc = RE->getExprLoc(); 15000 15001 // Find the current unresolved mapper expression. 15002 if (UpdateUMIt && UMIt != UMEnd) { 15003 UMIt++; 15004 assert( 15005 UMIt != UMEnd && 15006 "Expect the size of UnresolvedMappers to match with that of VarList"); 15007 } 15008 UpdateUMIt = true; 15009 if (UMIt != UMEnd) 15010 UnresolvedMapper = *UMIt; 15011 15012 const Expr *VE = RE->IgnoreParenLValueCasts(); 15013 15014 if (VE->isValueDependent() || VE->isTypeDependent() || 15015 VE->isInstantiationDependent() || 15016 VE->containsUnexpandedParameterPack()) { 15017 // Try to find the associated user-defined mapper. 15018 ExprResult ER = buildUserDefinedMapperRef( 15019 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15020 VE->getType().getCanonicalType(), UnresolvedMapper); 15021 if (ER.isInvalid()) 15022 continue; 15023 MVLI.UDMapperList.push_back(ER.get()); 15024 // We can only analyze this information once the missing information is 15025 // resolved. 15026 MVLI.ProcessedVarList.push_back(RE); 15027 continue; 15028 } 15029 15030 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15031 15032 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15033 SemaRef.Diag(ELoc, 15034 diag::err_omp_expected_named_var_member_or_array_expression) 15035 << RE->getSourceRange(); 15036 continue; 15037 } 15038 15039 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15040 ValueDecl *CurDeclaration = nullptr; 15041 15042 // Obtain the array or member expression bases if required. Also, fill the 15043 // components array with all the components identified in the process. 15044 const Expr *BE = checkMapClauseExpressionBase( 15045 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15046 if (!BE) 15047 continue; 15048 15049 assert(!CurComponents.empty() && 15050 "Invalid mappable expression information."); 15051 15052 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15053 // Add store "this" pointer to class in DSAStackTy for future checking 15054 DSAS->addMappedClassesQualTypes(TE->getType()); 15055 // Try to find the associated user-defined mapper. 15056 ExprResult ER = buildUserDefinedMapperRef( 15057 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15058 VE->getType().getCanonicalType(), UnresolvedMapper); 15059 if (ER.isInvalid()) 15060 continue; 15061 MVLI.UDMapperList.push_back(ER.get()); 15062 // Skip restriction checking for variable or field declarations 15063 MVLI.ProcessedVarList.push_back(RE); 15064 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15065 MVLI.VarComponents.back().append(CurComponents.begin(), 15066 CurComponents.end()); 15067 MVLI.VarBaseDeclarations.push_back(nullptr); 15068 continue; 15069 } 15070 15071 // For the following checks, we rely on the base declaration which is 15072 // expected to be associated with the last component. The declaration is 15073 // expected to be a variable or a field (if 'this' is being mapped). 15074 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15075 assert(CurDeclaration && "Null decl on map clause."); 15076 assert( 15077 CurDeclaration->isCanonicalDecl() && 15078 "Expecting components to have associated only canonical declarations."); 15079 15080 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15081 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15082 15083 assert((VD || FD) && "Only variables or fields are expected here!"); 15084 (void)FD; 15085 15086 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15087 // threadprivate variables cannot appear in a map clause. 15088 // OpenMP 4.5 [2.10.5, target update Construct] 15089 // threadprivate variables cannot appear in a from clause. 15090 if (VD && DSAS->isThreadPrivate(VD)) { 15091 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15092 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15093 << getOpenMPClauseName(CKind); 15094 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15095 continue; 15096 } 15097 15098 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15099 // A list item cannot appear in both a map clause and a data-sharing 15100 // attribute clause on the same construct. 15101 15102 // Check conflicts with other map clause expressions. We check the conflicts 15103 // with the current construct separately from the enclosing data 15104 // environment, because the restrictions are different. We only have to 15105 // check conflicts across regions for the map clauses. 15106 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15107 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15108 break; 15109 if (CKind == OMPC_map && 15110 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15111 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15112 break; 15113 15114 // OpenMP 4.5 [2.10.5, target update Construct] 15115 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15116 // If the type of a list item is a reference to a type T then the type will 15117 // be considered to be T for all purposes of this clause. 15118 auto I = llvm::find_if( 15119 CurComponents, 15120 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15121 return MC.getAssociatedDeclaration(); 15122 }); 15123 assert(I != CurComponents.end() && "Null decl on map clause."); 15124 QualType Type = 15125 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15126 15127 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15128 // A list item in a to or from clause must have a mappable type. 15129 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15130 // A list item must have a mappable type. 15131 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15132 DSAS, Type)) 15133 continue; 15134 15135 if (CKind == OMPC_map) { 15136 // target enter data 15137 // OpenMP [2.10.2, Restrictions, p. 99] 15138 // A map-type must be specified in all map clauses and must be either 15139 // to or alloc. 15140 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15141 if (DKind == OMPD_target_enter_data && 15142 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15143 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15144 << (IsMapTypeImplicit ? 1 : 0) 15145 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15146 << getOpenMPDirectiveName(DKind); 15147 continue; 15148 } 15149 15150 // target exit_data 15151 // OpenMP [2.10.3, Restrictions, p. 102] 15152 // A map-type must be specified in all map clauses and must be either 15153 // from, release, or delete. 15154 if (DKind == OMPD_target_exit_data && 15155 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15156 MapType == OMPC_MAP_delete)) { 15157 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15158 << (IsMapTypeImplicit ? 1 : 0) 15159 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15160 << getOpenMPDirectiveName(DKind); 15161 continue; 15162 } 15163 15164 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15165 // A list item cannot appear in both a map clause and a data-sharing 15166 // attribute clause on the same construct 15167 // 15168 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15169 // A list item cannot appear in both a map clause and a data-sharing 15170 // attribute clause on the same construct unless the construct is a 15171 // combined construct. 15172 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15173 isOpenMPTargetExecutionDirective(DKind)) || 15174 DKind == OMPD_target)) { 15175 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15176 if (isOpenMPPrivate(DVar.CKind)) { 15177 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15178 << getOpenMPClauseName(DVar.CKind) 15179 << getOpenMPClauseName(OMPC_map) 15180 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15181 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15182 continue; 15183 } 15184 } 15185 } 15186 15187 // Try to find the associated user-defined mapper. 15188 ExprResult ER = buildUserDefinedMapperRef( 15189 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15190 Type.getCanonicalType(), UnresolvedMapper); 15191 if (ER.isInvalid()) 15192 continue; 15193 MVLI.UDMapperList.push_back(ER.get()); 15194 15195 // Save the current expression. 15196 MVLI.ProcessedVarList.push_back(RE); 15197 15198 // Store the components in the stack so that they can be used to check 15199 // against other clauses later on. 15200 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15201 /*WhereFoundClauseKind=*/OMPC_map); 15202 15203 // Save the components and declaration to create the clause. For purposes of 15204 // the clause creation, any component list that has has base 'this' uses 15205 // null as base declaration. 15206 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15207 MVLI.VarComponents.back().append(CurComponents.begin(), 15208 CurComponents.end()); 15209 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15210 : CurDeclaration); 15211 } 15212 } 15213 15214 OMPClause *Sema::ActOnOpenMPMapClause( 15215 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15216 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15217 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15218 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15219 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15220 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15221 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15222 OMPC_MAP_MODIFIER_unknown, 15223 OMPC_MAP_MODIFIER_unknown}; 15224 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15225 15226 // Process map-type-modifiers, flag errors for duplicate modifiers. 15227 unsigned Count = 0; 15228 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15229 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15230 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15231 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15232 continue; 15233 } 15234 assert(Count < OMPMapClause::NumberOfModifiers && 15235 "Modifiers exceed the allowed number of map type modifiers"); 15236 Modifiers[Count] = MapTypeModifiers[I]; 15237 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15238 ++Count; 15239 } 15240 15241 MappableVarListInfo MVLI(VarList); 15242 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15243 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15244 MapType, IsMapTypeImplicit); 15245 15246 // We need to produce a map clause even if we don't have variables so that 15247 // other diagnostics related with non-existing map clauses are accurate. 15248 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15249 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15250 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15251 MapperIdScopeSpec.getWithLocInContext(Context), 15252 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15253 } 15254 15255 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15256 TypeResult ParsedType) { 15257 assert(ParsedType.isUsable()); 15258 15259 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15260 if (ReductionType.isNull()) 15261 return QualType(); 15262 15263 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15264 // A type name in a declare reduction directive cannot be a function type, an 15265 // array type, a reference type, or a type qualified with const, volatile or 15266 // restrict. 15267 if (ReductionType.hasQualifiers()) { 15268 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15269 return QualType(); 15270 } 15271 15272 if (ReductionType->isFunctionType()) { 15273 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15274 return QualType(); 15275 } 15276 if (ReductionType->isReferenceType()) { 15277 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15278 return QualType(); 15279 } 15280 if (ReductionType->isArrayType()) { 15281 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15282 return QualType(); 15283 } 15284 return ReductionType; 15285 } 15286 15287 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15288 Scope *S, DeclContext *DC, DeclarationName Name, 15289 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15290 AccessSpecifier AS, Decl *PrevDeclInScope) { 15291 SmallVector<Decl *, 8> Decls; 15292 Decls.reserve(ReductionTypes.size()); 15293 15294 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15295 forRedeclarationInCurContext()); 15296 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15297 // A reduction-identifier may not be re-declared in the current scope for the 15298 // same type or for a type that is compatible according to the base language 15299 // rules. 15300 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15301 OMPDeclareReductionDecl *PrevDRD = nullptr; 15302 bool InCompoundScope = true; 15303 if (S != nullptr) { 15304 // Find previous declaration with the same name not referenced in other 15305 // declarations. 15306 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15307 InCompoundScope = 15308 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15309 LookupName(Lookup, S); 15310 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15311 /*AllowInlineNamespace=*/false); 15312 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15313 LookupResult::Filter Filter = Lookup.makeFilter(); 15314 while (Filter.hasNext()) { 15315 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15316 if (InCompoundScope) { 15317 auto I = UsedAsPrevious.find(PrevDecl); 15318 if (I == UsedAsPrevious.end()) 15319 UsedAsPrevious[PrevDecl] = false; 15320 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15321 UsedAsPrevious[D] = true; 15322 } 15323 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15324 PrevDecl->getLocation(); 15325 } 15326 Filter.done(); 15327 if (InCompoundScope) { 15328 for (const auto &PrevData : UsedAsPrevious) { 15329 if (!PrevData.second) { 15330 PrevDRD = PrevData.first; 15331 break; 15332 } 15333 } 15334 } 15335 } else if (PrevDeclInScope != nullptr) { 15336 auto *PrevDRDInScope = PrevDRD = 15337 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15338 do { 15339 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15340 PrevDRDInScope->getLocation(); 15341 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15342 } while (PrevDRDInScope != nullptr); 15343 } 15344 for (const auto &TyData : ReductionTypes) { 15345 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15346 bool Invalid = false; 15347 if (I != PreviousRedeclTypes.end()) { 15348 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15349 << TyData.first; 15350 Diag(I->second, diag::note_previous_definition); 15351 Invalid = true; 15352 } 15353 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15354 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15355 Name, TyData.first, PrevDRD); 15356 DC->addDecl(DRD); 15357 DRD->setAccess(AS); 15358 Decls.push_back(DRD); 15359 if (Invalid) 15360 DRD->setInvalidDecl(); 15361 else 15362 PrevDRD = DRD; 15363 } 15364 15365 return DeclGroupPtrTy::make( 15366 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15367 } 15368 15369 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15370 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15371 15372 // Enter new function scope. 15373 PushFunctionScope(); 15374 setFunctionHasBranchProtectedScope(); 15375 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15376 15377 if (S != nullptr) 15378 PushDeclContext(S, DRD); 15379 else 15380 CurContext = DRD; 15381 15382 PushExpressionEvaluationContext( 15383 ExpressionEvaluationContext::PotentiallyEvaluated); 15384 15385 QualType ReductionType = DRD->getType(); 15386 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15387 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15388 // uses semantics of argument handles by value, but it should be passed by 15389 // reference. C lang does not support references, so pass all parameters as 15390 // pointers. 15391 // Create 'T omp_in;' variable. 15392 VarDecl *OmpInParm = 15393 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15394 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15395 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15396 // uses semantics of argument handles by value, but it should be passed by 15397 // reference. C lang does not support references, so pass all parameters as 15398 // pointers. 15399 // Create 'T omp_out;' variable. 15400 VarDecl *OmpOutParm = 15401 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15402 if (S != nullptr) { 15403 PushOnScopeChains(OmpInParm, S); 15404 PushOnScopeChains(OmpOutParm, S); 15405 } else { 15406 DRD->addDecl(OmpInParm); 15407 DRD->addDecl(OmpOutParm); 15408 } 15409 Expr *InE = 15410 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15411 Expr *OutE = 15412 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15413 DRD->setCombinerData(InE, OutE); 15414 } 15415 15416 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15417 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15418 DiscardCleanupsInEvaluationContext(); 15419 PopExpressionEvaluationContext(); 15420 15421 PopDeclContext(); 15422 PopFunctionScopeInfo(); 15423 15424 if (Combiner != nullptr) 15425 DRD->setCombiner(Combiner); 15426 else 15427 DRD->setInvalidDecl(); 15428 } 15429 15430 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15431 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15432 15433 // Enter new function scope. 15434 PushFunctionScope(); 15435 setFunctionHasBranchProtectedScope(); 15436 15437 if (S != nullptr) 15438 PushDeclContext(S, DRD); 15439 else 15440 CurContext = DRD; 15441 15442 PushExpressionEvaluationContext( 15443 ExpressionEvaluationContext::PotentiallyEvaluated); 15444 15445 QualType ReductionType = DRD->getType(); 15446 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15447 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15448 // uses semantics of argument handles by value, but it should be passed by 15449 // reference. C lang does not support references, so pass all parameters as 15450 // pointers. 15451 // Create 'T omp_priv;' variable. 15452 VarDecl *OmpPrivParm = 15453 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15454 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15455 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15456 // uses semantics of argument handles by value, but it should be passed by 15457 // reference. C lang does not support references, so pass all parameters as 15458 // pointers. 15459 // Create 'T omp_orig;' variable. 15460 VarDecl *OmpOrigParm = 15461 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15462 if (S != nullptr) { 15463 PushOnScopeChains(OmpPrivParm, S); 15464 PushOnScopeChains(OmpOrigParm, S); 15465 } else { 15466 DRD->addDecl(OmpPrivParm); 15467 DRD->addDecl(OmpOrigParm); 15468 } 15469 Expr *OrigE = 15470 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15471 Expr *PrivE = 15472 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15473 DRD->setInitializerData(OrigE, PrivE); 15474 return OmpPrivParm; 15475 } 15476 15477 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15478 VarDecl *OmpPrivParm) { 15479 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15480 DiscardCleanupsInEvaluationContext(); 15481 PopExpressionEvaluationContext(); 15482 15483 PopDeclContext(); 15484 PopFunctionScopeInfo(); 15485 15486 if (Initializer != nullptr) { 15487 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15488 } else if (OmpPrivParm->hasInit()) { 15489 DRD->setInitializer(OmpPrivParm->getInit(), 15490 OmpPrivParm->isDirectInit() 15491 ? OMPDeclareReductionDecl::DirectInit 15492 : OMPDeclareReductionDecl::CopyInit); 15493 } else { 15494 DRD->setInvalidDecl(); 15495 } 15496 } 15497 15498 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15499 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15500 for (Decl *D : DeclReductions.get()) { 15501 if (IsValid) { 15502 if (S) 15503 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15504 /*AddToContext=*/false); 15505 } else { 15506 D->setInvalidDecl(); 15507 } 15508 } 15509 return DeclReductions; 15510 } 15511 15512 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15513 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15514 QualType T = TInfo->getType(); 15515 if (D.isInvalidType()) 15516 return true; 15517 15518 if (getLangOpts().CPlusPlus) { 15519 // Check that there are no default arguments (C++ only). 15520 CheckExtraCXXDefaultArguments(D); 15521 } 15522 15523 return CreateParsedType(T, TInfo); 15524 } 15525 15526 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15527 TypeResult ParsedType) { 15528 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15529 15530 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15531 assert(!MapperType.isNull() && "Expect valid mapper type"); 15532 15533 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15534 // The type must be of struct, union or class type in C and C++ 15535 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15536 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15537 return QualType(); 15538 } 15539 return MapperType; 15540 } 15541 15542 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15543 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15544 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15545 Decl *PrevDeclInScope) { 15546 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15547 forRedeclarationInCurContext()); 15548 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15549 // A mapper-identifier may not be redeclared in the current scope for the 15550 // same type or for a type that is compatible according to the base language 15551 // rules. 15552 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15553 OMPDeclareMapperDecl *PrevDMD = nullptr; 15554 bool InCompoundScope = true; 15555 if (S != nullptr) { 15556 // Find previous declaration with the same name not referenced in other 15557 // declarations. 15558 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15559 InCompoundScope = 15560 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15561 LookupName(Lookup, S); 15562 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15563 /*AllowInlineNamespace=*/false); 15564 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15565 LookupResult::Filter Filter = Lookup.makeFilter(); 15566 while (Filter.hasNext()) { 15567 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15568 if (InCompoundScope) { 15569 auto I = UsedAsPrevious.find(PrevDecl); 15570 if (I == UsedAsPrevious.end()) 15571 UsedAsPrevious[PrevDecl] = false; 15572 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15573 UsedAsPrevious[D] = true; 15574 } 15575 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15576 PrevDecl->getLocation(); 15577 } 15578 Filter.done(); 15579 if (InCompoundScope) { 15580 for (const auto &PrevData : UsedAsPrevious) { 15581 if (!PrevData.second) { 15582 PrevDMD = PrevData.first; 15583 break; 15584 } 15585 } 15586 } 15587 } else if (PrevDeclInScope) { 15588 auto *PrevDMDInScope = PrevDMD = 15589 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15590 do { 15591 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15592 PrevDMDInScope->getLocation(); 15593 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15594 } while (PrevDMDInScope != nullptr); 15595 } 15596 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15597 bool Invalid = false; 15598 if (I != PreviousRedeclTypes.end()) { 15599 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15600 << MapperType << Name; 15601 Diag(I->second, diag::note_previous_definition); 15602 Invalid = true; 15603 } 15604 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15605 MapperType, VN, PrevDMD); 15606 DC->addDecl(DMD); 15607 DMD->setAccess(AS); 15608 if (Invalid) 15609 DMD->setInvalidDecl(); 15610 15611 // Enter new function scope. 15612 PushFunctionScope(); 15613 setFunctionHasBranchProtectedScope(); 15614 15615 CurContext = DMD; 15616 15617 return DMD; 15618 } 15619 15620 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15621 Scope *S, 15622 QualType MapperType, 15623 SourceLocation StartLoc, 15624 DeclarationName VN) { 15625 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15626 if (S) 15627 PushOnScopeChains(VD, S); 15628 else 15629 DMD->addDecl(VD); 15630 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15631 DMD->setMapperVarRef(MapperVarRefExpr); 15632 } 15633 15634 Sema::DeclGroupPtrTy 15635 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15636 ArrayRef<OMPClause *> ClauseList) { 15637 PopDeclContext(); 15638 PopFunctionScopeInfo(); 15639 15640 if (D) { 15641 if (S) 15642 PushOnScopeChains(D, S, /*AddToContext=*/false); 15643 D->CreateClauses(Context, ClauseList); 15644 } 15645 15646 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15647 } 15648 15649 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15650 SourceLocation StartLoc, 15651 SourceLocation LParenLoc, 15652 SourceLocation EndLoc) { 15653 Expr *ValExpr = NumTeams; 15654 Stmt *HelperValStmt = nullptr; 15655 15656 // OpenMP [teams Constrcut, Restrictions] 15657 // The num_teams expression must evaluate to a positive integer value. 15658 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15659 /*StrictlyPositive=*/true)) 15660 return nullptr; 15661 15662 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15663 OpenMPDirectiveKind CaptureRegion = 15664 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15665 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15666 ValExpr = MakeFullExpr(ValExpr).get(); 15667 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15668 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15669 HelperValStmt = buildPreInits(Context, Captures); 15670 } 15671 15672 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15673 StartLoc, LParenLoc, EndLoc); 15674 } 15675 15676 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15677 SourceLocation StartLoc, 15678 SourceLocation LParenLoc, 15679 SourceLocation EndLoc) { 15680 Expr *ValExpr = ThreadLimit; 15681 Stmt *HelperValStmt = nullptr; 15682 15683 // OpenMP [teams Constrcut, Restrictions] 15684 // The thread_limit expression must evaluate to a positive integer value. 15685 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15686 /*StrictlyPositive=*/true)) 15687 return nullptr; 15688 15689 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15690 OpenMPDirectiveKind CaptureRegion = 15691 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15692 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15693 ValExpr = MakeFullExpr(ValExpr).get(); 15694 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15695 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15696 HelperValStmt = buildPreInits(Context, Captures); 15697 } 15698 15699 return new (Context) OMPThreadLimitClause( 15700 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15701 } 15702 15703 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15704 SourceLocation StartLoc, 15705 SourceLocation LParenLoc, 15706 SourceLocation EndLoc) { 15707 Expr *ValExpr = Priority; 15708 15709 // OpenMP [2.9.1, task Constrcut] 15710 // The priority-value is a non-negative numerical scalar expression. 15711 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 15712 /*StrictlyPositive=*/false)) 15713 return nullptr; 15714 15715 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15716 } 15717 15718 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 15719 SourceLocation StartLoc, 15720 SourceLocation LParenLoc, 15721 SourceLocation EndLoc) { 15722 Expr *ValExpr = Grainsize; 15723 15724 // OpenMP [2.9.2, taskloop Constrcut] 15725 // The parameter of the grainsize clause must be a positive integer 15726 // expression. 15727 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 15728 /*StrictlyPositive=*/true)) 15729 return nullptr; 15730 15731 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15732 } 15733 15734 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 15735 SourceLocation StartLoc, 15736 SourceLocation LParenLoc, 15737 SourceLocation EndLoc) { 15738 Expr *ValExpr = NumTasks; 15739 15740 // OpenMP [2.9.2, taskloop Constrcut] 15741 // The parameter of the num_tasks clause must be a positive integer 15742 // expression. 15743 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 15744 /*StrictlyPositive=*/true)) 15745 return nullptr; 15746 15747 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 15748 } 15749 15750 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 15751 SourceLocation LParenLoc, 15752 SourceLocation EndLoc) { 15753 // OpenMP [2.13.2, critical construct, Description] 15754 // ... where hint-expression is an integer constant expression that evaluates 15755 // to a valid lock hint. 15756 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 15757 if (HintExpr.isInvalid()) 15758 return nullptr; 15759 return new (Context) 15760 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 15761 } 15762 15763 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 15764 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 15765 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 15766 SourceLocation EndLoc) { 15767 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 15768 std::string Values; 15769 Values += "'"; 15770 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 15771 Values += "'"; 15772 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 15773 << Values << getOpenMPClauseName(OMPC_dist_schedule); 15774 return nullptr; 15775 } 15776 Expr *ValExpr = ChunkSize; 15777 Stmt *HelperValStmt = nullptr; 15778 if (ChunkSize) { 15779 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 15780 !ChunkSize->isInstantiationDependent() && 15781 !ChunkSize->containsUnexpandedParameterPack()) { 15782 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 15783 ExprResult Val = 15784 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 15785 if (Val.isInvalid()) 15786 return nullptr; 15787 15788 ValExpr = Val.get(); 15789 15790 // OpenMP [2.7.1, Restrictions] 15791 // chunk_size must be a loop invariant integer expression with a positive 15792 // value. 15793 llvm::APSInt Result; 15794 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 15795 if (Result.isSigned() && !Result.isStrictlyPositive()) { 15796 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 15797 << "dist_schedule" << ChunkSize->getSourceRange(); 15798 return nullptr; 15799 } 15800 } else if (getOpenMPCaptureRegionForClause( 15801 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 15802 OMPD_unknown && 15803 !CurContext->isDependentContext()) { 15804 ValExpr = MakeFullExpr(ValExpr).get(); 15805 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15806 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15807 HelperValStmt = buildPreInits(Context, Captures); 15808 } 15809 } 15810 } 15811 15812 return new (Context) 15813 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 15814 Kind, ValExpr, HelperValStmt); 15815 } 15816 15817 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 15818 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 15819 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 15820 SourceLocation KindLoc, SourceLocation EndLoc) { 15821 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 15822 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 15823 std::string Value; 15824 SourceLocation Loc; 15825 Value += "'"; 15826 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 15827 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15828 OMPC_DEFAULTMAP_MODIFIER_tofrom); 15829 Loc = MLoc; 15830 } else { 15831 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 15832 OMPC_DEFAULTMAP_scalar); 15833 Loc = KindLoc; 15834 } 15835 Value += "'"; 15836 Diag(Loc, diag::err_omp_unexpected_clause_value) 15837 << Value << getOpenMPClauseName(OMPC_defaultmap); 15838 return nullptr; 15839 } 15840 DSAStack->setDefaultDMAToFromScalar(StartLoc); 15841 15842 return new (Context) 15843 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 15844 } 15845 15846 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 15847 DeclContext *CurLexicalContext = getCurLexicalContext(); 15848 if (!CurLexicalContext->isFileContext() && 15849 !CurLexicalContext->isExternCContext() && 15850 !CurLexicalContext->isExternCXXContext() && 15851 !isa<CXXRecordDecl>(CurLexicalContext) && 15852 !isa<ClassTemplateDecl>(CurLexicalContext) && 15853 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 15854 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 15855 Diag(Loc, diag::err_omp_region_not_file_context); 15856 return false; 15857 } 15858 ++DeclareTargetNestingLevel; 15859 return true; 15860 } 15861 15862 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 15863 assert(DeclareTargetNestingLevel > 0 && 15864 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 15865 --DeclareTargetNestingLevel; 15866 } 15867 15868 NamedDecl * 15869 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 15870 const DeclarationNameInfo &Id, 15871 NamedDeclSetType &SameDirectiveDecls) { 15872 LookupResult Lookup(*this, Id, LookupOrdinaryName); 15873 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 15874 15875 if (Lookup.isAmbiguous()) 15876 return nullptr; 15877 Lookup.suppressDiagnostics(); 15878 15879 if (!Lookup.isSingleResult()) { 15880 VarOrFuncDeclFilterCCC CCC(*this); 15881 if (TypoCorrection Corrected = 15882 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 15883 CTK_ErrorRecovery)) { 15884 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 15885 << Id.getName()); 15886 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 15887 return nullptr; 15888 } 15889 15890 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 15891 return nullptr; 15892 } 15893 15894 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 15895 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 15896 !isa<FunctionTemplateDecl>(ND)) { 15897 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 15898 return nullptr; 15899 } 15900 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 15901 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 15902 return ND; 15903 } 15904 15905 void Sema::ActOnOpenMPDeclareTargetName( 15906 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 15907 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 15908 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 15909 isa<FunctionTemplateDecl>(ND)) && 15910 "Expected variable, function or function template."); 15911 15912 // Diagnose marking after use as it may lead to incorrect diagnosis and 15913 // codegen. 15914 if (LangOpts.OpenMP >= 50 && 15915 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 15916 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 15917 15918 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 15919 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 15920 if (DevTy.hasValue() && *DevTy != DT) { 15921 Diag(Loc, diag::err_omp_device_type_mismatch) 15922 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 15923 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 15924 return; 15925 } 15926 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 15927 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 15928 if (!Res) { 15929 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 15930 SourceRange(Loc, Loc)); 15931 ND->addAttr(A); 15932 if (ASTMutationListener *ML = Context.getASTMutationListener()) 15933 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 15934 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 15935 } else if (*Res != MT) { 15936 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 15937 } 15938 } 15939 15940 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 15941 Sema &SemaRef, Decl *D) { 15942 if (!D || !isa<VarDecl>(D)) 15943 return; 15944 auto *VD = cast<VarDecl>(D); 15945 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15946 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15947 if (SemaRef.LangOpts.OpenMP >= 50 && 15948 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 15949 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 15950 VD->hasGlobalStorage()) { 15951 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 15952 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 15953 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 15954 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 15955 // If a lambda declaration and definition appears between a 15956 // declare target directive and the matching end declare target 15957 // directive, all variables that are captured by the lambda 15958 // expression must also appear in a to clause. 15959 SemaRef.Diag(VD->getLocation(), 15960 diag::err_omp_lambda_capture_in_declare_target_not_to); 15961 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 15962 << VD << 0 << SR; 15963 return; 15964 } 15965 } 15966 if (MapTy.hasValue()) 15967 return; 15968 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 15969 SemaRef.Diag(SL, diag::note_used_here) << SR; 15970 } 15971 15972 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 15973 Sema &SemaRef, DSAStackTy *Stack, 15974 ValueDecl *VD) { 15975 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 15976 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 15977 /*FullCheck=*/false); 15978 } 15979 15980 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 15981 SourceLocation IdLoc) { 15982 if (!D || D->isInvalidDecl()) 15983 return; 15984 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 15985 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 15986 if (auto *VD = dyn_cast<VarDecl>(D)) { 15987 // Only global variables can be marked as declare target. 15988 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 15989 !VD->isStaticDataMember()) 15990 return; 15991 // 2.10.6: threadprivate variable cannot appear in a declare target 15992 // directive. 15993 if (DSAStack->isThreadPrivate(VD)) { 15994 Diag(SL, diag::err_omp_threadprivate_in_target); 15995 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 15996 return; 15997 } 15998 } 15999 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16000 D = FTD->getTemplatedDecl(); 16001 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16002 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16003 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16004 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16005 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16006 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16007 return; 16008 } 16009 // Mark the function as must be emitted for the device. 16010 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16011 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16012 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16013 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16014 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16015 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16016 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16017 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16018 } 16019 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16020 // Problem if any with var declared with incomplete type will be reported 16021 // as normal, so no need to check it here. 16022 if ((E || !VD->getType()->isIncompleteType()) && 16023 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16024 return; 16025 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16026 // Checking declaration inside declare target region. 16027 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16028 isa<FunctionTemplateDecl>(D)) { 16029 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16030 Context, OMPDeclareTargetDeclAttr::MT_To, 16031 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16032 D->addAttr(A); 16033 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16034 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16035 } 16036 return; 16037 } 16038 } 16039 if (!E) 16040 return; 16041 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16042 } 16043 16044 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16045 CXXScopeSpec &MapperIdScopeSpec, 16046 DeclarationNameInfo &MapperId, 16047 const OMPVarListLocTy &Locs, 16048 ArrayRef<Expr *> UnresolvedMappers) { 16049 MappableVarListInfo MVLI(VarList); 16050 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16051 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16052 if (MVLI.ProcessedVarList.empty()) 16053 return nullptr; 16054 16055 return OMPToClause::Create( 16056 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16057 MVLI.VarComponents, MVLI.UDMapperList, 16058 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16059 } 16060 16061 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16062 CXXScopeSpec &MapperIdScopeSpec, 16063 DeclarationNameInfo &MapperId, 16064 const OMPVarListLocTy &Locs, 16065 ArrayRef<Expr *> UnresolvedMappers) { 16066 MappableVarListInfo MVLI(VarList); 16067 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16068 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16069 if (MVLI.ProcessedVarList.empty()) 16070 return nullptr; 16071 16072 return OMPFromClause::Create( 16073 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16074 MVLI.VarComponents, MVLI.UDMapperList, 16075 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16076 } 16077 16078 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16079 const OMPVarListLocTy &Locs) { 16080 MappableVarListInfo MVLI(VarList); 16081 SmallVector<Expr *, 8> PrivateCopies; 16082 SmallVector<Expr *, 8> Inits; 16083 16084 for (Expr *RefExpr : VarList) { 16085 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16086 SourceLocation ELoc; 16087 SourceRange ERange; 16088 Expr *SimpleRefExpr = RefExpr; 16089 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16090 if (Res.second) { 16091 // It will be analyzed later. 16092 MVLI.ProcessedVarList.push_back(RefExpr); 16093 PrivateCopies.push_back(nullptr); 16094 Inits.push_back(nullptr); 16095 } 16096 ValueDecl *D = Res.first; 16097 if (!D) 16098 continue; 16099 16100 QualType Type = D->getType(); 16101 Type = Type.getNonReferenceType().getUnqualifiedType(); 16102 16103 auto *VD = dyn_cast<VarDecl>(D); 16104 16105 // Item should be a pointer or reference to pointer. 16106 if (!Type->isPointerType()) { 16107 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16108 << 0 << RefExpr->getSourceRange(); 16109 continue; 16110 } 16111 16112 // Build the private variable and the expression that refers to it. 16113 auto VDPrivate = 16114 buildVarDecl(*this, ELoc, Type, D->getName(), 16115 D->hasAttrs() ? &D->getAttrs() : nullptr, 16116 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16117 if (VDPrivate->isInvalidDecl()) 16118 continue; 16119 16120 CurContext->addDecl(VDPrivate); 16121 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16122 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16123 16124 // Add temporary variable to initialize the private copy of the pointer. 16125 VarDecl *VDInit = 16126 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16127 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16128 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16129 AddInitializerToDecl(VDPrivate, 16130 DefaultLvalueConversion(VDInitRefExpr).get(), 16131 /*DirectInit=*/false); 16132 16133 // If required, build a capture to implement the privatization initialized 16134 // with the current list item value. 16135 DeclRefExpr *Ref = nullptr; 16136 if (!VD) 16137 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16138 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16139 PrivateCopies.push_back(VDPrivateRefExpr); 16140 Inits.push_back(VDInitRefExpr); 16141 16142 // We need to add a data sharing attribute for this variable to make sure it 16143 // is correctly captured. A variable that shows up in a use_device_ptr has 16144 // similar properties of a first private variable. 16145 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16146 16147 // Create a mappable component for the list item. List items in this clause 16148 // only need a component. 16149 MVLI.VarBaseDeclarations.push_back(D); 16150 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16151 MVLI.VarComponents.back().push_back( 16152 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16153 } 16154 16155 if (MVLI.ProcessedVarList.empty()) 16156 return nullptr; 16157 16158 return OMPUseDevicePtrClause::Create( 16159 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16160 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16161 } 16162 16163 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16164 const OMPVarListLocTy &Locs) { 16165 MappableVarListInfo MVLI(VarList); 16166 for (Expr *RefExpr : VarList) { 16167 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16168 SourceLocation ELoc; 16169 SourceRange ERange; 16170 Expr *SimpleRefExpr = RefExpr; 16171 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16172 if (Res.second) { 16173 // It will be analyzed later. 16174 MVLI.ProcessedVarList.push_back(RefExpr); 16175 } 16176 ValueDecl *D = Res.first; 16177 if (!D) 16178 continue; 16179 16180 QualType Type = D->getType(); 16181 // item should be a pointer or array or reference to pointer or array 16182 if (!Type.getNonReferenceType()->isPointerType() && 16183 !Type.getNonReferenceType()->isArrayType()) { 16184 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16185 << 0 << RefExpr->getSourceRange(); 16186 continue; 16187 } 16188 16189 // Check if the declaration in the clause does not show up in any data 16190 // sharing attribute. 16191 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16192 if (isOpenMPPrivate(DVar.CKind)) { 16193 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16194 << getOpenMPClauseName(DVar.CKind) 16195 << getOpenMPClauseName(OMPC_is_device_ptr) 16196 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16197 reportOriginalDsa(*this, DSAStack, D, DVar); 16198 continue; 16199 } 16200 16201 const Expr *ConflictExpr; 16202 if (DSAStack->checkMappableExprComponentListsForDecl( 16203 D, /*CurrentRegionOnly=*/true, 16204 [&ConflictExpr]( 16205 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16206 OpenMPClauseKind) -> bool { 16207 ConflictExpr = R.front().getAssociatedExpression(); 16208 return true; 16209 })) { 16210 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16211 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16212 << ConflictExpr->getSourceRange(); 16213 continue; 16214 } 16215 16216 // Store the components in the stack so that they can be used to check 16217 // against other clauses later on. 16218 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16219 DSAStack->addMappableExpressionComponents( 16220 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16221 16222 // Record the expression we've just processed. 16223 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16224 16225 // Create a mappable component for the list item. List items in this clause 16226 // only need a component. We use a null declaration to signal fields in 16227 // 'this'. 16228 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16229 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16230 "Unexpected device pointer expression!"); 16231 MVLI.VarBaseDeclarations.push_back( 16232 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16233 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16234 MVLI.VarComponents.back().push_back(MC); 16235 } 16236 16237 if (MVLI.ProcessedVarList.empty()) 16238 return nullptr; 16239 16240 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16241 MVLI.VarBaseDeclarations, 16242 MVLI.VarComponents); 16243 } 16244 16245 OMPClause *Sema::ActOnOpenMPAllocateClause( 16246 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16247 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16248 if (Allocator) { 16249 // OpenMP [2.11.4 allocate Clause, Description] 16250 // allocator is an expression of omp_allocator_handle_t type. 16251 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16252 return nullptr; 16253 16254 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16255 if (AllocatorRes.isInvalid()) 16256 return nullptr; 16257 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16258 DSAStack->getOMPAllocatorHandleT(), 16259 Sema::AA_Initializing, 16260 /*AllowExplicit=*/true); 16261 if (AllocatorRes.isInvalid()) 16262 return nullptr; 16263 Allocator = AllocatorRes.get(); 16264 } else { 16265 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16266 // allocate clauses that appear on a target construct or on constructs in a 16267 // target region must specify an allocator expression unless a requires 16268 // directive with the dynamic_allocators clause is present in the same 16269 // compilation unit. 16270 if (LangOpts.OpenMPIsDevice && 16271 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16272 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16273 } 16274 // Analyze and build list of variables. 16275 SmallVector<Expr *, 8> Vars; 16276 for (Expr *RefExpr : VarList) { 16277 assert(RefExpr && "NULL expr in OpenMP private clause."); 16278 SourceLocation ELoc; 16279 SourceRange ERange; 16280 Expr *SimpleRefExpr = RefExpr; 16281 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16282 if (Res.second) { 16283 // It will be analyzed later. 16284 Vars.push_back(RefExpr); 16285 } 16286 ValueDecl *D = Res.first; 16287 if (!D) 16288 continue; 16289 16290 auto *VD = dyn_cast<VarDecl>(D); 16291 DeclRefExpr *Ref = nullptr; 16292 if (!VD && !CurContext->isDependentContext()) 16293 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16294 Vars.push_back((VD || CurContext->isDependentContext()) 16295 ? RefExpr->IgnoreParens() 16296 : Ref); 16297 } 16298 16299 if (Vars.empty()) 16300 return nullptr; 16301 16302 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16303 ColonLoc, EndLoc, Vars); 16304 } 16305